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

Unified Diff: packages/analyzer/lib/src/summary/package_bundle_reader.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 5 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 | « packages/analyzer/lib/src/summary/name_filter.dart ('k') | packages/analyzer/lib/src/summary/prelink.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/analyzer/lib/src/summary/package_bundle_reader.dart
diff --git a/packages/analyzer/lib/src/summary/package_bundle_reader.dart b/packages/analyzer/lib/src/summary/package_bundle_reader.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c60f8ba6ca024cde45bbd0993ba8746a38de4248
--- /dev/null
+++ b/packages/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -0,0 +1,499 @@
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as pathos;
+
+/**
+ * The [ResultProvider] that provides results from input package summaries.
+ */
+class InputPackagesResultProvider extends ResynthesizerResultProvider {
+ InputPackagesResultProvider(
+ InternalAnalysisContext context, SummaryDataStore dataStore)
+ : super(context, dataStore) {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ createResynthesizer(sdkContext, sdkContext.typeProvider);
+ }
+
+ @override
+ bool hasResultsForSource(Source source) {
+ String uriString = source.uri.toString();
+ return resynthesizer.hasLibrarySummary(uriString);
+ }
+}
+
+/**
+ * The [UriResolver] that knows about sources that are served from their
+ * summaries.
+ */
+@deprecated
+class InSummaryPackageUriResolver extends UriResolver {
+ final SummaryDataStore _dataStore;
+
+ InSummaryPackageUriResolver(this._dataStore);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ actualUri ??= uri;
+ String uriString = uri.toString();
+ UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
+ if (unit != null) {
+ String summaryPath = _dataStore.uriToSummaryPath[uriString];
+ if (unit.fallbackModePath.isNotEmpty) {
+ return new _InSummaryFallbackSource(
+ new JavaFile(unit.fallbackModePath), actualUri, summaryPath);
+ } else {
+ return new InSummarySource(actualUri, summaryPath);
+ }
+ }
+ return null;
+ }
+}
+
+/**
+ * A placeholder of a source that is part of a package whose analysis results
+ * are served from its summary. This source uses its URI as [fullName] and has
+ * empty contents.
+ */
+class InSummarySource extends Source {
+ final Uri uri;
+
+ /**
+ * The summary file where this source was defined.
+ */
+ final String summaryPath;
+
+ InSummarySource(this.uri, this.summaryPath);
+
+ @override
+ TimestampedData<String> get contents => new TimestampedData<String>(0, '');
+
+ @override
+ String get encoding => uri.toString();
+
+ @override
+ String get fullName => encoding;
+
+ @override
+ int get hashCode => uri.hashCode;
+
+ @override
+ bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
+
+ @override
+ int get modificationStamp => 0;
+
+ @override
+ String get shortName => pathos.basename(fullName);
+
+ @override
+ UriKind get uriKind => UriKind.PACKAGE_URI;
+
+ @override
+ bool operator ==(Object object) => object is Source && object.uri == uri;
+
+ @override
+ bool exists() => true;
+
+ @override
+ String toString() => uri.toString();
+}
+
+/**
+ * The [UriResolver] that knows about sources that are served from their
+ * summaries.
+ */
+class InSummaryUriResolver extends UriResolver {
+ ResourceProvider resourceProvider;
+ final SummaryDataStore _dataStore;
+
+ InSummaryUriResolver(this.resourceProvider, this._dataStore);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ actualUri ??= uri;
+ String uriString = uri.toString();
+ UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
+ if (unit != null) {
+ String summaryPath = _dataStore.uriToSummaryPath[uriString];
+ if (unit.fallbackModePath.isNotEmpty) {
+ return new _InSummaryFallbackFileSource(
+ resourceProvider.getFile(unit.fallbackModePath),
+ actualUri,
+ summaryPath);
+ } else {
+ return new InSummarySource(actualUri, summaryPath);
+ }
+ }
+ return null;
+ }
+}
+
+/**
+ * The [ResultProvider] that provides results using summary resynthesizer.
+ */
+abstract class ResynthesizerResultProvider extends ResultProvider {
+ final InternalAnalysisContext context;
+ final SummaryDataStore _dataStore;
+
+ _FileBasedSummaryResynthesizer _resynthesizer;
+ ResynthesizerResultProvider _sdkProvider;
+
+ ResynthesizerResultProvider(this.context, this._dataStore);
+
+ SummaryResynthesizer get resynthesizer => _resynthesizer;
+
+ /**
+ * Add a new [bundle] to the resynthesizer.
+ */
+ void addBundle(String path, PackageBundle bundle) {
+ _dataStore.addBundle(path, bundle);
+ }
+
+ @override
+ bool compute(CacheEntry entry, ResultDescriptor result) {
+ if (_sdkProvider != null && _sdkProvider.compute(entry, result)) {
+ return true;
+ }
+ AnalysisTarget target = entry.target;
+ // Check whether there are results for the source.
+ if (!hasResultsForSource(target.librarySource ?? target.source)) {
+ return false;
+ }
+ // Constant expressions are always resolved in summaries.
+ if (result == CONSTANT_EXPRESSION_RESOLVED &&
+ target is ConstantEvaluationTarget) {
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ // Provide results for Source.
+ if (target is Source) {
+ String uriString = target.uri.toString();
+ // Provide known results.
+ if (result == LIBRARY_ELEMENT1 ||
+ result == LIBRARY_ELEMENT2 ||
+ result == LIBRARY_ELEMENT3 ||
+ result == LIBRARY_ELEMENT4 ||
+ result == LIBRARY_ELEMENT5 ||
+ result == LIBRARY_ELEMENT6 ||
+ result == LIBRARY_ELEMENT7 ||
+ result == LIBRARY_ELEMENT8 ||
+ result == LIBRARY_ELEMENT9 ||
+ result == LIBRARY_ELEMENT) {
+ LibraryElement libraryElement =
+ resynthesizer.getLibraryElement(uriString);
+ entry.setValue(result as ResultDescriptor<LibraryElement>,
+ libraryElement, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == READY_LIBRARY_ELEMENT2 ||
+ result == READY_LIBRARY_ELEMENT6 ||
+ result == READY_LIBRARY_ELEMENT7) {
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == MODIFICATION_TIME) {
+ entry.setValue(
+ result as ResultDescriptor<int>, 0, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == SOURCE_KIND) {
+ if (_dataStore.linkedMap.containsKey(uriString)) {
+ entry.setValue(result as ResultDescriptor<SourceKind>,
+ SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (_dataStore.unlinkedMap.containsKey(uriString)) {
+ entry.setValue(result as ResultDescriptor<SourceKind>,
+ SourceKind.PART, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ return false;
+ } else if (result == CONTAINING_LIBRARIES) {
+ List<String> libraryUriStrings =
+ _dataStore.getContainingLibraryUris(uriString);
+ if (libraryUriStrings != null) {
+ List<Source> librarySources = libraryUriStrings
+ .map((libraryUriString) =>
+ context.sourceFactory.resolveUri(target, libraryUriString))
+ .toList(growable: false);
+ entry.setValue(result as ResultDescriptor<List<Source>>,
+ librarySources, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ return false;
+ } else if (result == LINE_INFO) {
+ UnlinkedUnit unlinkedUnit = _dataStore.unlinkedMap[uriString];
+ List<int> lineStarts = unlinkedUnit.lineStarts;
+ if (lineStarts.isNotEmpty) {
+ LineInfo lineInfo = new LineInfo(lineStarts);
+ entry.setValue(result as ResultDescriptor<LineInfo>, lineInfo,
+ TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ return false;
+ }
+ } else if (target is LibrarySpecificUnit) {
+ if (result == CREATED_RESOLVED_UNIT1 ||
+ result == CREATED_RESOLVED_UNIT2 ||
+ result == CREATED_RESOLVED_UNIT3 ||
+ result == CREATED_RESOLVED_UNIT4 ||
+ result == CREATED_RESOLVED_UNIT5 ||
+ result == CREATED_RESOLVED_UNIT6 ||
+ result == CREATED_RESOLVED_UNIT7 ||
+ result == CREATED_RESOLVED_UNIT8 ||
+ result == CREATED_RESOLVED_UNIT9 ||
+ result == CREATED_RESOLVED_UNIT10 ||
+ result == CREATED_RESOLVED_UNIT11) {
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (result == COMPILATION_UNIT_ELEMENT) {
+ String libraryUri = target.library.uri.toString();
+ String unitUri = target.unit.uri.toString();
+ CompilationUnitElement unit = resynthesizer.getElement(
+ new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+ if (unit != null) {
+ entry.setValue(result as ResultDescriptor<CompilationUnitElement>,
+ unit, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ } else if (target is VariableElement) {
+ if (result == INFERRED_STATIC_VARIABLE) {
+ entry.setValue(result as ResultDescriptor<VariableElement>, target,
+ TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ // Unknown target.
+ return false;
+ }
+
+ /**
+ * Create the [resynthesizer] instance.
+ *
+ * Subclasses must call this method in their constructors.
+ */
+ void createResynthesizer(
+ InternalAnalysisContext sdkContext, TypeProvider typeProvider) {
+ // Set the type provider to prevent the context from computing it.
+ context.typeProvider = typeProvider;
+ // Create a chained resynthesizer.
+ _sdkProvider = sdkContext?.resultProvider;
+ _resynthesizer = new _FileBasedSummaryResynthesizer(
+ _sdkProvider?.resynthesizer,
+ context,
+ typeProvider,
+ context.sourceFactory,
+ context.analysisOptions.strongMode,
+ _dataStore);
+ }
+
+ /**
+ * Return `true` if this result provider can provide a result for the
+ * given [source]. The provider must ensure that [addBundle] is invoked for
+ * every bundle that would be required to provide results for the [source].
+ */
+ bool hasResultsForSource(Source source);
+}
+
+/**
+ * A [SummaryDataStore] is a container for the data extracted from a set of
+ * summary package bundles. It contains maps which can be used to find linked
+ * and unlinked summaries by URI.
+ */
+class SummaryDataStore {
+ /**
+ * List of all [PackageBundle]s.
+ */
+ final List<PackageBundle> bundles = <PackageBundle>[];
+
+ /**
+ * List of dependency information for the package bundles in this
+ * [SummaryDataStore], in a form that is ready to store in a newly generated
+ * summary. Computing this information has nonzero cost, so it is only
+ * recorded if the [SummaryDataStore] is constructed with the argument
+ * `recordDependencies`. Otherwise `null`.
+ */
+ final List<PackageDependencyInfoBuilder> dependencies;
+
+ /**
+ * Map from the URI of a compilation unit to the unlinked summary of that
+ * compilation unit.
+ */
+ final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};
+
+ /**
+ * Map from the URI of a library to the linked summary of that library.
+ */
+ final Map<String, LinkedLibrary> linkedMap = <String, LinkedLibrary>{};
+
+ /**
+ * Map from the URI of a library to the summary path that contained it.
+ */
+ final Map<String, String> uriToSummaryPath = <String, String>{};
+
+ /**
+ * Create a [SummaryDataStore] and populate it with the summaries in
+ * [summaryPaths]. If [recordDependencyInfo] is `true`, record
+ * [PackageDependencyInfo] for each summary, for later access via
+ * [dependencies].
+ */
+ SummaryDataStore(Iterable<String> summaryPaths,
+ {bool recordDependencyInfo: false})
+ : dependencies =
+ recordDependencyInfo ? <PackageDependencyInfoBuilder>[] : null {
+ summaryPaths.forEach(_fillMaps);
+ }
+
+ /**
+ * Add the given [bundle] loaded from the file with the given [path].
+ */
+ void addBundle(String path, PackageBundle bundle) {
+ bundles.add(bundle);
+ if (dependencies != null) {
+ Set<String> includedPackageNames = new Set<String>();
+ bool includesDartUris = false;
+ bool includesFileUris = false;
+ for (String uriString in bundle.unlinkedUnitUris) {
+ Uri uri = FastUri.parse(uriString);
+ String scheme = uri.scheme;
+ if (scheme == 'package') {
+ List<String> pathSegments = uri.pathSegments;
+ includedPackageNames.add(pathSegments.isEmpty ? '' : pathSegments[0]);
+ } else if (scheme == 'file') {
+ includesFileUris = true;
+ } else if (scheme == 'dart') {
+ includesDartUris = true;
+ }
+ }
+ dependencies.add(new PackageDependencyInfoBuilder(
+ includedPackageNames: includedPackageNames.toList()..sort(),
+ includesDartUris: includesDartUris,
+ includesFileUris: includesFileUris,
+ apiSignature: bundle.apiSignature,
+ summaryPath: path));
+ }
+ for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+ String uri = bundle.unlinkedUnitUris[i];
+ uriToSummaryPath[uri] = path;
+ unlinkedMap[uri] = bundle.unlinkedUnits[i];
+ }
+ for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+ String uri = bundle.linkedLibraryUris[i];
+ linkedMap[uri] = bundle.linkedLibraries[i];
+ }
+ }
+
+ /**
+ * Return a list of absolute URIs of the libraries that contain the unit with
+ * the given [unitUriString], or `null` if no such library is in the store.
+ */
+ List<String> getContainingLibraryUris(String unitUriString) {
+ // The unit is the defining unit of a library.
+ if (linkedMap.containsKey(unitUriString)) {
+ return <String>[unitUriString];
+ }
+ // Check every unlinked unit whether it uses [unitUri] as a part.
+ List<String> libraryUriStrings = <String>[];
+ unlinkedMap.forEach((unlinkedUnitUriString, unlinkedUnit) {
+ Uri libraryUri = FastUri.parse(unlinkedUnitUriString);
+ for (String partUriString in unlinkedUnit.publicNamespace.parts) {
+ Uri partUri = FastUri.parse(partUriString);
+ String partAbsoluteUriString =
+ resolveRelativeUri(libraryUri, partUri).toString();
+ if (partAbsoluteUriString == unitUriString) {
+ libraryUriStrings.add(unlinkedUnitUriString);
+ }
+ }
+ });
+ return libraryUriStrings.isNotEmpty ? libraryUriStrings : null;
+ }
+
+ void _fillMaps(String path) {
+ io.File file = new io.File(path);
+ List<int> buffer = file.readAsBytesSync();
+ PackageBundle bundle = new PackageBundle.fromBuffer(buffer);
+ addBundle(path, bundle);
+ }
+}
+
+/**
+ * A concrete resynthesizer that serves summaries from given file paths.
+ */
+class _FileBasedSummaryResynthesizer extends SummaryResynthesizer {
+ final SummaryDataStore _dataStore;
+
+ _FileBasedSummaryResynthesizer(
+ SummaryResynthesizer parent,
+ AnalysisContext context,
+ TypeProvider typeProvider,
+ SourceFactory sourceFactory,
+ bool strongMode,
+ this._dataStore)
+ : super(parent, context, typeProvider, sourceFactory, strongMode);
+
+ @override
+ LinkedLibrary getLinkedSummary(String uri) {
+ return _dataStore.linkedMap[uri];
+ }
+
+ @override
+ UnlinkedUnit getUnlinkedSummary(String uri) {
+ return _dataStore.unlinkedMap[uri];
+ }
+
+ @override
+ bool hasLibrarySummary(String uri) {
+ LinkedLibrary linkedLibrary = _dataStore.linkedMap[uri];
+ return linkedLibrary != null && !linkedLibrary.fallbackMode;
+ }
+}
+
+/**
+ * A source that is part of a package whose summary was generated in fallback
+ * mode. This source behaves identically to a [FileSource] except that it also
+ * provides [summaryPath].
+ */
+class _InSummaryFallbackFileSource extends FileSource
+ implements InSummarySource {
+ @override
+ final String summaryPath;
+
+ _InSummaryFallbackFileSource(File file, Uri uri, this.summaryPath)
+ : super(file, uri);
+}
+
+/**
+ * A source that is part of a package whose summary was generated in fallback
+ * mode. This source behaves identically to a [FileBasedSource] except that it
+ * also provides [summaryPath].
+ */
+@deprecated
+class _InSummaryFallbackSource extends FileBasedSource
+ implements InSummarySource {
+ @override
+ final String summaryPath;
+
+ _InSummaryFallbackSource(JavaFile file, Uri uri, this.summaryPath)
+ : super(file, uri);
+}
« no previous file with comments | « packages/analyzer/lib/src/summary/name_filter.dart ('k') | packages/analyzer/lib/src/summary/prelink.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698