Chromium Code Reviews| Index: pkg/analyzer/lib/src/summary/summarize_elements.dart |
| diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart |
| index bb501078399628e6a11915eb155b2405d3bd9af5..d09808e20bbe7f013e318c677d81469ea09d7eb8 100644 |
| --- a/pkg/analyzer/lib/src/summary/summarize_elements.dart |
| +++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart |
| @@ -138,6 +138,12 @@ class _LibrarySerializer { |
| */ |
| final BuilderContext ctx; |
| + /** |
| + * Map from imported element to the prefix which may be used to refer to that |
| + * element, or null if no prefix is needed. |
| + */ |
| + final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{}; |
| + |
| _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) { |
| dependencies.add(encodePrelinkedDependency(ctx)); |
| dependencyMap[libraryElement] = 0; |
| @@ -276,6 +282,37 @@ class _LibrarySerializer { |
| } |
| /** |
| + * Fill in [prefixMap] using information from [libraryElement.imports]. |
| + */ |
| + void computePrefixMap() { |
| + for (ImportElement import in libraryElement.imports) { |
|
scheglov
2016/01/09 22:51:31
We could skip analyzing an import if it does not h
Paul Berry
2016/01/10 02:08:28
Done.
|
| + import.importedLibrary.exportNamespace.definedNames |
| + .forEach((String name, Element e) { |
| + if (import.combinators.any((NamespaceCombinator combinator) => |
| + doesCombinatorReject(combinator, name))) { |
| + return; |
| + } |
| + prefixMap[e] = import.prefix; |
| + }); |
| + } |
| + } |
| + |
| + /** |
| + * Determine if the given [combinator] would reject an element having the |
| + * given [name]. |
| + */ |
| + bool doesCombinatorReject(NamespaceCombinator combinator, String name) { |
| + if (combinator is ShowElementCombinator) { |
| + return !combinator.shownNames.contains(name); |
| + } else if (combinator is HideElementCombinator) { |
| + return combinator.hiddenNames.contains(name); |
| + } else { |
| + throw new StateError( |
| + 'Unexpected combinator type ${combinator.runtimeType}'); |
| + } |
| + } |
| + |
| + /** |
| * Compute the appropriate De Bruijn index to represent the given type |
| * parameter [type]. |
| */ |
| @@ -519,6 +556,7 @@ class _LibrarySerializer { |
| * absolute URIs are stored in [unitUris]. |
| */ |
| PrelinkedLibraryBuilder serializeLibrary() { |
| + computePrefixMap(); |
| PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx); |
| addCompilationUnitElements(libraryElement.definingCompilationUnit, 0); |
| for (int i = 0; i < libraryElement.parts.length; i++) { |
| @@ -643,9 +681,18 @@ class _LibrarySerializer { |
| numTypeParameters = element.typeParameters.length; |
| } |
| int index = unlinkedReferences.length; |
| - // TODO(paulberry): set UnlinkedReference.prefix. |
| - unlinkedReferences |
| - .add(encodeUnlinkedReference(ctx, name: element.name)); |
| + // Figure out a prefix that may be used to refer to the given type. |
| + // TODO(paulberry): to avoid subtle relinking inconsistencies we |
| + // should use the actual prefix from the AST (a given type may be |
| + // reachable via multiple prefixes), but sadly, this information is |
| + // not recorded in the element model. |
| + int prefixReference = 0; |
| + PrefixElement prefix = prefixMap[element]; |
| + if (prefix != null) { |
| + prefixReference = serializePrefix(prefix); |
| + } |
| + unlinkedReferences.add(encodeUnlinkedReference(ctx, |
| + name: element.name, prefixReference: prefixReference)); |
| prelinkedReferences.add(encodePrelinkedReference(ctx, |
| dependency: serializeDependency(dependentLibrary), |
| kind: element is FunctionTypeAliasElement |