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 |