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

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

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