Chromium Code Reviews| 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 |