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

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

Issue 2979463002: Revert "Tweak public APIs and use them in patch_sdk, dart2js, and kernel-service." (Closed)
Patch Set: Created 3 years, 5 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;
10
9 import 'package:front_end/file_system.dart'; 11 import 'package:front_end/file_system.dart';
10 12
11 import 'package:kernel/ast.dart' 13 import 'package:kernel/ast.dart'
12 show 14 show
13 Arguments, 15 Arguments,
14 CanonicalName, 16 CanonicalName,
15 Class, 17 Class,
16 Constructor, 18 Constructor,
17 DartType, 19 DartType,
18 DynamicType, 20 DynamicType,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 KernelNamedTypeBuilder, 71 KernelNamedTypeBuilder,
70 KernelProcedureBuilder, 72 KernelProcedureBuilder,
71 LibraryBuilder, 73 LibraryBuilder,
72 MemberBuilder, 74 MemberBuilder,
73 NamedTypeBuilder, 75 NamedTypeBuilder,
74 TypeBuilder, 76 TypeBuilder,
75 TypeDeclarationBuilder, 77 TypeDeclarationBuilder,
76 TypeVariableBuilder; 78 TypeVariableBuilder;
77 79
78 import 'verifier.dart' show verifyProgram; 80 import 'verifier.dart' show verifyProgram;
81 import 'kernel_outline_shaker.dart'
82 show trimProgram, RetainedDataBuilder, RootsMarker;
79 83
80 class KernelTarget extends TargetImplementation { 84 class KernelTarget extends TargetImplementation {
81 /// The [FileSystem] which should be used to access files. 85 /// The [FileSystem] which should be used to access files.
82 final FileSystem fileSystem; 86 final FileSystem fileSystem;
83 87
84 final DillTarget dillTarget; 88 final DillTarget dillTarget;
85 89
86 /// Shared with [CompilerContext]. 90 /// Shared with [CompilerContext].
87 final Map<String, Source> uriToSource; 91 final Map<String, Source> uriToSource;
88 92
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 cls.implementedTypes.clear(); 207 cls.implementedTypes.clear();
204 cls.supertype = null; 208 cls.supertype = null;
205 cls.mixedInType = null; 209 cls.mixedInType = null;
206 builder.supertype = new KernelNamedTypeBuilder("Object", null, 210 builder.supertype = new KernelNamedTypeBuilder("Object", null,
207 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri)) 211 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri))
208 ..builder = objectClassBuilder; 212 ..builder = objectClassBuilder;
209 builder.interfaces = null; 213 builder.interfaces = null;
210 builder.mixedInType = null; 214 builder.mixedInType = null;
211 } 215 }
212 216
213 void handleInputError(InputError error, {bool isFullProgram}) { 217 void handleInputError(InputError error,
218 {bool isFullProgram, bool trimDependencies: false}) {
214 if (error != null) { 219 if (error != null) {
215 String message = error.format(); 220 String message = error.format();
216 print(message); 221 print(message);
217 errors.add(message); 222 errors.add(message);
218 } 223 }
219 program = erroneousProgram(isFullProgram); 224 program = erroneousProgram(isFullProgram);
220 } 225 }
221 226
222 @override 227 @override
223 Future<Program> buildOutlines({CanonicalName nameRoot}) async { 228 Future<Program> buildOutlines({CanonicalName nameRoot}) async {
(...skipping 27 matching lines...) Expand all
251 } 256 }
252 return program; 257 return program;
253 } 258 }
254 259
255 /// Build the kernel representation of the program loaded by this target. The 260 /// Build the kernel representation of the program loaded by this target. The
256 /// program will contain full bodies for the code loaded from sources, and 261 /// program will contain full bodies for the code loaded from sources, and
257 /// only references to the code loaded by the [DillTarget], which may or may 262 /// only references to the code loaded by the [DillTarget], which may or may
258 /// not include method bodies (depending on what was loaded into that target, 263 /// not include method bodies (depending on what was loaded into that target,
259 /// an outline or a full kernel program). 264 /// an outline or a full kernel program).
260 /// 265 ///
266 /// When [trimDependencies] is true, this also runs a tree-shaker that deletes
267 /// anything from the [DillTarget] that is not needed for the source program,
268 /// this includes function bodies and types that are not reachable. This
269 /// option is currently in flux and the internal implementation might change.
270 /// See [trimDependenciesInProgram] for more details.
271 ///
261 /// If [verify], run the default kernel verification on the resulting program. 272 /// If [verify], run the default kernel verification on the resulting program.
262 @override 273 @override
263 Future<Program> buildProgram({bool verify: false}) async { 274 Future<Program> buildProgram(
275 {bool verify: false, bool trimDependencies: false}) async {
264 if (loader.first == null) return null; 276 if (loader.first == null) return null;
265 if (errors.isNotEmpty) { 277 if (errors.isNotEmpty) {
266 handleInputError(null, isFullProgram: true); 278 handleInputError(null,
279 isFullProgram: true, trimDependencies: trimDependencies);
267 return program; 280 return program;
268 } 281 }
269 282
270 try { 283 try {
271 await loader.buildBodies(); 284 await loader.buildBodies();
272 loader.finishStaticInvocations(); 285 loader.finishStaticInvocations();
273 finishAllConstructors(); 286 finishAllConstructors();
274 loader.finishNativeMethods(); 287 loader.finishNativeMethods();
275 runBuildTransformations(); 288 runBuildTransformations();
276 289
277 if (verify) this.verify(); 290 if (verify) this.verify();
278 if (errors.isNotEmpty) { 291 if (errors.isNotEmpty) {
279 handleInputError(null, isFullProgram: true); 292 handleInputError(null,
293 isFullProgram: true, trimDependencies: trimDependencies);
280 } 294 }
281 handleRecoverableErrors(loader.unhandledErrors); 295 handleRecoverableErrors(loader.unhandledErrors);
282 } on InputError catch (e) { 296 } on InputError catch (e) {
283 handleInputError(e, isFullProgram: true); 297 handleInputError(e,
298 isFullProgram: true, trimDependencies: trimDependencies);
284 } catch (e, s) { 299 } catch (e, s) {
285 return reportCrash(e, s, loader?.currentUriForCrashReporting); 300 return reportCrash(e, s, loader?.currentUriForCrashReporting);
286 } 301 }
302 if (trimDependencies) trimDependenciesInProgram();
287 return program; 303 return program;
288 } 304 }
289 305
306 Future writeDepsFile(Uri output, Uri depsFile,
307 {Iterable<Uri> extraDependencies}) async {
308 String toRelativeFilePath(Uri uri) {
309 // Ninja expects to find file names relative to the current working
310 // directory. We've tried making them relative to the deps file, but that
311 // doesn't work for downstream projects. Making them absolute also
312 // doesn't work.
313 //
314 // We can test if it works by running ninja twice, for example:
315 //
316 // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
317 // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
318 //
319 // The second time, ninja should say:
320 //
321 // ninja: Entering directory `xcodebuild/ReleaseX64'
322 // ninja: no work to do.
323 //
324 // It's broken if it says something like this:
325 //
326 // ninja explain: expected depfile 'patched_sdk.d' to mention
327 // 'patched_sdk/platform.dill', got
328 // '/.../xcodebuild/ReleaseX64/patched_sdk/platform.dill'
329 return Uri.parse(relativizeUri(uri, base: Uri.base)).toFilePath();
330 }
331
332 if (loader.first == null) return null;
333 StringBuffer sb = new StringBuffer();
334 sb.write(toRelativeFilePath(output));
335 sb.write(":");
336 Set<String> allDependencies = new Set<String>();
337 allDependencies.addAll(loader.getDependencies().map(toRelativeFilePath));
338 if (extraDependencies != null) {
339 allDependencies.addAll(extraDependencies.map(toRelativeFilePath));
340 }
341 for (String path in allDependencies) {
342 sb.write(" ");
343 sb.write(path);
344 }
345 sb.writeln();
346 await new File.fromUri(depsFile).writeAsString("$sb");
347 ticker.logMs("Wrote deps file");
348 }
349
290 /// Adds a synthetic field named `#errors` to the main library that contains 350 /// Adds a synthetic field named `#errors` to the main library that contains
291 /// [recoverableErrors] formatted. 351 /// [recoverableErrors] formatted.
292 /// 352 ///
293 /// If [recoverableErrors] is empty, this method does nothing. 353 /// If [recoverableErrors] is empty, this method does nothing.
294 /// 354 ///
295 /// If there's no main library, this method uses [erroneousProgram] to 355 /// If there's no main library, this method uses [erroneousProgram] to
296 /// replace [program]. 356 /// replace [program].
297 void handleRecoverableErrors(List<InputError> recoverableErrors) { 357 void handleRecoverableErrors(List<InputError> recoverableErrors) {
298 if (recoverableErrors.isEmpty) return; 358 if (recoverableErrors.isEmpty) return;
299 KernelLibraryBuilder mainLibrary = loader.first; 359 KernelLibraryBuilder mainLibrary = loader.first;
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 backendTarget.performGlobalTransformations(loader.coreTypes, program, 683 backendTarget.performGlobalTransformations(loader.coreTypes, program,
624 logger: (String msg) => ticker.logMs(msg)); 684 logger: (String msg) => ticker.logMs(msg));
625 } 685 }
626 686
627 void verify() { 687 void verify() {
628 var verifyErrors = verifyProgram(program); 688 var verifyErrors = verifyProgram(program);
629 errors.addAll(verifyErrors.map((error) => '$error')); 689 errors.addAll(verifyErrors.map((error) => '$error'));
630 ticker.logMs("Verified program"); 690 ticker.logMs("Verified program");
631 } 691 }
632 692
693 /// Tree-shakes most code from the [dillTarget] by visiting all other
694 /// libraries in [program] and marking the APIs from the [dillTarget]
695 /// libraries that are in use.
696 ///
697 /// Note: while it's likely we'll do some trimming of programs for modular
698 /// compilation, it is unclear at this time when and how that trimming should
699 /// happen. We are likely going to remove the extra visitor my either marking
700 /// things while code is built, or by handling tree-shaking after the fact
701 /// (e.g. during serialization).
702 trimDependenciesInProgram() {
703 var toShake =
704 dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
705 var isIncluded = (Uri uri) => !toShake.contains(uri);
706 var data = new RetainedDataBuilder();
707 // TODO(sigmund): replace this step with data that is directly computed from
708 // the builders: we should know the tree-shaking roots without having to do
709 // a second visit over the tree.
710 new RootsMarker(loader.coreTypes, data).run(program, isIncluded);
711 trimProgram(program, data, isIncluded);
712 }
713
633 /// Return `true` if the given [library] was built by this [KernelTarget] 714 /// Return `true` if the given [library] was built by this [KernelTarget]
634 /// from sources, and not loaded from a [DillTarget]. 715 /// from sources, and not loaded from a [DillTarget].
635 bool isSourceLibrary(Library library) { 716 bool isSourceLibrary(Library library) {
636 return loader.libraries.contains(library); 717 return loader.libraries.contains(library);
637 } 718 }
638 } 719 }
639 720
640 /// Looks for a constructor call that matches `super()` from a constructor in 721 /// Looks for a constructor call that matches `super()` from a constructor in
641 /// [cls]. Such a constructor may have optional arguments, but no required 722 /// [cls]. Such a constructor may have optional arguments, but no required
642 /// arguments. 723 /// arguments.
643 Constructor defaultSuperConstructor(Class cls) { 724 Constructor defaultSuperConstructor(Class cls) {
644 Class superclass = cls.superclass; 725 Class superclass = cls.superclass;
645 while (superclass != null && superclass.isMixinApplication) { 726 while (superclass != null && superclass.isMixinApplication) {
646 superclass = superclass.superclass; 727 superclass = superclass.superclass;
647 } 728 }
648 for (Constructor constructor in superclass.constructors) { 729 for (Constructor constructor in superclass.constructors) {
649 if (constructor.name.name.isEmpty) { 730 if (constructor.name.name.isEmpty) {
650 return constructor.function.requiredParameterCount == 0 731 return constructor.function.requiredParameterCount == 0
651 ? constructor 732 ? constructor
652 : null; 733 : null;
653 } 734 }
654 } 735 }
655 return null; 736 return null;
656 } 737 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart ('k') | pkg/front_end/lib/src/fasta/kernel/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698