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

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

Issue 2974803002: Store FunctionType(s) of local functions by value. (Closed)
Patch Set: Created 3 years, 5 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
Index: pkg/analyzer/lib/src/summary/link.dart
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index a9fe8221fc4b989450592c48b1797b53780088d0..a3030278d1249bcab85bc21f7d87a07a5edd9254 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -221,25 +221,21 @@ EntityRefBuilder _createLinkedType(
type.typeArguments, result, compilationUnit, typeParameterContext);
return result;
}
- if (element is FunctionElement && element.enclosingElement == null) {
- // Element is a synthetic function element that was generated on the fly
- // to represent a type that has no associated source code location.
- result.syntheticReturnType = _createLinkedType(
- element.returnType, compilationUnit, typeParameterContext);
- result.entityKind =
- element.returnType?.element is GenericFunctionTypeElement
- ? EntityRefKind.genericFunctionType
- : EntityRefKind.syntheticFunction;
+ if (element is FunctionElementImpl) {
+ // Element is a local function, or a synthetic function element that was
+ // generated on the fly to represent a type that has no associated source
+ // code location. Store it as value.
+ result.syntheticReturnType =
+ _createLinkedType(element.returnType, compilationUnit, element);
+ result.entityKind = EntityRefKind.syntheticFunction;
result.syntheticParams = element.parameters
- .map((ParameterElement param) => _serializeSyntheticParam(
- param, compilationUnit, typeParameterContext))
+ .map((ParameterElement param) =>
+ _serializeSyntheticParam(param, compilationUnit, element))
+ .toList();
+ result.typeParameters = element.typeParameters
+ .map((TypeParameterElement e) =>
+ _serializeSyntheticTypeParameter(e, compilationUnit, element))
.toList();
- return result;
- }
- if (element is FunctionElement) {
- // Element is a local function inside another executable.
- result.reference = compilationUnit.addReference(element);
- // TODO(paulberry): do I need to store type arguments?
return result;
}
if (element is GenericFunctionTypeElement) {
@@ -307,6 +303,30 @@ UnlinkedParamBuilder _serializeSyntheticParam(
}
/**
+ * Create an [UnlinkedTypeParamBuilder] representing the given [typeParameter],
+ * which should be a type parameter of a synthetic function type (e.g. one
+ * produced during type inference as a result of computing the least upper
+ * bound of two function types).
+ */
+UnlinkedTypeParamBuilder _serializeSyntheticTypeParameter(
+ TypeParameterElement typeParameter,
+ CompilationUnitElementInBuildUnit compilationUnit,
+ TypeParameterizedElementMixin typeParameterContext) {
+ TypeParameterElementImpl impl = typeParameter as TypeParameterElementImpl;
+ EntityRefBuilder boundBuilder = typeParameter.bound != null
+ ? _createLinkedType(
+ typeParameter.bound, compilationUnit, typeParameterContext)
+ : null;
+ CodeRangeBuilder codeRangeBuilder =
+ new CodeRangeBuilder(offset: impl.codeOffset, length: impl.codeLength);
+ return new UnlinkedTypeParamBuilder(
+ name: typeParameter.name,
+ nameOffset: typeParameter.nameOffset,
+ bound: boundBuilder,
+ codeRange: codeRangeBuilder);
+}
+
+/**
* Store the given [typeArguments] in [encodedType], using [compilationUnit] and
* [typeParameterContext] to serialize them.
*/
@@ -1056,15 +1076,8 @@ abstract class CompilationUnitElementForLink
if (containingReference != 0 &&
_linkedUnit.references[containingReference].kind !=
ReferenceKind.prefix) {
- if (linkedReference.kind == ReferenceKind.function) {
- // Local function
- _references[index] = resolveRef(containingReference)
- .getLocalFunction(linkedReference.localIndex) ??
- UndefinedElementForLink.instance;
- } else {
- _references[index] =
- resolveRef(containingReference).getContainedName(name);
- }
+ _references[index] =
+ resolveRef(containingReference).getContainedName(name);
} else if (linkedReference.dependency == 0) {
if (linkedReference.kind == ReferenceKind.unresolved) {
_references[index] = UndefinedElementForLink.instance;
@@ -1104,8 +1117,9 @@ abstract class CompilationUnitElementForLink
} else if (entity.entityKind == EntityRefKind.genericFunctionType) {
return new GenericFunctionTypeElementForLink(this, context, entity).type;
} else if (entity.syntheticReturnType != null) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
+ FunctionElementImpl element =
+ new FunctionElementForLink_Synthetic(this, context, entity);
+ return element.type;
} else if (entity.implicitFunctionTypeIndices.isNotEmpty) {
DartType type = resolveRef(entity.reference).asStaticType;
for (int index in entity.implicitFunctionTypeIndices) {
@@ -1172,7 +1186,6 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
int numTypeParameters: 0,
int unitNum: 0,
int containingReference: 0,
- int localIndex: 0,
ReferenceKind kind: ReferenceKind.classOrEnum}) {
List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
@@ -1196,8 +1209,7 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
linkedReference.numTypeParameters == numTypeParameters &&
linkedReference.unit == unitNum &&
candidateContainingReference == containingReference &&
- linkedReference.kind == kind &&
- linkedReference.localIndex == localIndex) {
+ linkedReference.kind == kind) {
return i;
}
}
@@ -1208,8 +1220,7 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
numTypeParameters: numTypeParameters,
unit: unitNum,
containingReference: containingReference,
- kind: kind,
- localIndex: localIndex));
+ kind: kind));
return result;
}
@@ -1233,16 +1244,7 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
} else if (element is FunctionElementForLink_Initializer) {
return addRawReference('',
containingReference: addReference(element.enclosingElement),
- kind: ReferenceKind.function,
- localIndex: 0);
- } else if (element is FunctionElementForLink_Local_NonSynthetic) {
- ExecutableElementForLink parent = element.enclosingElement;
- int localIndex = parent.functions.indexOf(element);
- assert(localIndex != -1);
- return addRawReference(element.name,
- containingReference: addReference(parent),
- kind: ReferenceKind.function,
- localIndex: localIndex);
+ kind: ReferenceKind.function);
} else if (element is ExecutableElementForLink_NonLocal) {
ClassElementForLink_Class enclosingClass = element.enclosingClass;
ReferenceKind kind;
@@ -2896,6 +2898,9 @@ class FunctionElementForLink_FunctionTypedParam extends Object
}
@override
+ bool get isSynthetic => true;
+
+ @override
DartType get returnType {
if (_returnType == null) {
if (enclosingElement._unlinkedParam.type == null) {
@@ -3165,6 +3170,43 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
}
/**
+ * Synthetic function element which is created for local functions.
+ */
+class FunctionElementForLink_Synthetic extends ExecutableElementForLink
+ with ReferenceableElementForLink
+ implements FunctionElementForLink_Local {
+ @override
+ final ExecutableElementForLink enclosingElement;
+
+ final EntityRef _entityRef;
+
+ FunctionElementForLink_Synthetic(
+ CompilationUnitElementForLink compilationUnit,
+ this.enclosingElement,
+ this._entityRef)
+ : super(compilationUnit, null);
+
+ @override
+ TypeParameterizedElementMixin get enclosingTypeParameterContext =>
+ enclosingElement;
+
+ @override
+ DartType get returnType {
+ return _declaredReturnType ??= enclosingUnit.resynthesizerContext
+ .resolveTypeRef(this, _entityRef.syntheticReturnType);
+ }
+
+ @override
+ List<UnlinkedParam> get unlinkedParameters => _entityRef.syntheticParams;
+
+ @override
+ List<UnlinkedTypeParam> get unlinkedTypeParams => _entityRef.typeParameters;
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
* Element representing a typedef resynthesized from a summary during linking.
*/
class FunctionTypeAliasElementForLink extends Object
@@ -5329,7 +5371,7 @@ abstract class VariableElementForLink
_inferredType = DynamicTypeImpl.instance;
} else {
_inferredType = compilationUnit.getLinkedType(
- this, unlinkedVariable.inferredTypeSlot);
+ initializer, unlinkedVariable.inferredTypeSlot);
}
}
return _inferredType;

Powered by Google App Engine
This is Rietveld 408576698