| 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 | 8 |
| 9 import 'package:analyzer/src/generated/scanner.dart'; |
| 10 |
| 9 import 'ast.dart'; | 11 import 'ast.dart'; |
| 10 import 'constant.dart'; | 12 import 'constant.dart'; |
| 11 import 'element.dart'; | 13 import 'element.dart'; |
| 12 import 'element_resolver.dart'; | 14 import 'element_resolver.dart'; |
| 13 import 'engine.dart'; | 15 import 'engine.dart'; |
| 14 import 'error.dart'; | 16 import 'error.dart'; |
| 15 import 'error_verifier.dart'; | 17 import 'error_verifier.dart'; |
| 16 import 'html.dart' as ht; | 18 import 'html.dart' as ht; |
| 17 import 'java_core.dart'; | 19 import 'java_core.dart'; |
| 18 import 'java_engine.dart'; | 20 import 'java_engine.dart'; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 return super.visitArgumentList(node); | 99 return super.visitArgumentList(node); |
| 98 } | 100 } |
| 99 | 101 |
| 100 @override | 102 @override |
| 101 Object visitAsExpression(AsExpression node) { | 103 Object visitAsExpression(AsExpression node) { |
| 102 _checkForUnnecessaryCast(node); | 104 _checkForUnnecessaryCast(node); |
| 103 return super.visitAsExpression(node); | 105 return super.visitAsExpression(node); |
| 104 } | 106 } |
| 105 | 107 |
| 106 @override | 108 @override |
| 109 Object visitAssertStatement(AssertStatement node) { |
| 110 _checkForPossibleNullCondition(node.condition); |
| 111 return super.visitAssertStatement(node); |
| 112 } |
| 113 |
| 114 @override |
| 107 Object visitAssignmentExpression(AssignmentExpression node) { | 115 Object visitAssignmentExpression(AssignmentExpression node) { |
| 108 sc.TokenType operatorType = node.operator.type; | 116 sc.TokenType operatorType = node.operator.type; |
| 109 if (operatorType == sc.TokenType.EQ) { | 117 if (operatorType == sc.TokenType.EQ) { |
| 110 _checkForUseOfVoidResult(node.rightHandSide); | 118 _checkForUseOfVoidResult(node.rightHandSide); |
| 111 _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide); | 119 _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide); |
| 112 } else { | 120 } else { |
| 113 _checkForDeprecatedMemberUse(node.bestElement, node); | 121 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 114 } | 122 } |
| 115 return super.visitAssignmentExpression(node); | 123 return super.visitAssignmentExpression(node); |
| 116 } | 124 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 129 _enclosingClass = node.element; | 137 _enclosingClass = node.element; |
| 130 // Commented out until we decide that we want this hint in the analyzer | 138 // Commented out until we decide that we want this hint in the analyzer |
| 131 // checkForOverrideEqualsButNotHashCode(node); | 139 // checkForOverrideEqualsButNotHashCode(node); |
| 132 return super.visitClassDeclaration(node); | 140 return super.visitClassDeclaration(node); |
| 133 } finally { | 141 } finally { |
| 134 _enclosingClass = outerClass; | 142 _enclosingClass = outerClass; |
| 135 } | 143 } |
| 136 } | 144 } |
| 137 | 145 |
| 138 @override | 146 @override |
| 147 Object visitConditionalExpression(ConditionalExpression node) { |
| 148 _checkForPossibleNullCondition(node.condition); |
| 149 return super.visitConditionalExpression(node); |
| 150 } |
| 151 |
| 152 @override |
| 153 Object visitDoStatement(DoStatement node) { |
| 154 _checkForPossibleNullCondition(node.condition); |
| 155 return super.visitDoStatement(node); |
| 156 } |
| 157 |
| 158 @override |
| 139 Object visitExportDirective(ExportDirective node) { | 159 Object visitExportDirective(ExportDirective node) { |
| 140 _checkForDeprecatedMemberUse(node.uriElement, node); | 160 _checkForDeprecatedMemberUse(node.uriElement, node); |
| 141 return super.visitExportDirective(node); | 161 return super.visitExportDirective(node); |
| 142 } | 162 } |
| 143 | 163 |
| 144 @override | 164 @override |
| 165 Object visitForStatement(ForStatement node) { |
| 166 _checkForPossibleNullCondition(node.condition); |
| 167 return super.visitForStatement(node); |
| 168 } |
| 169 |
| 170 @override |
| 145 Object visitFunctionDeclaration(FunctionDeclaration node) { | 171 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 146 _checkForMissingReturn(node.returnType, node.functionExpression.body); | 172 _checkForMissingReturn(node.returnType, node.functionExpression.body); |
| 147 return super.visitFunctionDeclaration(node); | 173 return super.visitFunctionDeclaration(node); |
| 148 } | 174 } |
| 149 | 175 |
| 150 @override | 176 @override |
| 177 Object visitIfStatement(IfStatement node) { |
| 178 _checkForPossibleNullCondition(node.condition); |
| 179 return super.visitIfStatement(node); |
| 180 } |
| 181 |
| 182 @override |
| 151 Object visitImportDirective(ImportDirective node) { | 183 Object visitImportDirective(ImportDirective node) { |
| 152 _checkForDeprecatedMemberUse(node.uriElement, node); | 184 _checkForDeprecatedMemberUse(node.uriElement, node); |
| 153 ImportElement importElement = node.element; | 185 ImportElement importElement = node.element; |
| 154 if (importElement != null) { | 186 if (importElement != null) { |
| 155 if (importElement.isDeferred) { | 187 if (importElement.isDeferred) { |
| 156 _checkForLoadLibraryFunction(node, importElement); | 188 _checkForLoadLibraryFunction(node, importElement); |
| 157 } | 189 } |
| 158 } | 190 } |
| 159 return super.visitImportDirective(node); | 191 return super.visitImportDirective(node); |
| 160 } | 192 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 return super.visitSuperConstructorInvocation(node); | 248 return super.visitSuperConstructorInvocation(node); |
| 217 } | 249 } |
| 218 | 250 |
| 219 @override | 251 @override |
| 220 Object visitVariableDeclaration(VariableDeclaration node) { | 252 Object visitVariableDeclaration(VariableDeclaration node) { |
| 221 _checkForUseOfVoidResult(node.initializer); | 253 _checkForUseOfVoidResult(node.initializer); |
| 222 _checkForInvalidAssignment(node.name, node.initializer); | 254 _checkForInvalidAssignment(node.name, node.initializer); |
| 223 return super.visitVariableDeclaration(node); | 255 return super.visitVariableDeclaration(node); |
| 224 } | 256 } |
| 225 | 257 |
| 258 @override |
| 259 Object visitWhileStatement(WhileStatement node) { |
| 260 _checkForPossibleNullCondition(node.condition); |
| 261 return super.visitWhileStatement(node); |
| 262 } |
| 263 |
| 226 /** | 264 /** |
| 227 * Check for the passed is expression for the unnecessary type check hint code
s as well as null | 265 * Check for the passed is expression for the unnecessary type check hint code
s as well as null |
| 228 * checks expressed using an is expression. | 266 * checks expressed using an is expression. |
| 229 * | 267 * |
| 230 * @param node the is expression to check | 268 * @param node the is expression to check |
| 231 * @return `true` if and only if a hint code is generated on the passed node | 269 * @return `true` if and only if a hint code is generated on the passed node |
| 232 * See [HintCode.TYPE_CHECK_IS_NOT_NULL], [HintCode.TYPE_CHECK_IS_NULL], | 270 * See [HintCode.TYPE_CHECK_IS_NOT_NULL], [HintCode.TYPE_CHECK_IS_NULL], |
| 233 * [HintCode.UNNECESSARY_TYPE_CHECK_TRUE], and | 271 * [HintCode.UNNECESSARY_TYPE_CHECK_TRUE], and |
| 234 * [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]. | 272 * [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]. |
| 235 */ | 273 */ |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; | 650 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; |
| 613 if (!ExitDetector.exits(blockFunctionBody)) { | 651 if (!ExitDetector.exits(blockFunctionBody)) { |
| 614 _errorReporter.reportErrorForNode( | 652 _errorReporter.reportErrorForNode( |
| 615 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); | 653 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); |
| 616 return true; | 654 return true; |
| 617 } | 655 } |
| 618 return false; | 656 return false; |
| 619 } | 657 } |
| 620 | 658 |
| 621 /** | 659 /** |
| 660 * Produce a hint if the given [condition] could have a value of `null`. |
| 661 */ |
| 662 void _checkForPossibleNullCondition(Expression condition) { |
| 663 while (condition is ParenthesizedExpression) { |
| 664 condition = (condition as ParenthesizedExpression).expression; |
| 665 } |
| 666 if (condition is BinaryExpression) { |
| 667 _checkForPossibleNullConditionInBinaryExpression(condition); |
| 668 } else { |
| 669 _checkForPossibleNullConditionInSimpleExpression(condition); |
| 670 } |
| 671 } |
| 672 |
| 673 /** |
| 674 * Produce a hint if any of the parts of the given binary [condition] could |
| 675 * have a value of `null`. |
| 676 */ |
| 677 void _checkForPossibleNullConditionInBinaryExpression( |
| 678 BinaryExpression condition) { |
| 679 Token operator = condition.operator; |
| 680 if (operator != null && |
| 681 (operator.type == TokenType.AMPERSAND_AMPERSAND || |
| 682 operator.type == TokenType.BAR_BAR)) { |
| 683 _checkForPossibleNullCondition(condition.leftOperand); |
| 684 _checkForPossibleNullCondition(condition.rightOperand); |
| 685 } |
| 686 } |
| 687 |
| 688 /** |
| 689 * Produce a hint if the given [condition] could have a value of `null`. |
| 690 */ |
| 691 void _checkForPossibleNullConditionInSimpleExpression(Expression condition) { |
| 692 if (condition is MethodInvocation) { |
| 693 Token operator = condition.operator; |
| 694 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) { |
| 695 _errorReporter.reportErrorForNode( |
| 696 HintCode.NULL_AWARE_IN_CONDITION, condition); |
| 697 } |
| 698 } else if (condition is PropertyAccess) { |
| 699 Token operator = condition.operator; |
| 700 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) { |
| 701 _errorReporter.reportErrorForNode( |
| 702 HintCode.NULL_AWARE_IN_CONDITION, condition); |
| 703 } |
| 704 } |
| 705 } |
| 706 |
| 707 /** |
| 622 * Check for the passed class declaration for the | 708 * Check for the passed class declaration for the |
| 623 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. | 709 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. |
| 624 * | 710 * |
| 625 * @param node the class declaration to check | 711 * @param node the class declaration to check |
| 626 * @return `true` if and only if a hint code is generated on the passed node | 712 * @return `true` if and only if a hint code is generated on the passed node |
| 627 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]. | 713 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]. |
| 628 */ | 714 */ |
| 629 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { | 715 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { |
| 630 // ClassElement classElement = node.element; | 716 // ClassElement classElement = node.element; |
| 631 // if (classElement == null) { | 717 // if (classElement == null) { |
| (...skipping 4185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4817 */ | 4903 */ |
| 4818 InheritanceManager _manager; | 4904 InheritanceManager _manager; |
| 4819 | 4905 |
| 4820 GatherUsedLocalElementsVisitor _usedLocalElementsVisitor; | 4906 GatherUsedLocalElementsVisitor _usedLocalElementsVisitor; |
| 4821 | 4907 |
| 4822 HintGenerator(this._compilationUnits, this._context, this._errorListener) { | 4908 HintGenerator(this._compilationUnits, this._context, this._errorListener) { |
| 4823 _library = _compilationUnits[0].element.library; | 4909 _library = _compilationUnits[0].element.library; |
| 4824 _usedImportedElementsVisitor = | 4910 _usedImportedElementsVisitor = |
| 4825 new GatherUsedImportedElementsVisitor(_library); | 4911 new GatherUsedImportedElementsVisitor(_library); |
| 4826 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; | 4912 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; |
| 4827 _manager = new InheritanceManager(_compilationUnits[0].element.library); | 4913 _manager = new InheritanceManager(_library); |
| 4828 _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library); | 4914 _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library); |
| 4829 } | 4915 } |
| 4830 | 4916 |
| 4831 void generateForLibrary() { | 4917 void generateForLibrary() { |
| 4832 PerformanceStatistics.hints.makeCurrentWhile(() { | 4918 PerformanceStatistics.hints.makeCurrentWhile(() { |
| 4833 for (CompilationUnit unit in _compilationUnits) { | 4919 for (CompilationUnit unit in _compilationUnits) { |
| 4834 CompilationUnitElement element = unit.element; | 4920 CompilationUnitElement element = unit.element; |
| 4835 if (element != null) { | 4921 if (element != null) { |
| 4836 _generateForCompilationUnit(unit, element.source); | 4922 _generateForCompilationUnit(unit, element.source); |
| 4837 } | 4923 } |
| (...skipping 11127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15965 nonFields.add(node); | 16051 nonFields.add(node); |
| 15966 return null; | 16052 return null; |
| 15967 } | 16053 } |
| 15968 | 16054 |
| 15969 @override | 16055 @override |
| 15970 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 16056 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 15971 | 16057 |
| 15972 @override | 16058 @override |
| 15973 Object visitWithClause(WithClause node) => null; | 16059 Object visitWithClause(WithClause node) => null; |
| 15974 } | 16060 } |
| OLD | NEW |