| 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 f2c738f6f8709560e5790d6d3656313f58cfb0d4..33cddf75ae26ab1993f6bf07ce8392fc4c526de9 100644
|
| --- a/pkg/analyzer/lib/src/summary/link.dart
|
| +++ b/pkg/analyzer/lib/src/summary/link.dart
|
| @@ -2167,6 +2167,9 @@ class ExprTypeComputer {
|
| assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
|
| stack.add(function.functions[_getNextInt()].type);
|
| break;
|
| + case UnlinkedConstOperation.pushParameter:
|
| + stack.add(_findParameterType(_getNextString()));
|
| + break;
|
| default:
|
| // TODO(paulberry): implement.
|
| throw new UnimplementedError('$operation');
|
| @@ -2435,6 +2438,29 @@ class ExprTypeComputer {
|
| }
|
| }
|
|
|
| + /**
|
| + * Find the parameter in scope called [parameterName] and return its type.
|
| + */
|
| + DartType _findParameterType(String parameterName) {
|
| + FunctionElementForLink_Local f = this.function;
|
| + while (true) {
|
| + for (ParameterElement parameter in f.parameters) {
|
| + if (parameter.name == parameterName) {
|
| + return parameter.type;
|
| + }
|
| + }
|
| + Element parent = f.enclosingElement;
|
| + if (parent is FunctionElementForLink_Local) {
|
| + f = parent;
|
| + } else {
|
| + // Parameter not found. This should never happen in a well-formed
|
| + // summary.
|
| + assert(false);
|
| + return DynamicTypeImpl.instance;
|
| + }
|
| + }
|
| + }
|
| +
|
| int _getNextInt() {
|
| return unlinkedConst.ints[intPtr++];
|
| }
|
| @@ -2657,6 +2683,7 @@ class FieldElementForLink_ClassField extends VariableElementForLink
|
| unlinkedVariable.inferredTypeSlot,
|
| isStatic ? inferredType : _inferredInstanceType,
|
| _typeParameterContext);
|
| + initializer?.link(compilationUnit);
|
| }
|
| }
|
|
|
| @@ -2772,11 +2799,21 @@ class FunctionElementForLink_Initializer extends Object
|
| */
|
| final VariableElementForLink _variable;
|
|
|
| + /**
|
| + * The type inference node for this function, or `null` if it hasn't been
|
| + * computed yet.
|
| + */
|
| + TypeInferenceNode _typeInferenceNode;
|
| +
|
| List<FunctionElementForLink_Local_NonSynthetic> _functions;
|
|
|
| FunctionElementForLink_Initializer(this._variable);
|
|
|
| @override
|
| + TypeInferenceNode get asTypeInferenceNode =>
|
| + _typeInferenceNode ??= new TypeInferenceNode(this);
|
| +
|
| + @override
|
| CompilationUnitElementForLink get compilationUnit =>
|
| _variable.compilationUnit;
|
|
|
| @@ -2839,6 +2876,16 @@ class FunctionElementForLink_Initializer extends Object
|
| return index < functions.length ? functions[index] : null;
|
| }
|
|
|
| + /**
|
| + * Store the results of type inference for this initializer in
|
| + * [compilationUnit].
|
| + */
|
| + void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| + for (FunctionElementForLink_Local_NonSynthetic function in functions) {
|
| + function.link(compilationUnit);
|
| + }
|
| + }
|
| +
|
| @override
|
| noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
|
|
| @@ -2879,6 +2926,14 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
|
| @override
|
| final ExecutableElementForLink enclosingElement;
|
|
|
| + List<FunctionElementForLink_Local_NonSynthetic> _functions;
|
| +
|
| + /**
|
| + * The type inference node for this function, or `null` if it hasn't been
|
| + * computed yet.
|
| + */
|
| + TypeInferenceNode _typeInferenceNode;
|
| +
|
| FunctionElementForLink_Local_NonSynthetic(
|
| CompilationUnitElementForLink compilationUnit,
|
| this.enclosingElement,
|
| @@ -2886,14 +2941,23 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
|
| : super(compilationUnit, unlinkedExecutable);
|
|
|
| @override
|
| + TypeInferenceNode get asTypeInferenceNode =>
|
| + _typeInferenceNode ??= new TypeInferenceNode(this);
|
| +
|
| + @override
|
| TypeParameterizedElementMixin get enclosingTypeParameterContext =>
|
| enclosingElement;
|
|
|
| @override
|
| - bool get _hasTypeBeenInferred {
|
| - // TODO(paulberry): add logic to infer types of nonsynthetic functions.
|
| - return true;
|
| - }
|
| + List<FunctionElementForLink_Local_NonSynthetic> get functions =>
|
| + _functions ??= _unlinkedExecutable.localFunctions
|
| + .map((UnlinkedExecutable ex) =>
|
| + new FunctionElementForLink_Local_NonSynthetic(
|
| + compilationUnit, this, ex))
|
| + .toList();
|
| +
|
| + @override
|
| + bool get _hasTypeBeenInferred => _inferredReturnType != null;
|
|
|
| @override
|
| DartType buildType(
|
| @@ -2904,8 +2968,19 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
|
|
|
| @override
|
| FunctionElementForLink_Local getLocalFunction(int index) {
|
| - // TODO(paulberry): implement.
|
| - throw new UnimplementedError();
|
| + List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
|
| + return index < functions.length ? functions[index] : null;
|
| + }
|
| +
|
| + /**
|
| + * Store the results of type inference for this function in [compilationUnit].
|
| + */
|
| + void link(CompilationUnitElementInBuildUnit compilationUnit) {
|
| + compilationUnit._storeLinkedType(
|
| + _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this);
|
| + for (FunctionElementForLink_Local_NonSynthetic function in functions) {
|
| + function.link(compilationUnit);
|
| + }
|
| }
|
|
|
| @override
|
| @@ -2913,8 +2988,9 @@ class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
|
|
|
| @override
|
| void _setInferredType(DartType type) {
|
| - // TODO(paulberry): add logic to infer types of nonsynthetic functions.
|
| - throw new UnimplementedError();
|
| + // TODO(paulberry): store the inferred return type in the summary.
|
| + assert(!_hasTypeBeenInferred);
|
| + _inferredReturnType = type;
|
| }
|
| }
|
|
|
| @@ -4340,6 +4416,7 @@ class TopLevelVariableElementForLink extends VariableElementForLink
|
| compilationUnit._storeLinkedType(
|
| unlinkedVariable.inferredTypeSlot, inferredType, null);
|
| }
|
| + initializer?.link(compilationUnit);
|
| }
|
| }
|
| }
|
| @@ -4453,10 +4530,9 @@ class TypeInferenceNode extends Node<TypeInferenceNode> {
|
| case UnlinkedConstOperation.pushLocalFunctionReference:
|
| int popCount = unlinkedConst.ints[intPtr++];
|
| assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
|
| - collectDependencies(
|
| - dependencies,
|
| - unlinkedExecutable.localFunctions[unlinkedConst.ints[intPtr++]],
|
| - compilationUnit);
|
| + dependencies.add(functionElement
|
| + .getLocalFunction(unlinkedConst.ints[intPtr++])
|
| + .asTypeInferenceNode);
|
| break;
|
| default:
|
| break;
|
| @@ -4687,7 +4763,7 @@ abstract class VariableElementForLink
|
| unlinkedVariable.initializer?.bodyExpr != null) {
|
| _constNode = new ConstVariableNode(this);
|
| if (unlinkedVariable.type == null) {
|
| - _typeInferenceNode = new TypeInferenceNode(initializer);
|
| + _typeInferenceNode = initializer.asTypeInferenceNode;
|
| }
|
| }
|
| }
|
|
|