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

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

Issue 2014893004: In AST-based type inference, use function elements rather than variable elements. (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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/linker_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/link.dart
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 3ce9ce8cb01a8e32c88b782d6854e7ce678fe7fd..f2c738f6f8709560e5790d6d3656313f58cfb0d4 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1972,13 +1972,12 @@ abstract class ExecutableElementForLink_NonLocal
}
class ExprTypeComputer {
- VariableElementForLink variable;
- FunctionElementForLink_Initializer initializer;
- CompilationUnitElementForLink unit;
- LibraryElementForLink library;
- Linker linker;
- TypeProvider typeProvider;
- UnlinkedConst unlinkedConst;
+ final FunctionElementForLink_Local function;
+ final CompilationUnitElementForLink unit;
+ final LibraryElementForLink library;
+ final Linker linker;
+ final TypeProvider typeProvider;
+ final UnlinkedConst unlinkedConst;
final List<DartType> stack = <DartType>[];
int intPtr = 0;
@@ -1986,17 +1985,25 @@ class ExprTypeComputer {
int strPtr = 0;
int assignmentOperatorPtr = 0;
- ExprTypeComputer(VariableElementForLink variableElement) {
- this.variable = variableElement;
- initializer = variableElement.initializer;
- unit = variableElement.compilationUnit;
- library = unit.enclosingElement;
- linker = library._linker;
- typeProvider = linker.typeProvider;
- unlinkedConst = variableElement.unlinkedVariable.initializer?.bodyExpr;
+ factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
+ CompilationUnitElementForLink unit = functionElement.compilationUnit;
+ LibraryElementForLink library = unit.enclosingElement;
+ Linker linker = library._linker;
+ TypeProvider typeProvider = linker.typeProvider;
+ UnlinkedConst unlinkedConst = functionElement._unlinkedExecutable.bodyExpr;
+ return new ExprTypeComputer._(
+ functionElement, unit, library, linker, typeProvider, unlinkedConst);
}
+ ExprTypeComputer._(this.function, this.unit, this.library, this.linker,
+ this.typeProvider, this.unlinkedConst);
+
DartType compute() {
+ if (unlinkedConst == null) {
+ // No function body was stored for this function, so we can't infer its
+ // return type. Assume `dynamic`.
+ return DynamicTypeImpl.instance;
+ }
// Perform RPN evaluation of the constant, using a stack of inferred types.
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
@@ -2158,7 +2165,7 @@ class ExprTypeComputer {
case UnlinkedConstOperation.pushLocalFunctionReference:
int popCount = _getNextInt();
assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
- stack.add(initializer.functions[_getNextInt()].type);
+ stack.add(function.functions[_getNextInt()].type);
break;
default:
// TODO(paulberry): implement.
@@ -2315,7 +2322,7 @@ class ExprTypeComputer {
// Type argument explicitly specified.
if (i < ref.typeArguments.length) {
return unit.resolveTypeRef(
- ref.typeArguments[i], variable._typeParameterContext);
+ ref.typeArguments[i], function.typeParameterContext);
} else {
return null;
}
@@ -2448,7 +2455,7 @@ class ExprTypeComputer {
DartType _getNextTypeRef() {
EntityRef ref = _getNextRef();
- return unit.resolveTypeRef(ref, variable._typeParameterContext);
+ return unit.resolveTypeRef(ref, function.typeParameterContext);
}
/**
@@ -2758,7 +2765,7 @@ class FunctionElementForLink_FunctionTypedParam extends Object
* Element representing the initializer expression of a variable.
*/
class FunctionElementForLink_Initializer extends Object
- with ReferenceableElementForLink
+ with ReferenceableElementForLink, TypeParameterizedElementMixin
implements FunctionElementForLink_Local {
/**
* The variable for which this element is the initializer.
@@ -2770,6 +2777,10 @@ class FunctionElementForLink_Initializer extends Object
FunctionElementForLink_Initializer(this._variable);
@override
+ CompilationUnitElementForLink get compilationUnit =>
+ _variable.compilationUnit;
+
+ @override
VariableElementForLink get enclosingElement => _variable;
TypeParameterizedElementMixin get enclosingTypeParameterContext =>
@@ -2778,6 +2789,9 @@ class FunctionElementForLink_Initializer extends Object
: null;
@override
+ CompilationUnitElementForLink get enclosingUnit => _variable.compilationUnit;
+
+ @override
List<FunctionElementForLink_Local_NonSynthetic> get functions =>
_functions ??= _variable.unlinkedVariable.initializer.localFunctions
.map((UnlinkedExecutable ex) =>
@@ -2807,10 +2821,17 @@ class FunctionElementForLink_Initializer extends Object
}
@override
- int get typeParameterNestingLevel =>
- enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0;
+ TypeParameterizedElementMixin get typeParameterContext => this;
- List<TypeParameterElement> get typeParameters => const [];
+ @override
+ List<UnlinkedTypeParam> get unlinkedTypeParams => const [];
+
+ @override
+ bool get _hasTypeBeenInferred => _variable._inferredType != null;
+
+ @override
+ UnlinkedExecutable get _unlinkedExecutable =>
+ _variable.unlinkedVariable.initializer;
@override
FunctionElementForLink_Local getLocalFunction(int index) {
@@ -2820,6 +2841,12 @@ class FunctionElementForLink_Initializer extends Object
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ void _setInferredType(DartType type) {
+ assert(!_hasTypeBeenInferred);
+ _variable._inferredType = type;
+ }
}
/**
@@ -2829,7 +2856,18 @@ abstract class FunctionElementForLink_Local
implements
ExecutableElementForLink,
FunctionElementImpl,
- ReferenceableElementForLink {}
+ ReferenceableElementForLink {
+ /**
+ * Indicates whether type inference has completed for this function.
+ */
+ bool get _hasTypeBeenInferred;
+
+ /**
+ * Stores the given [type] as the inferred return type for this function.
+ * Should only be called if [_hasTypeBeenInferred] is `false`.
+ */
+ void _setInferredType(DartType type);
+}
/**
* Element representing a local function (possibly a closure) inside another
@@ -2852,6 +2890,12 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
enclosingElement;
@override
+ bool get _hasTypeBeenInferred {
+ // TODO(paulberry): add logic to infer types of nonsynthetic functions.
+ return true;
+ }
+
+ @override
DartType buildType(
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
assert(implicitFunctionTypeIndices.isEmpty);
@@ -2866,6 +2910,12 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ void _setInferredType(DartType type) {
+ // TODO(paulberry): add logic to infer types of nonsynthetic functions.
+ throw new UnimplementedError();
+ }
}
/**
@@ -4319,15 +4369,14 @@ class TypeInferenceDependencyWalker
*/
class TypeInferenceNode extends Node<TypeInferenceNode> {
/**
- * The [FieldElement] or [TopLevelVariableElement] to which this
- * node refers.
+ * The [FunctionElementForLink_Local] to which this node refers.
*/
- final VariableElementForLink variableElement;
+ final FunctionElementForLink_Local functionElement;
- TypeInferenceNode(this.variableElement);
+ TypeInferenceNode(this.functionElement);
@override
- bool get isEvaluated => variableElement._inferredType != null;
+ bool get isEvaluated => functionElement._hasTypeBeenInferred;
/**
* Collect the type inference dependencies in [unlinkedExecutable] (which
@@ -4420,24 +4469,22 @@ class TypeInferenceNode extends Node<TypeInferenceNode> {
@override
List<TypeInferenceNode> computeDependencies() {
List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
- collectDependencies(
- dependencies,
- variableElement.unlinkedVariable.initializer,
- variableElement.compilationUnit);
+ collectDependencies(dependencies, functionElement._unlinkedExecutable,
+ functionElement.compilationUnit);
return dependencies;
}
void evaluate(bool inCycle) {
if (inCycle) {
- variableElement._inferredType = DynamicTypeImpl.instance;
+ functionElement._setInferredType(DynamicTypeImpl.instance);
} else {
- variableElement._inferredType =
- new ExprTypeComputer(variableElement).compute();
+ functionElement
+ ._setInferredType(new ExprTypeComputer(functionElement).compute());
}
}
@override
- String toString() => 'TypeInferenceNode($variableElement)';
+ String toString() => 'TypeInferenceNode($functionElement)';
}
class TypeProviderForLink implements TypeProvider {
@@ -4640,7 +4687,7 @@ abstract class VariableElementForLink
unlinkedVariable.initializer?.bodyExpr != null) {
_constNode = new ConstVariableNode(this);
if (unlinkedVariable.type == null) {
- _typeInferenceNode = new TypeInferenceNode(this);
+ _typeInferenceNode = new TypeInferenceNode(initializer);
}
}
}
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/linker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698