From ca5bf28fa53cd7651b1dfd5bc779eedd06e8099b Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 14 Jan 2016 14:43:29 -0800 Subject: [PATCH] Chain SummaryResynthesizer(s). R=paulberry@google.com BUG= Review URL: https://codereview.chromium.org/1585093003 . --- .../lib/src/summary/resynthesize.dart | 60 +++++++++++++++---- pkg/analyzer/lib/src/summary/summary_sdk.dart | 10 +++- .../test/src/summary/resynthesize_test.dart | 2 + 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart index 3a43e0e1f90..f413289e41d 100644 --- a/pkg/analyzer/lib/src/summary/resynthesize.dart +++ b/pkg/analyzer/lib/src/summary/resynthesize.dart @@ -26,11 +26,28 @@ typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri); */ typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri); +/** + * Callback used by [SummaryResynthesizer] to check whether it can access + * summaries of the library with the given [uri]. + */ +typedef bool HasLibrarySummaryCallback(String uri); + /** * Implementation of [ElementResynthesizer] used when resynthesizing an element * model from summaries. */ class SummaryResynthesizer extends ElementResynthesizer { + /** + * The parent [SummaryResynthesizer] which is asked to resynthesis elements + * before this resynthesizer attempts to do this. Can be `null`. + */ + final SummaryResynthesizer parent; + + /** + * Callback used to check whether summaries for a given URI can be accessed. + */ + final HasLibrarySummaryCallback hasLibrarySummary; + /** * Callback used to obtain the prelinked summary for a given URI. */ @@ -72,8 +89,14 @@ class SummaryResynthesizer extends ElementResynthesizer { final Map _resynthesizedLibraries = {}; - SummaryResynthesizer(AnalysisContext context, this.typeProvider, - this.getPrelinkedSummary, this.getUnlinkedSummary, this.sourceFactory) + SummaryResynthesizer( + this.parent, + AnalysisContext context, + this.typeProvider, + this.hasLibrarySummary, + this.getPrelinkedSummary, + this.getUnlinkedSummary, + this.sourceFactory) : super(context); /** @@ -83,21 +106,28 @@ class SummaryResynthesizer extends ElementResynthesizer { @override Element getElement(ElementLocation location) { - if (location.components.length == 1) { - return getLibraryElement(location.components[0]); - } else if (location.components.length == 3) { - String uri = location.components[0]; + List components = location.components; + String libraryUri = components[0]; + // Ask the parent resynthesizer. + if (parent != null) { + if (parent.hasLibrarySummary(libraryUri)) { + return parent.getElement(location); + } + } + // Resynthesize locally. + if (components.length == 1) { + return getLibraryElement(libraryUri); + } else if (components.length == 3) { Map> libraryMap = - _resynthesizedElements[uri]; + _resynthesizedElements[libraryUri]; if (libraryMap == null) { - getLibraryElement(uri); - libraryMap = _resynthesizedElements[uri]; + getLibraryElement(libraryUri); + libraryMap = _resynthesizedElements[libraryUri]; assert(libraryMap != null); } - Map compilationUnitElements = - libraryMap[location.components[1]]; + Map compilationUnitElements = libraryMap[components[1]]; if (compilationUnitElements != null) { - Element element = compilationUnitElements[location.components[2]]; + Element element = compilationUnitElements[components[2]]; if (element != null) { return element; } @@ -113,6 +143,9 @@ class SummaryResynthesizer extends ElementResynthesizer { * hasn't been resynthesized already. */ LibraryElement getLibraryElement(String uri) { + if (parent != null && parent.hasLibrarySummary(uri)) { + return parent.getLibraryElement(uri); + } return _resynthesizedLibraries.putIfAbsent(uri, () { PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri); List serializedUnits = [ @@ -845,7 +878,8 @@ class _LibraryResynthesizer { if (type.paramReference != 0) { // TODO(paulberry): make this work for generic methods. return currentTypeParameters[ - currentTypeParameters.length - type.paramReference].type; + currentTypeParameters.length - type.paramReference] + .type; } else { // TODO(paulberry): handle references to things other than classes (note: // this should only occur in the case of erroneous code). diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart index 4d9b9feb6ce..e45cbc691ca 100644 --- a/pkg/analyzer/lib/src/summary/summary_sdk.dart +++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart @@ -46,8 +46,14 @@ class SummarySdkAnalysisContext extends SdkAnalysisContext { @override bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) { if (resynthesizer == null) { - resynthesizer = new SummaryResynthesizer(this, typeProvider, - _getPrelinkedSummary, _getUnlinkedSummary, sourceFactory); + resynthesizer = new SummaryResynthesizer( + null, + this, + typeProvider, + (String uri) => uri.startsWith('dart:'), + _getPrelinkedSummary, + _getUnlinkedSummary, + sourceFactory); _buildCoreLibrary(); _buildAsyncLibrary(); } diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart index 3665b018d37..11fcaf73b66 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart @@ -613,8 +613,10 @@ class C { return serializedUnit; } SummaryResynthesizer resynthesizer = new SummaryResynthesizer( + null, analysisContext, analysisContext.typeProvider, + (_) => true, getPrelinkedSummary, getUnlinkedSummary, analysisContext.sourceFactory);