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

Unified Diff: pkg/analyzer/lib/src/generated/declaration_resolver.dart

Issue 2435313002: More improvements to DeclarationResolver. (Closed)
Patch Set: Created 4 years, 2 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/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;
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/element.dart ('k') | pkg/analyzer/test/generated/declaration_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698