| Index: pkg/dev_compiler/lib/src/compiler/compiler.dart
|
| diff --git a/pkg/dev_compiler/lib/src/compiler/compiler.dart b/pkg/dev_compiler/lib/src/compiler/compiler.dart
|
| index ac1d60a6e66eee332fbae639b6ecacefb57459bf..55aefca1eaad64dce93ba870d35ae7256b5179af 100644
|
| --- a/pkg/dev_compiler/lib/src/compiler/compiler.dart
|
| +++ b/pkg/dev_compiler/lib/src/compiler/compiler.dart
|
| @@ -2,30 +2,35 @@
|
| // 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.
|
|
|
| +import 'dart:async';
|
| import 'dart:collection' show HashSet, Queue;
|
| import 'dart:convert' show JSON;
|
| import 'dart:io' show File;
|
|
|
| import 'package:analyzer/analyzer.dart'
|
| show AnalysisError, CompilationUnit, ErrorSeverity;
|
| +import 'package:analyzer/context/declared_variables.dart';
|
| import 'package:analyzer/dart/element/element.dart' show LibraryElement;
|
| import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
|
| import 'package:analyzer/file_system/physical_file_system.dart'
|
| show PhysicalResourceProvider;
|
| import 'package:analyzer/src/context/builder.dart' show ContextBuilder;
|
| -import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
|
| +import 'package:analyzer/src/dart/analysis/driver.dart';
|
| +import 'package:analyzer/src/dart/analysis/file_state.dart';
|
| import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode;
|
| -import 'package:analyzer/src/generated/engine.dart'
|
| - show AnalysisContext, AnalysisEngine;
|
| +import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
|
| +import 'package:analyzer/src/generated/resolver.dart';
|
| import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
|
| import 'package:analyzer/src/generated/source.dart'
|
| - show ContentCache, DartUriResolver;
|
| + show ContentCache, DartUriResolver, LineInfo;
|
| import 'package:analyzer/src/generated/source_io.dart'
|
| show Source, SourceKind, UriResolver;
|
| import 'package:analyzer/src/summary/package_bundle_reader.dart'
|
| - show InSummarySource, InputPackagesResultProvider, SummaryDataStore;
|
| + show InSummarySource, SummaryDataStore;
|
| import 'package:args/args.dart' show ArgParser, ArgResults;
|
| import 'package:args/src/usage_exception.dart' show UsageException;
|
| +import 'package:front_end/src/base/performace_logger.dart';
|
| +import 'package:front_end/src/incremental/byte_store.dart';
|
| import 'package:func/func.dart' show Func1;
|
| import 'package:path/path.dart' as path;
|
| import 'package:source_maps/source_maps.dart';
|
| @@ -47,24 +52,26 @@ import 'source_map_printer.dart' show SourceMapPrintingContext;
|
| /// for a single compile.
|
| ///
|
| /// This class exists to cache global state associated with a single in-memory
|
| -/// AnalysisContext, such as information about extension types in the Dart SDK.
|
| +/// [AnalysisDriver], such as information about extension types in the Dart SDK.
|
| /// It can be used once to produce a single module, or reused to save warm-up
|
| /// time. (Currently there is no warm up, but there may be in the future.)
|
| ///
|
| /// The SDK source code is assumed to be immutable for the life of this class.
|
| ///
|
| -/// For all other files, it is up to the [AnalysisContext] to decide whether or
|
| +/// For all other files, it is up to the [AnalysisDriver] to decide whether or
|
| /// not any caching is performed. By default an analysis context will assume
|
| /// sources are immutable for the life of the context, and cache information
|
| /// about them.
|
| class ModuleCompiler {
|
| - final AnalysisContext context;
|
| + final AnalysisDriver driver;
|
| final SummaryDataStore summaryData;
|
| - final ExtensionTypeSet _extensionTypes;
|
|
|
| - ModuleCompiler._(AnalysisContext context, this.summaryData)
|
| - : context = context,
|
| - _extensionTypes = new ExtensionTypeSet(context);
|
| + final Map<String, LibraryElement> _dartLibraries = {};
|
| + TypeProviderImpl _typeProvider;
|
| +
|
| + ExtensionTypeSet _extensionTypes;
|
| +
|
| + ModuleCompiler._(this.driver, this.summaryData);
|
|
|
| factory ModuleCompiler(AnalyzerOptions options,
|
| {ResourceProvider resourceProvider,
|
| @@ -104,33 +111,44 @@ class ModuleCompiler {
|
| summaryData: summaryData,
|
| resourceProvider: resourceProvider);
|
|
|
| - var context =
|
| - AnalysisEngine.instance.createAnalysisContext() as AnalysisContextImpl;
|
| - context.analysisOptions = analysisOptions;
|
| - context.sourceFactory = srcFactory;
|
| - if (sdkSummaryBundle != null) {
|
| - context.resultProvider =
|
| - new InputPackagesResultProvider(context, summaryData);
|
| - }
|
| - options.declaredVariables.forEach(context.declaredVariables.define);
|
| - context.declaredVariables.define('dart.isVM', 'false');
|
| -
|
| + var declaredVariables = new DeclaredVariables();
|
| + options.declaredVariables.forEach(declaredVariables.define);
|
| + declaredVariables.define('dart.isVM', 'false');
|
| // TODO(vsm): Should this be hardcoded?
|
| - context.declaredVariables.define('dart.library.html', 'true');
|
| - context.declaredVariables.define('dart.library.io', 'false');
|
| + declaredVariables.define('dart.library.html', 'true');
|
| + declaredVariables.define('dart.library.io', 'false');
|
|
|
| - if (!context.analysisOptions.strongMode) {
|
| - throw new ArgumentError('AnalysisContext must be strong mode');
|
| + if (!analysisOptions.strongMode) {
|
| + throw new ArgumentError('AnalysisOptions must be strong mode');
|
| + }
|
| + if (!srcFactory.dartSdk.context.analysisOptions.strongMode) {
|
| + throw new ArgumentError('AnalysisOptions must have strong mode SDK');
|
| }
|
| - if (!context.sourceFactory.dartSdk.context.analysisOptions.strongMode) {
|
| - throw new ArgumentError('AnalysisContext must have strong mode SDK');
|
| +
|
| + AnalysisDriver driver;
|
| + {
|
| + var logger = new PerformanceLog(new StringBuffer());
|
| + var scheduler = new AnalysisDriverScheduler(logger);
|
| + driver = new AnalysisDriver(
|
| + scheduler,
|
| + logger,
|
| + resourceProvider,
|
| + new MemoryByteStore(),
|
| + new FileContentOverlay(),
|
| + null,
|
| + srcFactory,
|
| + analysisOptions,
|
| + disableChangesAndCacheAllResults: true,
|
| + externalSummaries: summaryData);
|
| + scheduler.start();
|
| }
|
|
|
| - return new ModuleCompiler._(context, summaryData);
|
| + return new ModuleCompiler._(driver, summaryData);
|
| }
|
|
|
| bool _isFatalError(AnalysisError e, CompilerOptions options) {
|
| - if (errorSeverity(context, e) != ErrorSeverity.ERROR) return false;
|
| + if (errorSeverity(driver.analysisOptions, e) != ErrorSeverity.ERROR)
|
| + return false;
|
|
|
| // These errors are not fatal in the REPL compile mode as we
|
| // allow access to private members across library boundaries
|
| @@ -149,38 +167,43 @@ class ModuleCompiler {
|
| /// *Warning* - this may require resolving the entire world.
|
| /// If that is not desired, the analysis context must be pre-configured using
|
| /// summaries before calling this method.
|
| - JSModuleFile compile(BuildUnit unit, CompilerOptions options) {
|
| + Future<JSModuleFile> compile(BuildUnit unit, CompilerOptions options) async {
|
| var trees = <CompilationUnit>[];
|
| var errors = <AnalysisError>[];
|
| + var lineInfoMap = <String, LineInfo>{};
|
|
|
| var librariesToCompile = new Queue<LibraryElement>();
|
|
|
| var compilingSdk = false;
|
| - for (var sourcePath in unit.sources) {
|
| - var sourceUri = _sourceToUri(sourcePath);
|
| + for (var sourceUriStr in unit.sources) {
|
| + var sourceUri = _sourceToUri(sourceUriStr);
|
| if (sourceUri.scheme == "dart") {
|
| compilingSdk = true;
|
| }
|
| - var source = context.sourceFactory.forUri2(sourceUri);
|
| + var source = driver.sourceFactory.forUri2(sourceUri);
|
| + String sourcePath = source.fullName;
|
|
|
| var fileUsage = 'You need to pass at least one existing .dart file as an'
|
| ' argument.';
|
| if (source == null) {
|
| throw new UsageException(
|
| - 'Could not create a source for "$sourcePath". The file name is in'
|
| + 'Could not create a source for "$sourceUriStr". The file name is in'
|
| ' the wrong format or was not found.',
|
| fileUsage);
|
| } else if (!source.exists()) {
|
| throw new UsageException(
|
| - 'Given file "$sourcePath" does not exist.', fileUsage);
|
| + 'Given file "$sourceUriStr" does not exist.', fileUsage);
|
| }
|
|
|
| // Ignore parts. They need to be handled in the context of their library.
|
| - if (context.computeKindOf(source) == SourceKind.PART) {
|
| + SourceKind sourceKind = await driver.getSourceKind(sourcePath);
|
| + if (sourceKind == SourceKind.PART) {
|
| continue;
|
| }
|
|
|
| - librariesToCompile.add(context.computeLibraryElement(source));
|
| + UnitElementResult unitResult = await driver.getUnitElement(sourcePath);
|
| + LibraryElement library = unitResult.element.library;
|
| + librariesToCompile.add(library);
|
| }
|
|
|
| var libraries = new HashSet<LibraryElement>();
|
| @@ -193,21 +216,30 @@ class ModuleCompiler {
|
| librariesToCompile.addAll(library.importedLibraries);
|
| librariesToCompile.addAll(library.exportedLibraries);
|
|
|
| - var tree = context.resolveCompilationUnit(library.source, library);
|
| - trees.add(tree);
|
| - errors.addAll(context.computeErrors(library.source));
|
| + var definingResult = await driver.getResult(library.source.fullName);
|
| + trees.add(definingResult.unit);
|
| + errors.addAll(definingResult.errors);
|
| + lineInfoMap[definingResult.path] = definingResult.lineInfo;
|
|
|
| for (var part in library.parts) {
|
| - trees.add(context.resolveCompilationUnit(part.source, library));
|
| - errors.addAll(context.computeErrors(part.source));
|
| + var partResult = await driver.getResult(part.source.fullName);
|
| + trees.add(partResult.unit);
|
| + errors.addAll(partResult.errors);
|
| + lineInfoMap[partResult.path] = partResult.lineInfo;
|
| }
|
| }
|
|
|
| - sortErrors(context, errors);
|
| + sortErrors(driver.analysisOptions, errors);
|
| +
|
| + LibraryElement coreLibrary = await _getDartLibrary('dart:core');
|
| + LibraryElement asyncLibrary = await _getDartLibrary('dart:async');
|
| + _typeProvider ??= new TypeProviderImpl(coreLibrary, asyncLibrary);
|
| + _extensionTypes ??= await _newExtensionTypeSet();
|
|
|
| var messages = <String>[];
|
| - for (var e in errors) {
|
| - var m = formatError(context, e);
|
| + for (AnalysisError e in errors) {
|
| + var lineInfo = lineInfoMap[e.source.fullName];
|
| + var m = formatError(driver.analysisOptions, lineInfo, e);
|
| if (m != null) messages.add(m);
|
| }
|
|
|
| @@ -217,8 +249,14 @@ class ModuleCompiler {
|
| }
|
|
|
| try {
|
| - var codeGenerator =
|
| - new CodeGenerator(context, summaryData, options, _extensionTypes);
|
| + var codeGenerator = new CodeGenerator(
|
| + driver, summaryData, options, _extensionTypes,
|
| + types: _typeProvider,
|
| + coreLibrary: coreLibrary,
|
| + asyncLibrary: asyncLibrary,
|
| + interceptorsLibrary: await _getDartLibrary('dart:_interceptors'),
|
| + internalLibrary: await _getDartLibrary('dart:_internal'),
|
| + jsLibrary: await _getDartLibrary('dart:js'));
|
| return codeGenerator.compile(unit, trees, messages);
|
| } catch (e) {
|
| if (errors.any((e) => _isFatalError(e, options))) {
|
| @@ -230,6 +268,32 @@ class ModuleCompiler {
|
| rethrow;
|
| }
|
| }
|
| +
|
| + Future<LibraryElement> _getDartLibrary(String uri) async {
|
| + assert(uri.startsWith('dart:'));
|
| + LibraryElement library = _dartLibraries[uri];
|
| + if (library == null) {
|
| + library = await driver.getLibraryByUri(uri);
|
| + _dartLibraries[uri] = library;
|
| + }
|
| + return library;
|
| + }
|
| +
|
| + Future<ExtensionTypeSet> _newExtensionTypeSet() async {
|
| + return new ExtensionTypeSet(
|
| + coreLibrary: await _getDartLibrary('dart:core'),
|
| + collectionLibrary: await _getDartLibrary('dart:collection'),
|
| + mathLibrary: await _getDartLibrary('dart:math'),
|
| + htmlLibrary: await _getDartLibrary('dart:html'),
|
| + indexedDbLibrary: await _getDartLibrary('dart:indexed_db'),
|
| + svgLibrary: await _getDartLibrary('dart:svg'),
|
| + webAudioLibrary: await _getDartLibrary('dart:web_audio'),
|
| + webGlLibrary: await _getDartLibrary('dart:web_gl'),
|
| + webSqlLibrary: await _getDartLibrary('dart:web_sql'),
|
| + interceptorsLibrary: await _getDartLibrary('dart:_interceptors'),
|
| + nativeTypedDataLibrary:
|
| + await _getDartLibrary('dart:_native_typed_data'));
|
| + }
|
| }
|
|
|
| class CompilerOptions {
|
|
|