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

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

Issue 1649893002: Refactor code for resynthesizing references in summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/summary/resynthesize.dart
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 9e8cf80d933755547d1801ea59651abcccd0dbc8..8386be5556b9edec72d0b6f58b3b56d1eef80c92 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -418,6 +418,12 @@ class _LibraryResynthesizer {
*/
List<_ConstVariable> constVariables = <_ConstVariable>[];
+ /**
+ * List of [_ReferenceInfo] objects describing the references in the current
+ * compilation unit.
+ */
+ List<_ReferenceInfo> referenceInfos;
+
_LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
this.unlinkedUnits, this.librarySource) {
isCoreLibrary = librarySource.uri.toString() == 'dart:core';
@@ -1113,70 +1119,15 @@ class _LibraryResynthesizer {
currentTypeParameters.length - type.paramReference]
.type;
} else {
- LinkedReference referenceResolution =
- linkedUnit.references[type.reference];
- String name;
- if (type.reference < unlinkedUnit.references.length) {
- name = unlinkedUnit.references[type.reference].name;
- } else {
- name = referenceResolution.name;
- }
- ElementLocationImpl location;
- if (referenceResolution.dependency != 0) {
- location = getReferencedLocation(
- linkedLibrary.dependencies[referenceResolution.dependency],
- referenceResolution.unit,
- name);
- } else if (referenceResolution.kind == ReferenceKind.unresolved) {
- return summaryResynthesizer.typeProvider.undefinedType;
- } else if (name == 'dynamic') {
- return summaryResynthesizer.typeProvider.dynamicType;
- } else if (name == 'void') {
- return VoidTypeImpl.instance;
- } else {
- String referencedLibraryUri = librarySource.uri.toString();
- String partUri;
- if (referenceResolution.unit != 0) {
- String uri = unlinkedUnits[0].publicNamespace.parts[
- referenceResolution.unit - 1];
- Source partSource =
- summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
- partUri = partSource.uri.toString();
+ DartType getTypeParameter(int i) {
+ if (i < type.typeArguments.length) {
+ return buildType(type.typeArguments[i]);
} else {
- partUri = referencedLibraryUri;
- }
- location = new ElementLocationImpl.con3(
- <String>[referencedLibraryUri, partUri, name]);
- }
- List<DartType> typeArguments = const <DartType>[];
- if (referenceResolution.numTypeParameters != 0) {
- typeArguments = <DartType>[];
- for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
- if (i < type.typeArguments.length) {
- typeArguments.add(buildType(type.typeArguments[i]));
- } else {
- typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
- }
+ return summaryResynthesizer.typeProvider.dynamicType;
}
}
- switch (referenceResolution.kind) {
- case ReferenceKind.classOrEnum:
- return new InterfaceTypeImpl.elementWithNameAndArgs(
- new ClassElementHandle(summaryResynthesizer, location),
- name,
- typeArguments);
- case ReferenceKind.typedef:
- return new FunctionTypeImpl.elementWithNameAndArgs(
- new FunctionTypeAliasElementHandle(
- summaryResynthesizer, location),
- name,
- typeArguments,
- typeArguments.isNotEmpty);
- default:
- // TODO(paulberry): figure out how to handle this case (which should
- // only occur in the event of erroneous code).
- throw new UnimplementedError();
- }
+ _ReferenceInfo referenceInfo = referenceInfos[type.reference];
+ return referenceInfo.buildType(getTypeParameter);
}
}
@@ -1316,6 +1267,72 @@ class _LibraryResynthesizer {
}
/**
+ * Populate [referenceInfos] with the correct information for the current
+ * compilation unit.
+ */
+ void populateReferenceInfos() {
+ int numLinkedReferences = linkedUnit.references.length;
+ int numUnlinkedReferences = unlinkedUnit.references.length;
+ referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
+ for (int i = 0; i < numLinkedReferences; i++) {
+ LinkedReference linkedReference = linkedUnit.references[i];
+ String name;
+ if (i < numUnlinkedReferences) {
+ name = unlinkedUnit.references[i].name;
+ } else {
+ name = linkedUnit.references[i].name;
+ }
+ ElementHandle element;
+ DartType type;
+ if (linkedReference.kind == ReferenceKind.unresolved) {
+ type = summaryResynthesizer.typeProvider.undefinedType;
+ } else if (name == 'dynamic') {
+ type = summaryResynthesizer.typeProvider.dynamicType;
+ } else if (name == 'void') {
+ type = VoidTypeImpl.instance;
+ } else {
+ ElementLocation location;
+ if (linkedReference.dependency != 0) {
+ location = getReferencedLocation(
+ linkedLibrary.dependencies[linkedReference.dependency],
+ linkedReference.unit,
+ name);
+ } else {
+ String referencedLibraryUri = librarySource.uri.toString();
+ String partUri;
+ if (linkedReference.unit != 0) {
+ String uri = unlinkedUnits[0].publicNamespace.parts[
+ linkedReference.unit - 1];
+ Source partSource = summaryResynthesizer.sourceFactory
+ .resolveUri(librarySource, uri);
+ partUri = partSource.uri.toString();
+ } else {
+ partUri = referencedLibraryUri;
+ }
+ location = new ElementLocationImpl.con3(
+ <String>[referencedLibraryUri, partUri, name]);
+ }
+ switch (linkedReference.kind) {
+ case ReferenceKind.classOrEnum:
+ element = new ClassElementHandle(summaryResynthesizer, location);
+ break;
+ case ReferenceKind.typedef:
+ element = new FunctionTypeAliasElementHandle(
+ summaryResynthesizer, location);
+ break;
+ default:
+ // This is an element that doesn't (yet) need to be referred to
+ // directly, so don't bother populating an element for it.
+ // TODO(paulberry): add support for more kinds, as needed.
+ break;
+ }
+ }
+ referenceInfos[i] = new _ReferenceInfo(
+ name, element, type, linkedReference.numTypeParameters);
+ }
+ }
+
+ /**
* Populate a [CompilationUnitElement] by deserializing all the elements
* contained in it.
*/
@@ -1326,6 +1343,7 @@ class _LibraryResynthesizer {
for (EntityRef t in linkedUnit.types) {
linkedTypeMap[t.slot] = t;
}
+ populateReferenceInfos();
unitHolder = new ElementHolder();
unlinkedUnit.classes.forEach(buildClass);
unlinkedUnit.enums.forEach(buildEnum);
@@ -1366,5 +1384,101 @@ class _LibraryResynthesizer {
linkedUnit = null;
unlinkedUnit = null;
linkedTypeMap = null;
+ referenceInfos = null;
+ }
+}
+
+/**
+ * Data structure used during resynthesis to record all the information that is
+ * known about how to reserialize a single entry in [LinkedUnit.references]
+ * (and its associated entry in [UnlinkedUnit.references], if it exists).
+ */
+class _ReferenceInfo {
+ /**
+ * The name of the entity referred to by this reference.
+ */
+ final String name;
+
+ /**
+ * The element referred to by this reference, or `null` if there is no
+ * associated element (e.g. because it is a reference to an undefined
+ * entity).
+ */
+ final ElementHandle element;
+
+ /**
+ * If this reference refers to a non-generic type, the type it refers to.
+ * Otherwise `null`.
+ */
+ DartType type;
+
+ /**
+ * The number of type parameters accepted by the entity referred to by this
+ * reference, or zero if it doesn't accept any type parameters.
+ */
+ final int numTypeParameters;
+
+ /**
+ * Create a new [_ReferenceInfo] object referring to an element called [name]
+ * via the element handle [elementHandle], and having [numTypeParameters]
+ * type parameters.
+ *
+ * For the special types `dynamic` and `void`, [specialType] should point to
+ * the type itself. Otherwise, pass `null` and the type will be computed
+ * when appropriate.
+ */
+ _ReferenceInfo(
+ this.name, this.element, DartType specialType, this.numTypeParameters) {
+ if (specialType != null) {
+ type = specialType;
+ } else if (numTypeParameters == 0) {
+ // We can precompute the type because it doesn't depend on type
+ // parameters.
+ type = _buildType(null);
+ }
+ }
+
+ /**
+ * Build a [DartType] corresponding to the result of applying the entity
+ * referred to by this [_ReferenceInfo] to some type parameters. The type
scheglov 2016/01/28 22:52:51 I guess the "apply" operation is commutative, but
Paul Berry 2016/01/28 23:05:56 Done.
+ * parameters are retrieved by calling [getTypeParameter].
+ *
+ * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
+ * is returned.
+ */
+ DartType buildType(DartType getTypeParameter(int i)) {
+ DartType result =
+ numTypeParameters == 0 ? type : _buildType(getTypeParameter);
+ if (result == null) {
+ // TODO(paulberry): figure out how to handle this case (which should
+ // only occur in the event of erroneous code).
+ throw new UnimplementedError();
+ }
+ return result;
+ }
+
+ /**
+ * If this reference refers to a type, build a [DartType] which instantiates
+ * it with type arguments returned by [getTypeParameter]. Otherwise return
+ * `null`.
+ */
+ DartType _buildType(DartType getTypeParameter(int i)) {
scheglov 2016/01/28 22:52:51 Would it be better to name this function "getTypeA
Paul Berry 2016/01/28 23:05:56 Done.
+ List<DartType> typeArguments = const <DartType>[];
+ if (numTypeParameters != 0) {
+ typeArguments = <DartType>[];
+ for (int i = 0; i < numTypeParameters; i++) {
+ typeArguments.add(getTypeParameter(i));
+ }
+ }
+ ElementHandle element = this.element; // To allow type promotion
+ if (element is ClassElementHandle) {
+ return new InterfaceTypeImpl.elementWithNameAndArgs(
+ element, name, typeArguments);
+ } else if (element is FunctionTypeAliasElementHandle) {
+ return new FunctionTypeImpl.elementWithNameAndArgs(
+ element, name, typeArguments, typeArguments.isNotEmpty);
+ } else {
+ return null;
+ }
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698