| Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/VariableResolverVisitor.java
|
| diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/VariableResolverVisitor.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/VariableResolverVisitor.java
|
| index 149aa7a430510d453aa81ac805bf97e2dc2853b4..e3dec9cac9821b26b047387b4955612cd6928700 100644
|
| --- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/VariableResolverVisitor.java
|
| +++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/VariableResolverVisitor.java
|
| @@ -15,6 +15,8 @@ package com.google.dart.engine.internal.resolver;
|
|
|
| import com.google.dart.engine.ast.ASTNode;
|
| import com.google.dart.engine.ast.ConstructorName;
|
| +import com.google.dart.engine.ast.FunctionDeclaration;
|
| +import com.google.dart.engine.ast.FunctionExpression;
|
| import com.google.dart.engine.ast.Label;
|
| import com.google.dart.engine.ast.MethodInvocation;
|
| import com.google.dart.engine.ast.PrefixedIdentifier;
|
| @@ -22,10 +24,12 @@ import com.google.dart.engine.ast.PropertyAccess;
|
| import com.google.dart.engine.ast.SimpleIdentifier;
|
| import com.google.dart.engine.element.Element;
|
| import com.google.dart.engine.element.ElementKind;
|
| +import com.google.dart.engine.element.ExecutableElement;
|
| import com.google.dart.engine.element.VariableElement;
|
| import com.google.dart.engine.internal.element.LocalVariableElementImpl;
|
| import com.google.dart.engine.internal.element.ParameterElementImpl;
|
| import com.google.dart.engine.source.Source;
|
| +import com.google.dart.engine.utilities.general.ObjectUtilities;
|
|
|
| /**
|
| * Instances of the class {@code VariableResolverVisitor} are used to resolve
|
| @@ -35,6 +39,12 @@ import com.google.dart.engine.source.Source;
|
| */
|
| public class VariableResolverVisitor extends ScopedVisitor {
|
| /**
|
| + * The method or function that we are currently visiting, or {@code null} if we are not inside a
|
| + * method or function.
|
| + */
|
| + private ExecutableElement enclosingFunction;
|
| +
|
| + /**
|
| * Initialize a newly created visitor to resolve the nodes in a compilation unit.
|
| *
|
| * @param library the library containing the compilation unit being resolved
|
| @@ -46,6 +56,32 @@ public class VariableResolverVisitor extends ScopedVisitor {
|
| }
|
|
|
| @Override
|
| + public Void visitFunctionDeclaration(FunctionDeclaration node) {
|
| + ExecutableElement outerFunction = enclosingFunction;
|
| + try {
|
| + enclosingFunction = node.getElement();
|
| + return super.visitFunctionDeclaration(node);
|
| + } finally {
|
| + enclosingFunction = outerFunction;
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public Void visitFunctionExpression(FunctionExpression node) {
|
| + if (!(node.getParent() instanceof FunctionDeclaration)) {
|
| + ExecutableElement outerFunction = enclosingFunction;
|
| + try {
|
| + enclosingFunction = node.getElement();
|
| + return super.visitFunctionExpression(node);
|
| + } finally {
|
| + enclosingFunction = outerFunction;
|
| + }
|
| + } else {
|
| + return super.visitFunctionExpression(node);
|
| + }
|
| + }
|
| +
|
| + @Override
|
| public Void visitSimpleIdentifier(SimpleIdentifier node) {
|
| // Ignore if already resolved - declaration or type.
|
| if (node.getStaticElement() != null) {
|
| @@ -79,12 +115,22 @@ public class VariableResolverVisitor extends ScopedVisitor {
|
| if (kind == ElementKind.LOCAL_VARIABLE) {
|
| node.setStaticElement(element);
|
| if (node.inSetterContext()) {
|
| - ((LocalVariableElementImpl) element).markPotentiallyMutated();
|
| + LocalVariableElementImpl variableImpl = (LocalVariableElementImpl) element;
|
| + variableImpl.markPotentiallyMutated();
|
| + if (!ObjectUtilities.equals(element.getEnclosingElement(), enclosingFunction)) {
|
| + variableImpl.markPotentiallyMutatedInClosure();
|
| + }
|
| }
|
| } else if (kind == ElementKind.PARAMETER) {
|
| node.setStaticElement(element);
|
| if (node.inSetterContext()) {
|
| - ((ParameterElementImpl) element).markPotentiallyMutated();
|
| + ParameterElementImpl parameterImpl = (ParameterElementImpl) element;
|
| + parameterImpl.markPotentiallyMutated();
|
| + // If we are in some closure, check if it is not the same as where variable is declared.
|
| + if (enclosingFunction != null
|
| + && !ObjectUtilities.equals(element.getEnclosingElement(), enclosingFunction)) {
|
| + parameterImpl.markPotentiallyMutatedInClosure();
|
| + }
|
| }
|
| }
|
| return null;
|
|
|