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

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

Issue 2320573003: Issue 26874. Don't report CAN_BE_NULL_AFTER_NULL_AWARE for members of the Null class. (Closed)
Patch Set: Created 4 years, 3 months 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
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/hint_code_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 analyzer.src.generated.resolver; 5 library analyzer.src.generated.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 * is deprecated. 57 * is deprecated.
58 */ 58 */
59 bool inDeprecatedMember; 59 bool inDeprecatedMember;
60 60
61 /** 61 /**
62 * The error reporter by which errors will be reported. 62 * The error reporter by which errors will be reported.
63 */ 63 */
64 final ErrorReporter _errorReporter; 64 final ErrorReporter _errorReporter;
65 65
66 /** 66 /**
67 * The type [Null].
68 */
69 final InterfaceType _nullType;
70
71 /**
67 * The type Future<Null>, which is needed for determining whether it is safe 72 * The type Future<Null>, which is needed for determining whether it is safe
68 * to have a bare "return;" in an async method. 73 * to have a bare "return;" in an async method.
69 */ 74 */
70 final InterfaceType _futureNullType; 75 final InterfaceType _futureNullType;
71 76
72 /** 77 /**
73 * The type system primitives 78 * The type system primitives
74 */ 79 */
75 TypeSystem _typeSystem; 80 TypeSystem _typeSystem;
76 81
77 /** 82 /**
78 * The current library 83 * The current library
79 */ 84 */
80 LibraryElement _currentLibrary; 85 LibraryElement _currentLibrary;
81 86
82 /** 87 /**
83 * Create a new instance of the [BestPracticesVerifier]. 88 * Create a new instance of the [BestPracticesVerifier].
84 * 89 *
85 * @param errorReporter the error reporter 90 * @param errorReporter the error reporter
86 */ 91 */
87 BestPracticesVerifier( 92 BestPracticesVerifier(
88 this._errorReporter, TypeProvider typeProvider, this._currentLibrary, 93 this._errorReporter, TypeProvider typeProvider, this._currentLibrary,
89 {TypeSystem typeSystem}) 94 {TypeSystem typeSystem})
90 : _futureNullType = typeProvider.futureNullType, 95 : _nullType = typeProvider.nullType,
96 _futureNullType = typeProvider.futureNullType,
91 _typeSystem = typeSystem ?? new TypeSystemImpl() { 97 _typeSystem = typeSystem ?? new TypeSystemImpl() {
92 inDeprecatedMember = _currentLibrary.isDeprecated; 98 inDeprecatedMember = _currentLibrary.isDeprecated;
93 } 99 }
94 100
95 @override 101 @override
96 Object visitAnnotation(Annotation node) { 102 Object visitAnnotation(Annotation node) {
97 if (node.elementAnnotation?.isFactory == true) { 103 if (node.elementAnnotation?.isFactory == true) {
98 AstNode parent = node.parent; 104 AstNode parent = node.parent;
99 if (parent is MethodDeclaration) { 105 if (parent is MethodDeclaration) {
100 _checkForInvalidFactory(parent); 106 _checkForInvalidFactory(parent);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 _checkForMissingReturn(node.returnType, node.body); 274 _checkForMissingReturn(node.returnType, node.body);
269 _checkForUnnecessaryNoSuchMethod(node); 275 _checkForUnnecessaryNoSuchMethod(node);
270 return super.visitMethodDeclaration(node); 276 return super.visitMethodDeclaration(node);
271 } finally { 277 } finally {
272 inDeprecatedMember = wasInDeprecatedMember; 278 inDeprecatedMember = wasInDeprecatedMember;
273 } 279 }
274 } 280 }
275 281
276 @override 282 @override
277 Object visitMethodInvocation(MethodInvocation node) { 283 Object visitMethodInvocation(MethodInvocation node) {
278 _checkForCanBeNullAfterNullAware(node.realTarget, node.operator); 284 _checkForCanBeNullAfterNullAware(
285 node.realTarget, node.operator, null, node.methodName);
279 DartType staticInvokeType = node.staticInvokeType; 286 DartType staticInvokeType = node.staticInvokeType;
280 if (staticInvokeType is InterfaceType) { 287 if (staticInvokeType is InterfaceType) {
281 MethodElement methodElement = staticInvokeType.lookUpMethod( 288 MethodElement methodElement = staticInvokeType.lookUpMethod(
282 FunctionElement.CALL_METHOD_NAME, _currentLibrary); 289 FunctionElement.CALL_METHOD_NAME, _currentLibrary);
283 _checkForDeprecatedMemberUse(methodElement, node); 290 _checkForDeprecatedMemberUse(methodElement, node);
284 } 291 }
285 return super.visitMethodInvocation(node); 292 return super.visitMethodInvocation(node);
286 } 293 }
287 294
288 @override 295 @override
289 Object visitPostfixExpression(PostfixExpression node) { 296 Object visitPostfixExpression(PostfixExpression node) {
290 _checkForDeprecatedMemberUse(node.bestElement, node); 297 _checkForDeprecatedMemberUse(node.bestElement, node);
291 return super.visitPostfixExpression(node); 298 return super.visitPostfixExpression(node);
292 } 299 }
293 300
294 @override 301 @override
295 Object visitPrefixExpression(PrefixExpression node) { 302 Object visitPrefixExpression(PrefixExpression node) {
296 _checkForDeprecatedMemberUse(node.bestElement, node); 303 _checkForDeprecatedMemberUse(node.bestElement, node);
297 return super.visitPrefixExpression(node); 304 return super.visitPrefixExpression(node);
298 } 305 }
299 306
300 @override 307 @override
301 Object visitPropertyAccess(PropertyAccess node) { 308 Object visitPropertyAccess(PropertyAccess node) {
302 _checkForCanBeNullAfterNullAware(node.realTarget, node.operator); 309 _checkForCanBeNullAfterNullAware(
310 node.realTarget, node.operator, node.propertyName, null);
303 return super.visitPropertyAccess(node); 311 return super.visitPropertyAccess(node);
304 } 312 }
305 313
306 @override 314 @override
307 Object visitRedirectingConstructorInvocation( 315 Object visitRedirectingConstructorInvocation(
308 RedirectingConstructorInvocation node) { 316 RedirectingConstructorInvocation node) {
309 _checkForDeprecatedMemberUse(node.staticElement, node); 317 _checkForDeprecatedMemberUse(node.staticElement, node);
310 return super.visitRedirectingConstructorInvocation(node); 318 return super.visitRedirectingConstructorInvocation(node);
311 } 319 }
312 320
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 bool problemReported = false; 522 bool problemReported = false;
515 for (Expression argument in argumentList.arguments) { 523 for (Expression argument in argumentList.arguments) {
516 if (_checkForArgumentTypeNotAssignableForArgument(argument)) { 524 if (_checkForArgumentTypeNotAssignableForArgument(argument)) {
517 problemReported = true; 525 problemReported = true;
518 } 526 }
519 } 527 }
520 return problemReported; 528 return problemReported;
521 } 529 }
522 530
523 /** 531 /**
524 * Produce a hint if the given [target] could have a value of `null`. 532 * Produce a hint if the given [target] could have a value of `null`, and
533 * [identifier] is not a name of a getter or a method that exists in the
534 * class [Null].
525 */ 535 */
526 void _checkForCanBeNullAfterNullAware(Expression target, Token operator) { 536 void _checkForCanBeNullAfterNullAware(
537 Expression target, Token operator, SimpleIdentifier propertyName, SimpleId entifier methodName) {
527 if (operator?.type == TokenType.QUESTION_PERIOD) { 538 if (operator?.type == TokenType.QUESTION_PERIOD) {
528 return; 539 return;
529 } 540 }
541 bool isNullTypeMember() {
542 if (propertyName != null) {
543 String name = propertyName.name;
544 return _nullType.lookUpGetter(name, _currentLibrary) != null;
545 }
546 if (methodName != null) {
547 String name = methodName.name;
548 return _nullType.lookUpMethod(name, _currentLibrary) != null;
549 }
550 return false;
551 }
552
530 target = target?.unParenthesized; 553 target = target?.unParenthesized;
531 if (target is MethodInvocation) { 554 if (target is MethodInvocation) {
532 if (target.operator?.type == TokenType.QUESTION_PERIOD) { 555 if (target.operator?.type == TokenType.QUESTION_PERIOD &&
556 !isNullTypeMember()) {
533 _errorReporter.reportErrorForNode( 557 _errorReporter.reportErrorForNode(
534 HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target); 558 HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
535 } 559 }
536 } else if (target is PropertyAccess) { 560 } else if (target is PropertyAccess) {
537 if (target.operator.type == TokenType.QUESTION_PERIOD) { 561 if (target.operator.type == TokenType.QUESTION_PERIOD &&
562 !isNullTypeMember()) {
538 _errorReporter.reportErrorForNode( 563 _errorReporter.reportErrorForNode(
539 HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target); 564 HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
540 } 565 }
541 } 566 }
542 } 567 }
543 568
544 /** 569 /**
545 * Given some [Element], look at the associated metadata and report the use of the member if 570 * Given some [Element], look at the associated metadata and report the use of the member if
546 * it is declared as deprecated. 571 * it is declared as deprecated.
547 * 572 *
(...skipping 10588 matching lines...) Expand 10 before | Expand all | Expand 10 after
11136 return null; 11161 return null;
11137 } 11162 }
11138 if (identical(node.staticElement, variable)) { 11163 if (identical(node.staticElement, variable)) {
11139 if (node.inSetterContext()) { 11164 if (node.inSetterContext()) {
11140 result = true; 11165 result = true;
11141 } 11166 }
11142 } 11167 }
11143 return null; 11168 return null;
11144 } 11169 }
11145 } 11170 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/hint_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698