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

Side by Side Diff: third_party/pkg/di/lib/generator.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
« no previous file with comments | « third_party/pkg/di/lib/errors.dart ('k') | third_party/pkg/di/lib/injector.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 library di.generator; 1 library di.generator;
2 2
3 import 'package:analyzer/src/generated/java_io.dart'; 3 import 'package:analyzer/src/generated/java_io.dart';
4 import 'package:analyzer/src/generated/source_io.dart'; 4 import 'package:analyzer/src/generated/source_io.dart';
5 import 'package:analyzer/src/generated/ast.dart'; 5 import 'package:analyzer/src/generated/ast.dart';
6 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; 6 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
7 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk; 7 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/engine.dart'; 9 import 'package:analyzer/src/generated/engine.dart';
10 import 'package:path/path.dart' as path;
10 11
11 import 'dart:io'; 12 import 'dart:io';
12 13
13 const String PACKAGE_PREFIX = 'package:'; 14 const String PACKAGE_PREFIX = 'package:';
14 const String DART_PACKAGE_PREFIX = 'dart:'; 15 const String DART_PACKAGE_PREFIX = 'dart:';
16 const List<String> _DEFAULT_INJECTABLE_ANNOTATIONS =
17 const ['di.annotations.Injectable'];
15 18
16 main(args) { 19 main(List<String> args) {
17 if (args.length < 4) { 20 if (args.length < 4) {
18 print('Usage: generator path_to_sdk file_to_resolve annotations output [pack age_roots+]'); 21 print('Usage: generator path_to_sdk file_to_resolve annotations output [pack age_roots+]');
19 exit(0); 22 exit(0);
20 } 23 }
21 24
22 var pathToSdk = args[0]; 25 var pathToSdk = args[0];
23 var entryPoint = args[1]; 26 var entryPoint = args[1];
24 var classAnnotations = args[2].split(','); 27 var classAnnotations = args[2].split(',')
28 ..addAll(_DEFAULT_INJECTABLE_ANNOTATIONS);
25 var output = args[3]; 29 var output = args[3];
26 var packageRoots = (args.length < 5) ? [Platform.packageRoot] : args.sublist(4 ); 30 var packageRoots = (args.length < 5) ? [Platform.packageRoot] : args.sublist(4 );
27 31
28 print('pathToSdk: $pathToSdk'); 32 print('pathToSdk: $pathToSdk');
29 print('entryPoint: $entryPoint'); 33 print('entryPoint: $entryPoint');
30 print('classAnnotations: ${classAnnotations.join(', ')}'); 34 print('classAnnotations: ${classAnnotations.join(', ')}');
31 print('output: $output'); 35 print('output: $output');
32 print('packageRoots: $packageRoots'); 36 print('packageRoots: $packageRoots');
33 37
34 var code = generateCode(entryPoint, classAnnotations, pathToSdk, packageRoots) ; 38 var code = generateCode(entryPoint, classAnnotations, pathToSdk, packageRoots, output);
35 code.forEach((chunk, code) { 39 code.forEach((chunk, code) {
36 String fileName = output; 40 String fileName = output;
37 if (chunk.library != null) { 41 if (chunk.library != null) {
38 var lastDot = fileName.lastIndexOf('.'); 42 var lastDot = fileName.lastIndexOf('.');
39 fileName = fileName.substring(0, lastDot) + '-' + chunk.library.name + fil eName.substring(lastDot); 43 fileName = fileName.substring(0, lastDot) + '-' + chunk.library.name + fil eName.substring(lastDot);
40 } 44 }
41 new File(fileName).writeAsStringSync(code); 45 new File(fileName).writeAsStringSync(code);
42 }); 46 });
43 } 47 }
44 48
45 Map<Chunk, String> generateCode(String entryPoint, List<String> classAnnotations , 49 Map<Chunk, String> generateCode(String entryPoint, List<String> classAnnotations ,
46 String pathToSdk, List<String> packageRoots) { 50 String pathToSdk, List<String> packageRoots, String outputFilename) {
47 var c = new SourceCrawler(pathToSdk, packageRoots); 51 var c = new SourceCrawler(pathToSdk, packageRoots);
48 List<String> imports = <String>[]; 52 List<String> imports = <String>[];
49 Map<Chunk, List<ClassElement>> typeFactoryTypes = <Chunk, List<ClassElement>>{ }; 53 Map<Chunk, List<ClassElement>> typeFactoryTypes = <Chunk, List<ClassElement>>{ };
50 Map<String, String> typeToImport = new Map<String, String>(); 54 Map<String, String> typeToImport = new Map<String, String>();
51 c.crawl(entryPoint, (CompilationUnitElement compilationUnit, SourceFile source ) { 55 c.crawl(entryPoint, (CompilationUnitElement compilationUnit, SourceFile source ) {
52 new CompilationUnitVisitor(c.context, source, classAnnotations, imports, 56 new CompilationUnitVisitor(c.context, source, classAnnotations, imports,
53 typeToImport, typeFactoryTypes).visit(compilationUnit, source); 57 typeToImport, typeFactoryTypes, outputFilename).visit(compilationUnit, source);
54 }); 58 });
55 return printLibraryCode(typeToImport, imports, typeFactoryTypes); 59 return printLibraryCode(typeToImport, imports, typeFactoryTypes);
56 } 60 }
57 61
58 Map<Chunk, String> printLibraryCode(Map<String, String> typeToImport, 62 Map<Chunk, String> printLibraryCode(Map<String, String> typeToImport,
59 List<String> imports, Map<Chunk, List<ClassElement>> typeFactoryTypes) { 63 List<String> imports, Map<Chunk, List<ClassElement>> typeFactoryTypes) {
60 Map<Chunk, StringBuffer> factories = <Chunk, StringBuffer>{}; 64 Map<Chunk, StringBuffer> factories = <Chunk, StringBuffer>{};
61 Map<Chunk, String> result = <Chunk, String>{}; 65 Map<Chunk, String> result = <Chunk, String>{};
62 typeFactoryTypes.forEach((Chunk chunk, List<ClassElement> classes) { 66 typeFactoryTypes.forEach((Chunk chunk, List<ClassElement> classes) {
63 List<String> requiredImports = <String>[]; 67 List<String> requiredImports = <String>[];
64 String resolveClassIdentifier(InterfaceType type) { 68 String resolveClassIdentifier(InterfaceType type) {
65 if (type.element.library.isDartCore) { 69 if (type.element.library.isDartCore) {
66 return type.name; 70 return type.name;
67 } 71 }
68 String import = typeToImport[getCanonicalName(type)]; 72 String import = typeToImport[getCanonicalName(type)];
69 if (!requiredImports.contains(import)) { 73 if (!requiredImports.contains(import)) {
70 requiredImports.add(import); 74 requiredImports.add(import);
71 } 75 }
72 return 'import_${imports.indexOf(import)}.${type.name}'; 76 String prefix = _calculateImportPrefix(import, imports);
77 return '$prefix.${type.name}';
73 } 78 }
74 factories[chunk] = new StringBuffer(); 79 factories[chunk] = new StringBuffer();
75 classes.forEach((ClassElement clazz) { 80 classes.forEach((ClassElement clazz) {
76 StringBuffer factory = new StringBuffer(); 81 StringBuffer factory = new StringBuffer();
77 bool skip = false; 82 bool skip = false;
78 factory.write( 83 factory.write('${resolveClassIdentifier(clazz.type)}: (f) => ');
79 '${resolveClassIdentifier(clazz.type)}: (f) => ');
80 factory.write('new ${resolveClassIdentifier(clazz.type)}('); 84 factory.write('new ${resolveClassIdentifier(clazz.type)}(');
81 ConstructorElement constr = 85 ConstructorElement constr =
82 clazz.constructors.firstWhere((c) => c.name.isEmpty, 86 clazz.constructors.firstWhere((c) => c.name.isEmpty,
83 orElse: () { 87 orElse: () {
84 throw 'Unable to find default constructor for $clazz in ${clazz.sour ce}'; 88 throw 'Unable to find default constructor for '
89 '$clazz in ${clazz.source}';
85 }); 90 });
86 factory.write(constr.parameters.map((param) { 91 factory.write(constr.parameters.map((param) {
87 if (param.type.element is! ClassElement) { 92 if (param.type.element is! ClassElement) {
88 throw 'Unable to resolve type for constructor parameter ' 93 throw 'Unable to resolve type for constructor parameter '
89 '"${param.name}" for type "$clazz" in ${clazz.source}'; 94 '"${param.name}" for type "$clazz" in ${clazz.source}';
90 } 95 }
91 if (_isParameterized(param)) { 96 if (_isParameterized(param)) {
92 print('WARNING: parameterized types are not supported: $param in $claz z in ${clazz.source}. Skipping!'); 97 print('WARNING: parameterized types are not supported: '
98 '$param in $clazz in ${clazz.source}. Skipping!');
93 skip = true; 99 skip = true;
94 } 100 }
95 return 'f(${resolveClassIdentifier(param.type)})'; 101 var annotations = [];
102 if (param.metadata.isNotEmpty) {
103 annotations = param.metadata.map(
104 (item) => resolveClassIdentifier(item.element.returnType));
105 }
106 StringBuffer output =
107 new StringBuffer('f(${resolveClassIdentifier(param.type)}');
108 if (annotations.isNotEmpty) {
109 output.write(', ${annotations.first}');
110 }
111 output.write(')');
112 return output;
96 }).join(', ')); 113 }).join(', '));
97 factory.write('),\n'); 114 factory.write('),\n');
98 if (!skip) { 115 if (!skip) {
99 factories[chunk].write(factory); 116 factories[chunk].write(factory);
100 } 117 }
101 }); 118 });
102 StringBuffer code = new StringBuffer(); 119 StringBuffer code = new StringBuffer();
103 String libSuffix = chunk.library == null ? '' : '.${chunk.library.name}'; 120 String libSuffix = chunk.library == null ? '' : '.${chunk.library.name}';
104 code.write('library di.generated.type_factories$libSuffix;\n'); 121 code.write('library di.generated.type_factories$libSuffix;\n');
105 requiredImports.forEach((import) { 122 requiredImports.forEach((import) {
106 code.write ('import "$import" as import_${imports.indexOf(import)};\n'); 123 String prefix = _calculateImportPrefix(import, imports);
124 code.write ('import "$import" as $prefix;\n');
107 }); 125 });
108 code..write('var typeFactories = {\n${factories[chunk]}\n};\n') 126 code..write('var typeFactories = {\n${factories[chunk]}\n};\n')
109 ..write('main() {}\n'); 127 ..write('main() {}\n');
110 result[chunk] = code.toString(); 128 result[chunk] = code.toString();
111 }); 129 });
112 130
113 return result; 131 return result;
114 } 132 }
115 133
134 String _calculateImportPrefix(String import, List<String> imports) =>
135 'import_${imports.indexOf(import)}';
136
116 _isParameterized(ParameterElement param) { 137 _isParameterized(ParameterElement param) {
117 String typeName = param.type.toString(); 138 String typeName = param.type.toString();
118 139
119 if (typeName.indexOf('<') > -1) { 140 if (typeName.indexOf('<') > -1) {
120 String parameters = 141 String parameters =
121 typeName.substring(typeName.indexOf('<') + 1, typeName.length - 1); 142 typeName.substring(typeName.indexOf('<') + 1, typeName.length - 1);
122 return parameters.split(', ').any((p) => p != 'dynamic'); 143 return parameters.split(', ').any((p) => p != 'dynamic');
123 } 144 }
124 return false; 145 return false;
125 } 146 }
126 147
127 class CompilationUnitVisitor { 148 class CompilationUnitVisitor {
128 List<String> imports; 149 List<String> imports;
129 Map<String, String> typeToImport; 150 Map<String, String> typeToImport;
130 Map<Chunk, List<ClassElement>> typeFactoryTypes; 151 Map<Chunk, List<ClassElement>> typeFactoryTypes;
131 List<String> classAnnotations; 152 List<String> classAnnotations;
132 SourceFile source; 153 SourceFile source;
133 AnalysisContext context; 154 AnalysisContext context;
155 String outputFilename;
134 156
135 CompilationUnitVisitor(this.context, this.source, 157 CompilationUnitVisitor(this.context, this.source,
136 this.classAnnotations, this.imports, this.typeToImport, 158 this.classAnnotations, this.imports, this.typeToImport,
137 this.typeFactoryTypes); 159 this.typeFactoryTypes, this.outputFilename);
138 160
139 visit(CompilationUnitElement compilationUnit, SourceFile source) { 161 visit(CompilationUnitElement compilationUnit, SourceFile source) {
162 if (typeFactoryTypes[source.chunk] == null) {
163 typeFactoryTypes[source.chunk] = <ClassElement>[];
164 }
140 visitLibrary(compilationUnit.enclosingElement, source); 165 visitLibrary(compilationUnit.enclosingElement, source);
141 166
142 List<ClassElement> types = <ClassElement>[]; 167 List<ClassElement> types = <ClassElement>[];
143 types.addAll(compilationUnit.types); 168 types.addAll(compilationUnit.types);
144 169
145 for (CompilationUnitElement part in compilationUnit.enclosingElement.parts) { 170 for (CompilationUnitElement part in compilationUnit.enclosingElement.parts) {
146 types.addAll(part.types); 171 types.addAll(part.types);
147 } 172 }
148 173
149 types.forEach((clazz) => visitClassElement(clazz, source)); 174 types.forEach((clazz) => visitClassElement(clazz, source));
(...skipping 13 matching lines...) Expand all
163 (ann.element as ConstructorElement).enclosingElement.type) == 188 (ann.element as ConstructorElement).enclosingElement.type) ==
164 'di.annotations.Injectables') { 189 'di.annotations.Injectables') {
165 var listLiteral = 190 var listLiteral =
166 library.metadata[annotationIdx].arguments.arguments.first; 191 library.metadata[annotationIdx].arguments.arguments.first;
167 for (Expression expr in listLiteral.elements) { 192 for (Expression expr in listLiteral.elements) {
168 Element element = (expr as SimpleIdentifier).bestElement; 193 Element element = (expr as SimpleIdentifier).bestElement;
169 if (element == null || element is! ClassElement) { 194 if (element == null || element is! ClassElement) {
170 throw 'Unable to resolve type "$expr" from @Injectables ' 195 throw 'Unable to resolve type "$expr" from @Injectables '
171 'in ${library.element.source}'; 196 'in ${library.element.source}';
172 } 197 }
173 if (typeFactoryTypes[source.chunk] == null) {
174 typeFactoryTypes[source.chunk] = <ClassElement>[];
175 }
176 if (!typeFactoryTypes[source.chunk].contains(element)) { 198 if (!typeFactoryTypes[source.chunk].contains(element)) {
177 typeFactoryTypes[source.chunk].add(element as ClassElement); 199 typeFactoryTypes[source.chunk].add(element as ClassElement);
178 } 200 }
179 } 201 }
180 } 202 }
181 annotationIdx++; 203 annotationIdx++;
182 }); 204 });
183 } 205 }
184 }); 206 });
185 } 207 }
186 208
187 visitClassElement(ClassElement classElement, SourceFile source) { 209 visitClassElement(ClassElement classElement, SourceFile source) {
188 if (classElement.name.startsWith('_')) { 210 if (classElement.name.startsWith('_')) {
189 return; // ignore private classes. 211 return; // ignore private classes.
190 } 212 }
191 typeToImport[getCanonicalName(classElement.type)] = 213 var importUri = source.entryPointImport;
192 source.entryPointImport; 214 if (Uri.parse(importUri).scheme == '') {
193 if (!imports.contains(source.entryPointImport)) { 215 importUri = path.relative(importUri, from: path.dirname(outputFilename));
194 imports.add(source.entryPointImport); 216 }
217 typeToImport[getCanonicalName(classElement.type)] = importUri;
218 if (!imports.contains(importUri)) {
219 imports.add(importUri);
195 } 220 }
196 for (ElementAnnotation ann in classElement.metadata) { 221 for (ElementAnnotation ann in classElement.metadata) {
197 if (ann.element is ConstructorElement) { 222 if (ann.element is ConstructorElement) {
198 ConstructorElement con = ann.element; 223 ConstructorElement con = ann.element;
199 if (classAnnotations 224 if (classAnnotations
200 .contains(getQualifiedName(con.enclosingElement.type))) { 225 .contains(getQualifiedName(con.enclosingElement.type))) {
201 if (typeFactoryTypes[source.chunk] == null) { 226 if (typeFactoryTypes[source.chunk] == null) {
202 typeFactoryTypes[source.chunk] = <ClassElement>[]; 227 typeFactoryTypes[source.chunk] = <ClassElement>[];
203 } 228 }
204 if (!typeFactoryTypes[source.chunk].contains(classElement)) { 229 if (!typeFactoryTypes[source.chunk].contains(classElement)) {
(...skipping 20 matching lines...) Expand all
225 typedef CompilationUnitCrawler(CompilationUnitElement compilationUnit, 250 typedef CompilationUnitCrawler(CompilationUnitElement compilationUnit,
226 SourceFile source); 251 SourceFile source);
227 252
228 class SourceCrawler { 253 class SourceCrawler {
229 final List<String> packageRoots; 254 final List<String> packageRoots;
230 final String sdkPath; 255 final String sdkPath;
231 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); 256 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
232 257
233 SourceCrawler(this.sdkPath, this.packageRoots); 258 SourceCrawler(this.sdkPath, this.packageRoots);
234 259
235 void crawl(String entryPoint, CompilationUnitCrawler _visitor) { 260 void crawl(String entryPoint, CompilationUnitCrawler _visitor,
261 {bool preserveComments : false}) {
236 JavaSystemIO.setProperty("com.google.dart.sdk", sdkPath); 262 JavaSystemIO.setProperty("com.google.dart.sdk", sdkPath);
237 DartSdk sdk = DirectoryBasedDartSdk.defaultSdk; 263 DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
238 264
239 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); 265 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
240 contextOptions.cacheSize = 256; 266 contextOptions.cacheSize = 256;
241 contextOptions.preserveComments = false; 267 contextOptions.preserveComments = preserveComments;
242 contextOptions.analyzeFunctionBodies = false; 268 contextOptions.analyzeFunctionBodies = false;
243 context.analysisOptions = contextOptions; 269 context.analysisOptions = contextOptions;
244 sdk.context.analysisOptions = contextOptions; 270 sdk.context.analysisOptions = contextOptions;
245 271
246 var packageUriResolver = 272 var packageUriResolver =
247 new PackageUriResolver(packageRoots.map( 273 new PackageUriResolver(packageRoots.map(
248 (pr) => new JavaFile.fromUri(new Uri.file(pr))).toList()); 274 (pr) => new JavaFile.fromUri(new Uri.file(pr))).toList());
249 context.sourceFactory = new SourceFactory.con2([ 275 context.sourceFactory = new SourceFactory([
250 new DartUriResolver(sdk), 276 new DartUriResolver(sdk),
251 new FileUriResolver(), 277 new FileUriResolver(),
252 packageUriResolver 278 packageUriResolver
253 ]); 279 ]);
254 280
255 var entryPointFile; 281 var entryPointFile;
256 var entryPointImport; 282 var entryPointImport;
257 if (entryPoint.startsWith(PACKAGE_PREFIX)) { 283 if (entryPoint.startsWith(PACKAGE_PREFIX)) {
258 entryPointFile = new JavaFile(packageUriResolver 284 entryPointFile = new JavaFile(packageUriResolver
259 .resolveAbsolute(context.sourceFactory.contentCache, 285 .resolveAbsolute(Uri.parse(entryPoint)).toString());
260 Uri.parse(entryPoint)).toString());
261 entryPointImport = entryPoint; 286 entryPointImport = entryPoint;
262 } else { 287 } else {
263 entryPointFile = new JavaFile(entryPoint); 288 entryPointFile = new JavaFile(entryPoint);
264 entryPointImport = entryPointFile.getAbsolutePath(); 289 entryPointImport = entryPointFile.getAbsolutePath();
265 } 290 }
266 291
267 Source source = new FileBasedSource.con1( 292 Source source = new FileBasedSource.con1(entryPointFile);
268 context.sourceFactory.contentCache, entryPointFile);
269 ChangeSet changeSet = new ChangeSet(); 293 ChangeSet changeSet = new ChangeSet();
270 changeSet.added(source); 294 changeSet.addedSource(source);
271 context.applyChanges(changeSet); 295 context.applyChanges(changeSet);
272 LibraryElement rootLib = context.computeLibraryElement(source); 296 LibraryElement rootLib = context.computeLibraryElement(source);
273 CompilationUnit resolvedUnit = 297 CompilationUnit resolvedUnit =
274 context.resolveCompilationUnit(source, rootLib); 298 context.resolveCompilationUnit(source, rootLib);
275 299
276 var sourceFile = new SourceFile( 300 var sourceFile = new SourceFile(
277 entryPointFile.getAbsolutePath(), 301 entryPointFile.getAbsolutePath(),
278 entryPointImport, 302 entryPointImport,
279 resolvedUnit, 303 resolvedUnit,
280 resolvedUnit.element, 304 resolvedUnit.element,
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 490
467 SourceFile(this.canonicalPath, this.entryPointImport, this.compilationUnit, 491 SourceFile(this.canonicalPath, this.entryPointImport, this.compilationUnit,
468 this.compilationUnitElement, this.chunk); 492 this.compilationUnitElement, this.chunk);
469 493
470 operator ==(o) { 494 operator ==(o) {
471 if (o is String) return o == canonicalPath; 495 if (o is String) return o == canonicalPath;
472 if (o is! SourceFile) return false; 496 if (o is! SourceFile) return false;
473 return o.canonicalPath == canonicalPath; 497 return o.canonicalPath == canonicalPath;
474 } 498 }
475 } 499 }
OLDNEW
« no previous file with comments | « third_party/pkg/di/lib/errors.dart ('k') | third_party/pkg/di/lib/injector.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698