| // 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. |
| |
| import 'dart:async'; |
| |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/error/error.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:front_end/incremental_kernel_generator.dart'; |
| import 'package:front_end/incremental_resolved_ast_generator.dart'; |
| import 'package:front_end/src/base/processed_options.dart'; |
| import 'package:front_end/src/base/source.dart'; |
| import 'package:front_end/src/incremental_resolved_ast_generator_impl.dart'; |
| import 'package:kernel/analyzer/loader.dart'; |
| import 'package:kernel/kernel.dart' hide Source; |
| import 'package:kernel/repository.dart'; |
| |
| dynamic unimplemented() { |
| // TODO(paulberry): get rid of this. |
| throw new UnimplementedError(); |
| } |
| |
| DartOptions _convertOptions(ProcessedOptions options) { |
| // TODO(paulberry): make sure options.compileSdk is handled correctly. |
| return new DartOptions( |
| strongMode: true, // TODO(paulberry): options.strongMode, |
| sdk: null, // TODO(paulberry): _uriToPath(options.sdkRoot, options), |
| sdkSummary: |
| null, // TODO(paulberry): options.compileSdk ? null : _uriToPath(options.sdkSummary, options), |
| packagePath: |
| null, // TODO(paulberry): _uriToPath(options.packagesFileUri, options), |
| declaredVariables: null // TODO(paulberry): options.declaredVariables |
| ); |
| } |
| |
| /// Implementation of [IncrementalKernelGenerator]. |
| /// |
| /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is |
| /// used to obtain resolved ASTs, and these are fed into kernel code generation |
| /// logic. |
| /// |
| /// Note that the kernel doesn't expect to take resolved ASTs as a direct input; |
| /// it expects to request resolved ASTs from an [AnalysisContext]. To deal with |
| /// this, we create [_AnalysisContextProxy] which returns the resolved ASTs when |
| /// requested. TODO(paulberry): Make this unnecessary. |
| class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| final IncrementalResolvedAstGenerator _resolvedAstGenerator; |
| final ProcessedOptions _options; |
| |
| IncrementalKernelGeneratorImpl(Uri source, ProcessedOptions options) |
| : _resolvedAstGenerator = |
| new IncrementalResolvedAstGeneratorImpl(source, options), |
| _options = options; |
| |
| @override |
| Future<DeltaProgram> computeDelta( |
| {Future<Null> watch(Uri uri, bool used)}) async { |
| var deltaLibraries = await _resolvedAstGenerator.computeDelta(); |
| var kernelOptions = _convertOptions(_options); |
| var packages = null; // TODO(paulberry) |
| var kernels = <Uri, Program>{}; |
| for (Uri uri in deltaLibraries.newState.keys) { |
| // The kernel generation code doesn't currently support building a kernel |
| // directly from resolved ASTs--it wants to query an analysis context. So |
| // we provide it with a proxy analysis context that feeds it the resolved |
| // ASTs. |
| var strongMode = true; // TODO(paulberry): set this correctly |
| var analysisOptions = new _AnalysisOptionsProxy(strongMode); |
| var context = |
| new _AnalysisContextProxy(deltaLibraries.newState, analysisOptions); |
| var repository = new Repository(); |
| var loader = |
| new DartLoader(repository, kernelOptions, packages, context: context); |
| loader.loadLibrary(uri); |
| kernels[uri] = new Program(repository.libraries); |
| // TODO(paulberry) rework watch invocation to eliminate race condition, |
| // include part source files, and prevent watch from being a bottleneck |
| if (watch != null) await watch(uri, true); |
| } |
| // TODO(paulberry) invoke watch with used=false for each unused source |
| return new DeltaProgram(kernels); |
| } |
| |
| @override |
| void invalidate(String path) => _resolvedAstGenerator.invalidate(path); |
| |
| @override |
| void invalidateAll() => _resolvedAstGenerator.invalidateAll(); |
| } |
| |
| class _AnalysisContextProxy implements AnalysisContext { |
| final Map<Uri, ResolvedLibrary> _resolvedLibraries; |
| |
| @override |
| final _SourceFactoryProxy sourceFactory = new _SourceFactoryProxy(); |
| |
| @override |
| final AnalysisOptions analysisOptions; |
| |
| _AnalysisContextProxy(this._resolvedLibraries, this.analysisOptions); |
| |
| List<AnalysisError> computeErrors(Source source) { |
| // TODO(paulberry): do we need to return errors sometimes? |
| return []; |
| } |
| |
| LibraryElement computeLibraryElement(Source source) { |
| assert(_resolvedLibraries.containsKey(source.uri)); |
| return resolutionMap |
| .elementDeclaredByCompilationUnit( |
| _resolvedLibraries[source.uri].definingCompilationUnit) |
| .library; |
| } |
| |
| noSuchMethod(Invocation invocation) => unimplemented(); |
| |
| CompilationUnit resolveCompilationUnit( |
| Source unitSource, LibraryElement library) { |
| assert(_resolvedLibraries.containsKey(library.source.uri)); |
| var resolvedLibrary = _resolvedLibraries[library.source.uri]; |
| if (unitSource == library.source) { |
| return resolvedLibrary.definingCompilationUnit; |
| } else { |
| assert(resolvedLibrary.partUnits.containsKey(unitSource.uri)); |
| return resolvedLibrary.partUnits[unitSource.uri]; |
| } |
| } |
| } |
| |
| class _AnalysisOptionsProxy implements AnalysisOptions { |
| final bool strongMode; |
| |
| _AnalysisOptionsProxy(this.strongMode); |
| |
| noSuchMethod(Invocation invocation) => unimplemented(); |
| } |
| |
| class _SourceFactoryProxy implements SourceFactory { |
| Source forUri2(Uri absoluteUri) => new _SourceProxy(absoluteUri); |
| |
| noSuchMethod(Invocation invocation) => unimplemented(); |
| } |
| |
| class _SourceProxy extends BasicSource { |
| _SourceProxy(Uri uri) : super(uri); |
| |
| noSuchMethod(Invocation invocation) => unimplemented(); |
| } |