Skip to content

Commit 6aaca21

Browse files
ayazhafizjasonaden
authored andcommittedJul 8, 2019
fix(compiler): give ASTWithSource its own visit method (#31347)
ASTWithSource contains more information that AST and should have its own visit method, if desired. This implements that. PR Close #31347
1 parent 50c4ec6 commit 6aaca21

File tree

2 files changed

+88
-79
lines changed

2 files changed

+88
-79
lines changed
 

‎packages/compiler-cli/src/ngtsc/indexer/test/template_spec.ts

Lines changed: 81 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {AbsoluteSourceSpan, IdentifierKind} from '..';
10+
import {runInEachFileSystem} from '../../file_system/testing';
1011
import {getTemplateIdentifiers} from '../src/template';
1112
import * as util from './util';
1213

@@ -17,112 +18,114 @@ function bind(template: string) {
1718
});
1819
}
1920

20-
describe('getTemplateIdentifiers', () => {
21-
it('should generate nothing in HTML-only template', () => {
22-
const refs = getTemplateIdentifiers(bind('<div></div>'));
21+
runInEachFileSystem(() => {
22+
describe('getTemplateIdentifiers', () => {
23+
it('should generate nothing in HTML-only template', () => {
24+
const refs = getTemplateIdentifiers(bind('<div></div>'));
2325

24-
expect(refs.size).toBe(0);
25-
});
26-
27-
it('should ignore comments', () => {
28-
const refs = getTemplateIdentifiers(bind('<!-- {{comment}} -->'));
29-
30-
expect(refs.size).toBe(0);
31-
});
32-
33-
it('should handle arbitrary whitespace', () => {
34-
const template = '<div>\n\n {{foo}}</div>';
35-
const refs = getTemplateIdentifiers(bind(template));
36-
37-
const [ref] = Array.from(refs);
38-
expect(ref).toEqual({
39-
name: 'foo',
40-
kind: IdentifierKind.Property,
41-
span: new AbsoluteSourceSpan(12, 15),
26+
expect(refs.size).toBe(0);
4227
});
43-
});
4428

45-
it('should ignore identifiers defined in the template', () => {
46-
const template = `
47-
<input #model />
48-
{{model.valid}}
49-
`;
50-
const refs = getTemplateIdentifiers(bind(template));
29+
it('should ignore comments', () => {
30+
const refs = getTemplateIdentifiers(bind('<!-- {{comment}} -->'));
5131

52-
const refArr = Array.from(refs);
53-
const modelId = refArr.find(ref => ref.name === 'model');
54-
expect(modelId).toBeUndefined();
55-
});
32+
expect(refs.size).toBe(0);
33+
});
5634

57-
describe('generates identifiers for PropertyReads', () => {
58-
it('should discover component properties', () => {
59-
const template = '{{foo}}';
35+
it('should handle arbitrary whitespace', () => {
36+
const template = '<div>\n\n {{foo}}</div>';
6037
const refs = getTemplateIdentifiers(bind(template));
61-
expect(refs.size).toBe(1);
6238

6339
const [ref] = Array.from(refs);
6440
expect(ref).toEqual({
6541
name: 'foo',
6642
kind: IdentifierKind.Property,
67-
span: new AbsoluteSourceSpan(2, 5),
43+
span: new AbsoluteSourceSpan(12, 15),
6844
});
6945
});
7046

71-
it('should discover nested properties', () => {
72-
const template = '<div><span>{{foo}}</span></div>';
47+
it('should ignore identifiers defined in the template', () => {
48+
const template = `
49+
<input #model />
50+
{{model.valid}}
51+
`;
7352
const refs = getTemplateIdentifiers(bind(template));
7453

7554
const refArr = Array.from(refs);
76-
expect(refArr).toEqual(jasmine.arrayContaining([{
77-
name: 'foo',
78-
kind: IdentifierKind.Property,
79-
span: new AbsoluteSourceSpan(13, 16),
80-
}]));
55+
const modelId = refArr.find(ref => ref.name === 'model');
56+
expect(modelId).toBeUndefined();
8157
});
8258

83-
it('should ignore identifiers that are not implicitly received by the template', () => {
84-
const template = '{{foo.bar.baz}}';
85-
const refs = getTemplateIdentifiers(bind(template));
86-
expect(refs.size).toBe(1);
59+
describe('generates identifiers for PropertyReads', () => {
60+
it('should discover component properties', () => {
61+
const template = '{{foo}}';
62+
const refs = getTemplateIdentifiers(bind(template));
63+
expect(refs.size).toBe(1);
64+
65+
const [ref] = Array.from(refs);
66+
expect(ref).toEqual({
67+
name: 'foo',
68+
kind: IdentifierKind.Property,
69+
span: new AbsoluteSourceSpan(2, 5),
70+
});
71+
});
8772

88-
const [ref] = Array.from(refs);
89-
expect(ref.name).toBe('foo');
90-
});
91-
});
73+
it('should discover nested properties', () => {
74+
const template = '<div><span>{{foo}}</span></div>';
75+
const refs = getTemplateIdentifiers(bind(template));
9276

93-
describe('generates identifiers for MethodCalls', () => {
94-
it('should discover component method calls', () => {
95-
const template = '{{foo()}}';
96-
const refs = getTemplateIdentifiers(bind(template));
97-
expect(refs.size).toBe(1);
77+
const refArr = Array.from(refs);
78+
expect(refArr).toEqual(jasmine.arrayContaining([{
79+
name: 'foo',
80+
kind: IdentifierKind.Property,
81+
span: new AbsoluteSourceSpan(13, 16),
82+
}]));
83+
});
9884

99-
const [ref] = Array.from(refs);
100-
expect(ref).toEqual({
101-
name: 'foo',
102-
kind: IdentifierKind.Method,
103-
span: new AbsoluteSourceSpan(2, 5),
85+
it('should ignore identifiers that are not implicitly received by the template', () => {
86+
const template = '{{foo.bar.baz}}';
87+
const refs = getTemplateIdentifiers(bind(template));
88+
expect(refs.size).toBe(1);
89+
90+
const [ref] = Array.from(refs);
91+
expect(ref.name).toBe('foo');
10492
});
10593
});
10694

107-
it('should discover nested properties', () => {
108-
const template = '<div><span>{{foo()}}</span></div>';
109-
const refs = getTemplateIdentifiers(bind(template));
95+
describe('generates identifiers for MethodCalls', () => {
96+
it('should discover component method calls', () => {
97+
const template = '{{foo()}}';
98+
const refs = getTemplateIdentifiers(bind(template));
99+
expect(refs.size).toBe(1);
100+
101+
const [ref] = Array.from(refs);
102+
expect(ref).toEqual({
103+
name: 'foo',
104+
kind: IdentifierKind.Method,
105+
span: new AbsoluteSourceSpan(2, 5),
106+
});
107+
});
110108

111-
const refArr = Array.from(refs);
112-
expect(refArr).toEqual(jasmine.arrayContaining([{
113-
name: 'foo',
114-
kind: IdentifierKind.Method,
115-
span: new AbsoluteSourceSpan(13, 16),
116-
}]));
117-
});
109+
it('should discover nested properties', () => {
110+
const template = '<div><span>{{foo()}}</span></div>';
111+
const refs = getTemplateIdentifiers(bind(template));
118112

119-
it('should ignore identifiers that are not implicitly received by the template', () => {
120-
const template = '{{foo().bar().baz()}}';
121-
const refs = getTemplateIdentifiers(bind(template));
122-
expect(refs.size).toBe(1);
113+
const refArr = Array.from(refs);
114+
expect(refArr).toEqual(jasmine.arrayContaining([{
115+
name: 'foo',
116+
kind: IdentifierKind.Method,
117+
span: new AbsoluteSourceSpan(13, 16),
118+
}]));
119+
});
123120

124-
const [ref] = Array.from(refs);
125-
expect(ref.name).toBe('foo');
121+
it('should ignore identifiers that are not implicitly received by the template', () => {
122+
const template = '{{foo().bar().baz()}}';
123+
const refs = getTemplateIdentifiers(bind(template));
124+
expect(refs.size).toBe(1);
125+
126+
const [ref] = Array.from(refs);
127+
expect(ref.name).toBe('foo');
128+
});
126129
});
127130
});
128131
});

‎packages/compiler/src/expression_parser/ast.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,12 @@ export class ASTWithSource extends AST {
209209
public errors: ParserError[]) {
210210
super(new ParseSpan(0, source == null ? 0 : source.length));
211211
}
212-
visit(visitor: AstVisitor, context: any = null): any { return this.ast.visit(visitor, context); }
212+
visit(visitor: AstVisitor, context: any = null): any {
213+
if (visitor.visitASTWithSource) {
214+
return visitor.visitASTWithSource(this, context);
215+
}
216+
return this.ast.visit(visitor, context);
217+
}
213218
toString(): string { return `${this.source} in ${this.location}`; }
214219
}
215220

@@ -240,6 +245,7 @@ export interface AstVisitor {
240245
visitQuote(ast: Quote, context: any): any;
241246
visitSafeMethodCall(ast: SafeMethodCall, context: any): any;
242247
visitSafePropertyRead(ast: SafePropertyRead, context: any): any;
248+
visitASTWithSource?(ast: ASTWithSource, context: any): any;
243249
visit?(ast: AST, context?: any): any;
244250
}
245251

0 commit comments

Comments
 (0)
Please sign in to comment.