| Index: pkg/compiler/lib/src/compiler.dart
|
| diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
|
| index 4020814d323c1f390d0e0e1db379bc828cfb3241..2eebdb39db1c68af188fc47500a0e01c6976987e 100644
|
| --- a/pkg/compiler/lib/src/compiler.dart
|
| +++ b/pkg/compiler/lib/src/compiler.dart
|
| @@ -403,17 +403,17 @@ abstract class Compiler implements LibraryLoaderListener {
|
| // The resulting future will complete with true if the compilation
|
| // succeeded.
|
| Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () {
|
| - measurer.startWallClock();
|
| -
|
| - return new Future.sync(() => runInternal(uri))
|
| - .catchError((error) => _reporter.onError(uri, error))
|
| - .whenComplete(() {
|
| - tracer.close();
|
| - measurer.stopWallClock();
|
| - }).then((_) {
|
| - return !compilationFailed;
|
| - });
|
| - });
|
| + measurer.startWallClock();
|
| +
|
| + return new Future.sync(() => runInternal(uri))
|
| + .catchError((error) => _reporter.onError(uri, error))
|
| + .whenComplete(() {
|
| + tracer.close();
|
| + measurer.stopWallClock();
|
| + }).then((_) {
|
| + return !compilationFailed;
|
| + });
|
| + });
|
|
|
| /// This method is called immediately after the [LibraryElement] [library] has
|
| /// been created.
|
| @@ -449,9 +449,7 @@ abstract class Compiler implements LibraryLoaderListener {
|
| //
|
| // This could for example happen if dart:async is disabled, then loading it
|
| // should not try to find the given element.
|
| - // TODO(johnniwinther): This should just be library.isSynthesized, but that
|
| - // does not work yet for deserialized elements.
|
| - if (!library.compilationUnit.script.isSynthesized) {
|
| + if (!library.isSynthesized) {
|
| if (uri == Uris.dart_core) {
|
| initializeCoreClasses();
|
| identicalFunction = coreLibrary.find('identical');
|
| @@ -809,112 +807,112 @@ abstract class Compiler implements LibraryLoaderListener {
|
| }
|
|
|
| /// Performs the compilation when all libraries have been loaded.
|
| - void compileLoadedLibraries()
|
| - => selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
|
| -
|
| - computeMain();
|
| -
|
| - mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
|
| -
|
| - // In order to see if a library is deferred, we must compute the
|
| - // compile-time constants that are metadata. This means adding
|
| - // something to the resolution queue. So we cannot wait with
|
| - // this until after the resolution queue is processed.
|
| - deferredLoadTask.beforeResolution(this);
|
| - impactStrategy = backend.createImpactStrategy(
|
| - supportDeferredLoad: deferredLoadTask.isProgramSplit,
|
| - supportDumpInfo: options.dumpInfo,
|
| - supportSerialization: serialization.supportSerialization);
|
| -
|
| - phase = PHASE_RESOLVING;
|
| - if (analyzeAll) {
|
| - libraryLoader.libraries.forEach((LibraryElement library) {
|
| - reporter.log('Enqueuing ${library.canonicalUri}');
|
| - fullyEnqueueLibrary(library, enqueuer.resolution);
|
| - });
|
| - } else if (options.analyzeMain) {
|
| - if (mainApp != null) {
|
| - fullyEnqueueLibrary(mainApp, enqueuer.resolution);
|
| - }
|
| - if (librariesToAnalyzeWhenRun != null) {
|
| - for (Uri libraryUri in librariesToAnalyzeWhenRun) {
|
| - fullyEnqueueLibrary(
|
| - libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution);
|
| + void compileLoadedLibraries() =>
|
| + selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
|
| + computeMain();
|
| +
|
| + mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
|
| +
|
| + // In order to see if a library is deferred, we must compute the
|
| + // compile-time constants that are metadata. This means adding
|
| + // something to the resolution queue. So we cannot wait with
|
| + // this until after the resolution queue is processed.
|
| + deferredLoadTask.beforeResolution(this);
|
| + impactStrategy = backend.createImpactStrategy(
|
| + supportDeferredLoad: deferredLoadTask.isProgramSplit,
|
| + supportDumpInfo: options.dumpInfo,
|
| + supportSerialization: serialization.supportSerialization);
|
| +
|
| + phase = PHASE_RESOLVING;
|
| + if (analyzeAll) {
|
| + libraryLoader.libraries.forEach((LibraryElement library) {
|
| + reporter.log('Enqueuing ${library.canonicalUri}');
|
| + fullyEnqueueLibrary(library, enqueuer.resolution);
|
| + });
|
| + } else if (options.analyzeMain) {
|
| + if (mainApp != null) {
|
| + fullyEnqueueLibrary(mainApp, enqueuer.resolution);
|
| + }
|
| + if (librariesToAnalyzeWhenRun != null) {
|
| + for (Uri libraryUri in librariesToAnalyzeWhenRun) {
|
| + fullyEnqueueLibrary(
|
| + libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution);
|
| + }
|
| + }
|
| + }
|
| + // Elements required by enqueueHelpers are global dependencies
|
| + // that are not pulled in by a particular element.
|
| + backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
|
| + resolveLibraryMetadata();
|
| + reporter.log('Resolving...');
|
| + processQueue(enqueuer.resolution, mainFunction);
|
| + enqueuer.resolution.logSummary(reporter.log);
|
| +
|
| + _reporter.reportSuppressedMessagesSummary();
|
| +
|
| + if (compilationFailed) {
|
| + if (!options.generateCodeWithCompileTimeErrors) return;
|
| + if (!backend
|
| + .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) {
|
| + return;
|
| + }
|
| }
|
| - }
|
| - }
|
| - // Elements required by enqueueHelpers are global dependencies
|
| - // that are not pulled in by a particular element.
|
| - backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
|
| - resolveLibraryMetadata();
|
| - reporter.log('Resolving...');
|
| - processQueue(enqueuer.resolution, mainFunction);
|
| - enqueuer.resolution.logSummary(reporter.log);
|
| -
|
| - _reporter.reportSuppressedMessagesSummary();
|
| -
|
| - if (compilationFailed) {
|
| - if (!options.generateCodeWithCompileTimeErrors) return;
|
| - if (!backend.enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) {
|
| - return;
|
| - }
|
| - }
|
|
|
| - if (options.analyzeOnly) {
|
| - if (!analyzeAll && !compilationFailed) {
|
| - // No point in reporting unused code when [analyzeAll] is true: all
|
| - // code is artificially used.
|
| - // If compilation failed, it is possible that the error prevents the
|
| - // compiler from analyzing all the code.
|
| - // TODO(johnniwinther): Reenable this when the reporting is more
|
| - // precise.
|
| - //reportUnusedCode();
|
| - }
|
| - return;
|
| - }
|
| - assert(mainFunction != null);
|
| - phase = PHASE_DONE_RESOLVING;
|
| + if (options.analyzeOnly) {
|
| + if (!analyzeAll && !compilationFailed) {
|
| + // No point in reporting unused code when [analyzeAll] is true: all
|
| + // code is artificially used.
|
| + // If compilation failed, it is possible that the error prevents the
|
| + // compiler from analyzing all the code.
|
| + // TODO(johnniwinther): Reenable this when the reporting is more
|
| + // precise.
|
| + //reportUnusedCode();
|
| + }
|
| + return;
|
| + }
|
| + assert(mainFunction != null);
|
| + phase = PHASE_DONE_RESOLVING;
|
|
|
| - world.populate();
|
| - // Compute whole-program-knowledge that the backend needs. (This might
|
| - // require the information computed in [world.populate].)
|
| - backend.onResolutionComplete();
|
| + world.populate();
|
| + // Compute whole-program-knowledge that the backend needs. (This might
|
| + // require the information computed in [world.populate].)
|
| + backend.onResolutionComplete();
|
|
|
| - deferredLoadTask.onResolutionComplete(mainFunction);
|
| + deferredLoadTask.onResolutionComplete(mainFunction);
|
|
|
| - reporter.log('Inferring types...');
|
| - typesTask.onResolutionComplete(mainFunction);
|
| + reporter.log('Inferring types...');
|
| + typesTask.onResolutionComplete(mainFunction);
|
|
|
| - if (stopAfterTypeInference) return;
|
| + if (stopAfterTypeInference) return;
|
|
|
| - backend.onTypeInferenceComplete();
|
| + backend.onTypeInferenceComplete();
|
|
|
| - reporter.log('Compiling...');
|
| - phase = PHASE_COMPILING;
|
| - backend.onCodegenStart();
|
| - // TODO(johnniwinther): Move these to [CodegenEnqueuer].
|
| - if (hasIsolateSupport) {
|
| - backend.enableIsolateSupport(enqueuer.codegen);
|
| - }
|
| - if (compileAll) {
|
| - libraryLoader.libraries.forEach((LibraryElement library) {
|
| - fullyEnqueueLibrary(library, enqueuer.codegen);
|
| - });
|
| - }
|
| - processQueue(enqueuer.codegen, mainFunction);
|
| - enqueuer.codegen.logSummary(reporter.log);
|
| + reporter.log('Compiling...');
|
| + phase = PHASE_COMPILING;
|
| + backend.onCodegenStart();
|
| + // TODO(johnniwinther): Move these to [CodegenEnqueuer].
|
| + if (hasIsolateSupport) {
|
| + backend.enableIsolateSupport(enqueuer.codegen);
|
| + }
|
| + if (compileAll) {
|
| + libraryLoader.libraries.forEach((LibraryElement library) {
|
| + fullyEnqueueLibrary(library, enqueuer.codegen);
|
| + });
|
| + }
|
| + processQueue(enqueuer.codegen, mainFunction);
|
| + enqueuer.codegen.logSummary(reporter.log);
|
|
|
| - int programSize = backend.assembleProgram();
|
| + int programSize = backend.assembleProgram();
|
|
|
| - if (options.dumpInfo) {
|
| - dumpInfoTask.reportSize(programSize);
|
| - dumpInfoTask.dumpInfo();
|
| - }
|
| + if (options.dumpInfo) {
|
| + dumpInfoTask.reportSize(programSize);
|
| + dumpInfoTask.dumpInfo();
|
| + }
|
|
|
| - backend.sourceInformationStrategy.onComplete();
|
| + backend.sourceInformationStrategy.onComplete();
|
|
|
| - checkQueues();
|
| - });
|
| + checkQueues();
|
| + });
|
|
|
| void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
|
| void enqueueAll(Element element) {
|
| @@ -950,48 +948,53 @@ abstract class Compiler implements LibraryLoaderListener {
|
| /**
|
| * Empty the [world] queue.
|
| */
|
| - void emptyQueue(Enqueuer world)
|
| - => selfTask.measureSubtask("Compiler.emptyQueue", () {
|
| - world.forEach((WorkItem work) {
|
| - reporter.withCurrentElement(
|
| - work.element, () => selfTask.measureSubtask("world.applyImpact", () {
|
| - world.applyImpact(
|
| - work.element,
|
| - selfTask.measureSubtask("work.run", () => work.run(this, world)));
|
| - }));
|
| - });
|
| - });
|
| -
|
| - void processQueue(Enqueuer world, Element main)
|
| - => selfTask.measureSubtask("Compiler.processQueue", () {
|
| - world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
|
| - if (main != null && !main.isMalformed) {
|
| - FunctionElement mainMethod = main;
|
| - mainMethod.computeType(resolution);
|
| - if (mainMethod.functionSignature.parameterCount != 0) {
|
| - // The first argument could be a list of strings.
|
| - backend.listImplementation.ensureResolved(resolution);
|
| - backend.registerInstantiatedType(
|
| - backend.listImplementation.rawType, world, globalDependencies);
|
| - backend.stringImplementation.ensureResolved(resolution);
|
| - backend.registerInstantiatedType(
|
| - backend.stringImplementation.rawType, world, globalDependencies);
|
| -
|
| - backend.registerMainHasArguments(world);
|
| - }
|
| - world.addToWorkList(main);
|
| - }
|
| - if (options.verbose) {
|
| - progress.reset();
|
| - }
|
| - emptyQueue(world);
|
| - world.queueIsClosed = true;
|
| - // Notify the impact strategy impacts are no longer needed for this
|
| - // enqueuer.
|
| - impactStrategy.onImpactUsed(world.impactUse);
|
| - backend.onQueueClosed();
|
| - assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
|
| - });
|
| + void emptyQueue(Enqueuer world) =>
|
| + selfTask.measureSubtask("Compiler.emptyQueue", () {
|
| + world.forEach((WorkItem work) {
|
| + reporter.withCurrentElement(
|
| + work.element,
|
| + () => selfTask.measureSubtask("world.applyImpact", () {
|
| + world.applyImpact(
|
| + work.element,
|
| + selfTask.measureSubtask(
|
| + "work.run", () => work.run(this, world)));
|
| + }));
|
| + });
|
| + });
|
| +
|
| + void processQueue(Enqueuer world, Element main) =>
|
| + selfTask.measureSubtask("Compiler.processQueue", () {
|
| + world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
|
| + if (main != null && !main.isMalformed) {
|
| + FunctionElement mainMethod = main;
|
| + mainMethod.computeType(resolution);
|
| + if (mainMethod.functionSignature.parameterCount != 0) {
|
| + // The first argument could be a list of strings.
|
| + backend.listImplementation.ensureResolved(resolution);
|
| + backend.registerInstantiatedType(
|
| + backend.listImplementation.rawType, world, globalDependencies);
|
| + backend.stringImplementation.ensureResolved(resolution);
|
| + backend.registerInstantiatedType(
|
| + backend.stringImplementation.rawType,
|
| + world,
|
| + globalDependencies);
|
| +
|
| + backend.registerMainHasArguments(world);
|
| + }
|
| + world.addToWorkList(main);
|
| + }
|
| + if (options.verbose) {
|
| + progress.reset();
|
| + }
|
| + emptyQueue(world);
|
| + world.queueIsClosed = true;
|
| + // Notify the impact strategy impacts are no longer needed for this
|
| + // enqueuer.
|
| + impactStrategy.onImpactUsed(world.impactUse);
|
| + backend.onQueueClosed();
|
| + assert(
|
| + compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
|
| + });
|
|
|
| /**
|
| * Perform various checks of the queues. This includes checking that
|
| @@ -1032,47 +1035,47 @@ abstract class Compiler implements LibraryLoaderListener {
|
| }
|
| }
|
|
|
| - WorldImpact analyzeElement(Element element)
|
| - => selfTask.measureSubtask("Compiler.analyzeElement", () {
|
| - assert(invariant(
|
| - element,
|
| - element.impliesType ||
|
| - element.isField ||
|
| - element.isFunction ||
|
| - element.isConstructor ||
|
| - element.isGetter ||
|
| - element.isSetter,
|
| - message: 'Unexpected element kind: ${element.kind}'));
|
| - assert(invariant(element, element is AnalyzableElement,
|
| - message: 'Element $element is not analyzable.'));
|
| - assert(invariant(element, element.isDeclaration));
|
| - return resolution.computeWorldImpact(element);
|
| - });
|
| -
|
| - WorldImpact analyze(ResolutionWorkItem work,
|
| - ResolutionEnqueuer world)
|
| - => selfTask.measureSubtask("Compiler.analyze", () {
|
| - assert(invariant(work.element, identical(world, enqueuer.resolution)));
|
| - assert(invariant(work.element, !work.isAnalyzed,
|
| - message: 'Element ${work.element} has already been analyzed'));
|
| - if (shouldPrintProgress) {
|
| - // TODO(ahe): Add structured diagnostics to the compiler API and
|
| - // use it to separate this from the --verbose option.
|
| - if (phase == PHASE_RESOLVING) {
|
| - reporter.log('Resolved ${enqueuer.resolution.processedElements.length} '
|
| - 'elements.');
|
| - progress.reset();
|
| - }
|
| - }
|
| - AstElement element = work.element;
|
| - if (world.hasBeenProcessed(element)) {
|
| - return const WorldImpact();
|
| - }
|
| - WorldImpact worldImpact = analyzeElement(element);
|
| - backend.onElementResolved(element);
|
| - world.registerProcessedElement(element);
|
| - return worldImpact;
|
| - });
|
| + WorldImpact analyzeElement(Element element) =>
|
| + selfTask.measureSubtask("Compiler.analyzeElement", () {
|
| + assert(invariant(
|
| + element,
|
| + element.impliesType ||
|
| + element.isField ||
|
| + element.isFunction ||
|
| + element.isConstructor ||
|
| + element.isGetter ||
|
| + element.isSetter,
|
| + message: 'Unexpected element kind: ${element.kind}'));
|
| + assert(invariant(element, element is AnalyzableElement,
|
| + message: 'Element $element is not analyzable.'));
|
| + assert(invariant(element, element.isDeclaration));
|
| + return resolution.computeWorldImpact(element);
|
| + });
|
| +
|
| + WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) =>
|
| + selfTask.measureSubtask("Compiler.analyze", () {
|
| + assert(invariant(work.element, identical(world, enqueuer.resolution)));
|
| + assert(invariant(work.element, !work.isAnalyzed,
|
| + message: 'Element ${work.element} has already been analyzed'));
|
| + if (shouldPrintProgress) {
|
| + // TODO(ahe): Add structured diagnostics to the compiler API and
|
| + // use it to separate this from the --verbose option.
|
| + if (phase == PHASE_RESOLVING) {
|
| + reporter
|
| + .log('Resolved ${enqueuer.resolution.processedElements.length} '
|
| + 'elements.');
|
| + progress.reset();
|
| + }
|
| + }
|
| + AstElement element = work.element;
|
| + if (world.hasBeenProcessed(element)) {
|
| + return const WorldImpact();
|
| + }
|
| + WorldImpact worldImpact = analyzeElement(element);
|
| + backend.onElementResolved(element);
|
| + world.registerProcessedElement(element);
|
| + return worldImpact;
|
| + });
|
|
|
| WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) {
|
| assert(invariant(work.element, identical(world, enqueuer.codegen)));
|
|
|