OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.kernel_target; | 5 library fasta.kernel_target; |
6 | 6 |
7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
8 | 8 |
9 import 'dart:io' show File, IOSink; | 9 import 'dart:io' show File, IOSink; |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 final FileSystem fileSystem; | 94 final FileSystem fileSystem; |
95 | 95 |
96 final bool strongMode; | 96 final bool strongMode; |
97 | 97 |
98 final DillTarget dillTarget; | 98 final DillTarget dillTarget; |
99 | 99 |
100 /// Shared with [CompilerContext]. | 100 /// Shared with [CompilerContext]. |
101 final Map<String, Source> uriToSource; | 101 final Map<String, Source> uriToSource; |
102 | 102 |
103 SourceLoader<Library> loader; | 103 SourceLoader<Library> loader; |
104 Program program; | 104 Program _program; |
105 | 105 |
106 final List errors = []; | 106 final List errors = []; |
107 | 107 |
108 final TypeBuilder dynamicType = | 108 final TypeBuilder dynamicType = |
109 new KernelNamedTypeBuilder("dynamic", null, -1, null); | 109 new KernelNamedTypeBuilder("dynamic", null, -1, null); |
110 | 110 |
111 KernelTarget(this.fileSystem, DillTarget dillTarget, | 111 KernelTarget(this.fileSystem, DillTarget dillTarget, |
112 TranslateUri uriTranslator, this.strongMode, | 112 TranslateUri uriTranslator, this.strongMode, |
113 [Map<String, Source> uriToSource]) | 113 [Map<String, Source> uriToSource]) |
114 : dillTarget = dillTarget, | 114 : dillTarget = dillTarget, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 builder.mixedInType = null; | 218 builder.mixedInType = null; |
219 } | 219 } |
220 | 220 |
221 Future<Program> handleInputError(Uri uri, InputError error, | 221 Future<Program> handleInputError(Uri uri, InputError error, |
222 {bool isFullProgram}) { | 222 {bool isFullProgram}) { |
223 if (error != null) { | 223 if (error != null) { |
224 String message = error.format(); | 224 String message = error.format(); |
225 print(message); | 225 print(message); |
226 errors.add(message); | 226 errors.add(message); |
227 } | 227 } |
228 program = erroneousProgram(isFullProgram); | 228 _program = erroneousProgram(isFullProgram); |
229 return uri == null | 229 return uri == null |
230 ? new Future<Program>.value(program) | 230 ? new Future<Program>.value(_program) |
231 : writeLinkedProgram(uri, program, isFullProgram: isFullProgram); | 231 : writeLinkedProgram(uri, _program, isFullProgram: isFullProgram); |
232 } | 232 } |
233 | 233 |
234 @override | 234 @override |
235 Future<Null> computeOutline({CanonicalName nameRoot}) async { | 235 Future<Program> buildOutlines({CanonicalName nameRoot}) async { |
236 if (loader.first == null) return null; | 236 if (loader.first == null) return null; |
237 try { | 237 try { |
238 loader.createTypeInferenceEngine(); | 238 loader.createTypeInferenceEngine(); |
239 await loader.buildOutlines(); | 239 await loader.buildOutlines(); |
240 loader.coreLibrary | 240 loader.coreLibrary |
241 .becomeCoreLibrary(const DynamicType(), const VoidType()); | 241 .becomeCoreLibrary(const DynamicType(), const VoidType()); |
242 dynamicType.bind(loader.coreLibrary["dynamic"]); | 242 dynamicType.bind(loader.coreLibrary["dynamic"]); |
243 loader.resolveParts(); | 243 loader.resolveParts(); |
244 loader.computeLibraryScopes(); | 244 loader.computeLibraryScopes(); |
245 loader.resolveTypes(); | 245 loader.resolveTypes(); |
246 loader.checkSemantics(); | 246 loader.checkSemantics(); |
247 loader.buildProgram(); | 247 loader.buildProgram(); |
248 List<SourceClassBuilder> sourceClasses = collectAllSourceClasses(); | 248 List<SourceClassBuilder> sourceClasses = collectAllSourceClasses(); |
249 installDefaultSupertypes(); | 249 installDefaultSupertypes(); |
250 installDefaultConstructors(sourceClasses); | 250 installDefaultConstructors(sourceClasses); |
251 loader.resolveConstructors(); | 251 loader.resolveConstructors(); |
252 loader.finishTypeVariables(objectClassBuilder); | 252 loader.finishTypeVariables(objectClassBuilder); |
253 program = | 253 _program = |
254 link(new List<Library>.from(loader.libraries), nameRoot: nameRoot); | 254 link(new List<Library>.from(loader.libraries), nameRoot: nameRoot); |
255 loader.computeHierarchy(program); | 255 loader.computeHierarchy(_program); |
256 loader.checkOverrides(sourceClasses); | 256 loader.checkOverrides(sourceClasses); |
257 loader.prepareInitializerInference(); | 257 loader.prepareInitializerInference(); |
258 loader.performInitializerInference(); | 258 loader.performInitializerInference(); |
| 259 return _program; |
259 } on InputError catch (e) { | 260 } on InputError catch (e) { |
260 await handleInputError(null, e, isFullProgram: false); | 261 return handleInputError(null, e, isFullProgram: false); |
261 } catch (e, s) { | 262 } catch (e, s) { |
262 await reportCrash(e, s, loader?.currentUriForCrashReporting); | 263 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
263 } | 264 } |
264 } | 265 } |
265 | 266 |
266 Future<Null> writeOutline(Uri uri) async { | 267 Future<Null> writeOutline(Uri uri) async { |
267 try { | 268 try { |
268 if (uri != null) { | 269 if (uri != null) { |
269 await writeLinkedProgram(uri, program, isFullProgram: false); | 270 await writeLinkedProgram(uri, _program, isFullProgram: false); |
270 } | 271 } |
271 } on InputError catch (e) { | 272 } on InputError catch (e) { |
272 handleInputError(uri, e, isFullProgram: false); | 273 handleInputError(uri, e, isFullProgram: false); |
273 } catch (e, s) { | 274 } catch (e, s) { |
274 reportCrash(e, s, loader?.currentUriForCrashReporting); | 275 reportCrash(e, s, loader?.currentUriForCrashReporting); |
275 } | 276 } |
276 } | 277 } |
277 | 278 |
278 Future<Program> writeProgram(Uri uri, | 279 @override |
279 {bool dumpIr: false, bool verify: false}) async { | 280 Future<Program> buildProgram() async { |
280 if (loader.first == null) return null; | 281 if (loader.first == null) return null; |
281 if (errors.isNotEmpty) { | 282 if (errors.isNotEmpty) { |
282 return handleInputError(uri, null, isFullProgram: true); | 283 return handleInputError(null, null, isFullProgram: true); |
283 } | 284 } |
284 try { | 285 try { |
285 await loader.buildBodies(); | 286 await loader.buildBodies(); |
286 loader.finishStaticInvocations(); | 287 loader.finishStaticInvocations(); |
287 finishAllConstructors(); | 288 finishAllConstructors(); |
288 loader.finishNativeMethods(); | 289 loader.finishNativeMethods(); |
289 runBuildTransformations(); | 290 runBuildTransformations(); |
290 | 291 |
| 292 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); |
| 293 if (errors.isNotEmpty) { |
| 294 return handleInputError(null, null, isFullProgram: true); |
| 295 } |
| 296 return _program; |
| 297 } on InputError catch (e) { |
| 298 return handleInputError(null, e, isFullProgram: true); |
| 299 } catch (e, s) { |
| 300 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
| 301 } |
| 302 } |
| 303 |
| 304 Future<Null> writeProgram(Uri uri, |
| 305 {bool dumpIr: false, bool verify: false}) async { |
| 306 if (loader.first == null) return null; |
| 307 try { |
291 if (dumpIr) this.dumpIr(); | 308 if (dumpIr) this.dumpIr(); |
292 if (verify) this.verify(); | 309 if (verify) this.verify(); |
293 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); | 310 await writeLinkedProgram(uri, _program, isFullProgram: true); |
294 if (errors.isNotEmpty) { | |
295 return handleInputError(uri, null, isFullProgram: true); | |
296 } | |
297 if (uri == null) return program; | |
298 return await writeLinkedProgram(uri, program, isFullProgram: true); | |
299 } on InputError catch (e) { | 311 } on InputError catch (e) { |
300 return handleInputError(uri, e, isFullProgram: true); | 312 return handleInputError(uri, e, isFullProgram: true); |
301 } catch (e, s) { | 313 } catch (e, s) { |
302 return reportCrash(e, s, loader?.currentUriForCrashReporting); | 314 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
303 } | 315 } |
304 } | 316 } |
305 | 317 |
306 Future writeDepsFile(Uri output, Uri depsFile, | 318 Future writeDepsFile(Uri output, Uri depsFile, |
307 {Iterable<Uri> extraDependencies}) async { | 319 {Iterable<Uri> extraDependencies}) async { |
308 String toRelativeFilePath(Uri uri) { | 320 String toRelativeFilePath(Uri uri) { |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 /// first time. | 696 /// first time. |
685 void runBuildTransformations() { | 697 void runBuildTransformations() { |
686 transformMixinApplications(); | 698 transformMixinApplications(); |
687 otherTransformations(); | 699 otherTransformations(); |
688 } | 700 } |
689 | 701 |
690 /// Run all transformations that are needed when linking a program. | 702 /// Run all transformations that are needed when linking a program. |
691 void runLinkTransformations(Program program) {} | 703 void runLinkTransformations(Program program) {} |
692 | 704 |
693 void transformMixinApplications() { | 705 void transformMixinApplications() { |
694 new MixinFullResolution().transform(program); | 706 new MixinFullResolution().transform(_program); |
695 ticker.logMs("Transformed mixin applications"); | 707 ticker.logMs("Transformed mixin applications"); |
696 } | 708 } |
697 | 709 |
698 void otherTransformations() { | 710 void otherTransformations() { |
699 // TODO(ahe): Don't generate type variables in the first place. | 711 // TODO(ahe): Don't generate type variables in the first place. |
700 if (!strongMode) { | 712 if (!strongMode) { |
701 program.accept(new Erasure()); | 713 _program.accept(new Erasure()); |
702 ticker.logMs("Erased type variables in generic methods"); | 714 ticker.logMs("Erased type variables in generic methods"); |
703 } | 715 } |
704 // TODO(kmillikin): Make this run on a per-method basis. | 716 // TODO(kmillikin): Make this run on a per-method basis. |
705 transformAsync.transformProgram(program); | 717 transformAsync.transformProgram(_program); |
706 ticker.logMs("Transformed async methods"); | 718 ticker.logMs("Transformed async methods"); |
707 } | 719 } |
708 | 720 |
709 void dumpIr() { | 721 void dumpIr() { |
710 StringBuffer sb = new StringBuffer(); | 722 StringBuffer sb = new StringBuffer(); |
711 for (Library library in loader.libraries) { | 723 for (Library library in loader.libraries) { |
712 Printer printer = new Printer(sb); | 724 Printer printer = new Printer(sb); |
713 printer.writeLibraryFile(library); | 725 printer.writeLibraryFile(library); |
714 } | 726 } |
715 print("$sb"); | 727 print("$sb"); |
716 ticker.logMs("Dumped IR"); | 728 ticker.logMs("Dumped IR"); |
717 } | 729 } |
718 | 730 |
719 void verify() { | 731 void verify() { |
720 errors.addAll(verifyProgram(program)); | 732 errors.addAll(verifyProgram(_program)); |
721 ticker.logMs("Verified program"); | 733 ticker.logMs("Verified program"); |
722 } | 734 } |
723 } | 735 } |
724 | 736 |
725 /// Looks for a constructor call that matches `super()` from a constructor in | 737 /// Looks for a constructor call that matches `super()` from a constructor in |
726 /// [cls]. Such a constructor may have optional arguments, but no required | 738 /// [cls]. Such a constructor may have optional arguments, but no required |
727 /// arguments. | 739 /// arguments. |
728 Constructor defaultSuperConstructor(Class cls) { | 740 Constructor defaultSuperConstructor(Class cls) { |
729 Class superclass = cls.superclass; | 741 Class superclass = cls.superclass; |
730 while (superclass != null && superclass.isMixinApplication) { | 742 while (superclass != null && superclass.isMixinApplication) { |
731 superclass = superclass.superclass; | 743 superclass = superclass.superclass; |
732 } | 744 } |
733 for (Constructor constructor in superclass.constructors) { | 745 for (Constructor constructor in superclass.constructors) { |
734 if (constructor.name.name.isEmpty) { | 746 if (constructor.name.name.isEmpty) { |
735 return constructor.function.requiredParameterCount == 0 | 747 return constructor.function.requiredParameterCount == 0 |
736 ? constructor | 748 ? constructor |
737 : null; | 749 : null; |
738 } | 750 } |
739 } | 751 } |
740 return null; | 752 return null; |
741 } | 753 } |
OLD | NEW |