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 { |