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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 _enclosingClass = node.element; | 131 _enclosingClass = node.element; |
130 // Commented out until we decide that we want this hint in the analyzer | 132 // Commented out until we decide that we want this hint in the analyzer |
131 // checkForOverrideEqualsButNotHashCode(node); | 133 // checkForOverrideEqualsButNotHashCode(node); |
132 return super.visitClassDeclaration(node); | 134 return super.visitClassDeclaration(node); |
133 } finally { | 135 } finally { |
134 _enclosingClass = outerClass; | 136 _enclosingClass = outerClass; |
135 } | 137 } |
136 } | 138 } |
137 | 139 |
138 @override | 140 @override |
141 Object visitDoStatement(DoStatement node) { | |
142 _checkForPossibleNullCondition(node.condition); | |
143 return super.visitDoStatement(node); | |
144 } | |
145 | |
146 @override | |
139 Object visitExportDirective(ExportDirective node) { | 147 Object visitExportDirective(ExportDirective node) { |
140 _checkForDeprecatedMemberUse(node.uriElement, node); | 148 _checkForDeprecatedMemberUse(node.uriElement, node); |
141 return super.visitExportDirective(node); | 149 return super.visitExportDirective(node); |
142 } | 150 } |
143 | 151 |
144 @override | 152 @override |
153 Object visitForStatement(ForStatement node) { | |
154 _checkForPossibleNullCondition(node.condition); | |
155 return super.visitForStatement(node); | |
156 } | |
157 | |
158 @override | |
145 Object visitFunctionDeclaration(FunctionDeclaration node) { | 159 Object visitFunctionDeclaration(FunctionDeclaration node) { |
146 _checkForMissingReturn(node.returnType, node.functionExpression.body); | 160 _checkForMissingReturn(node.returnType, node.functionExpression.body); |
147 return super.visitFunctionDeclaration(node); | 161 return super.visitFunctionDeclaration(node); |
148 } | 162 } |
149 | 163 |
150 @override | 164 @override |
165 Object visitIfStatement(IfStatement node) { | |
166 _checkForPossibleNullCondition(node.condition); | |
167 return super.visitIfStatement(node); | |
168 } | |
169 | |
170 @override | |
151 Object visitImportDirective(ImportDirective node) { | 171 Object visitImportDirective(ImportDirective node) { |
152 _checkForDeprecatedMemberUse(node.uriElement, node); | 172 _checkForDeprecatedMemberUse(node.uriElement, node); |
153 ImportElement importElement = node.element; | 173 ImportElement importElement = node.element; |
154 if (importElement != null) { | 174 if (importElement != null) { |
155 if (importElement.isDeferred) { | 175 if (importElement.isDeferred) { |
156 _checkForLoadLibraryFunction(node, importElement); | 176 _checkForLoadLibraryFunction(node, importElement); |
157 } | 177 } |
158 } | 178 } |
159 return super.visitImportDirective(node); | 179 return super.visitImportDirective(node); |
160 } | 180 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 return super.visitSuperConstructorInvocation(node); | 236 return super.visitSuperConstructorInvocation(node); |
217 } | 237 } |
218 | 238 |
219 @override | 239 @override |
220 Object visitVariableDeclaration(VariableDeclaration node) { | 240 Object visitVariableDeclaration(VariableDeclaration node) { |
221 _checkForUseOfVoidResult(node.initializer); | 241 _checkForUseOfVoidResult(node.initializer); |
222 _checkForInvalidAssignment(node.name, node.initializer); | 242 _checkForInvalidAssignment(node.name, node.initializer); |
223 return super.visitVariableDeclaration(node); | 243 return super.visitVariableDeclaration(node); |
224 } | 244 } |
225 | 245 |
246 @override | |
247 Object visitWhileStatement(WhileStatement node) { | |
248 _checkForPossibleNullCondition(node.condition); | |
249 return super.visitWhileStatement(node); | |
250 } | |
251 | |
226 /** | 252 /** |
227 * Check for the passed is expression for the unnecessary type check hint code s as well as null | 253 * 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. | 254 * checks expressed using an is expression. |
229 * | 255 * |
230 * @param node the is expression to check | 256 * @param node the is expression to check |
231 * @return `true` if and only if a hint code is generated on the passed node | 257 * @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], | 258 * See [HintCode.TYPE_CHECK_IS_NOT_NULL], [HintCode.TYPE_CHECK_IS_NULL], |
233 * [HintCode.UNNECESSARY_TYPE_CHECK_TRUE], and | 259 * [HintCode.UNNECESSARY_TYPE_CHECK_TRUE], and |
234 * [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]. | 260 * [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]. |
235 */ | 261 */ |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; | 638 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; |
613 if (!ExitDetector.exits(blockFunctionBody)) { | 639 if (!ExitDetector.exits(blockFunctionBody)) { |
614 _errorReporter.reportErrorForNode( | 640 _errorReporter.reportErrorForNode( |
615 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); | 641 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); |
616 return true; | 642 return true; |
617 } | 643 } |
618 return false; | 644 return false; |
619 } | 645 } |
620 | 646 |
621 /** | 647 /** |
648 * Produce a hint if the given [condition] could have a value of `null`. | |
649 */ | |
650 void _checkForPossibleNullCondition(Expression condition) { | |
651 while (condition is ParenthesizedExpression) { | |
652 condition = (condition as ParenthesizedExpression).expression; | |
653 } | |
654 if (condition is MethodInvocation) { | |
655 Token operator = condition.operator; | |
656 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) { | |
scheglov
2015/10/25 17:48:52
if (operator?.type == TokenType.QUESTION_PERIOD) m
Brian Wilkerson
2015/10/25 22:11:40
I don't happen to find it to be very readable, but
| |
657 _errorReporter.reportErrorForNode( | |
658 HintCode.NULL_AWARE_IN_CONDITION, condition); | |
659 } | |
660 } else if (condition is PropertyAccess) { | |
661 Token operator = condition.operator; | |
662 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) { | |
663 _errorReporter.reportErrorForNode( | |
664 HintCode.NULL_AWARE_IN_CONDITION, condition); | |
665 } | |
666 } | |
scheglov
2015/10/25 17:48:52
We could also validate every part of &&, ||, etc e
Brian Wilkerson
2015/10/25 22:11:40
Done
| |
667 } | |
668 | |
669 /** | |
622 * Check for the passed class declaration for the | 670 * Check for the passed class declaration for the |
623 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. | 671 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. |
624 * | 672 * |
625 * @param node the class declaration to check | 673 * @param node the class declaration to check |
626 * @return `true` if and only if a hint code is generated on the passed node | 674 * @return `true` if and only if a hint code is generated on the passed node |
627 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]. | 675 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]. |
628 */ | 676 */ |
629 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { | 677 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { |
630 // ClassElement classElement = node.element; | 678 // ClassElement classElement = node.element; |
631 // if (classElement == null) { | 679 // if (classElement == null) { |
(...skipping 4185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4817 */ | 4865 */ |
4818 InheritanceManager _manager; | 4866 InheritanceManager _manager; |
4819 | 4867 |
4820 GatherUsedLocalElementsVisitor _usedLocalElementsVisitor; | 4868 GatherUsedLocalElementsVisitor _usedLocalElementsVisitor; |
4821 | 4869 |
4822 HintGenerator(this._compilationUnits, this._context, this._errorListener) { | 4870 HintGenerator(this._compilationUnits, this._context, this._errorListener) { |
4823 _library = _compilationUnits[0].element.library; | 4871 _library = _compilationUnits[0].element.library; |
4824 _usedImportedElementsVisitor = | 4872 _usedImportedElementsVisitor = |
4825 new GatherUsedImportedElementsVisitor(_library); | 4873 new GatherUsedImportedElementsVisitor(_library); |
4826 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; | 4874 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; |
4827 _manager = new InheritanceManager(_compilationUnits[0].element.library); | 4875 _manager = new InheritanceManager(_library); |
4828 _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library); | 4876 _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library); |
4829 } | 4877 } |
4830 | 4878 |
4831 void generateForLibrary() { | 4879 void generateForLibrary() { |
4832 PerformanceStatistics.hints.makeCurrentWhile(() { | 4880 PerformanceStatistics.hints.makeCurrentWhile(() { |
4833 for (CompilationUnit unit in _compilationUnits) { | 4881 for (CompilationUnit unit in _compilationUnits) { |
4834 CompilationUnitElement element = unit.element; | 4882 CompilationUnitElement element = unit.element; |
4835 if (element != null) { | 4883 if (element != null) { |
4836 _generateForCompilationUnit(unit, element.source); | 4884 _generateForCompilationUnit(unit, element.source); |
4837 } | 4885 } |
(...skipping 11127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15965 nonFields.add(node); | 16013 nonFields.add(node); |
15966 return null; | 16014 return null; |
15967 } | 16015 } |
15968 | 16016 |
15969 @override | 16017 @override |
15970 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 16018 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
15971 | 16019 |
15972 @override | 16020 @override |
15973 Object visitWithClause(WithClause node) => null; | 16021 Object visitWithClause(WithClause node) => null; |
15974 } | 16022 } |
OLD | NEW |