Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: third_party/pkg/angular/lib/tools/source_metadata_extractor.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 library angular.source_metadata_extractor ; 1 library angular.source_metadata_extractor ;
2 2
3 import 'package:analyzer/src/generated/ast.dart'; 3 import 'package:analyzer/src/generated/ast.dart';
4 import 'package:analyzer/src/generated/element.dart';
4 5
5 import 'package:angular/tools/source_crawler.dart'; 6 import 'package:angular/tools/source_crawler.dart';
6 import 'package:angular/tools/common.dart'; 7 import 'package:angular/tools/common.dart';
7 8
8 const String _COMPONENT = '-component'; 9 const String _COMPONENT = '-component';
9 const String _DIRECTIVE = '-directive'; 10 const String _DIRECTIVE = '-directive';
10 String _ATTR_DIRECTIVE = '-attr' + _DIRECTIVE; 11 String _ATTR_DIRECTIVE = '-attr' + _DIRECTIVE;
11 RegExp _ATTR_SELECTOR_REGEXP = new RegExp(r'\[([^\]]+)\]'); 12 RegExp _ATTR_SELECTOR_REGEXP = new RegExp(r'\[([^\]]+)\]');
12 const List<String> _specs = const ['=>!', '=>', '<=>', '@', '&']; 13 const List<String> _specs = const ['=>!', '=>', '<=>', '@', '&'];
13 const Map<String, String> _attrAnnotationsToSpec = const { 14 const Map<String, String> _attrAnnotationsToSpec = const {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 substring(0, className.length - _DIRECTIVE.length); 92 substring(0, className.length - _DIRECTIVE.length);
92 } else { 93 } else {
93 throw "Directive name '$className' must have a \$selector field."; 94 throw "Directive name '$className' must have a \$selector field.";
94 } 95 }
95 } 96 }
96 } 97 }
97 var reprocessedAttrs = <String>[]; 98 var reprocessedAttrs = <String>[];
98 dirInfo.expressionAttrs.forEach((String attr) { 99 dirInfo.expressionAttrs.forEach((String attr) {
99 if (attr == '.') { 100 if (attr == '.') {
100 var matches = _ATTR_SELECTOR_REGEXP.allMatches(dirInfo.selector); 101 var matches = _ATTR_SELECTOR_REGEXP.allMatches(dirInfo.selector);
101 if (matches.length > 0) { 102 if (matches.isNotEmpty) {
102 reprocessedAttrs.add(matches.last.group(1)); 103 reprocessedAttrs.add(matches.last.group(1));
103 } 104 }
104 } else { 105 } else {
105 reprocessedAttrs.add(attr); 106 reprocessedAttrs.add(attr);
106 } 107 }
107 }); 108 });
108 dirInfo.expressionAttrs = reprocessedAttrs; 109 dirInfo.expressionAttrs = reprocessedAttrs;
109 directives.add(dirInfo); 110 directives.add(dirInfo);
111 });
110 112
111 }); 113 directives.addAll(metadataVisitor.templates.map(
114 (tmpl) => new DirectiveInfo()..template = tmpl));
112 115
113 return directives; 116 return directives;
114 } 117 }
115 } 118 }
116 119
117 class DirectiveMetadataCollectingVisitor { 120 class DirectiveMetadataCollectingAstVisitor extends RecursiveAstVisitor {
118 List<DirectiveMetadata> metadata = <DirectiveMetadata>[]; 121 final List<DirectiveMetadata> metadata;
122 final List<String> templates;
119 123
120 call(CompilationUnit cu) { 124 DirectiveMetadataCollectingAstVisitor(this.metadata, this.templates);
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 125
134 bool isComponent = ann.name.name == 'NgComponent'; 126 visitMethodInvocation(MethodInvocation node) {
127 if (node.methodName.name == 'ngRoute') {
128 NamedExpression viewHtmlExpression =
129 node.argumentList.arguments
130 .firstWhere((e) => e is NamedExpression &&
131 e.name.label.name == 'viewHtml', orElse: () => null);
132 if (viewHtmlExpression != null) {
133 if (viewHtmlExpression.expression is! StringLiteral) {
134 throw 'viewHtml must be a string literal';
135 }
136 templates.add(
137 (viewHtmlExpression.expression as StringLiteral).stringValue);
138 }
139 }
140 super.visitMethodInvocation(node);
141 }
135 142
136 meta = new DirectiveMetadata() 143 visitClassDeclaration(ClassDeclaration clazz) {
137 ..className = clazz.name.name 144 // Check class annotations for presense of Component/Decorator.
138 ..type = isComponent ? COMPONENT : DIRECTIVE; 145 clazz.metadata.forEach((Annotation ann) {
139 metadata.add(meta); 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 != 'Component'
150 && ann.name.name != 'Decorator') return;
140 151
141 ann.arguments.arguments.forEach((Expression arg) { 152 bool isComponent = ann.name.name == 'Component';
142 if (arg is NamedExpression) { 153
143 NamedExpression namedArg = arg; 154 var meta = new DirectiveMetadata()
144 var paramName = namedArg.name.label.name; 155 ..className = clazz.name.name
145 if (paramName == 'selector') { 156 ..type = isComponent ? COMPONENT : DIRECTIVE;
146 meta.selector = assertString(namedArg.expression).stringValue; 157 metadata.add(meta);
147 } 158
148 if (paramName == 'template') { 159 ann.arguments.arguments.forEach((Expression arg) {
149 meta.template = assertString(namedArg.expression).stringValue; 160 if (arg is NamedExpression) {
150 } 161 NamedExpression namedArg = arg;
151 if (paramName == 'map') { 162 var paramName = namedArg.name.label.name;
152 MapLiteral map = namedArg.expression; 163 if (paramName == 'selector') {
153 map.entries.forEach((MapLiteralEntry entry) { 164 meta.selector = assertString(namedArg.expression).stringValue;
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 }
164 } 165 }
165 }); 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;
174 });
175 }
176 if (paramName == 'exportExpressions') {
177 meta.exportExpressions = getStringValues(namedArg.expression);
178 }
179 if (paramName == 'exportExpressionAttrs') {
180 meta.exportExpressionAttrs = getStringValues(namedArg.expression);
181 }
182 }
166 }); 183 });
167 184
168 // Check fields/getters/setter for presense of attr mapping annotations. 185 if (meta != null) _walkSuperclassChain(clazz, meta, _extractMappingsFromCl ass);
169 if (meta != null) { 186 });
170 clazz.members.forEach((ClassMember member) { 187
171 if (member is FieldDeclaration || 188 return super.visitClassDeclaration(clazz);
172 (member is MethodDeclaration && 189 }
173 (member.isSetter || member.isGetter))) { 190
174 member.metadata.forEach((Annotation ann) { 191 _walkSuperclassChain(ClassDeclaration clazz, DirectiveMetadata meta,
175 if (_attrAnnotationsToSpec.containsKey(ann.name.name)) { 192 metadataExtractor(ClassDeclaration clazz, DirectiveMetada ta meta)) {
176 String fieldName; 193 while (clazz != null) {
177 if (member is FieldDeclaration) { 194 metadataExtractor(clazz, meta);
178 fieldName = member.fields.variables.first.name.name; 195 if (clazz.element != null && clazz.element.supertype != null) {
179 } else { // MethodDeclaration 196 clazz = clazz.element.supertype.element.node;
180 fieldName = (member as MethodDeclaration).name.name; 197 } else {
181 } 198 clazz = null;
182 StringLiteral attNameLiteral = ann.arguments.arguments.first; 199 }
183 if (meta.attributeMappings 200 }
184 .containsKey(attNameLiteral.stringValue)) { 201 }
185 throw 'Attribute mapping already defined for $fieldName'; 202
186 } 203 _extractMappingsFromClass(ClassDeclaration clazz, DirectiveMetadata meta) {
187 meta.attributeMappings[attNameLiteral.stringValue] = 204 // Check fields/getters/setter for presence of attr mapping annotations.
188 _attrAnnotationsToSpec[ann.name.name] + fieldName; 205 clazz.members.forEach((ClassMember member) {
189 } 206 if (member is FieldDeclaration ||
190 }); 207 (member is MethodDeclaration &&
208 (member.isSetter || member.isGetter))) {
209 member.metadata.forEach((Annotation ann) {
210 if (_attrAnnotationsToSpec.containsKey(ann.name.name)) {
211 String fieldName;
212 if (member is FieldDeclaration) {
213 fieldName = member.fields.variables.first.name.name;
214 } else { // MethodDeclaration
215 fieldName = (member as MethodDeclaration).name.name;
216 }
217 StringLiteral attNameLiteral = ann.arguments.arguments.first;
218 if (meta.attributeMappings
219 .containsKey(attNameLiteral.stringValue)) {
220 throw 'Attribute mapping already defined for '
221 '${clazz.name}.$fieldName';
222 }
223 meta.attributeMappings[attNameLiteral.stringValue] =
224 _attrAnnotationsToSpec[ann.name.name] + fieldName;
191 } 225 }
192 }); 226 });
193 } 227 }
194 }); 228 });
195 } 229 }
196 } 230 }
197 231
232 class DirectiveMetadataCollectingVisitor {
233 List<DirectiveMetadata> metadata = <DirectiveMetadata>[];
234 List<String> templates = <String>[];
235
236 call(CompilationUnit cu) {
237 cu.accept(new DirectiveMetadataCollectingAstVisitor(metadata, templates));
238 }
239 }
240
198 List<String> getStringValues(ListLiteral listLiteral) { 241 List<String> getStringValues(ListLiteral listLiteral) {
199 List<String> res = <String>[]; 242 List<String> res = <String>[];
200 for (Expression element in listLiteral.elements) { 243 for (Expression element in listLiteral.elements) {
201 res.add(assertString(element).stringValue); 244 res.add(assertString(element).stringValue);
202 } 245 }
203 return res; 246 return res;
204 } 247 }
205 248
206 StringLiteral assertString(Expression key) { 249 StringLiteral assertString(Expression key) {
207 if (key is! StringLiteral) { 250 if (key is! StringLiteral) {
208 throw 'must be a string literal: ${key.runtimeType}'; 251 throw 'must be a string literal: ${key.runtimeType}';
209 } 252 }
210 return key; 253 return key;
211 } 254 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698