| 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 |