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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 686113007: Report HintCode.UNUSED_LOCAL_VARIABLE for local variables whose value is never used. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library engine.resolver; 5 library engine.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'java_core.dart'; 10 import 'java_core.dart';
(...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 _errorReporter.reportErrorForNode(HintCode.IS_NOT_DOUBLE, node, []); 1903 _errorReporter.reportErrorForNode(HintCode.IS_NOT_DOUBLE, node, []);
1904 } 1904 }
1905 return true; 1905 return true;
1906 } 1906 }
1907 } 1907 }
1908 return false; 1908 return false;
1909 } 1909 }
1910 } 1910 }
1911 1911
1912 /** 1912 /**
1913 * Instances of the class [UnusedLocalVariableVerifier] traverse an element
1914 * structure looking for cases of [HintCode.UNUSED_LOCAL_VARIABLE].
1915 */
1916 class UnusedLocalVariableVerifier extends RecursiveElementVisitor {
1917 /**
1918 * The error reporter by which errors will be reported.
1919 */
1920 final ErrorReporter _errorReporter;
1921
1922 /**
1923 * Create a new instance of the [UnusedLocalVariableVerifier].
1924 */
1925 UnusedLocalVariableVerifier(this._errorReporter);
1926
1927 @override
1928 visitLocalVariableElement(LocalVariableElement element) {
1929 if (element is LocalVariableElementImpl && !element.isUsed) {
1930 _errorReporter.reportErrorForElement(
1931 HintCode.UNUSED_LOCAL_VARIABLE,
1932 element,
1933 [element.displayName]);
1934 }
1935 }
1936 }
1937
1938 /**
1913 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f or cases of 1939 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f or cases of
1914 * [HintCode#DEAD_CODE]. 1940 * [HintCode#DEAD_CODE].
1915 */ 1941 */
1916 class DeadCodeVerifier extends RecursiveAstVisitor<Object> { 1942 class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
1917 /** 1943 /**
1918 * The error reporter by which errors will be reported. 1944 * The error reporter by which errors will be reported.
1919 */ 1945 */
1920 final ErrorReporter _errorReporter; 1946 final ErrorReporter _errorReporter;
1921 1947
1922 /** 1948 /**
(...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
3467 } finally { 3493 } finally {
3468 _inFieldContext = wasInField; 3494 _inFieldContext = wasInField;
3469 } 3495 }
3470 return null; 3496 return null;
3471 } 3497 }
3472 3498
3473 @override 3499 @override
3474 Object visitCatchClause(CatchClause node) { 3500 Object visitCatchClause(CatchClause node) {
3475 SimpleIdentifier exceptionParameter = node.exceptionParameter; 3501 SimpleIdentifier exceptionParameter = node.exceptionParameter;
3476 if (exceptionParameter != null) { 3502 if (exceptionParameter != null) {
3503 // exception
3477 LocalVariableElementImpl exception = new LocalVariableElementImpl.forNode( exceptionParameter); 3504 LocalVariableElementImpl exception = new LocalVariableElementImpl.forNode( exceptionParameter);
3478 _currentHolder.addLocalVariable(exception); 3505 _currentHolder.addLocalVariable(exception);
3479 exceptionParameter.staticElement = exception; 3506 exceptionParameter.staticElement = exception;
3507 // we cannot catch an exception without declaring a variable,
3508 // so the exception variable is always used
3509 exception.markUsed();
3510 // stack trace
3480 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; 3511 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
3481 if (stackTraceParameter != null) { 3512 if (stackTraceParameter != null) {
3482 LocalVariableElementImpl stackTrace = new LocalVariableElementImpl.forNo de(stackTraceParameter); 3513 LocalVariableElementImpl stackTrace = new LocalVariableElementImpl.forNo de(stackTraceParameter);
3483 _currentHolder.addLocalVariable(stackTrace); 3514 _currentHolder.addLocalVariable(stackTrace);
3484 stackTraceParameter.staticElement = stackTrace; 3515 stackTraceParameter.staticElement = stackTrace;
3485 } 3516 }
3486 } 3517 }
3487 return super.visitCatchClause(node); 3518 return super.visitCatchClause(node);
3488 } 3519 }
3489 3520
(...skipping 1897 matching lines...) Expand 10 before | Expand all | Expand 10 after
5387 } finally { 5418 } finally {
5388 timeCounter.stop(); 5419 timeCounter.stop();
5389 } 5420 }
5390 } 5421 }
5391 5422
5392 void _generateForCompilationUnit(CompilationUnit unit, Source source) { 5423 void _generateForCompilationUnit(CompilationUnit unit, Source source) {
5393 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); 5424 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
5394 unit.accept(_importsVerifier); 5425 unit.accept(_importsVerifier);
5395 // dead code analysis 5426 // dead code analysis
5396 unit.accept(new DeadCodeVerifier(errorReporter)); 5427 unit.accept(new DeadCodeVerifier(errorReporter));
5428 unit.element.accept(new UnusedLocalVariableVerifier(errorReporter));
5397 // dart2js analysis 5429 // dart2js analysis
5398 if (_enableDart2JSHints) { 5430 if (_enableDart2JSHints) {
5399 unit.accept(new Dart2JSVerifier(errorReporter)); 5431 unit.accept(new Dart2JSVerifier(errorReporter));
5400 } 5432 }
5401 // Dart best practices 5433 // Dart best practices
5402 unit.accept(new BestPracticesVerifier(errorReporter)); 5434 unit.accept(new BestPracticesVerifier(errorReporter));
5403 unit.accept(new OverrideVerifier(_manager, errorReporter)); 5435 unit.accept(new OverrideVerifier(_manager, errorReporter));
5404 // Find to-do comments 5436 // Find to-do comments
5405 new ToDoFinder(errorReporter).findIn(unit); 5437 new ToDoFinder(errorReporter).findIn(unit);
5406 // pub analysis 5438 // pub analysis
(...skipping 9866 matching lines...) Expand 10 before | Expand all | Expand 10 after
15273 return null; 15305 return null;
15274 } 15306 }
15275 // Ignore if qualified. 15307 // Ignore if qualified.
15276 AstNode parent = node.parent; 15308 AstNode parent = node.parent;
15277 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { 15309 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
15278 return null; 15310 return null;
15279 } 15311 }
15280 if (parent is PropertyAccess && identical(parent.propertyName, node)) { 15312 if (parent is PropertyAccess && identical(parent.propertyName, node)) {
15281 return null; 15313 return null;
15282 } 15314 }
15283 if (parent is MethodInvocation && identical(parent.methodName, node)) { 15315 if (parent is MethodInvocation &&
15316 identical(parent.methodName, node) &&
15317 parent.target != null) {
15284 return null; 15318 return null;
15285 } 15319 }
15286 if (parent is ConstructorName) { 15320 if (parent is ConstructorName) {
15287 return null; 15321 return null;
15288 } 15322 }
15289 if (parent is Label) { 15323 if (parent is Label) {
15290 return null; 15324 return null;
15291 } 15325 }
15292 // Prepare VariableElement. 15326 // Prepare VariableElement.
15293 Element element = nameScope.lookup(node, definingLibrary); 15327 Element element = nameScope.lookup(node, definingLibrary);
15294 if (element is! VariableElement) { 15328 if (element is! VariableElement) {
15295 return null; 15329 return null;
15296 } 15330 }
15297 // Must be local or parameter. 15331 // Must be local or parameter.
15298 ElementKind kind = element.kind; 15332 ElementKind kind = element.kind;
15299 if (kind == ElementKind.LOCAL_VARIABLE) { 15333 if (kind == ElementKind.LOCAL_VARIABLE) {
15300 node.staticElement = element; 15334 node.staticElement = element;
15335 LocalVariableElementImpl variableImpl = element as LocalVariableElementImp l;
15301 if (node.inSetterContext()) { 15336 if (node.inSetterContext()) {
15302 LocalVariableElementImpl variableImpl = element as LocalVariableElementI mpl;
15303 variableImpl.markPotentiallyMutatedInScope(); 15337 variableImpl.markPotentiallyMutatedInScope();
15304 if (element.enclosingElement != _enclosingFunction) { 15338 if (element.enclosingElement != _enclosingFunction) {
15305 variableImpl.markPotentiallyMutatedInClosure(); 15339 variableImpl.markPotentiallyMutatedInClosure();
15306 } 15340 }
15307 } 15341 }
15342 if (node.inGetterContext()) {
15343 if (parent.parent is ExpressionStatement &&
15344 (parent is PrefixExpression ||
15345 parent is PostfixExpression ||
15346 parent is AssignmentExpression && parent.leftHandSide == node)) {
15347 // v++;
15348 // ++v;
15349 // v += 2;
15350 } else {
15351 variableImpl.markUsed();
15352 }
15353 }
15354 if (parent is MethodInvocation && parent.methodName == node) {
15355 variableImpl.markUsed();
15356 }
15308 } else if (kind == ElementKind.PARAMETER) { 15357 } else if (kind == ElementKind.PARAMETER) {
15309 node.staticElement = element; 15358 node.staticElement = element;
15310 if (node.inSetterContext()) { 15359 if (node.inSetterContext()) {
15311 ParameterElementImpl parameterImpl = element as ParameterElementImpl; 15360 ParameterElementImpl parameterImpl = element as ParameterElementImpl;
15312 parameterImpl.markPotentiallyMutatedInScope(); 15361 parameterImpl.markPotentiallyMutatedInScope();
15313 // If we are in some closure, check if it is not the same as where varia ble is declared. 15362 // If we are in some closure, check if it is not the same as where varia ble is declared.
15314 if (_enclosingFunction != null && (element.enclosingElement != _enclosin gFunction)) { 15363 if (_enclosingFunction != null && (element.enclosingElement != _enclosin gFunction)) {
15315 parameterImpl.markPotentiallyMutatedInClosure(); 15364 parameterImpl.markPotentiallyMutatedInClosure();
15316 } 15365 }
15317 } 15366 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
15507 /** 15556 /**
15508 * Return the tag that has the given identifier, or {@code null} if there is n o such tag (the 15557 * Return the tag that has the given identifier, or {@code null} if there is n o such tag (the
15509 * identifier is not defined). 15558 * identifier is not defined).
15510 * 15559 *
15511 * @return the tag that has the given identifier 15560 * @return the tag that has the given identifier
15512 */ 15561 */
15513 String getTagWithId(String identifier) { 15562 String getTagWithId(String identifier) {
15514 return idToTagMap[identifier]; 15563 return idToTagMap[identifier];
15515 } 15564 }
15516 } 15565 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698