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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_target.dart

Issue 2894283002: Reapply CL: first step for modular support in fasta (Closed)
Patch Set: new changes since first CL Created 3 years, 7 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
OLDNEW
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; 9 import 'dart:io' show File;
10 10
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 KernelNamedTypeBuilder, 76 KernelNamedTypeBuilder,
77 KernelProcedureBuilder, 77 KernelProcedureBuilder,
78 LibraryBuilder, 78 LibraryBuilder,
79 MemberBuilder, 79 MemberBuilder,
80 NamedTypeBuilder, 80 NamedTypeBuilder,
81 TypeBuilder, 81 TypeBuilder,
82 TypeDeclarationBuilder, 82 TypeDeclarationBuilder,
83 TypeVariableBuilder; 83 TypeVariableBuilder;
84 84
85 import 'verifier.dart' show verifyProgram; 85 import 'verifier.dart' show verifyProgram;
86 import 'kernel_outline_shaker.dart'
87 show trimProgram, RetainedDataBuilder, RootsMarker;
86 88
87 class KernelTarget extends TargetImplementation { 89 class KernelTarget extends TargetImplementation {
88 /// The [FileSystem] which should be used to access files. 90 /// The [FileSystem] which should be used to access files.
89 final FileSystem fileSystem; 91 final FileSystem fileSystem;
90 92
91 final bool strongMode; 93 final bool strongMode;
92 94
93 final DillTarget dillTarget; 95 final DillTarget dillTarget;
94 96
95 /// Shared with [CompilerContext]. 97 /// Shared with [CompilerContext].
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 cls.implementedTypes.clear(); 209 cls.implementedTypes.clear();
208 cls.supertype = null; 210 cls.supertype = null;
209 cls.mixedInType = null; 211 cls.mixedInType = null;
210 builder.supertype = new KernelNamedTypeBuilder("Object", null, 212 builder.supertype = new KernelNamedTypeBuilder("Object", null,
211 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri)) 213 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri))
212 ..builder = objectClassBuilder; 214 ..builder = objectClassBuilder;
213 builder.interfaces = null; 215 builder.interfaces = null;
214 builder.mixedInType = null; 216 builder.mixedInType = null;
215 } 217 }
216 218
217 void handleInputError(InputError error, {bool isFullProgram}) { 219 void handleInputError(InputError error,
220 {bool isFullProgram, bool trimDependencies: false}) {
218 if (error != null) { 221 if (error != null) {
219 String message = error.format(); 222 String message = error.format();
220 print(message); 223 print(message);
221 errors.add(message); 224 errors.add(message);
222 } 225 }
223 _program = erroneousProgram(isFullProgram); 226 _program = erroneousProgram(isFullProgram);
224 } 227 }
225 228
226 @override 229 @override
227 Future<Program> buildOutlines({CanonicalName nameRoot}) async { 230 Future<Program> buildOutlines({CanonicalName nameRoot}) async {
(...skipping 21 matching lines...) Expand all
249 loader.prepareInitializerInference(); 252 loader.prepareInitializerInference();
250 loader.performInitializerInference(); 253 loader.performInitializerInference();
251 } on InputError catch (e) { 254 } on InputError catch (e) {
252 handleInputError(e, isFullProgram: false); 255 handleInputError(e, isFullProgram: false);
253 } catch (e, s) { 256 } catch (e, s) {
254 return reportCrash(e, s, loader?.currentUriForCrashReporting); 257 return reportCrash(e, s, loader?.currentUriForCrashReporting);
255 } 258 }
256 return _program; 259 return _program;
257 } 260 }
258 261
262 /// Build the kernel representation of the program loaded by this target. The
263 /// program will contain full bodies for the code loaded from sources, and
264 /// only references to the code loaded by the [DillTarget], which may or may
265 /// not include method bodies (depending on what was loaded into that target,
266 /// an outline or a full kernel program).
267 ///
268 /// When [trimDependencies] is true, this also runs a tree-shaker that deletes
ahe 2017/05/22 11:49:04 This documentation states what is currently going
Siggi Cherem (dart-lang) 2017/05/22 23:15:48 added a note about it.
269 /// anything from the [DillTarget] that is not needed for the source program,
270 /// this includes function bodies and types that are not reachable.
271 ///
272 /// If [verify], run the default kernel verification on the resulting program.
259 @override 273 @override
260 Future<Program> buildProgram({bool verify: false}) async { 274 Future<Program> buildProgram(
275 {bool verify: false, bool trimDependencies: false}) async {
261 if (loader.first == null) return null; 276 if (loader.first == null) return null;
262 if (errors.isNotEmpty) { 277 if (errors.isNotEmpty) {
263 handleInputError(null, isFullProgram: true); 278 handleInputError(null,
279 isFullProgram: true, trimDependencies: trimDependencies);
280 if (trimDependencies) trimDependenciesInProgram();
264 return _program; 281 return _program;
265 } 282 }
283
266 try { 284 try {
267 await loader.buildBodies(); 285 await loader.buildBodies();
268 loader.finishStaticInvocations(); 286 loader.finishStaticInvocations();
269 finishAllConstructors(); 287 finishAllConstructors();
270 loader.finishNativeMethods(); 288 loader.finishNativeMethods();
271 runBuildTransformations(); 289 runBuildTransformations();
272 290
273 if (verify) this.verify(); 291 if (verify) this.verify();
274 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); 292 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format()));
275 if (errors.isNotEmpty) { 293 if (errors.isNotEmpty) {
276 handleInputError(null, isFullProgram: true); 294 handleInputError(null,
295 isFullProgram: true, trimDependencies: trimDependencies);
277 } 296 }
278 } on InputError catch (e) { 297 } on InputError catch (e) {
279 handleInputError(e, isFullProgram: true); 298 handleInputError(e,
299 isFullProgram: true, trimDependencies: trimDependencies);
280 } catch (e, s) { 300 } catch (e, s) {
281 return reportCrash(e, s, loader?.currentUriForCrashReporting); 301 return reportCrash(e, s, loader?.currentUriForCrashReporting);
282 } 302 }
303 if (trimDependencies) trimDependenciesInProgram();
283 return _program; 304 return _program;
284 } 305 }
285 306
286 Future writeDepsFile(Uri output, Uri depsFile, 307 Future writeDepsFile(Uri output, Uri depsFile,
287 {Iterable<Uri> extraDependencies}) async { 308 {Iterable<Uri> extraDependencies}) async {
288 String toRelativeFilePath(Uri uri) { 309 String toRelativeFilePath(Uri uri) {
289 // Ninja expects to find file names relative to the current working 310 // Ninja expects to find file names relative to the current working
290 // directory. We've tried making them relative to the deps file, but that 311 // directory. We've tried making them relative to the deps file, but that
291 // doesn't work for downstream projects. Making them absolute also 312 // doesn't work for downstream projects. Making them absolute also
292 // doesn't work. 313 // doesn't work.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 library.build(loader.coreLibrary); 368 library.build(loader.coreLibrary);
348 return link(<Library>[library.library]); 369 return link(<Library>[library.library]);
349 } 370 }
350 371
351 /// Creates a program by combining [libraries] with the libraries of 372 /// Creates a program by combining [libraries] with the libraries of
352 /// `dillTarget.loader.program`. 373 /// `dillTarget.loader.program`.
353 Program link(List<Library> libraries, {CanonicalName nameRoot}) { 374 Program link(List<Library> libraries, {CanonicalName nameRoot}) {
354 Map<String, Source> uriToSource = 375 Map<String, Source> uriToSource =
355 new Map<String, Source>.from(this.uriToSource); 376 new Map<String, Source>.from(this.uriToSource);
356 377
357 libraries.addAll(dillTarget.loader.libraries); 378 List<Library> extraLibraries = dillTarget.loader.libraries;
379 libraries.addAll(extraLibraries);
ahe 2017/05/22 11:49:04 Seems like an unnecessary change.
Siggi Cherem (dart-lang) 2017/05/22 23:15:48 Ouch, my apologies. I undid a bunch of other chang
358 // TODO(scheglov) Should we also somehow update `uriToSource`? 380 // TODO(scheglov) Should we also somehow update `uriToSource`?
359 // uriToSource.addAll(binary.uriToSource); 381 // uriToSource.addAll(binary.uriToSource);
360 382
361 // TODO(ahe): Remove this line. Kernel seems to generate a default line map 383 // TODO(ahe): Remove this line. Kernel seems to generate a default line map
362 // that used when there's no fileUri on an element. Instead, ensure all 384 // that used when there's no fileUri on an element. Instead, ensure all
363 // elements have a fileUri. 385 // elements have a fileUri.
364 uriToSource[""] = new Source(<int>[0], const <int>[]); 386 uriToSource[""] = new Source(<int>[0], const <int>[]);
365 Program program = new Program( 387 Program program = new Program(
366 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource); 388 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource);
367 if (loader.first != null) { 389 if (loader.first != null) {
390 // TODO(sigmund): do only for full program
368 Builder builder = loader.first.lookup("main", -1, null); 391 Builder builder = loader.first.lookup("main", -1, null);
369 if (builder is KernelProcedureBuilder) { 392 if (builder is KernelProcedureBuilder) {
370 program.mainMethod = builder.procedure; 393 program.mainMethod = builder.procedure;
371 } 394 }
372 } 395 }
373 if (errors.isEmpty || dillTarget.isLoaded) { 396
374 runLinkTransformations(program);
375 }
376 ticker.logMs("Linked program"); 397 ticker.logMs("Linked program");
377 return program; 398 return program;
378 } 399 }
379 400
380 void installDefaultSupertypes() { 401 void installDefaultSupertypes() {
381 Class objectClass = this.objectClass; 402 Class objectClass = this.objectClass;
382 loader.builders.forEach((Uri uri, LibraryBuilder library) { 403 loader.builders.forEach((Uri uri, LibraryBuilder library) {
383 library.forEach((String name, Builder builder) { 404 library.forEach((String name, Builder builder) {
384 if (builder is SourceClassBuilder) { 405 if (builder is SourceClassBuilder) {
385 Class cls = builder.target; 406 Class cls = builder.target;
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 }); 652 });
632 } 653 }
633 654
634 /// Run all transformations that are needed when building a program for the 655 /// Run all transformations that are needed when building a program for the
635 /// first time. 656 /// first time.
636 void runBuildTransformations() { 657 void runBuildTransformations() {
637 transformMixinApplications(); 658 transformMixinApplications();
638 otherTransformations(); 659 otherTransformations();
639 } 660 }
640 661
641 /// Run all transformations that are needed when linking a program.
642 void runLinkTransformations(Program program) {}
643
644 void transformMixinApplications() { 662 void transformMixinApplications() {
645 new MixinFullResolution().transform(_program); 663 new MixinFullResolution().transform(_program);
646 ticker.logMs("Transformed mixin applications"); 664 ticker.logMs("Transformed mixin applications");
647 } 665 }
648 666
649 void otherTransformations() { 667 void otherTransformations() {
650 // TODO(ahe): Don't generate type variables in the first place. 668 // TODO(ahe): Don't generate type variables in the first place.
651 if (!strongMode) { 669 if (!strongMode) {
652 _program.accept(new Erasure()); 670 _program.accept(new Erasure());
653 ticker.logMs("Erased type variables in generic methods"); 671 ticker.logMs("Erased type variables in generic methods");
654 } 672 }
655 // TODO(kmillikin): Make this run on a per-method basis. 673 // TODO(kmillikin): Make this run on a per-method basis.
656 transformAsync.transformProgram(_program); 674 transformAsync.transformProgram(_program);
657 ticker.logMs("Transformed async methods"); 675 ticker.logMs("Transformed async methods");
658 } 676 }
659 677
660 void verify() { 678 void verify() {
661 var verifyErrors = verifyProgram(_program); 679 var verifyErrors = verifyProgram(_program);
662 errors.addAll(verifyErrors.map((error) => '$error')); 680 errors.addAll(verifyErrors.map((error) => '$error'));
663 ticker.logMs("Verified program"); 681 ticker.logMs("Verified program");
664 } 682 }
683
684 /// Tree-shakes most code from the [dillTarget] by visiting all other
685 /// libraries in [_program] and marking the APIs from the [dillTarget]
686 /// libraries that are in use.
687 trimDependenciesInProgram() {
688 var toShake =
689 dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
690 var isIncluded = (Uri uri) => !toShake.contains(uri);
691 var data = new RetainedDataBuilder();
692 // TODO(sigmund): replace this step with data that is directly computed from
693 // the builders: we should know the tree-shaking roots without having to do
694 // a second visit over the tree.
695 new RootsMarker(data).run(_program, isIncluded);
696 trimProgram(_program, data, isIncluded);
697 }
665 } 698 }
666 699
667 /// Looks for a constructor call that matches `super()` from a constructor in 700 /// Looks for a constructor call that matches `super()` from a constructor in
668 /// [cls]. Such a constructor may have optional arguments, but no required 701 /// [cls]. Such a constructor may have optional arguments, but no required
669 /// arguments. 702 /// arguments.
670 Constructor defaultSuperConstructor(Class cls) { 703 Constructor defaultSuperConstructor(Class cls) {
671 Class superclass = cls.superclass; 704 Class superclass = cls.superclass;
672 while (superclass != null && superclass.isMixinApplication) { 705 while (superclass != null && superclass.isMixinApplication) {
673 superclass = superclass.superclass; 706 superclass = superclass.superclass;
674 } 707 }
675 for (Constructor constructor in superclass.constructors) { 708 for (Constructor constructor in superclass.constructors) {
676 if (constructor.name.name.isEmpty) { 709 if (constructor.name.name.isEmpty) {
677 return constructor.function.requiredParameterCount == 0 710 return constructor.function.requiredParameterCount == 0
678 ? constructor 711 ? constructor
679 : null; 712 : null;
680 } 713 }
681 } 714 }
682 return null; 715 return null;
683 } 716 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698