forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mostly because it also reports UNCHECKED_USE_OF_NULLABLE_VALUE, and we want to report it during resolution, to use for migration. Change-Id: I89f988d9be34a70dfe0e590a5fede2696423c89c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132029 Reviewed-by: Paul Berry <paulberry@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
- Loading branch information
Showing
5 changed files
with
146 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/element/element.dart'; | ||
import 'package:analyzer/dart/element/type.dart'; | ||
import 'package:analyzer/error/error.dart'; | ||
import 'package:analyzer/error/listener.dart'; | ||
import 'package:analyzer/src/dart/element/type.dart'; | ||
import 'package:analyzer/src/error/codes.dart'; | ||
import 'package:analyzer/src/generated/resolver.dart'; | ||
import 'package:meta/meta.dart'; | ||
|
||
/// Helper for verifying expression that should be of type bool. | ||
class BoolExpressionVerifier { | ||
final TypeSystemImpl _typeSystem; | ||
final ErrorReporter _errorReporter; | ||
|
||
final ClassElement _boolElement; | ||
final InterfaceType _boolType; | ||
|
||
BoolExpressionVerifier({ | ||
@required TypeSystemImpl typeSystem, | ||
@required ErrorReporter errorReporter, | ||
}) : _typeSystem = typeSystem, | ||
_errorReporter = errorReporter, | ||
_boolElement = typeSystem.typeProvider.boolElement, | ||
_boolType = typeSystem.typeProvider.boolType; | ||
|
||
/// Check to ensure that the [condition] is of type bool, are. Otherwise an | ||
/// error is reported on the expression. | ||
/// | ||
/// See [StaticTypeWarningCode.NON_BOOL_CONDITION]. | ||
void checkForNonBoolCondition(Expression condition) { | ||
checkForNonBoolExpression( | ||
condition, | ||
errorCode: StaticTypeWarningCode.NON_BOOL_CONDITION, | ||
); | ||
} | ||
|
||
/// Verify that the given [expression] is of type 'bool', and report | ||
/// [errorCode] if not, or a nullability error if its improperly nullable. | ||
void checkForNonBoolExpression(Expression expression, | ||
{@required ErrorCode errorCode}) { | ||
var type = expression.staticType; | ||
if (!_checkForUseOfVoidResult(expression) && | ||
!_typeSystem.isAssignableTo(type, _boolType)) { | ||
if (type.element == _boolElement) { | ||
_errorReporter.reportErrorForNode( | ||
StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE, | ||
expression, | ||
); | ||
} else { | ||
_errorReporter.reportErrorForNode(errorCode, expression); | ||
} | ||
} | ||
} | ||
|
||
/// Checks to ensure that the given [expression] is assignable to bool. | ||
void checkForNonBoolNegationExpression(Expression expression) { | ||
checkForNonBoolExpression( | ||
expression, | ||
errorCode: StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, | ||
); | ||
} | ||
|
||
/** | ||
* Check for situations where the result of a method or function is used, when | ||
* it returns 'void'. Or, in rare cases, when other types of expressions are | ||
* void, such as identifiers. | ||
* | ||
* TODO(scheglov) Move this in a separate verifier. | ||
*/ | ||
bool _checkForUseOfVoidResult(Expression expression) { | ||
if (expression == null || | ||
!identical(expression.staticType, VoidTypeImpl.instance)) { | ||
return false; | ||
} | ||
|
||
if (expression is MethodInvocation) { | ||
SimpleIdentifier methodName = expression.methodName; | ||
_errorReporter.reportErrorForNode( | ||
StaticWarningCode.USE_OF_VOID_RESULT, | ||
methodName, | ||
); | ||
} else { | ||
_errorReporter.reportErrorForNode( | ||
StaticWarningCode.USE_OF_VOID_RESULT, | ||
expression, | ||
); | ||
} | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.