Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(851)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1422813003: Add hint for use of ?. in conditions (issue 24649) (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Add checks for asserts, and conditional expressions Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698