feat(ivy): record absolute position of template expressions (#31391)
Currently, template expressions and statements have their location recorded relative to the HTML element they are in, with no handle to absolute location in a source file except for a line/column location. However, the line/column location is also not entirely accurate, as it points an entire semantic expression, and not necessarily the start of an expression recorded by the expression parser. To support record of the source code expressions originate from, add a new `sourceSpan` field to `ASTWithSource` that records the absolute byte offset of an expression within a source code. Implement part 2 of [refactoring template parsing for stability](https://hackmd.io/@X3ECPVy-RCuVfba-pnvIpw/BkDUxaW84/%2FMA1oxh6jRXqSmZBcLfYdyw?type=book). PR Close #31391
This commit is contained in:
@ -434,7 +434,8 @@ describe('parser', () => {
|
||||
|
||||
it('should support custom interpolation', () => {
|
||||
const parser = new Parser(new Lexer());
|
||||
const ast = parser.parseInterpolation('{% a %}', null, {start: '{%', end: '%}'}) !.ast as any;
|
||||
const ast =
|
||||
parser.parseInterpolation('{% a %}', null, 0, {start: '{%', end: '%}'}) !.ast as any;
|
||||
expect(ast.strings).toEqual(['', '']);
|
||||
expect(ast.expressions.length).toEqual(1);
|
||||
expect(ast.expressions[0].name).toEqual('a');
|
||||
@ -492,7 +493,8 @@ describe('parser', () => {
|
||||
|
||||
describe('wrapLiteralPrimitive', () => {
|
||||
it('should wrap a literal primitive', () => {
|
||||
expect(unparse(validate(createParser().wrapLiteralPrimitive('foo', null)))).toEqual('"foo"');
|
||||
expect(unparse(validate(createParser().wrapLiteralPrimitive('foo', null, 0))))
|
||||
.toEqual('"foo"');
|
||||
});
|
||||
});
|
||||
|
||||
@ -528,33 +530,35 @@ function createParser() {
|
||||
return new Parser(new Lexer());
|
||||
}
|
||||
|
||||
function parseAction(text: string, location: any = null): ASTWithSource {
|
||||
return createParser().parseAction(text, location);
|
||||
function parseAction(text: string, location: any = null, offset: number = 0): ASTWithSource {
|
||||
return createParser().parseAction(text, location, offset);
|
||||
}
|
||||
|
||||
function parseBinding(text: string, location: any = null): ASTWithSource {
|
||||
return createParser().parseBinding(text, location);
|
||||
function parseBinding(text: string, location: any = null, offset: number = 0): ASTWithSource {
|
||||
return createParser().parseBinding(text, location, offset);
|
||||
}
|
||||
|
||||
function parseTemplateBindingsResult(
|
||||
key: string, value: string, location: any = null): TemplateBindingParseResult {
|
||||
return createParser().parseTemplateBindings(key, value, location);
|
||||
key: string, value: string, location: any = null,
|
||||
offset: number = 0): TemplateBindingParseResult {
|
||||
return createParser().parseTemplateBindings(key, value, location, offset);
|
||||
}
|
||||
function parseTemplateBindings(
|
||||
key: string, value: string, location: any = null): TemplateBinding[] {
|
||||
key: string, value: string, location: any = null, offset: number = 0): TemplateBinding[] {
|
||||
return parseTemplateBindingsResult(key, value, location).templateBindings;
|
||||
}
|
||||
|
||||
function parseInterpolation(text: string, location: any = null): ASTWithSource|null {
|
||||
return createParser().parseInterpolation(text, location);
|
||||
function parseInterpolation(text: string, location: any = null, offset: number = 0): ASTWithSource|
|
||||
null {
|
||||
return createParser().parseInterpolation(text, location, offset);
|
||||
}
|
||||
|
||||
function splitInterpolation(text: string, location: any = null): SplitInterpolation|null {
|
||||
return createParser().splitInterpolation(text, location);
|
||||
}
|
||||
|
||||
function parseSimpleBinding(text: string, location: any = null): ASTWithSource {
|
||||
return createParser().parseSimpleBinding(text, location);
|
||||
function parseSimpleBinding(text: string, location: any = null, offset: number = 0): ASTWithSource {
|
||||
return createParser().parseSimpleBinding(text, location, offset);
|
||||
}
|
||||
|
||||
function checkInterpolation(exp: string, expected?: string) {
|
||||
@ -595,4 +599,4 @@ function expectActionError(text: string, message: string) {
|
||||
|
||||
function expectBindingError(text: string, message: string) {
|
||||
expectError(validate(parseBinding(text)), message);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user