| Index: pkg/analyzer/lib/src/generated/incremental_resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
|
| index 12e646516f06b4775d31a7d1cd0b993220e6d4ee..97a36a994f8003e96d1efad13b31890109e0d65f 100644
|
| --- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
|
| @@ -656,17 +656,20 @@ class IncrementalResolver {
|
| */
|
| void resolve(AstNode node) {
|
| AstNode rootNode = _findResolutionRoot(node);
|
| - Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener);
|
| - if (_elementModelChanged(rootNode.parent)) {
|
| + if (_elementModelChanged(rootNode)) {
|
| throw new AnalysisException("Cannot resolve node: element model changed");
|
| }
|
| + // update elements
|
| _definingUnit.accept(
|
| new _ElementNameOffsetUpdater(
|
| _updateOffset,
|
| _updateNewLength - _updateOldLength));
|
| - _resolveTypes(node, scope);
|
| - _resolveVariables(node, scope);
|
| - _resolveReferences(node, scope);
|
| + _updateElements(rootNode);
|
| + // resolve root in scope
|
| + Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener);
|
| + _resolveTypes(rootNode, scope);
|
| + _resolveVariables(rootNode, scope);
|
| + _resolveReferences(rootNode, scope);
|
| }
|
|
|
| /**
|
| @@ -715,16 +718,13 @@ class IncrementalResolver {
|
| * Throws [AnalysisException] if there is no such node.
|
| */
|
| AstNode _findResolutionRoot(AstNode node) {
|
| - AstNode result = node;
|
| - AstNode parent = result.parent;
|
| - while (parent != null && !_canBeResolved(parent)) {
|
| - result = parent;
|
| - parent = result.parent;
|
| - }
|
| - if (parent == null) {
|
| - throw new AnalysisException("Cannot resolve node: no resolvable node");
|
| + while (node != null) {
|
| + if (_canBeResolved(node)) {
|
| + return node;
|
| + }
|
| + node = node.parent;
|
| }
|
| - return result;
|
| + throw new AnalysisException("Cannot resolve node: no resolvable node");
|
| }
|
|
|
| /**
|
| @@ -769,6 +769,32 @@ class IncrementalResolver {
|
| _errorListener);
|
| node.accept(visitor);
|
| }
|
| +
|
| + void _updateElements(AstNode node) {
|
| + // build elements in node
|
| + ElementHolder holder;
|
| + _ElementsRestorer elementsRestorer = new _ElementsRestorer(node);
|
| + try {
|
| + holder = new ElementHolder();
|
| + ElementBuilder builder = new ElementBuilder(holder);
|
| + node.accept(builder);
|
| + } finally {
|
| + elementsRestorer.restore();
|
| + }
|
| + // apply compatible changes to elements
|
| + if (node is FunctionDeclaration) {
|
| + FunctionElementImpl oldElement = node.element;
|
| + FunctionElementImpl newElement = holder.functions[0];
|
| + oldElement.labels = newElement.labels;
|
| + oldElement.localVariables = newElement.localVariables;
|
| + }
|
| + if (node is MethodDeclaration) {
|
| + MethodElementImpl oldElement = node.element;
|
| + MethodElementImpl newElement = holder.methods[0];
|
| + oldElement.labels = newElement.labels;
|
| + oldElement.localVariables = newElement.localVariables;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -973,3 +999,54 @@ class _ElementsGatherer extends GeneralizingElementVisitor {
|
| }
|
| }
|
| }
|
| +
|
| +
|
| +/**
|
| + * [ElementBuilder] not just builds elements, it also applies them to nodes.
|
| + * But we want to keep externally visible (and referenced) elements instances.
|
| + * So, we need to remember them and restore.
|
| + */
|
| +class _ElementsRestorer extends RecursiveAstVisitor {
|
| + final Map<AstNode, Element> _elements = <AstNode, Element>{};
|
| +
|
| + _ElementsRestorer(AstNode root) {
|
| + root.accept(this);
|
| + }
|
| +
|
| + void restore() {
|
| + _elements.forEach((AstNode node, Element element) {
|
| + if (node is ConstructorDeclaration) {
|
| + node.element = element;
|
| + } else if (node is FunctionExpression) {
|
| + node.element = element;
|
| + } else if (node is SimpleIdentifier) {
|
| + node.staticElement = element;
|
| + }
|
| + });
|
| + }
|
| +
|
| + @override
|
| + visitBlockFunctionBody(BlockFunctionBody node) {
|
| + }
|
| +
|
| + @override
|
| + visitConstructorDeclaration(ConstructorDeclaration node) {
|
| + _elements[node] = node.element;
|
| + super.visitConstructorDeclaration(node);
|
| + }
|
| +
|
| + @override
|
| + visitExpressionFunctionBody(ExpressionFunctionBody node) {
|
| + }
|
| +
|
| + @override
|
| + visitFunctionExpression(FunctionExpression node) {
|
| + _elements[node] = node.element;
|
| + super.visitFunctionExpression(node);
|
| + }
|
| +
|
| + @override
|
| + visitSimpleIdentifier(SimpleIdentifier node) {
|
| + _elements[node] = node.staticElement;
|
| + }
|
| +}
|
|
|