@@ -107,92 +107,120 @@ class SourceMetadataExtractor {
107
107
});
108
108
dirInfo.expressionAttrs = reprocessedAttrs;
109
109
directives.add (dirInfo);
110
-
111
110
});
112
111
112
+ directives.addAll (metadataVisitor.templates.map (
113
+ (tmpl) => new DirectiveInfo ()..template = tmpl));
114
+
113
115
return directives;
114
116
}
115
117
}
116
118
117
- class DirectiveMetadataCollectingVisitor {
118
- List <DirectiveMetadata > metadata = < DirectiveMetadata > [];
119
+ class DirectiveMetadataCollectingAstVisitor extends RecursiveAstVisitor {
120
+ final List <DirectiveMetadata > metadata;
121
+ final List <String > templates;
122
+
123
+ DirectiveMetadataCollectingAstVisitor (this .metadata, this .templates);
124
+
125
+ visitMethodInvocation (MethodInvocation node) {
126
+ if (node.methodName.name == 'ngRoute' ) {
127
+ NamedExpression viewHtmlExpression =
128
+ node.argumentList.arguments
129
+ .firstWhere ((e) => e is NamedExpression &&
130
+ e.name.label.name == 'viewHtml' , orElse: () => null );
131
+ if (viewHtmlExpression != null ) {
132
+ if (viewHtmlExpression.expression is ! StringLiteral ) {
133
+ throw 'viewHtml must be a string literal' ;
134
+ }
135
+ templates.add (
136
+ (viewHtmlExpression.expression as StringLiteral ).stringValue);
137
+ }
138
+ }
139
+ super .visitMethodInvocation (node);
140
+ }
119
141
120
- call (CompilationUnit cu) {
121
- cu.declarations.forEach ((CompilationUnitMember declaration) {
122
- // We only care about classes.
123
- if (declaration is ! ClassDeclaration ) return ;
124
- ClassDeclaration clazz = declaration;
125
- // Check class annotations for presense of NgComponent/NgDirective.
126
- DirectiveMetadata meta;
127
- clazz.metadata.forEach ((Annotation ann) {
128
- if (ann.arguments == null ) return ; // Ignore non-class annotations.
129
- // TODO(pavelj): this is not a safe check for the type of the
130
- // annotations, but good enough for now.
131
- if (ann.name.name != 'NgComponent'
132
- && ann.name.name != 'NgDirective' ) return ;
133
-
134
- bool isComponent = ann.name.name == 'NgComponent' ;
135
-
136
- meta = new DirectiveMetadata ()
137
- ..className = clazz.name.name
138
- ..type = isComponent ? COMPONENT : DIRECTIVE ;
139
- metadata.add (meta);
140
-
141
- ann.arguments.arguments.forEach ((Expression arg) {
142
- if (arg is NamedExpression ) {
143
- NamedExpression namedArg = arg;
144
- var paramName = namedArg.name.label.name;
145
- if (paramName == 'selector' ) {
146
- meta.selector = assertString (namedArg.expression).stringValue;
147
- }
148
- if (paramName == 'template' ) {
149
- meta.template = assertString (namedArg.expression).stringValue;
150
- }
151
- if (paramName == 'map' ) {
152
- MapLiteral map = namedArg.expression;
153
- map.entries.forEach ((MapLiteralEntry entry) {
154
- meta.attributeMappings[assertString (entry.key).stringValue] =
155
- assertString (entry.value).stringValue;
156
- });
157
- }
158
- if (paramName == 'exportExpressions' ) {
159
- meta.exportExpressions = getStringValues (namedArg.expression);
160
- }
161
- if (paramName == 'exportExpressionAttrs' ) {
162
- meta.exportExpressionAttrs = getStringValues (namedArg.expression);
163
- }
142
+ visitClassDeclaration (ClassDeclaration clazz) {
143
+ // Check class annotations for presense of NgComponent/NgDirective.
144
+ DirectiveMetadata meta;
145
+ clazz.metadata.forEach ((Annotation ann) {
146
+ if (ann.arguments == null ) return ; // Ignore non-class annotations.
147
+ // TODO(pavelj): this is not a safe check for the type of the
148
+ // annotations, but good enough for now.
149
+ if (ann.name.name != 'NgComponent'
150
+ && ann.name.name != 'NgDirective' ) return ;
151
+
152
+ bool isComponent = ann.name.name == 'NgComponent' ;
153
+
154
+ meta = new DirectiveMetadata ()
155
+ ..className = clazz.name.name
156
+ ..type = isComponent ? COMPONENT : DIRECTIVE ;
157
+ metadata.add (meta);
158
+
159
+ ann.arguments.arguments.forEach ((Expression arg) {
160
+ if (arg is NamedExpression ) {
161
+ NamedExpression namedArg = arg;
162
+ var paramName = namedArg.name.label.name;
163
+ if (paramName == 'selector' ) {
164
+ meta.selector = assertString (namedArg.expression).stringValue;
164
165
}
165
- });
166
- });
167
-
168
- // Check fields/getters/setter for presense of attr mapping annotations.
169
- if (meta != null ) {
170
- clazz.members.forEach ((ClassMember member) {
171
- if (member is FieldDeclaration ||
172
- (member is MethodDeclaration &&
173
- (member.isSetter || member.isGetter))) {
174
- member.metadata.forEach ((Annotation ann) {
175
- if (_attrAnnotationsToSpec.containsKey (ann.name.name)) {
176
- String fieldName;
177
- if (member is FieldDeclaration ) {
178
- fieldName = member.fields.variables.first.name.name;
179
- } else { // MethodDeclaration
180
- fieldName = (member as MethodDeclaration ).name.name;
181
- }
182
- StringLiteral attNameLiteral = ann.arguments.arguments.first;
183
- if (meta.attributeMappings
184
- .containsKey (attNameLiteral.stringValue)) {
185
- throw 'Attribute mapping already defined for '
186
- '${clazz .name }.$fieldName ' ;
187
- }
188
- meta.attributeMappings[attNameLiteral.stringValue] =
189
- _attrAnnotationsToSpec[ann.name.name] + fieldName;
190
- }
166
+ if (paramName == 'template' ) {
167
+ meta.template = assertString (namedArg.expression).stringValue;
168
+ }
169
+ if (paramName == 'map' ) {
170
+ MapLiteral map = namedArg.expression;
171
+ map.entries.forEach ((MapLiteralEntry entry) {
172
+ meta.attributeMappings[assertString (entry.key).stringValue] =
173
+ assertString (entry.value).stringValue;
191
174
});
192
175
}
193
- });
194
- }
176
+ if (paramName == 'exportExpressions' ) {
177
+ meta.exportExpressions = getStringValues (namedArg.expression);
178
+ }
179
+ if (paramName == 'exportExpressionAttrs' ) {
180
+ meta.exportExpressionAttrs = getStringValues (namedArg.expression);
181
+ }
182
+ }
183
+ });
195
184
});
185
+
186
+ // Check fields/getters/setter for presense of attr mapping annotations.
187
+ if (meta != null ) {
188
+ clazz.members.forEach ((ClassMember member) {
189
+ if (member is FieldDeclaration ||
190
+ (member is MethodDeclaration &&
191
+ (member.isSetter || member.isGetter))) {
192
+ member.metadata.forEach ((Annotation ann) {
193
+ if (_attrAnnotationsToSpec.containsKey (ann.name.name)) {
194
+ String fieldName;
195
+ if (member is FieldDeclaration ) {
196
+ fieldName = member.fields.variables.first.name.name;
197
+ } else { // MethodDeclaration
198
+ fieldName = (member as MethodDeclaration ).name.name;
199
+ }
200
+ StringLiteral attNameLiteral = ann.arguments.arguments.first;
201
+ if (meta.attributeMappings
202
+ .containsKey (attNameLiteral.stringValue)) {
203
+ throw 'Attribute mapping already defined for '
204
+ '${clazz .name }.$fieldName ' ;
205
+ }
206
+ meta.attributeMappings[attNameLiteral.stringValue] =
207
+ _attrAnnotationsToSpec[ann.name.name] + fieldName;
208
+ }
209
+ });
210
+ }
211
+ });
212
+ }
213
+
214
+ return super .visitClassDeclaration (clazz);
215
+ }
216
+ }
217
+
218
+ class DirectiveMetadataCollectingVisitor {
219
+ List <DirectiveMetadata > metadata = < DirectiveMetadata > [];
220
+ List <String > templates = < String > [];
221
+
222
+ call (CompilationUnit cu) {
223
+ cu.accept (new DirectiveMetadataCollectingAstVisitor (metadata, templates));
196
224
}
197
225
}
198
226
0 commit comments