Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Unified Diff: pkg/analyzer/lib/src/dart/analysis/library_context.dart

Issue 2661023005: Isolate the part of AnalysisDriver that manages the AnalysisContext. (Closed)
Patch Set: Un-do unrelated change Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/driver.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/dart/analysis/library_context.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
new file mode 100644
index 0000000000000000000000000000000000000000..aac7379f2a027ca30e32a9a2d53a4f945b7f03a3
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -0,0 +1,234 @@
+// 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 'package:analyzer/context/declared_variables.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement;
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisContext, AnalysisEngine, AnalysisOptions;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT;
+import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit;
+
+/**
+ * Context information necessary to analyze one or more libraries within an
+ * [AnalysisDriver].
+ *
+ * Currently this is implemented as a wrapper around [AnalysisContext].
+ * TODO(paulberry): make a front end API that this can make use of instead.
+ */
+class LibraryContext {
+ /**
+ * The [AnalysisContext] which is used to do the analysis.
+ */
+ final AnalysisContext _analysisContext;
+
+ /**
+ * Create a [LibraryContext] which is prepared to analyze [library].
+ */
+ factory LibraryContext.forSingleLibrary(
+ FileState library,
+ PerformanceLog logger,
+ PackageBundle sdkBundle,
+ ByteStore byteStore,
+ AnalysisOptions options,
+ DeclaredVariables declaredVariables,
+ SourceFactory sourceFactory,
+ FileSystemState fsState) {
+ return logger.run('Create library context', () {
+ Map<String, FileState> libraries = <String, FileState>{};
+ SummaryDataStore store = new SummaryDataStore(const <String>[]);
+
+ if (sdkBundle != null) {
+ store.addBundle(null, sdkBundle);
+ }
+
+ void appendLibraryFiles(FileState library) {
+ if (!libraries.containsKey(library.uriStr)) {
+ // Serve 'dart:' URIs from the SDK bundle.
+ if (sdkBundle != null && library.uri.scheme == 'dart') {
+ return;
+ }
+
+ libraries[library.uriStr] = library;
+
+ // Append the defining unit.
+ store.addUnlinkedUnit(library.uriStr, library.unlinked);
+
+ // Append parts.
+ for (FileState part in library.partedFiles) {
+ store.addUnlinkedUnit(part.uriStr, part.unlinked);
+ }
+
+ // Append referenced libraries.
+ library.importedFiles.forEach(appendLibraryFiles);
+ library.exportedFiles.forEach(appendLibraryFiles);
+ }
+ }
+
+ logger.run('Append library files', () {
+ return appendLibraryFiles(library);
+ });
+
+ Set<String> libraryUrisToLink = new Set<String>();
+ logger.run('Load linked bundles', () {
+ for (FileState library in libraries.values) {
+ if (library.exists) {
+ String key = '${library.transitiveSignature}.linked';
+ List<int> bytes = byteStore.get(key);
+ if (bytes != null) {
+ LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+ store.addLinkedLibrary(library.uriStr, linked);
+ } else {
+ libraryUrisToLink.add(library.uriStr);
+ }
+ }
+ }
+ int numOfLoaded = libraries.length - libraryUrisToLink.length;
+ logger.writeln('Loaded $numOfLoaded linked bundles.');
+ });
+
+ Map<String, LinkedLibraryBuilder> linkedLibraries = {};
+ logger.run('Link bundles', () {
+ linkedLibraries = link(libraryUrisToLink, (String uri) {
+ LinkedLibrary linkedLibrary = store.linkedMap[uri];
+ return linkedLibrary;
+ }, (String uri) {
+ UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
+ return unlinkedUnit;
+ }, (_) => null, options.strongMode);
+ logger.writeln('Linked ${linkedLibraries.length} bundles.');
+ });
+
+ linkedLibraries.forEach((uri, linkedBuilder) {
+ FileState library = libraries[uri];
+ String key = '${library.transitiveSignature}.linked';
+ List<int> bytes = linkedBuilder.toBuffer();
+ LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+ store.addLinkedLibrary(uri, linked);
+ byteStore.put(key, bytes);
+ });
+
+ var analysisContext = _createAnalysisContext(
+ options, declaredVariables, sourceFactory, fsState, store);
+
+ return new LibraryContext._(analysisContext);
+ });
+ }
+
+ LibraryContext._(this._analysisContext);
+
+ /**
+ * Computes a [CompilationUnitElement] for the given library/unit pair.
+ */
+ CompilationUnitElement computeUnitElement(
+ Source librarySource, Source unitSource) {
+ return _analysisContext.computeResult(
+ new LibrarySpecificUnit(librarySource, unitSource),
+ COMPILATION_UNIT_ELEMENT);
+ }
+
+ /**
+ * Cleans up any persistent resources used by this [LibraryContext].
+ *
+ * Should be called once the [LibraryContext] is no longer needed.
+ */
+ void dispose() {
+ _analysisContext.dispose();
+ }
+
+ /**
+ * Computes a resolved [CompilationUnit] and a list of [AnalysisError]s for
+ * the given library/unit pair.
+ */
+ ResolutionResult resolveUnit(Source librarySource, Source unitSource) {
+ CompilationUnit resolvedUnit =
+ _analysisContext.resolveCompilationUnit2(unitSource, librarySource);
+ List<AnalysisError> errors = _analysisContext.computeErrors(unitSource);
+ return new ResolutionResult(resolvedUnit, errors);
+ }
+
+ static AnalysisContext _createAnalysisContext(
+ AnalysisOptions _analysisOptions,
+ DeclaredVariables declaredVariables,
+ SourceFactory _sourceFactory,
+ FileSystemState _fsState,
+ SummaryDataStore store) {
+ AnalysisContextImpl analysisContext =
+ AnalysisEngine.instance.createAnalysisContext();
+ analysisContext.useSdkCachePartition = false;
+ analysisContext.analysisOptions = _analysisOptions;
+ analysisContext.declaredVariables.addAll(declaredVariables);
+ analysisContext.sourceFactory = _sourceFactory.clone();
+ analysisContext.contentCache = new _ContentCacheWrapper(_fsState);
+ analysisContext.resultProvider =
+ new InputPackagesResultProvider(analysisContext, store);
+ return analysisContext;
+ }
+}
+
+/**
+ * Container object holding the result of a call to
+ * [LibraryContext.resolveUnit].
+ */
+class ResolutionResult {
+ final CompilationUnit resolvedUnit;
+ final List<AnalysisError> errors;
+
+ ResolutionResult(this.resolvedUnit, this.errors);
+}
+
+/**
+ * [ContentCache] wrapper around [FileContentOverlay].
+ */
+class _ContentCacheWrapper implements ContentCache {
+ final FileSystemState fsState;
+
+ _ContentCacheWrapper(this.fsState);
+
+ @override
+ void accept(ContentCacheVisitor visitor) {
+ throw new UnimplementedError();
+ }
+
+ @override
+ String getContents(Source source) {
+ return _getFileForSource(source).content;
+ }
+
+ @override
+ bool getExists(Source source) {
+ if (source.isInSystemLibrary) {
+ return true;
+ }
+ return _getFileForSource(source).exists;
+ }
+
+ @override
+ int getModificationStamp(Source source) {
+ if (source.isInSystemLibrary) {
+ return 0;
+ }
+ return _getFileForSource(source).exists ? 0 : -1;
+ }
+
+ @override
+ String setContents(Source source, String contents) {
+ throw new UnimplementedError();
+ }
+
+ FileState _getFileForSource(Source source) {
+ String path = source.fullName;
+ return fsState.getFileForPath(path);
+ }
+}
« no previous file with comments | « pkg/analyzer/lib/src/dart/analysis/driver.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698