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

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: 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698