| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 KernelNamedTypeBuilder, | 79 KernelNamedTypeBuilder, |
| 80 KernelProcedureBuilder, | 80 KernelProcedureBuilder, |
| 81 LibraryBuilder, | 81 LibraryBuilder, |
| 82 MemberBuilder, | 82 MemberBuilder, |
| 83 NamedTypeBuilder, | 83 NamedTypeBuilder, |
| 84 TypeBuilder, | 84 TypeBuilder, |
| 85 TypeDeclarationBuilder, | 85 TypeDeclarationBuilder, |
| 86 TypeVariableBuilder; | 86 TypeVariableBuilder; |
| 87 | 87 |
| 88 import 'verifier.dart' show verifyProgram; | 88 import 'verifier.dart' show verifyProgram; |
| 89 import 'kernel_outline_shaker.dart' show trimProgram; |
| 89 | 90 |
| 90 class KernelTarget extends TargetImplementation { | 91 class KernelTarget extends TargetImplementation { |
| 91 /// The [FileSystem] which should be used to access files. | 92 /// The [FileSystem] which should be used to access files. |
| 92 final FileSystem fileSystem; | 93 final FileSystem fileSystem; |
| 93 | 94 |
| 94 final bool strongMode; | 95 final bool strongMode; |
| 95 | 96 |
| 96 final DillTarget dillTarget; | 97 final DillTarget dillTarget; |
| 97 | 98 |
| 98 /// Shared with [CompilerContext]. | 99 /// Shared with [CompilerContext]. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 cls.supertype = null; | 212 cls.supertype = null; |
| 212 cls.mixedInType = null; | 213 cls.mixedInType = null; |
| 213 builder.supertype = new KernelNamedTypeBuilder("Object", null, | 214 builder.supertype = new KernelNamedTypeBuilder("Object", null, |
| 214 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri)) | 215 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri)) |
| 215 ..builder = objectClassBuilder; | 216 ..builder = objectClassBuilder; |
| 216 builder.interfaces = null; | 217 builder.interfaces = null; |
| 217 builder.mixedInType = null; | 218 builder.mixedInType = null; |
| 218 } | 219 } |
| 219 | 220 |
| 220 Future<Program> handleInputError(Uri uri, InputError error, | 221 Future<Program> handleInputError(Uri uri, InputError error, |
| 221 {bool isFullProgram}) { | 222 {bool isFullProgram, bool trimDependencies: false}) { |
| 222 if (error != null) { | 223 if (error != null) { |
| 223 String message = error.format(); | 224 String message = error.format(); |
| 224 print(message); | 225 print(message); |
| 225 errors.add(message); | 226 errors.add(message); |
| 226 } | 227 } |
| 227 _program = erroneousProgram(isFullProgram); | 228 _program = erroneousProgram(isFullProgram); |
| 229 if (trimDependencies) { |
| 230 var excluded = |
| 231 dillTarget.loader.libraries.map((lib) => lib.importUri).toSet(); |
| 232 trimProgram(_program, (uri) => !excluded.contains(uri)); |
| 233 } |
| 228 return uri == null | 234 return uri == null |
| 229 ? new Future<Program>.value(_program) | 235 ? new Future<Program>.value(_program) |
| 230 : writeLinkedProgram(uri, _program, isFullProgram: isFullProgram); | 236 : writeLinkedProgram(uri, _program, isFullProgram: isFullProgram); |
| 231 } | 237 } |
| 232 | 238 |
| 233 @override | 239 @override |
| 234 Future<Program> buildOutlines({CanonicalName nameRoot}) async { | 240 Future<Program> buildOutlines({CanonicalName nameRoot}) async { |
| 235 if (loader.first == null) return null; | 241 if (loader.first == null) return null; |
| 236 try { | 242 try { |
| 237 loader.createTypeInferenceEngine(); | 243 loader.createTypeInferenceEngine(); |
| 238 await loader.buildOutlines(); | 244 await loader.buildOutlines(); |
| 239 loader.coreLibrary | 245 loader.coreLibrary |
| 240 .becomeCoreLibrary(const DynamicType(), const VoidType()); | 246 .becomeCoreLibrary(const DynamicType(), const VoidType()); |
| 241 dynamicType.bind(loader.coreLibrary["dynamic"]); | 247 dynamicType.bind(loader.coreLibrary["dynamic"]); |
| 242 loader.resolveParts(); | 248 loader.resolveParts(); |
| 243 loader.computeLibraryScopes(); | 249 loader.computeLibraryScopes(); |
| 244 loader.resolveTypes(); | 250 loader.resolveTypes(); |
| 245 loader.checkSemantics(); | 251 loader.checkSemantics(); |
| 246 loader.buildProgram(); | 252 loader.buildProgram(); |
| 247 List<SourceClassBuilder> sourceClasses = collectAllSourceClasses(); | 253 List<SourceClassBuilder> sourceClasses = collectAllSourceClasses(); |
| 248 installDefaultSupertypes(); | 254 installDefaultSupertypes(); |
| 249 installDefaultConstructors(sourceClasses); | 255 installDefaultConstructors(sourceClasses); |
| 250 loader.resolveConstructors(); | 256 loader.resolveConstructors(); |
| 251 loader.finishTypeVariables(objectClassBuilder); | 257 loader.finishTypeVariables(objectClassBuilder); |
| 252 _program = | 258 var outline = |
| 253 link(new List<Library>.from(loader.libraries), nameRoot: nameRoot); | 259 link(new List<Library>.from(loader.libraries), nameRoot: nameRoot); |
| 254 loader.computeHierarchy(_program); | 260 loader.computeHierarchy(outline); |
| 255 loader.checkOverrides(sourceClasses); | 261 loader.checkOverrides(sourceClasses); |
| 256 loader.prepareInitializerInference(); | 262 loader.prepareInitializerInference(); |
| 257 loader.performInitializerInference(); | 263 loader.performInitializerInference(); |
| 258 return _program; | 264 return _program = outline; |
| 259 } on InputError catch (e) { | 265 } on InputError catch (e) { |
| 260 return handleInputError(null, e, isFullProgram: false); | 266 return handleInputError(null, e, isFullProgram: false); |
| 261 } catch (e, s) { | 267 } catch (e, s) { |
| 262 return reportCrash(e, s, loader?.currentUriForCrashReporting); | 268 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
| 263 } | 269 } |
| 264 } | 270 } |
| 265 | 271 |
| 266 Future<Null> writeOutline(Uri uri) async { | 272 Future<Null> writeOutline(Uri uri) async { |
| 267 try { | 273 try { |
| 268 if (uri != null) { | 274 if (uri != null) { |
| 269 await writeLinkedProgram(uri, _program, isFullProgram: false); | 275 await writeLinkedProgram(uri, _program, isFullProgram: false); |
| 270 } | 276 } |
| 271 } on InputError catch (e) { | 277 } on InputError catch (e) { |
| 272 handleInputError(uri, e, isFullProgram: false); | 278 handleInputError(uri, e, isFullProgram: false, trimDependencies: false); |
| 273 } catch (e, s) { | 279 } catch (e, s) { |
| 274 reportCrash(e, s, loader?.currentUriForCrashReporting); | 280 reportCrash(e, s, loader?.currentUriForCrashReporting); |
| 275 } | 281 } |
| 276 } | 282 } |
| 277 | 283 |
| 278 @override | 284 @override |
| 279 Future<Program> buildProgram({bool verify: false}) async { | 285 Future<Program> buildProgram( |
| 286 {bool verify: false, bool trimDependencies: false}) async { |
| 280 if (loader.first == null) return null; | 287 if (loader.first == null) return null; |
| 281 if (errors.isNotEmpty) { | 288 if (errors.isNotEmpty) { |
| 282 return handleInputError(null, null, isFullProgram: true); | 289 return handleInputError(null, null, |
| 290 isFullProgram: true, trimDependencies: trimDependencies); |
| 283 } | 291 } |
| 284 try { | 292 try { |
| 285 await loader.buildBodies(); | 293 await loader.buildBodies(); |
| 294 _program = link(new List<Library>.from(loader.libraries), |
| 295 trimDependencies: trimDependencies); |
| 286 loader.finishStaticInvocations(); | 296 loader.finishStaticInvocations(); |
| 287 finishAllConstructors(); | 297 finishAllConstructors(); |
| 288 loader.finishNativeMethods(); | 298 loader.finishNativeMethods(); |
| 289 runBuildTransformations(); | 299 runBuildTransformations(); |
| 290 | 300 |
| 291 if (verify) this.verify(); | 301 if (verify) this.verify(); |
| 292 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); | 302 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); |
| 293 if (errors.isNotEmpty) { | 303 if (errors.isNotEmpty) { |
| 294 return handleInputError(null, null, isFullProgram: true); | 304 return handleInputError(null, null, |
| 305 isFullProgram: true, trimDependencies: trimDependencies); |
| 295 } | 306 } |
| 296 return _program; | 307 return _program; |
| 297 } on InputError catch (e) { | 308 } on InputError catch (e) { |
| 298 return handleInputError(null, e, isFullProgram: true); | 309 return handleInputError(null, e, |
| 310 isFullProgram: true, trimDependencies: trimDependencies); |
| 299 } catch (e, s) { | 311 } catch (e, s) { |
| 300 return reportCrash(e, s, loader?.currentUriForCrashReporting); | 312 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
| 301 } | 313 } |
| 302 } | 314 } |
| 303 | 315 |
| 304 Future<Null> writeProgram(Uri uri) async { | 316 Future<Null> writeProgram(Uri uri) async { |
| 305 if (loader.first == null) return null; | 317 if (loader.first == null) return null; |
| 306 try { | 318 try { |
| 307 await writeLinkedProgram(uri, _program, isFullProgram: true); | 319 await writeLinkedProgram(uri, _program, isFullProgram: true); |
| 308 } on InputError catch (e) { | 320 } on InputError catch (e) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 library.addBuilder(mainBuilder.name, mainBuilder, -1); | 395 library.addBuilder(mainBuilder.name, mainBuilder, -1); |
| 384 mainBuilder.body = new ExpressionStatement( | 396 mainBuilder.body = new ExpressionStatement( |
| 385 new Throw(new StringLiteral("${errors.join('\n')}"))); | 397 new Throw(new StringLiteral("${errors.join('\n')}"))); |
| 386 } | 398 } |
| 387 library.build(loader.coreLibrary); | 399 library.build(loader.coreLibrary); |
| 388 return link(<Library>[library.library]); | 400 return link(<Library>[library.library]); |
| 389 } | 401 } |
| 390 | 402 |
| 391 /// Creates a program by combining [libraries] with the libraries of | 403 /// Creates a program by combining [libraries] with the libraries of |
| 392 /// `dillTarget.loader.program`. | 404 /// `dillTarget.loader.program`. |
| 393 Program link(List<Library> libraries, {CanonicalName nameRoot}) { | 405 Program link(List<Library> libraries, |
| 406 {CanonicalName nameRoot, trimDependencies: false}) { |
| 394 Map<String, Source> uriToSource = | 407 Map<String, Source> uriToSource = |
| 395 new Map<String, Source>.from(this.uriToSource); | 408 new Map<String, Source>.from(this.uriToSource); |
| 396 | 409 |
| 397 libraries.addAll(dillTarget.loader.libraries); | 410 List<Library> extraLibraries = dillTarget.loader.libraries; |
| 411 libraries.addAll(extraLibraries); |
| 398 // TODO(scheglov) Should we also somehow update `uriToSource`? | 412 // TODO(scheglov) Should we also somehow update `uriToSource`? |
| 399 // uriToSource.addAll(binary.uriToSource); | 413 // uriToSource.addAll(binary.uriToSource); |
| 400 | 414 |
| 401 // TODO(ahe): Remove this line. Kernel seems to generate a default line map | 415 // TODO(ahe): Remove this line. Kernel seems to generate a default line map |
| 402 // that used when there's no fileUri on an element. Instead, ensure all | 416 // that used when there's no fileUri on an element. Instead, ensure all |
| 403 // elements have a fileUri. | 417 // elements have a fileUri. |
| 404 uriToSource[""] = new Source(<int>[0], const <int>[]); | 418 uriToSource[""] = new Source(<int>[0], const <int>[]); |
| 405 Program program = new Program( | 419 Program program = new Program( |
| 406 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource); | 420 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource); |
| 407 if (loader.first != null) { | 421 if (loader.first != null) { |
| 422 // TODO(sigmund): do only for full program |
| 408 Builder builder = loader.first.lookup("main", -1, null); | 423 Builder builder = loader.first.lookup("main", -1, null); |
| 409 if (builder is KernelProcedureBuilder) { | 424 if (builder is KernelProcedureBuilder) { |
| 410 program.mainMethod = builder.procedure; | 425 program.mainMethod = builder.procedure; |
| 411 } | 426 } |
| 412 } | 427 } |
| 413 if (errors.isEmpty || dillTarget.isLoaded) { | 428 if (trimDependencies) { |
| 414 runLinkTransformations(program); | 429 var excluded = extraLibraries.map((lib) => lib.importUri).toSet(); |
| 430 trimProgram(program, (uri) => !excluded.contains(uri)); |
| 415 } | 431 } |
| 432 |
| 416 ticker.logMs("Linked program"); | 433 ticker.logMs("Linked program"); |
| 417 return program; | 434 return program; |
| 418 } | 435 } |
| 419 | 436 |
| 420 Future<Program> writeLinkedProgram(Uri uri, Program program, | 437 Future<Program> writeLinkedProgram(Uri uri, Program program, |
| 421 {bool isFullProgram}) async { | 438 {bool isFullProgram}) async { |
| 422 File output = new File.fromUri(uri); | 439 File output = new File.fromUri(uri); |
| 423 IOSink sink = output.openWrite(); | 440 IOSink sink = output.openWrite(); |
| 424 try { | 441 try { |
| 425 new BinaryPrinter(sink).writeProgramFile(program); | 442 new BinaryPrinter(sink).writeProgramFile(program); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 }); | 706 }); |
| 690 } | 707 } |
| 691 | 708 |
| 692 /// Run all transformations that are needed when building a program for the | 709 /// Run all transformations that are needed when building a program for the |
| 693 /// first time. | 710 /// first time. |
| 694 void runBuildTransformations() { | 711 void runBuildTransformations() { |
| 695 transformMixinApplications(); | 712 transformMixinApplications(); |
| 696 otherTransformations(); | 713 otherTransformations(); |
| 697 } | 714 } |
| 698 | 715 |
| 699 /// Run all transformations that are needed when linking a program. | |
| 700 void runLinkTransformations(Program program) {} | |
| 701 | |
| 702 void transformMixinApplications() { | 716 void transformMixinApplications() { |
| 703 new MixinFullResolution().transform(_program); | 717 new MixinFullResolution().transform(_program); |
| 704 ticker.logMs("Transformed mixin applications"); | 718 ticker.logMs("Transformed mixin applications"); |
| 705 } | 719 } |
| 706 | 720 |
| 707 void otherTransformations() { | 721 void otherTransformations() { |
| 708 // TODO(ahe): Don't generate type variables in the first place. | 722 // TODO(ahe): Don't generate type variables in the first place. |
| 709 if (!strongMode) { | 723 if (!strongMode) { |
| 710 _program.accept(new Erasure()); | 724 _program.accept(new Erasure()); |
| 711 ticker.logMs("Erased type variables in generic methods"); | 725 ticker.logMs("Erased type variables in generic methods"); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 732 } | 746 } |
| 733 for (Constructor constructor in superclass.constructors) { | 747 for (Constructor constructor in superclass.constructors) { |
| 734 if (constructor.name.name.isEmpty) { | 748 if (constructor.name.name.isEmpty) { |
| 735 return constructor.function.requiredParameterCount == 0 | 749 return constructor.function.requiredParameterCount == 0 |
| 736 ? constructor | 750 ? constructor |
| 737 : null; | 751 : null; |
| 738 } | 752 } |
| 739 } | 753 } |
| 740 return null; | 754 return null; |
| 741 } | 755 } |
| OLD | NEW |