| Index: pkg/analyzer/lib/src/generated/declaration_resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
|
| index df4afc29c81429b4694dc568b16cac26f826441c..4d24b8b615f4afa40e5f6918af793b684b7b27ca 100644
|
| --- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
|
| @@ -65,14 +65,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitCatchClause(CatchClause node) {
|
| - SimpleIdentifier exceptionParameter = node.exceptionParameter;
|
| - if (exceptionParameter != null) {
|
| - _match(exceptionParameter, _walker.getVariable());
|
| - SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
|
| - if (stackTraceParameter != null) {
|
| - _match(stackTraceParameter, _walker.getVariable());
|
| - }
|
| - }
|
| + _walker.elementBuilder.buildCatchVariableElements(node);
|
| return super.visitCatchClause(node);
|
| }
|
|
|
| @@ -98,8 +91,9 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| - ConstructorElement element = _match(node.name, _walker.getConstructor());
|
| - _walk(new ElementWalker.forExecutable(element), () {
|
| + ConstructorElement element = _match(node.name, _walker.getConstructor(),
|
| + offset: node.name?.offset ?? node.returnType.offset);
|
| + _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
|
| node.element = element;
|
| super.visitConstructorDeclaration(node);
|
| });
|
| @@ -109,9 +103,8 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| - VariableElement element = _match(node.identifier, _walker.getVariable());
|
| - super.visitDeclaredIdentifier(node);
|
| - _resolveMetadata(node, node.metadata, element);
|
| + // Declared identifiers can only occur inside executable elements.
|
| + _walker.elementBuilder.visitDeclaredIdentifier(node);
|
| return null;
|
| }
|
|
|
| @@ -121,7 +114,9 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| _match(node.parameter.identifier, _walker.getParameter());
|
| Expression defaultValue = node.defaultValue;
|
| if (defaultValue != null) {
|
| - _walk(new ElementWalker.forExecutable(element.initializer), () {
|
| + _walk(
|
| + new ElementWalker.forExecutable(element.initializer, _enclosingUnit),
|
| + () {
|
| defaultValue.accept(this);
|
| });
|
| }
|
| @@ -194,7 +189,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| }
|
| }
|
| node.functionExpression.element = element;
|
| - _walk(new ElementWalker.forExecutable(element), () {
|
| + _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
|
| super.visitFunctionDeclaration(node);
|
| });
|
| _resolveMetadata(node, node.metadata, element);
|
| @@ -205,8 +200,9 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| Object visitFunctionExpression(FunctionExpression node) {
|
| if (node.parent is! FunctionDeclaration) {
|
| FunctionElement element = _walker.getFunction();
|
| + _matchOffset(element, node.offset);
|
| node.element = element;
|
| - _walk(new ElementWalker.forExecutable(element), () {
|
| + _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
|
| super.visitFunctionExpression(node);
|
| });
|
| return null;
|
| @@ -250,9 +246,9 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitLabeledStatement(LabeledStatement node) {
|
| - for (Label label in node.labels) {
|
| - _match(label.label, _walker.getLabel());
|
| - }
|
| + bool onSwitchStatement = node.statement is SwitchStatement;
|
| + _walker.elementBuilder
|
| + .buildLabelElements(node.labels, onSwitchStatement, false);
|
| return super.visitLabeledStatement(node);
|
| }
|
|
|
| @@ -287,7 +283,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| elementName: nameOfMethod + '=');
|
| }
|
| }
|
| - _walk(new ElementWalker.forExecutable(element), () {
|
| + _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
|
| super.visitMethodDeclaration(node);
|
| });
|
| _resolveMetadata(node, node.metadata, element);
|
| @@ -325,17 +321,13 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitSwitchCase(SwitchCase node) {
|
| - for (Label label in node.labels) {
|
| - _match(label.label, _walker.getLabel());
|
| - }
|
| + _walker.elementBuilder.buildLabelElements(node.labels, false, true);
|
| return super.visitSwitchCase(node);
|
| }
|
|
|
| @override
|
| Object visitSwitchDefault(SwitchDefault node) {
|
| - for (Label label in node.labels) {
|
| - _match(label.label, _walker.getLabel());
|
| - }
|
| + _walker.elementBuilder.buildLabelElements(node.labels, false, true);
|
| return super.visitSwitchDefault(node);
|
| }
|
|
|
| @@ -359,7 +351,9 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| VariableElement element = _match(node.name, _walker.getVariable());
|
| Expression initializer = node.initializer;
|
| if (initializer != null) {
|
| - _walk(new ElementWalker.forExecutable(element.initializer), () {
|
| + _walk(
|
| + new ElementWalker.forExecutable(element.initializer, _enclosingUnit),
|
| + () {
|
| super.visitVariableDeclaration(node);
|
| });
|
| return null;
|
| @@ -370,12 +364,16 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitVariableDeclarationList(VariableDeclarationList node) {
|
| - super.visitVariableDeclarationList(node);
|
| - if (node.parent is! FieldDeclaration &&
|
| - node.parent is! TopLevelVariableDeclaration) {
|
| - _resolveMetadata(node, node.metadata, node.variables[0].element);
|
| + if (_walker.elementBuilder != null) {
|
| + return _walker.elementBuilder.visitVariableDeclarationList(node);
|
| + } else {
|
| + super.visitVariableDeclarationList(node);
|
| + if (node.parent is! FieldDeclaration &&
|
| + node.parent is! TopLevelVariableDeclaration) {
|
| + _resolveMetadata(node, node.metadata, node.variables[0].element);
|
| + }
|
| + return null;
|
| }
|
| - return null;
|
| }
|
|
|
| /**
|
| @@ -390,16 +388,26 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
|
| */
|
| Element/*=E*/ _match/*<E extends Element>*/(
|
| SimpleIdentifier identifier, Element/*=E*/ element,
|
| - {String elementName}) {
|
| + {String elementName, int offset}) {
|
| elementName ??= identifier?.name ?? '';
|
| + offset ??= identifier.offset;
|
| if (element.name != elementName) {
|
| throw new StateError(
|
| 'Expected an element matching `$elementName`, got `${element.name}`');
|
| }
|
| identifier?.staticElement = element;
|
| + _matchOffset(element, offset);
|
| return element;
|
| }
|
|
|
| + void _matchOffset(Element element, int offset) {
|
| + if (element.nameOffset != 0 && element.nameOffset != offset) {
|
| + throw new StateError('Element offset mismatch');
|
| + } else {
|
| + (element as ElementImpl).nameOffset = offset;
|
| + }
|
| + }
|
| +
|
| /**
|
| * Associate each of the annotation [nodes] with the corresponding
|
| * [ElementAnnotation] in [annotations]. If there is a problem, report it
|
| @@ -461,6 +469,19 @@ class ElementWalker {
|
| */
|
| final Element element;
|
|
|
| + /**
|
| + * If [element] is an executable element, an element builder which is
|
| + * accumulating the executable element's local variables and labels.
|
| + * Otherwise `null`.
|
| + */
|
| + LocalElementBuilder elementBuilder;
|
| +
|
| + /**
|
| + * If [element] is an executable element, the element holder associated with
|
| + * [elementBuilder]. Otherwise `null`.
|
| + */
|
| + ElementHolder _elementHolder;
|
| +
|
| List<PropertyAccessorElement> _accessors;
|
| int _accessorIndex = 0;
|
| List<ClassElement> _classes;
|
| @@ -471,8 +492,6 @@ class ElementWalker {
|
| int _enumIndex = 0;
|
| List<ExecutableElement> _functions;
|
| int _functionIndex = 0;
|
| - List<LabelElement> _labels;
|
| - int _labelIndex = 0;
|
| List<ParameterElement> _parameters;
|
| int _parameterIndex = 0;
|
| List<FunctionTypeAliasElement> _typedefs;
|
| @@ -514,13 +533,9 @@ class ElementWalker {
|
| * Creates an [ElementWalker] which walks the child elements of a compilation
|
| * unit element.
|
| */
|
| - ElementWalker.forExecutable(ExecutableElement element)
|
| - : element = element,
|
| - _functions = element.functions,
|
| - _labels = element.labels,
|
| - _parameters = element.parameters,
|
| - _typeParameters = element.typeParameters,
|
| - _variables = element.localVariables;
|
| + ElementWalker.forExecutable(
|
| + ExecutableElement element, CompilationUnitElement compilationUnit)
|
| + : this._forExecutable(element, compilationUnit, new ElementHolder());
|
|
|
| /**
|
| * Creates an [ElementWalker] which walks the child elements of a parameter
|
| @@ -540,6 +555,16 @@ class ElementWalker {
|
| _parameters = element.parameters,
|
| _typeParameters = element.typeParameters;
|
|
|
| + ElementWalker._forExecutable(ExecutableElement element,
|
| + CompilationUnitElement compilationUnit, ElementHolder elementHolder)
|
| + : element = element,
|
| + elementBuilder =
|
| + new LocalElementBuilder(elementHolder, compilationUnit),
|
| + _elementHolder = elementHolder,
|
| + _functions = element.functions,
|
| + _parameters = element.parameters,
|
| + _typeParameters = element.typeParameters;
|
| +
|
| /**
|
| * Returns the next non-synthetic child of [element] which is an accessor;
|
| * throws an [IndexError] if there are no more.
|
| @@ -572,12 +597,6 @@ class ElementWalker {
|
| ExecutableElement getFunction() => _functions[_functionIndex++];
|
|
|
| /**
|
| - * Returns the next non-synthetic child of [element] which is a label; throws
|
| - * an [IndexError] if there are no more.
|
| - */
|
| - LabelElement getLabel() => _labels[_labelIndex++];
|
| -
|
| - /**
|
| * Returns the next non-synthetic child of [element] which is a parameter;
|
| * throws an [IndexError] if there are no more.
|
| */
|
| @@ -620,11 +639,15 @@ class ElementWalker {
|
| check(_constructors, _constructorIndex);
|
| check(_enums, _enumIndex);
|
| check(_functions, _functionIndex);
|
| - check(_labels, _labelIndex);
|
| check(_parameters, _parameterIndex);
|
| check(_typedefs, _typedefIndex);
|
| check(_typeParameters, _typeParameterIndex);
|
| check(_variables, _variableIndex);
|
| + Element element = this.element;
|
| + if (element is ExecutableElementImpl) {
|
| + element.labels = _elementHolder.labels;
|
| + element.localVariables = _elementHolder.localVariables;
|
| + }
|
| }
|
|
|
| static bool _isNotSynthetic(Element e) => !e.isSynthetic;
|
|
|