OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |