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

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

Issue 1694763003: Test and fix resynthesis of nested generic functions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove workarounds now that #25769 is fixed 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/test/src/summary/resynthesize_test.dart » ('j') | 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 0ca1f06f236299d37a4cab2557b1f29dcbc8169e..c5916809b46db9fd017d7ff5c4dad4ebde1d9372 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -709,14 +709,16 @@ class _LibraryResynthesizer {
/**
* Type parameters for the generic class, typedef, or executable currently
- * being resynthesized, if any. If multiple entities with type parameters
- * are nested (e.g. a generic executable inside a generic class), this is the
- * concatenation of all type parameters from all declarations currently in
- * force, with the outermost declaration appearing first. If there are no
- * type parameters, or we are not currently resynthesizing a class, typedef,
- * or executable, then this is an empty list.
+ * being resynthesized, if any. This is a list of lists; if multiple
+ * entities with type parameters are nested (e.g. a generic executable inside
+ * a generic class), then the zeroth element of [currentTypeParameters]
+ * contains the type parameters for the outermost nested entity, and further
+ * elements contain the type parameters for entities that are more deeply
+ * nested. If we are not currently resynthesizing a class, typedef, or
+ * executable, then this is an empty list.
*/
- List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
+ final List<List<TypeParameterElement>> currentTypeParameters =
+ <List<TypeParameterElement>>[];
/**
* If a class is currently being resynthesized, map from field name to the
@@ -744,13 +746,6 @@ class _LibraryResynthesizer {
}
/**
- * Return a list of type arguments corresponding to [currentTypeParameters].
- */
- List<TypeParameterType> get currentTypeArguments => currentTypeParameters
- ?.map((TypeParameterElement param) => param.type)
- ?.toList();
-
- /**
* Build the annotations for the given [element].
*/
void buildAnnotations(
@@ -789,14 +784,10 @@ class _LibraryResynthesizer {
*/
void buildClass(UnlinkedClass serializedClass) {
try {
- currentTypeParameters =
- serializedClass.typeParameters.map(buildTypeParameter).toList();
- for (int i = 0; i < serializedClass.typeParameters.length; i++) {
- finishTypeParameter(
- serializedClass.typeParameters[i], currentTypeParameters[i]);
- }
ClassElementImpl classElement = new ClassElementImpl(
serializedClass.name, serializedClass.nameOffset);
+ classElement.typeParameters =
+ buildTypeParameters(serializedClass.typeParameters);
classElement.abstract = serializedClass.isAbstract;
classElement.mixinApplication = serializedClass.isMixinApplication;
InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
@@ -812,7 +803,6 @@ class _LibraryResynthesizer {
classElement.interfaces =
serializedClass.interfaces.map(buildType).toList();
classElement.mixins = serializedClass.mixins.map(buildType).toList();
- classElement.typeParameters = currentTypeParameters;
ElementHolder memberHolder = new ElementHolder();
fields = <String, FieldElementImpl>{};
for (UnlinkedVariable serializedVariable in serializedClass.fields) {
@@ -843,7 +833,7 @@ class _LibraryResynthesizer {
constructor.synthetic = true;
constructor.returnType = correspondingType;
constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
- constructor, null, currentTypeArguments, false);
+ constructor, null, getCurrentTypeArguments(), false);
memberHolder.addConstructor(constructor);
}
classElement.constructors = memberHolder.constructors;
@@ -851,14 +841,15 @@ class _LibraryResynthesizer {
classElement.accessors = memberHolder.accessors;
classElement.fields = memberHolder.fields;
classElement.methods = memberHolder.methods;
- correspondingType.typeArguments = currentTypeArguments;
+ correspondingType.typeArguments = getCurrentTypeArguments();
classElement.type = correspondingType;
buildDocumentation(classElement, serializedClass.documentationComment);
buildAnnotations(classElement, serializedClass.annotations);
resolveConstructorInitializers(classElement);
unitHolder.addType(classElement);
} finally {
- currentTypeParameters = <TypeParameterElement>[];
+ currentTypeParameters.removeLast();
+ assert(currentTypeParameters.isEmpty);
fields = null;
constructors = null;
}
@@ -1088,13 +1079,8 @@ class _LibraryResynthesizer {
*/
void buildExecutableCommonParts(ExecutableElementImpl executableElement,
UnlinkedExecutable serializedExecutable) {
- List<TypeParameterType> oldTypeArguments = currentTypeArguments;
- int oldTypeParametersLength = currentTypeParameters.length;
- if (serializedExecutable.typeParameters.isNotEmpty) {
- executableElement.typeParameters =
- serializedExecutable.typeParameters.map(buildTypeParameter).toList();
- currentTypeParameters.addAll(executableElement.typeParameters);
- }
+ executableElement.typeParameters =
+ buildTypeParameters(serializedExecutable.typeParameters);
executableElement.parameters =
serializedExecutable.parameters.map(buildParameter).toList();
if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) {
@@ -1111,10 +1097,8 @@ class _LibraryResynthesizer {
serializedExecutable.returnType == null;
}
executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
- executableElement, null, oldTypeArguments, false);
+ executableElement, null, getCurrentTypeArguments(skipLevels: 1), false);
executableElement.external = serializedExecutable.isExternal;
- currentTypeParameters.removeRange(
- oldTypeParametersLength, currentTypeParameters.length);
buildDocumentation(
executableElement, serializedExecutable.documentationComment);
buildAnnotations(executableElement, serializedExecutable.annotations);
@@ -1122,6 +1106,7 @@ class _LibraryResynthesizer {
serializedExecutable.localFunctions.map(buildLocalFunction).toList();
executableElement.localVariables =
serializedExecutable.localVariables.map(buildLocalVariable).toList();
+ currentTypeParameters.removeLast();
}
/**
@@ -1503,7 +1488,7 @@ class _LibraryResynthesizer {
parameterTypeElement.shareParameters(parameterElement.parameters);
parameterTypeElement.returnType = buildType(serializedParameter.type);
parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
- parameterTypeElement, null, currentTypeArguments, false);
+ parameterTypeElement, null, getCurrentTypeArguments(), false);
} else {
if (serializedParameter.isInitializingFormal &&
serializedParameter.type == null) {
@@ -1576,9 +1561,7 @@ class _LibraryResynthesizer {
}
}
if (type.paramReference != 0) {
- return currentTypeParameters[
- currentTypeParameters.length - type.paramReference]
- .type;
+ return getTypeParameterFromScope(type.paramReference);
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
@@ -1599,28 +1582,24 @@ class _LibraryResynthesizer {
*/
void buildTypedef(UnlinkedTypedef serializedTypedef) {
try {
- currentTypeParameters =
- serializedTypedef.typeParameters.map(buildTypeParameter).toList();
- for (int i = 0; i < serializedTypedef.typeParameters.length; i++) {
- finishTypeParameter(
- serializedTypedef.typeParameters[i], currentTypeParameters[i]);
- }
FunctionTypeAliasElementImpl functionTypeAliasElement =
new FunctionTypeAliasElementImpl(
serializedTypedef.name, serializedTypedef.nameOffset);
+ functionTypeAliasElement.typeParameters =
+ buildTypeParameters(serializedTypedef.typeParameters);
functionTypeAliasElement.parameters =
serializedTypedef.parameters.map(buildParameter).toList();
functionTypeAliasElement.returnType =
buildType(serializedTypedef.returnType);
functionTypeAliasElement.type =
new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
- functionTypeAliasElement.typeParameters = currentTypeParameters;
buildDocumentation(
functionTypeAliasElement, serializedTypedef.documentationComment);
buildAnnotations(functionTypeAliasElement, serializedTypedef.annotations);
unitHolder.addTypeAlias(functionTypeAliasElement);
} finally {
- currentTypeParameters = <TypeParameterElement>[];
+ currentTypeParameters.removeLast();
+ assert(currentTypeParameters.isEmpty);
}
}
@@ -1643,6 +1622,22 @@ class _LibraryResynthesizer {
}
/**
+ * Build [TypeParameterElements] corresponding to the type parameters in
+ * [serializedTypeParameters] and store them in [currentTypeParameters].
+ * Also return them.
+ */
+ List<TypeParameterElement> buildTypeParameters(
+ List<UnlinkedTypeParam> serializedTypeParameters) {
+ List<TypeParameterElement> typeParameters =
+ serializedTypeParameters.map(buildTypeParameter).toList();
+ currentTypeParameters.add(typeParameters);
+ for (int i = 0; i < serializedTypeParameters.length; i++) {
+ finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
+ }
+ return typeParameters;
+ }
+
+ /**
* Resynthesize a [TopLevelVariableElement] or [FieldElement].
*/
void buildVariable(UnlinkedVariable serializedVariable,
@@ -1721,6 +1716,25 @@ class _LibraryResynthesizer {
}
/**
+ * Return a list of type arguments corresponding to [currentTypeParameters],
+ * skipping the innermost [skipLevels] nesting levels.
+ *
+ * Type parameters are listed in nesting order from innermost to outermost,
+ * and then in declaration order. So for instance if we are resynthesizing a
+ * method declared as `class C<T, U> { void m<V, W>() { ... } }`, then the
+ * type parameters will be returned in the order `[V, W, T, U]`.
+ */
+ List<TypeParameterType> getCurrentTypeArguments({int skipLevels: 0}) {
+ assert(currentTypeParameters.length >= skipLevels);
+ List<TypeParameterType> result = <TypeParameterType>[];
+ for (int i = currentTypeParameters.length - 1 - skipLevels; i >= 0; i--) {
+ result.addAll(currentTypeParameters[i]
+ .map((TypeParameterElement param) => param.type));
+ }
+ return result;
+ }
+
+ /**
* Build the components of an [ElementLocationImpl] for the entity in the
* given [unit] of the dependency located at [dependencyIndex], and having
* the given [name].
@@ -1757,6 +1771,24 @@ class _LibraryResynthesizer {
}
/**
+ * Get the type parameter from the surrounding scope whose De Bruijn index is
+ * [index].
+ */
+ DartType getTypeParameterFromScope(int index) {
+ for (int i = currentTypeParameters.length - 1; i >= 0; i--) {
+ List<TypeParameterElement> paramsAtThisNestingLevel =
+ currentTypeParameters[i];
+ int numParamsAtThisNestingLevel = paramsAtThisNestingLevel.length;
+ if (index <= numParamsAtThisNestingLevel) {
+ return paramsAtThisNestingLevel[numParamsAtThisNestingLevel - index]
+ .type;
+ }
+ index -= numParamsAtThisNestingLevel;
+ }
+ throw new StateError('Type parameter not found');
+ }
+
+ /**
* Populate [referenceInfos] with the correct information for the current
* compilation unit.
*/
@@ -1888,6 +1920,7 @@ class _LibraryResynthesizer {
elementMap[accessor.identifier] = accessor;
}
resummarizedElements[absoluteUri] = elementMap;
+ assert(currentTypeParameters.isEmpty);
}
/**
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698