| Index: pkg/analyzer/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
|
| index 394d6b3ae757653f4fd1b7329bb511de97e69eb3..7d9268530f8484c113dcf2bceee102c32378f5df 100644
|
| --- a/pkg/analyzer/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart
|
| @@ -1910,6 +1910,32 @@ class Dart2JSVerifier extends RecursiveAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * Instances of the class [UnusedLocalVariableVerifier] traverse an element
|
| + * structure looking for cases of [HintCode.UNUSED_LOCAL_VARIABLE].
|
| + */
|
| +class UnusedLocalVariableVerifier extends RecursiveElementVisitor {
|
| + /**
|
| + * The error reporter by which errors will be reported.
|
| + */
|
| + final ErrorReporter _errorReporter;
|
| +
|
| + /**
|
| + * Create a new instance of the [UnusedLocalVariableVerifier].
|
| + */
|
| + UnusedLocalVariableVerifier(this._errorReporter);
|
| +
|
| + @override
|
| + visitLocalVariableElement(LocalVariableElement element) {
|
| + if (element is LocalVariableElementImpl && !element.isUsed) {
|
| + _errorReporter.reportErrorForElement(
|
| + HintCode.UNUSED_LOCAL_VARIABLE,
|
| + element,
|
| + [element.displayName]);
|
| + }
|
| + }
|
| +}
|
| +
|
| +/**
|
| * Instances of the class `DeadCodeVerifier` traverse an AST structure looking for cases of
|
| * [HintCode#DEAD_CODE].
|
| */
|
| @@ -3474,9 +3500,14 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
|
| Object visitCatchClause(CatchClause node) {
|
| SimpleIdentifier exceptionParameter = node.exceptionParameter;
|
| if (exceptionParameter != null) {
|
| + // exception
|
| LocalVariableElementImpl exception = new LocalVariableElementImpl.forNode(exceptionParameter);
|
| _currentHolder.addLocalVariable(exception);
|
| exceptionParameter.staticElement = exception;
|
| + // we cannot catch an exception without declaring a variable,
|
| + // so the exception variable is always used
|
| + exception.markUsed();
|
| + // stack trace
|
| SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
|
| if (stackTraceParameter != null) {
|
| LocalVariableElementImpl stackTrace = new LocalVariableElementImpl.forNode(stackTraceParameter);
|
| @@ -5394,6 +5425,7 @@ class HintGenerator {
|
| unit.accept(_importsVerifier);
|
| // dead code analysis
|
| unit.accept(new DeadCodeVerifier(errorReporter));
|
| + unit.element.accept(new UnusedLocalVariableVerifier(errorReporter));
|
| // dart2js analysis
|
| if (_enableDart2JSHints) {
|
| unit.accept(new Dart2JSVerifier(errorReporter));
|
| @@ -15280,7 +15312,9 @@ class VariableResolverVisitor extends ScopedVisitor {
|
| if (parent is PropertyAccess && identical(parent.propertyName, node)) {
|
| return null;
|
| }
|
| - if (parent is MethodInvocation && identical(parent.methodName, node)) {
|
| + if (parent is MethodInvocation &&
|
| + identical(parent.methodName, node) &&
|
| + parent.target != null) {
|
| return null;
|
| }
|
| if (parent is ConstructorName) {
|
| @@ -15298,13 +15332,28 @@ class VariableResolverVisitor extends ScopedVisitor {
|
| ElementKind kind = element.kind;
|
| if (kind == ElementKind.LOCAL_VARIABLE) {
|
| node.staticElement = element;
|
| + LocalVariableElementImpl variableImpl = element as LocalVariableElementImpl;
|
| if (node.inSetterContext()) {
|
| - LocalVariableElementImpl variableImpl = element as LocalVariableElementImpl;
|
| variableImpl.markPotentiallyMutatedInScope();
|
| if (element.enclosingElement != _enclosingFunction) {
|
| variableImpl.markPotentiallyMutatedInClosure();
|
| }
|
| }
|
| + if (node.inGetterContext()) {
|
| + if (parent.parent is ExpressionStatement &&
|
| + (parent is PrefixExpression ||
|
| + parent is PostfixExpression ||
|
| + parent is AssignmentExpression && parent.leftHandSide == node)) {
|
| + // v++;
|
| + // ++v;
|
| + // v += 2;
|
| + } else {
|
| + variableImpl.markUsed();
|
| + }
|
| + }
|
| + if (parent is MethodInvocation && parent.methodName == node) {
|
| + variableImpl.markUsed();
|
| + }
|
| } else if (kind == ElementKind.PARAMETER) {
|
| node.staticElement = element;
|
| if (node.inSetterContext()) {
|
|
|