Fix constant evaluation for the new bool operators
Change-Id: I4a30544b2d0e5cff8287dbe5fc83387b4e92a875
Reviewed-on: https://dart-review.googlesource.com/c/88437
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 189a436..4666351 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -1893,8 +1893,12 @@
BoolState logicalAnd(InstanceState rightOperand) {
assertBool(this);
assertBool(rightOperand);
- return BoolState.from(
- convertToBool().value & rightOperand.convertToBool().value);
+ bool leftValue = convertToBool().value;
+ bool rightValue = rightOperand.convertToBool().value;
+ if (leftValue == null || rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(leftValue & rightValue);
}
/**
@@ -1918,8 +1922,12 @@
BoolState logicalOr(InstanceState rightOperand) {
assertBool(this);
assertBool(rightOperand);
- return BoolState.from(
- convertToBool().value | rightOperand.convertToBool().value);
+ bool leftValue = convertToBool().value;
+ bool rightValue = rightOperand.convertToBool().value;
+ if (leftValue == null || rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(leftValue | rightValue);
}
/**
@@ -1946,8 +1954,12 @@
BoolState logicalXor(InstanceState rightOperand) {
assertBool(this);
assertBool(rightOperand);
- return BoolState.from(
- convertToBool().value ^ rightOperand.convertToBool().value);
+ bool leftValue = convertToBool().value;
+ bool rightValue = rightOperand.convertToBool().value;
+ if (leftValue == null || rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(leftValue ^ rightValue);
}
/**
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index f6af9c7..b144d20 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -112,7 +112,7 @@
expect(result.type, typeProvider.nullType);
}
- test_visitBinaryExpression_and_bool() async {
+ test_visitBinaryExpression_and_bool_known_known() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = false & true;
''');
@@ -121,6 +121,37 @@
expect(result.type, typeProvider.boolType);
}
+ test_visitBinaryExpression_and_bool_known_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const b = bool.fromEnvironment('y');
+const c = false & b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_and_bool_unknown_known() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const c = a & true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_and_bool_unknown_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a & b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
test_visitBinaryExpression_and_int() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = 3 & 5;
@@ -139,7 +170,7 @@
experiments: [EnableString.constant_update_2018]);
}
- test_visitBinaryExpression_or_bool() async {
+ test_visitBinaryExpression_or_bool_known_known() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = false | true;
''');
@@ -148,6 +179,37 @@
expect(result.type, typeProvider.boolType);
}
+ test_visitBinaryExpression_or_bool_known_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const b = bool.fromEnvironment('y');
+const c = false | b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_or_bool_unknown_known() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const c = a | true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_or_bool_unknown_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a | b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
test_visitBinaryExpression_or_int() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = 3 | 5;
@@ -263,7 +325,7 @@
expect(result.isNull, isTrue);
}
- test_visitBinaryExpression_xor_bool() async {
+ test_visitBinaryExpression_xor_bool_known_known() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = false ^ true;
''');
@@ -272,6 +334,37 @@
expect(result.type, typeProvider.boolType);
}
+ test_visitBinaryExpression_xor_bool_known_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const b = bool.fromEnvironment('y');
+const c = false ^ b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_xor_bool_unknown_known() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const c = a ^ true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_xor_bool_unknown_unknown() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a ^ b;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [EnableString.constant_update_2018]);
+ expect(result.type, typeProvider.boolType);
+ }
+
test_visitBinaryExpression_xor_int() async {
CompilationUnit compilationUnit = await resolveSource('''
const c = 3 ^ 5;