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

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

Issue 1966783003: First steps toward AST-based type inference involving closures. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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 307a9f2e3d1e79eec75f29aad2cca9244f0c699c..bc2fc0def4aac9a61b6d6dc3af59ca5e3b26bb05 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -218,12 +218,9 @@ EntityRefBuilder _createLinkedType(
type.typeArguments, result, compilationUnit, typeParameterContext);
return result;
}
- if (element is FunctionElement) {
- // Element is a FunctionElement but not a TopLevelFunctionElementForLink
- // or a MethodElementForLink. This means that it's a synthetic function
- // element that was generated on the fly to represent a type that has no
- // associated source code location.
- assert(element.enclosingElement == null);
+ 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.syntheticParams = element.parameters
@@ -232,6 +229,12 @@ EntityRefBuilder _createLinkedType(
.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;
+ }
// TODO(paulberry): implement other cases.
throw new UnimplementedError('${element.runtimeType}');
}
@@ -1075,6 +1078,7 @@ 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;
@@ -1098,7 +1102,8 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
linkedReference.numTypeParameters == numTypeParameters &&
linkedReference.unit == unitNum &&
candidateContainingReference == containingReference &&
- linkedReference.kind == kind) {
+ linkedReference.kind == kind &&
+ linkedReference.localIndex == localIndex) {
return i;
}
}
@@ -1109,7 +1114,8 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
numTypeParameters: numTypeParameters,
unit: unitNum,
containingReference: containingReference,
- kind: kind));
+ kind: kind,
+ localIndex: localIndex));
return result;
}
@@ -1151,6 +1157,28 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
containingReference:
enclosingClass != null ? addReference(enclosingClass) : null,
kind: kind);
+ } else if (element is FunctionElementForLink_Local) {
+ FunctionElementImpl parent = element.enclosingElement;
+ int localIndex = parent.functions.indexOf(element);
+ assert(localIndex != -1);
+ return addRawReference(element.name,
+ containingReference: addReference(parent),
+ kind: ReferenceKind.function,
+ localIndex: localIndex);
+ } else if (element is FunctionElementForLink_Initializer) {
+ return addRawReference('',
+ containingReference: addReference(element.enclosingElement),
+ kind: ReferenceKind.function);
+ } else if (element is TopLevelVariableElementForLink) {
+ return addRawReference(element.name,
+ kind: ReferenceKind.topLevelPropertyAccessor);
+ } else if (element is FieldElementForLink_ClassField) {
+ ClassElementForLink_Class enclosingClass = element.enclosingElement;
+ // TODO(paulberry): do we need to set numTypeParameters to nonzero if the
+ // class has type parameters?
+ return addRawReference(element.name,
+ containingReference: addReference(enclosingClass),
+ kind: ReferenceKind.propertyAccessor);
}
// TODO(paulberry): implement other cases
throw new UnimplementedError('${element.runtimeType}');
@@ -1916,6 +1944,7 @@ abstract class ExecutableElementForLink extends Object
class ExprTypeComputer {
VariableElementForLink variable;
+ FunctionElementForLink_Initializer initializer;
CompilationUnitElementForLink unit;
LibraryElementForLink library;
Linker linker;
@@ -1930,6 +1959,7 @@ class ExprTypeComputer {
ExprTypeComputer(VariableElementForLink variableElement) {
this.variable = variableElement;
+ initializer = variableElement.initializer;
unit = variableElement.compilationUnit;
library = unit.enclosingElement;
linker = library._linker;
@@ -2096,6 +2126,11 @@ class ExprTypeComputer {
stack.removeLast();
stack.add(BottomTypeImpl.instance);
break;
+ case UnlinkedConstOperation.pushLocalFunctionReference:
+ int popCount = _getNextInt();
+ assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
+ stack.add(initializer.functions[_getNextInt()].type);
+ break;
default:
// TODO(paulberry): implement.
throw new UnimplementedError('$operation');
@@ -2699,9 +2734,21 @@ class FunctionElementForLink_Initializer implements FunctionElementImpl {
*/
final VariableElementForLink _variable;
+ List<FunctionElementForLink_Local> _functions;
+
FunctionElementForLink_Initializer(this._variable);
@override
+ VariableElementForLink get enclosingElement => _variable;
+
+ @override
+ List<FunctionElementForLink_Local> get functions => _functions ??= _variable
+ .unlinkedVariable.initializer.localFunctions
+ .map(
+ (UnlinkedExecutable ex) => new FunctionElementForLink_Local(this, ex))
+ .toList();
+
+ @override
DartType get returnType {
// If this is a variable whose type needs inferring, infer it.
if (_variable.hasImplicitType) {
@@ -2727,6 +2774,33 @@ class FunctionElementForLink_Initializer implements FunctionElementImpl {
}
/**
+ * Element representing a local function (possibly a closure) inside another
+ * executable.
+ */
+class FunctionElementForLink_Local implements FunctionElementImpl {
+ /**
+ * The unlinked representation of the local function in the summary.
+ */
+ final UnlinkedExecutable _executable;
+
+ @override
+ final FunctionElementImpl enclosingElement;
+
+ DartType _type;
+
+ FunctionElementForLink_Local(this.enclosingElement, this._executable);
+
+ @override
+ String get name => _executable.name;
+
+ @override
+ DartType get type => _type ??= new FunctionTypeImpl(this);
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
* Element representing a typedef resynthesized from a summary during linking.
*/
class FunctionTypeAliasElementForLink extends Object

Powered by Google App Engine
This is Rietveld 408576698