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

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

Issue 1739923002: Move package summary reading code into analyzer. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | pkg/analyzer_cli/lib/src/package_analyzer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/summary/package_bundle_reader.dart
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a58bfd3757f9c02e09ded69f10270924a0bc7311
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -0,0 +1,224 @@
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as pathos;
+
+/**
+ * If [uri] has the `package` scheme in form of `package:pkg/file.dart`,
+ * return the `pkg` name. Otherwise return `null`.
+ */
+String _getPackageName(Uri uri) {
+ if (uri.scheme != 'package') {
+ return null;
+ }
+ String path = uri.path;
+ int index = path.indexOf('/');
+ if (index == -1) {
+ return null;
+ }
+ return path.substring(0, index);
+}
+
+/**
+ * The [ResultProvider] that provides results from input package summaries.
+ */
+class InputPackagesResultProvider extends ResultProvider {
+ final InternalAnalysisContext _context;
+ final Map<String, String> _packageSummaryInputs;
+
+ _FileBasedSummaryResynthesizer _resynthesizer;
+ SummaryResultProvider _sdkProvider;
+
+ InputPackagesResultProvider(this._context, this._packageSummaryInputs) {
+ InternalAnalysisContext sdkContext = _context.sourceFactory.dartSdk.context;
+ _sdkProvider = sdkContext.resultProvider;
+ // Set the type provider to prevent the context from computing it.
+ _context.typeProvider = sdkContext.typeProvider;
+ // Create a chained resynthesizer.
+ _resynthesizer = new _FileBasedSummaryResynthesizer(
+ _sdkProvider.resynthesizer,
+ _context,
+ _context.typeProvider,
+ _context.sourceFactory,
+ _context.analysisOptions.strongMode,
+ _packageSummaryInputs.values.toList());
+ }
+
+ @override
+ bool compute(CacheEntry entry, ResultDescriptor result) {
+ if (_sdkProvider.compute(entry, result)) {
+ return true;
+ }
+ AnalysisTarget target = entry.target;
+ // Only library results are supported for now.
+ if (target is Source) {
+ Uri uri = target.uri;
+ // We know how to server results to input packages.
+ String sourcePackageName = _getPackageName(uri);
+ if (!_packageSummaryInputs.containsKey(sourcePackageName)) {
+ return false;
+ }
+ // Provide known results.
+ String uriString = uri.toString();
+ 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_ELEMENT ||
+ false) {
+ LibraryElement libraryElement =
+ _resynthesizer.getLibraryElement(uriString);
+ entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == READY_LIBRARY_ELEMENT2 ||
+ result == READY_LIBRARY_ELEMENT5 ||
+ result == READY_LIBRARY_ELEMENT6) {
+ entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == SOURCE_KIND) {
+ if (_resynthesizer.linkedMap.containsKey(uriString)) {
+ entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (_resynthesizer.unlinkedMap.containsKey(uriString)) {
+ entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ return false;
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ * The [UriResolver] that knows about sources that are parts of packages which
+ * are served from their summaries.
+ */
+class InSummaryPackageUriResolver extends UriResolver {
+ final Map<String, String> _packageSummaryInputs;
+
+ InSummaryPackageUriResolver(this._packageSummaryInputs);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ actualUri ??= uri;
+ String packageName = _getPackageName(actualUri);
+ if (_packageSummaryInputs.containsKey(packageName)) {
+ return new _InSummarySource(actualUri);
+ }
+ return null;
+ }
+}
+
+/**
+ * A concrete resynthesizer that serves summaries from given file paths.
+ */
+class _FileBasedSummaryResynthesizer extends SummaryResynthesizer {
+ final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};
+ final Map<String, LinkedLibrary> linkedMap = <String, LinkedLibrary>{};
+
+ _FileBasedSummaryResynthesizer(
+ SummaryResynthesizer parent,
+ AnalysisContext context,
+ TypeProvider typeProvider,
+ SourceFactory sourceFactory,
+ bool strongMode,
+ List<String> summaryPaths)
+ : super(parent, context, typeProvider, sourceFactory, strongMode) {
+ summaryPaths.forEach(_fillMaps);
+ }
+
+ @override
+ LinkedLibrary getLinkedSummary(String uri) {
+ return linkedMap[uri];
+ }
+
+ @override
+ UnlinkedUnit getUnlinkedSummary(String uri) {
+ return unlinkedMap[uri];
+ }
+
+ @override
+ bool hasLibrarySummary(String uri) {
+ return linkedMap.containsKey(uri);
+ }
+
+ void _fillMaps(String path) {
+ io.File file = new io.File(path);
+ List<int> buffer = file.readAsBytesSync();
+ PackageBundle bundle = new PackageBundle.fromBuffer(buffer);
+ for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+ unlinkedMap[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+ }
+ for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+ linkedMap[bundle.linkedLibraryUris[i]] = bundle.linkedLibraries[i];
+ }
+ }
+}
+
+/**
+ * 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;
+
+ _InSummarySource(this.uri);
+
+ @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 => false;
+
+ @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 _InSummarySource && object.uri == uri;
+
+ @override
+ bool exists() => true;
+
+ @override
+ Uri resolveRelativeUri(Uri relativeUri) {
+ Uri baseUri = uri;
+ return baseUri.resolveUri(relativeUri);
+ }
+
+ @override
+ String toString() => uri.toString();
+}
« no previous file with comments | « no previous file | pkg/analyzer_cli/lib/src/package_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698