Chromium Code Reviews| 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 19cf95c00f091e368532970d5a09b7053792e7b5..468c97d0e290c452f57deed4f0fa8f94b37c4cf9 100644 |
| --- a/pkg/analyzer/lib/src/summary/link.dart |
| +++ b/pkg/analyzer/lib/src/summary/link.dart |
| @@ -200,6 +200,16 @@ EntityRefBuilder _createLinkedType( |
| } |
| return result; |
| } |
| + if (element is TopLevelFunctionElementForLink) { |
| + result.reference = compilationUnit.addReference(element); |
| + if (type.typeArguments.isNotEmpty) { |
| + result.typeArguments = type.typeArguments |
| + .map((DartType t) => |
| + _createLinkedType(t, compilationUnit, typeParameterContext)) |
| + .toList(); |
| + } |
| + return result; |
| + } |
| if (element is MethodElementForLink) { |
| result.reference = compilationUnit.addReference(element); |
| if (type.typeArguments.isNotEmpty) { |
| @@ -666,6 +676,7 @@ abstract class CompilationUnitElementForLink |
| Map<String, ReferenceableElementForLink> _containedNames; |
| List<TopLevelVariableElementForLink> _topLevelVariables; |
| List<ClassElementForLink_Enum> _enums; |
| + List<TopLevelFunctionElementForLink> _functions; |
| /** |
| * Index of this unit in the list of units in the enclosing library. |
| @@ -692,6 +703,17 @@ abstract class CompilationUnitElementForLink |
| } |
| @override |
| + List<TopLevelFunctionElementForLink> get functions { |
| + if (_functions == null) { |
| + _functions = <TopLevelFunctionElementForLink>[]; |
| + for (UnlinkedExecutable executable in _unlinkedUnit.executables) { |
|
Paul Berry
2016/04/18 20:08:27
Is CompilationUnitElement.functions supposed to re
scheglov
2016/04/18 20:24:34
You're right.
Done.
|
| + _functions.add(new TopLevelFunctionElementForLink(this, executable)); |
| + } |
| + } |
| + return _functions; |
| + } |
| + |
| + @override |
| String get identifier => _absoluteUri; |
| /** |
| @@ -761,6 +783,9 @@ abstract class CompilationUnitElementForLink |
| for (TopLevelVariableElementForLink variable in topLevelVariables) { |
| _containedNames[variable.name] = variable; |
| } |
| + for (TopLevelFunctionElementForLink function in functions) { |
| + _containedNames[function.name] = function; |
| + } |
| // TODO(paulberry): fill in other top level entities (typedefs |
| // and executables). |
| } |
| @@ -944,13 +969,13 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink { |
| numTypeParameters: element.typeParameters.length, |
| unitNum: element.enclosingElement.unitNum); |
| } else if (element is ExecutableElementForLink) { |
| - // TODO(paulberry): will this code ever be executed for an executable |
| - // element that's not inside a class? |
| - assert(element.enclosingElement is ClassElementForLink_Class); |
| + ClassElementForLink_Class enclosingClass = element.enclosingClass; |
| ReferenceKind kind; |
| switch (element._unlinkedExecutable.kind) { |
| case UnlinkedExecutableKind.functionOrMethod: |
| - kind = ReferenceKind.method; |
| + kind = enclosingClass != null |
| + ? ReferenceKind.method |
| + : ReferenceKind.topLevelFunction; |
| break; |
| case UnlinkedExecutableKind.setter: |
| kind = ReferenceKind.propertyAccessor; |
| @@ -961,7 +986,8 @@ class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink { |
| } |
| return addRawReference(element.name, |
| numTypeParameters: element.typeParameters.length, |
| - containingReference: addReference(element.enclosingElement), |
| + containingReference: |
| + enclosingClass != null ? addReference(enclosingClass) : null, |
| kind: kind); |
| } |
| // TODO(paulberry): implement other cases |
| @@ -1146,7 +1172,7 @@ class ConstConstructorNode extends ConstNode { |
| UnlinkedConstructorInitializerKind.thisInvocation) { |
| defaultSuperInvocationNeeded = false; |
| ConstructorElementForLink constructor = constructorElement |
| - .enclosingElement |
| + .enclosingClass |
| .getContainedName(constructorInitializer.name) |
| .asConstructor; |
| safeAddDependency(constructor?._constNode); |
| @@ -1192,7 +1218,7 @@ class ConstConstructorNode extends ConstNode { |
| EntityRef redirectedConstructor = |
| constructorElement._unlinkedExecutable.redirectedConstructor; |
| if (redirectedConstructor != null) { |
| - return constructorElement.enclosingElement.enclosingElement |
| + return constructorElement.enclosingUnit |
| ._resolveRef(redirectedConstructor.reference) |
| .asConstructor; |
| } else { |
| @@ -1314,10 +1340,11 @@ class ConstructorElementForLink extends ExecutableElementForLink |
| */ |
| ConstConstructorNode _constNode; |
| - ConstructorElementForLink(ClassElementForLink_Class enclosingElement, |
| + ConstructorElementForLink(ClassElementForLink_Class enclosingClass, |
| UnlinkedExecutable unlinkedExecutable) |
| - : super(enclosingElement, unlinkedExecutable) { |
| - if (enclosingElement.enclosingElement.isInBuildUnit && |
| + : super(enclosingClass.enclosingElement, enclosingClass, |
| + unlinkedExecutable) { |
| + if (enclosingClass.enclosingElement.isInBuildUnit && |
| _unlinkedExecutable != null && |
| _unlinkedExecutable.constCycleSlot != 0) { |
| _constNode = new ConstConstructorNode(this); |
| @@ -1573,18 +1600,18 @@ abstract class ExecutableElementForLink extends Object |
| String _displayName; |
| /** |
| - * TODO(paulberry): this won't always be a class element. |
| + * Return the class in which this executable appears, maybe `null` for a |
| + * top-level function. |
| */ |
| - @override |
| - final ClassElementForLink_Class enclosingElement; |
| - |
| - ExecutableElementForLink(this.enclosingElement, this._unlinkedExecutable); |
| + final ClassElementForLink_Class enclosingClass; |
| /** |
| * Return the compilation unit in which this executable appears. |
| */ |
| - CompilationUnitElementForLink get compilationUnit => |
| - enclosingElement.enclosingElement; |
| + final CompilationUnitElementForLink enclosingUnit; |
| + |
| + ExecutableElementForLink( |
| + this.enclosingUnit, this.enclosingClass, this._unlinkedExecutable); |
| @override |
| String get displayName { |
| @@ -1598,8 +1625,11 @@ abstract class ExecutableElementForLink extends Object |
| } |
| @override |
| + Element get enclosingElement => enclosingClass ?? enclosingUnit; |
| + |
| + @override |
| TypeParameterizedElementForLink get enclosingTypeParameterContext => |
| - enclosingElement; |
| + enclosingClass; |
| @override |
| bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null; |
| @@ -1632,7 +1662,7 @@ abstract class ExecutableElementForLink extends Object |
| for (int i = 0; i < numParameters; i++) { |
| UnlinkedParam unlinkedParam = _unlinkedExecutable.parameters[i]; |
| _parameters[i] = new ParameterElementForLink( |
| - this, unlinkedParam, this, enclosingElement.enclosingElement, i); |
| + this, unlinkedParam, this, enclosingUnit, i); |
| } |
| } |
| return _parameters; |
| @@ -1647,8 +1677,8 @@ abstract class ExecutableElementForLink extends Object |
| if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) { |
| // TODO(paulberry): implement. |
| throw new UnimplementedError(); |
| - } else if (!compilationUnit.isInBuildUnit) { |
| - _inferredReturnType = compilationUnit.getLinkedType( |
| + } else if (!enclosingUnit.isInBuildUnit) { |
| + _inferredReturnType = enclosingUnit.getLinkedType( |
| _unlinkedExecutable.inferredReturnTypeSlot, this); |
| return _inferredReturnType; |
| } else if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter && |
| @@ -1660,8 +1690,8 @@ abstract class ExecutableElementForLink extends Object |
| _declaredReturnType = DynamicTypeImpl.instance; |
| } |
| } else { |
| - _declaredReturnType = enclosingElement.enclosingElement |
| - ._resolveTypeRef(_unlinkedExecutable.returnType, this); |
| + _declaredReturnType = |
| + enclosingUnit._resolveTypeRef(_unlinkedExecutable.returnType, this); |
| } |
| } |
| return _declaredReturnType; |
| @@ -2021,11 +2051,11 @@ class ExprTypeComputer { |
| // to infer the type of type arguments. |
| stack.length -= numNamed + numPositional; |
| strPtr += numNamed; |
| - EntityRef ref = unlinkedConst.references[refPtr++]; |
| + EntityRef ref = _getNextRef(); |
| ConstructorElementForLink element = |
| unit._resolveRef(ref.reference).asConstructor; |
| if (element != null) { |
| - stack.add(element.enclosingElement.buildType( |
| + stack.add(element.enclosingClass.buildType( |
| (int i) => i >= ref.typeArguments.length |
| ? DynamicTypeImpl.instance |
| : unit._resolveTypeRef( |
| @@ -2066,7 +2096,7 @@ class ExprTypeComputer { |
| List<String> namedArgNames = _getNextStrings(numNamed); |
| List<DartType> namedArgTypeList = _popList(numNamed); |
| List<DartType> positionalArgTypes = _popList(numPositional); |
| - EntityRef ref = unlinkedConst.references[refPtr++]; |
| + EntityRef ref = _getNextRef(); |
| ReferenceableElementForLink element = unit._resolveRef(ref.reference); |
| stack.add(() { |
| DartType rawType = element.asStaticType; |
| @@ -2123,7 +2153,7 @@ class ExprTypeComputer { |
| } |
| void _doPushReference() { |
| - EntityRef ref = unlinkedConst.references[refPtr++]; |
| + EntityRef ref = _getNextRef(); |
| if (ref.paramReference != 0) { |
| stack.add(typeProvider.typeType); |
| } else { |
| @@ -2133,8 +2163,7 @@ class ExprTypeComputer { |
| // Nor can implicit function types derived from |
| // function-typed parameters. |
| assert(ref.implicitFunctionTypeIndices.isEmpty); |
| - ReferenceableElementForLink element = |
| - variable.compilationUnit._resolveRef(ref.reference); |
| + ReferenceableElementForLink element = unit._resolveRef(ref.reference); |
| stack.add(element.asStaticType); |
| } |
| } |
| @@ -2143,6 +2172,8 @@ class ExprTypeComputer { |
| return unlinkedConst.ints[intPtr++]; |
| } |
| + EntityRef _getNextRef() => unlinkedConst.references[refPtr++]; |
| + |
| String _getNextString() { |
| return unlinkedConst.strings[strPtr++]; |
| } |
| @@ -2156,7 +2187,7 @@ class ExprTypeComputer { |
| } |
| DartType _getNextTypeRef() { |
| - EntityRef ref = unlinkedConst.references[refPtr++]; |
| + EntityRef ref = _getNextRef(); |
| return unit._resolveTypeRef(ref, variable._typeParameterContext); |
| } |
| @@ -3091,9 +3122,10 @@ class Linker { |
| */ |
| class MethodElementForLink extends ExecutableElementForLink |
| implements MethodElementImpl { |
| - MethodElementForLink(ClassElementForLink_Class enclosingElement, |
| + MethodElementForLink(ClassElementForLink_Class enclosingClass, |
| UnlinkedExecutable unlinkedExecutable) |
| - : super(enclosingElement, unlinkedExecutable); |
| + : super(enclosingClass.enclosingElement, enclosingClass, |
| + unlinkedExecutable); |
| @override |
| String get identifier => name; |
| @@ -3365,10 +3397,11 @@ class PropertyAccessorElementForLink_Executable extends ExecutableElementForLink |
| SyntheticVariableElementForLink variable; |
| PropertyAccessorElementForLink_Executable( |
| - ClassElementForLink_Class enclosingElement, |
| + ClassElementForLink_Class enclosingClass, |
| UnlinkedExecutable unlinkedExecutable, |
| this.variable) |
| - : super(enclosingElement, unlinkedExecutable); |
| + : super(enclosingClass.enclosingElement, enclosingClass, |
| + unlinkedExecutable); |
| @override |
| PropertyAccessorElementForLink_Executable get correspondingGetter => |
| @@ -3599,6 +3632,33 @@ class SyntheticVariableElementForLink implements PropertyInducingElementImpl { |
| } |
| /** |
| + * Element representing a top-level function. |
| + */ |
| +class TopLevelFunctionElementForLink extends ExecutableElementForLink |
| + implements FunctionElementImpl, ReferenceableElementForLink { |
| + DartType _returnType; |
| + |
| + TopLevelFunctionElementForLink( |
| + CompilationUnitElementForLink enclosingUnit, UnlinkedExecutable _buf) |
| + : super(enclosingUnit, null, _buf); |
| + |
| + @override |
| + ConstVariableNode get asConstVariable => null; |
| + |
| + @override |
| + DartType get asStaticType => type; |
| + |
| + @override |
| + TypeInferenceNode get asTypeInferenceNode => null; |
| + |
| + @override |
| + ElementKind get kind => ElementKind.FUNCTION; |
| + |
| + @override |
| + noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| +} |
| + |
| +/** |
| * Element representing a top level variable resynthesized from a |
| * summary during linking. |
| */ |