|  | // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | /// Defines the front-end API for converting source code to Dart Kernel objects. | 
|  | library front_end.kernel_generator_impl; | 
|  |  | 
|  | import 'dart:async' show Future; | 
|  |  | 
|  | import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity; | 
|  |  | 
|  | import 'package:kernel/kernel.dart' show CanonicalName, Component; | 
|  |  | 
|  | import 'base/processed_options.dart' show ProcessedOptions; | 
|  |  | 
|  | import 'fasta/compiler_context.dart' show CompilerContext; | 
|  |  | 
|  | import 'fasta/crash.dart' show withCrashReporting; | 
|  |  | 
|  | import 'fasta/dill/dill_target.dart' show DillTarget; | 
|  |  | 
|  | import 'fasta/fasta_codes.dart' show LocatedMessage; | 
|  |  | 
|  | import 'fasta/kernel/kernel_api.dart'; | 
|  |  | 
|  | import 'fasta/kernel/kernel_target.dart' show KernelTarget; | 
|  |  | 
|  | import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent; | 
|  |  | 
|  | import 'fasta/kernel/verifier.dart' show verifyComponent; | 
|  |  | 
|  | import 'fasta/loader.dart' show Loader; | 
|  |  | 
|  | import 'fasta/uri_translator.dart' show UriTranslator; | 
|  |  | 
|  | import 'api_prototype/front_end.dart' show CompilerResult; | 
|  |  | 
|  | import 'api_prototype/file_system.dart' show FileSystem; | 
|  |  | 
|  | /// Implementation for the | 
|  | /// `package:front_end/src/api_prototype/kernel_generator.dart` and | 
|  | /// `package:front_end/src/api_prototype/summary_generator.dart` APIs. | 
|  | Future<CompilerResult> generateKernel(ProcessedOptions options, | 
|  | {bool buildSummary: false, | 
|  | bool buildComponent: true, | 
|  | bool truncateSummary: false, | 
|  | bool includeOffsets: true, | 
|  | bool includeHierarchyAndCoreTypes: false}) async { | 
|  | return await CompilerContext.runWithOptions(options, (_) async { | 
|  | return await generateKernelInternal( | 
|  | buildSummary: buildSummary, | 
|  | buildComponent: buildComponent, | 
|  | truncateSummary: truncateSummary, | 
|  | includeOffsets: includeOffsets, | 
|  | includeHierarchyAndCoreTypes: includeHierarchyAndCoreTypes); | 
|  | }); | 
|  | } | 
|  |  | 
|  | Future<CompilerResult> generateKernelInternal( | 
|  | {bool buildSummary: false, | 
|  | bool buildComponent: true, | 
|  | bool truncateSummary: false, | 
|  | bool includeOffsets: true, | 
|  | bool retainDataForTesting: false, | 
|  | bool includeHierarchyAndCoreTypes: false}) async { | 
|  | ProcessedOptions options = CompilerContext.current.options; | 
|  | FileSystem fs = options.fileSystem; | 
|  |  | 
|  | Loader sourceLoader; | 
|  | return withCrashReporting<CompilerResult>(() async { | 
|  | UriTranslator uriTranslator = await options.getUriTranslator(); | 
|  |  | 
|  | DillTarget dillTarget = | 
|  | new DillTarget(options.ticker, uriTranslator, options.target); | 
|  |  | 
|  | List<Component> loadedComponents = new List<Component>(); | 
|  |  | 
|  | Component sdkSummary = await options.loadSdkSummary(null); | 
|  | // By using the nameRoot of the the summary, we enable sharing the | 
|  | // sdkSummary between multiple invocations. | 
|  | CanonicalName nameRoot = sdkSummary?.root ?? new CanonicalName.root(); | 
|  | if (sdkSummary != null) { | 
|  | dillTarget.loader.appendLibraries(sdkSummary); | 
|  | } | 
|  |  | 
|  | // TODO(sigmund): provide better error reporting if input summaries or | 
|  | // linked dependencies were listed out of order (or provide mechanism to | 
|  | // sort them). | 
|  | for (Component inputSummary in await options.loadInputSummaries(nameRoot)) { | 
|  | loadedComponents.add(inputSummary); | 
|  | dillTarget.loader.appendLibraries(inputSummary); | 
|  | } | 
|  |  | 
|  | // Linked dependencies are meant to be part of the component so they are not | 
|  | // marked external. | 
|  | for (Component dependency in await options.loadLinkDependencies(nameRoot)) { | 
|  | loadedComponents.add(dependency); | 
|  | dillTarget.loader.appendLibraries(dependency); | 
|  | } | 
|  |  | 
|  | await dillTarget.buildOutlines(); | 
|  |  | 
|  | KernelTarget kernelTarget = | 
|  | new KernelTarget(fs, false, dillTarget, uriTranslator); | 
|  | sourceLoader = kernelTarget.loader; | 
|  | kernelTarget.setEntryPoints(options.inputs); | 
|  | Component summaryComponent = | 
|  | await kernelTarget.buildOutlines(nameRoot: nameRoot); | 
|  | List<int> summary = null; | 
|  | if (buildSummary) { | 
|  | if (options.verify) { | 
|  | for (LocatedMessage error in verifyComponent(summaryComponent)) { | 
|  | options.report(error, Severity.error); | 
|  | } | 
|  | } | 
|  | if (options.debugDump) { | 
|  | printComponentText(summaryComponent, | 
|  | libraryFilter: kernelTarget.isSourceLibrary); | 
|  | } | 
|  |  | 
|  | // Create the requested component ("truncating" or not). | 
|  | // | 
|  | // Note: we don't pass the library argument to the constructor to | 
|  | // preserve the the libraries parent pointer (it should continue to point | 
|  | // to the component within KernelTarget). | 
|  | Component trimmedSummaryComponent = | 
|  | new Component(nameRoot: summaryComponent.root) | 
|  | ..libraries.addAll(truncateSummary | 
|  | ? kernelTarget.loader.libraries | 
|  | : summaryComponent.libraries); | 
|  | trimmedSummaryComponent.metadata.addAll(summaryComponent.metadata); | 
|  | trimmedSummaryComponent.uriToSource.addAll(summaryComponent.uriToSource); | 
|  |  | 
|  | // As documented, we only run outline transformations when we are building | 
|  | // summaries without building a full component (at this time, that's | 
|  | // the only need we have for these transformations). | 
|  | if (!buildComponent) { | 
|  | options.target.performOutlineTransformations(trimmedSummaryComponent); | 
|  | options.ticker.logMs("Transformed outline"); | 
|  | } | 
|  | // Don't include source (but do add it above to include importUris). | 
|  | summary = serializeComponent(trimmedSummaryComponent, | 
|  | includeSources: false, includeOffsets: includeOffsets); | 
|  | options.ticker.logMs("Generated outline"); | 
|  | } | 
|  |  | 
|  | Component component; | 
|  | if (buildComponent) { | 
|  | component = await kernelTarget.buildComponent(verify: options.verify); | 
|  | if (options.debugDump) { | 
|  | printComponentText(component, | 
|  | libraryFilter: kernelTarget.isSourceLibrary); | 
|  | } | 
|  | options.ticker.logMs("Generated component"); | 
|  | } | 
|  |  | 
|  | return new InternalCompilerResult( | 
|  | summary: summary, | 
|  | component: component, | 
|  | sdkComponent: sdkSummary, | 
|  | loadedComponents: loadedComponents, | 
|  | classHierarchy: | 
|  | includeHierarchyAndCoreTypes ? kernelTarget.loader.hierarchy : null, | 
|  | coreTypes: | 
|  | includeHierarchyAndCoreTypes ? kernelTarget.loader.coreTypes : null, | 
|  | deps: new List<Uri>.from(CompilerContext.current.dependencies), | 
|  | kernelTargetForTesting: retainDataForTesting ? kernelTarget : null); | 
|  | }, () => sourceLoader?.currentUriForCrashReporting ?? options.inputs.first); | 
|  | } | 
|  |  | 
|  | /// Result object of [generateKernel]. | 
|  | class InternalCompilerResult implements CompilerResult { | 
|  | /// The generated summary bytes, if it was requested. | 
|  | final List<int> summary; | 
|  |  | 
|  | /// The generated component, if it was requested. | 
|  | final Component component; | 
|  |  | 
|  | final Component sdkComponent; | 
|  |  | 
|  | final List<Component> loadedComponents; | 
|  |  | 
|  | /// Dependencies traversed by the compiler. Used only for generating | 
|  | /// dependency .GN files in the dart-sdk build system. | 
|  | /// Note this might be removed when we switch to compute dependencies without | 
|  | /// using the compiler itself. | 
|  | final List<Uri> deps; | 
|  |  | 
|  | final ClassHierarchy classHierarchy; | 
|  |  | 
|  | final CoreTypes coreTypes; | 
|  |  | 
|  | /// The [KernelTarget] used to generated the component. | 
|  | /// | 
|  | /// This is only provided for use in testing. | 
|  | final KernelTarget kernelTargetForTesting; | 
|  |  | 
|  | InternalCompilerResult( | 
|  | {this.summary, | 
|  | this.component, | 
|  | this.sdkComponent, | 
|  | this.loadedComponents, | 
|  | this.deps, | 
|  | this.classHierarchy, | 
|  | this.coreTypes, | 
|  | this.kernelTargetForTesting}); | 
|  | } |