mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 13:38:03 +00:00
Issue 51567. Implement constant equality as primitive equality
Bug: https://github.com/dart-lang/sdk/issues/51567 Change-Id: I7821598a761573519205b0ea06b13f433639282b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286241 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
16e935ebad
commit
ad15774558
|
@ -544,6 +544,7 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
|
|||
_substitution = substitution {
|
||||
_dartObjectComputer = DartObjectComputer(
|
||||
typeSystem,
|
||||
_library.featureSet,
|
||||
_errorReporter,
|
||||
);
|
||||
}
|
||||
|
@ -1566,11 +1567,12 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
|
|||
/// class and for collecting errors during evaluation.
|
||||
class DartObjectComputer {
|
||||
final TypeSystemImpl _typeSystem;
|
||||
final FeatureSet _featureSet;
|
||||
|
||||
/// The error reporter that we are using to collect errors.
|
||||
final ErrorReporter _errorReporter;
|
||||
|
||||
DartObjectComputer(this._typeSystem, this._errorReporter);
|
||||
DartObjectComputer(this._typeSystem, this._featureSet, this._errorReporter);
|
||||
|
||||
DartObjectImpl? add(BinaryExpression node, DartObjectImpl? leftOperand,
|
||||
DartObjectImpl? rightOperand) {
|
||||
|
@ -1698,7 +1700,7 @@ class DartObjectComputer {
|
|||
DartObjectImpl? rightOperand) {
|
||||
if (leftOperand != null && rightOperand != null) {
|
||||
try {
|
||||
return leftOperand.equalEqual(_typeSystem, rightOperand);
|
||||
return leftOperand.equalEqual(_typeSystem, _featureSet, rightOperand);
|
||||
} on EvaluationException catch (exception) {
|
||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||
}
|
||||
|
@ -1770,7 +1772,8 @@ class DartObjectComputer {
|
|||
DartObjectImpl? rightOperand) {
|
||||
if (leftOperand != null && rightOperand != null) {
|
||||
try {
|
||||
return leftOperand.lazyEqualEqual(_typeSystem, rightOperand);
|
||||
return leftOperand.lazyEqualEqual(
|
||||
_typeSystem, _featureSet, rightOperand);
|
||||
} on EvaluationException catch (exception) {
|
||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||
}
|
||||
|
@ -1878,7 +1881,7 @@ class DartObjectComputer {
|
|||
DartObjectImpl? rightOperand) {
|
||||
if (leftOperand != null && rightOperand != null) {
|
||||
try {
|
||||
return leftOperand.notEqual(_typeSystem, rightOperand);
|
||||
return leftOperand.notEqual(_typeSystem, _featureSet, rightOperand);
|
||||
} on EvaluationException catch (exception) {
|
||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||
}
|
||||
|
|
|
@ -429,7 +429,10 @@ class DartObjectImpl implements DartObject {
|
|||
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||
/// object of this kind.
|
||||
DartObjectImpl equalEqual(
|
||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
||||
TypeSystemImpl typeSystem,
|
||||
FeatureSet featureSet,
|
||||
DartObjectImpl rightOperand,
|
||||
) {
|
||||
if (isNull || rightOperand.isNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
|
@ -439,12 +442,22 @@ class DartObjectImpl implements DartObject {
|
|||
: BoolState.FALSE_STATE,
|
||||
);
|
||||
}
|
||||
if (isBoolNumStringOrNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.equalEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
if (featureSet.isEnabled(Feature.patterns)) {
|
||||
if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.equalEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (isBoolNumStringOrNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.equalEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
}
|
||||
}
|
||||
throw EvaluationException(
|
||||
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
|
||||
|
@ -598,7 +611,10 @@ class DartObjectImpl implements DartObject {
|
|||
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||
/// object of this kind.
|
||||
DartObjectImpl lazyEqualEqual(
|
||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
||||
TypeSystemImpl typeSystem,
|
||||
FeatureSet featureSet,
|
||||
DartObjectImpl rightOperand,
|
||||
) {
|
||||
if (isNull || rightOperand.isNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
|
@ -608,12 +624,22 @@ class DartObjectImpl implements DartObject {
|
|||
: BoolState.FALSE_STATE,
|
||||
);
|
||||
}
|
||||
if (isBoolNumStringOrNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.lazyEqualEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
if (featureSet.isEnabled(Feature.patterns)) {
|
||||
if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.equalEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (isBoolNumStringOrNull) {
|
||||
return DartObjectImpl(
|
||||
typeSystem,
|
||||
typeSystem.typeProvider.boolType,
|
||||
state.equalEqual(typeSystem, rightOperand.state),
|
||||
);
|
||||
}
|
||||
}
|
||||
throw EvaluationException(
|
||||
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
|
||||
|
@ -739,8 +765,12 @@ class DartObjectImpl implements DartObject {
|
|||
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||
/// object of this kind.
|
||||
DartObjectImpl notEqual(
|
||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
||||
return equalEqual(typeSystem, rightOperand).logicalNot(typeSystem);
|
||||
TypeSystemImpl typeSystem,
|
||||
FeatureSet featureSet,
|
||||
DartObjectImpl rightOperand,
|
||||
) {
|
||||
return equalEqual(typeSystem, featureSet, rightOperand)
|
||||
.logicalNot(typeSystem);
|
||||
}
|
||||
|
||||
/// Return the result of converting this object to a 'String'.
|
||||
|
|
|
@ -29,6 +29,166 @@ main() {
|
|||
@reflectiveTest
|
||||
class ConstantVisitorTest extends ConstantVisitorTestSupport
|
||||
with ConstantVisitorTestCases {
|
||||
test_equalEqual_double_object() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = 1.2 == Object();
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_int_int_false() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = 1 == 2;
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_int_int_true() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = 1 == 1;
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool true
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_int_null() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const int? a = 1;
|
||||
const v = a == null;
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_int_object() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = 1 == Object();
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_int_userClass() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
||||
const v = 1 == A();
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_null_object() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const Object? a = null;
|
||||
const v = a == Object();
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_string_object() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = 'foo' == Object();
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_userClass_hasEqEq() async {
|
||||
await assertErrorsInCode('''
|
||||
class A {
|
||||
const A();
|
||||
bool operator ==(other) => false;
|
||||
}
|
||||
|
||||
const v = A() == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 72, 8),
|
||||
]);
|
||||
// TODO(scheglov) check the invalid value
|
||||
}
|
||||
|
||||
test_equalEqual_userClass_hasHashCode() async {
|
||||
await assertErrorsInCode('''
|
||||
class A {
|
||||
const A();
|
||||
int get hashCode => 0;
|
||||
}
|
||||
|
||||
const v = A() == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 61, 8),
|
||||
]);
|
||||
// TODO(scheglov) check the invalid value
|
||||
}
|
||||
|
||||
test_equalEqual_userClass_hasPrimitiveEquality_false() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class A {
|
||||
final int f;
|
||||
const A(this.f);
|
||||
}
|
||||
|
||||
const v = A(0) == 0;
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool false
|
||||
''');
|
||||
}
|
||||
|
||||
test_equalEqual_userClass_hasPrimitiveEquality_language219() async {
|
||||
await assertErrorsInCode('''
|
||||
// @dart = 2.19
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
||||
const v = A() == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 52, 8),
|
||||
]);
|
||||
_evaluateConstantOrNull('v', errorCodes: [
|
||||
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING,
|
||||
]);
|
||||
}
|
||||
|
||||
test_equalEqual_userClass_hasPrimitiveEquality_true() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class A {
|
||||
final int f;
|
||||
const A(this.f);
|
||||
}
|
||||
|
||||
const v = A(0) == A(0);
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
bool true
|
||||
''');
|
||||
}
|
||||
|
||||
test_hasPrimitiveEquality_bool() async {
|
||||
await assertNoErrorsInCode('''
|
||||
const v = true;
|
||||
|
@ -2314,6 +2474,19 @@ const a = const A<int?>();
|
|||
);
|
||||
}
|
||||
|
||||
test_assertInitializer_intInDoubleContext_true() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class A {
|
||||
const A(double x): assert((x + 3) / 2 == 1.5);
|
||||
}
|
||||
const v = const A(0);
|
||||
''');
|
||||
final value = _evaluateConstant('v');
|
||||
assertDartObjectText(value, r'''
|
||||
A
|
||||
''');
|
||||
}
|
||||
|
||||
test_fieldInitializer_functionReference_withTypeParameter() async {
|
||||
await resolveTestCode('''
|
||||
void g<U>(U a) {}
|
||||
|
@ -2519,16 +2692,6 @@ const a = const A(1);
|
|||
);
|
||||
}
|
||||
|
||||
test_assertInitializer_intInDoubleContext_true() async {
|
||||
await resolveTestCode('''
|
||||
class A {
|
||||
const A(double x): assert((x + 3) / 2 == 1.5);
|
||||
}
|
||||
const a = const A(0);
|
||||
''');
|
||||
_assertValidConstant('a');
|
||||
}
|
||||
|
||||
test_assertInitializer_simple_false() async {
|
||||
await resolveTestCode('''
|
||||
class A {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// 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/analysis/features.dart';
|
||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/dart/element/type_provider.dart';
|
||||
|
@ -11,6 +12,7 @@ import 'package:test/test.dart';
|
|||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../../generated/test_analysis_context.dart';
|
||||
import '../../../util/feature_sets.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
|
@ -27,6 +29,7 @@ final Matcher throwsEvaluationException =
|
|||
class DartObjectImplTest {
|
||||
late final TypeProvider _typeProvider;
|
||||
late final TypeSystemImpl _typeSystem;
|
||||
FeatureSet _featureSet = FeatureSets.latestWithExperiments;
|
||||
|
||||
void setUp() {
|
||||
var analysisContext = TestAnalysisContext();
|
||||
|
@ -358,14 +361,29 @@ class DartObjectImplTest {
|
|||
_assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
|
||||
}
|
||||
|
||||
void test_equalEqual_double_false_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
|
||||
}
|
||||
|
||||
void test_equalEqual_double_true() {
|
||||
_assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
|
||||
}
|
||||
|
||||
void test_equalEqual_double_true_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
|
||||
}
|
||||
|
||||
void test_equalEqual_double_unknown() {
|
||||
_assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
||||
}
|
||||
|
||||
void test_equalEqual_double_unknown_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
||||
}
|
||||
|
||||
void test_equalEqual_int_false() {
|
||||
_assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
|
||||
}
|
||||
|
@ -378,7 +396,8 @@ class DartObjectImplTest {
|
|||
_assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
|
||||
}
|
||||
|
||||
void test_equalEqual_list_empty() {
|
||||
void test_equalEqual_list_error_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertEqualEqual(
|
||||
null,
|
||||
_listValue(_typeProvider.intType, []),
|
||||
|
@ -386,15 +405,16 @@ class DartObjectImplTest {
|
|||
);
|
||||
}
|
||||
|
||||
void test_equalEqual_list_false() {
|
||||
void test_equalEqual_list_true() {
|
||||
_assertEqualEqual(
|
||||
null,
|
||||
_boolValue(true),
|
||||
_listValue(_typeProvider.intType, []),
|
||||
_listValue(_typeProvider.intType, []),
|
||||
);
|
||||
}
|
||||
|
||||
void test_equalEqual_map_empty() {
|
||||
void test_equalEqual_map_error_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertEqualEqual(
|
||||
null,
|
||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||
|
@ -402,9 +422,9 @@ class DartObjectImplTest {
|
|||
);
|
||||
}
|
||||
|
||||
void test_equalEqual_map_false() {
|
||||
void test_equalEqual_map_true() {
|
||||
_assertEqualEqual(
|
||||
null,
|
||||
_boolValue(true),
|
||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||
);
|
||||
|
@ -1582,11 +1602,21 @@ class DartObjectImplTest {
|
|||
_assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
|
||||
}
|
||||
|
||||
void test_notEqual_double_false() {
|
||||
void test_notEqual_double_double_false() {
|
||||
_assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
|
||||
}
|
||||
|
||||
void test_notEqual_double_true() {
|
||||
void test_notEqual_double_double_false_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
|
||||
}
|
||||
|
||||
void test_notEqual_double_double_true() {
|
||||
_assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
|
||||
}
|
||||
|
||||
void test_notEqual_double_double_true_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
|
||||
}
|
||||
|
||||
|
@ -1594,6 +1624,11 @@ class DartObjectImplTest {
|
|||
_assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
||||
}
|
||||
|
||||
void test_notEqual_double_unknown_language219() {
|
||||
_featureSet = FeatureSets.language_2_19;
|
||||
_assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
||||
}
|
||||
|
||||
void test_notEqual_int_false() {
|
||||
_assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
|
||||
}
|
||||
|
@ -1996,10 +2031,10 @@ class DartObjectImplTest {
|
|||
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
||||
if (expected == null) {
|
||||
expect(() {
|
||||
left.equalEqual(_typeSystem, right);
|
||||
return left.equalEqual(_typeSystem, _featureSet, right);
|
||||
}, throwsEvaluationException);
|
||||
} else {
|
||||
DartObjectImpl result = left.equalEqual(_typeSystem, right);
|
||||
DartObjectImpl result = left.equalEqual(_typeSystem, _featureSet, right);
|
||||
expect(result, isNotNull);
|
||||
expect(result, expected);
|
||||
}
|
||||
|
@ -2189,10 +2224,10 @@ class DartObjectImplTest {
|
|||
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
||||
if (expected == null) {
|
||||
expect(() {
|
||||
left.notEqual(_typeSystem, right);
|
||||
left.notEqual(_typeSystem, _featureSet, right);
|
||||
}, throwsEvaluationException);
|
||||
} else {
|
||||
DartObjectImpl result = left.notEqual(_typeSystem, right);
|
||||
DartObjectImpl result = left.notEqual(_typeSystem, _featureSet, right);
|
||||
expect(result, isNotNull);
|
||||
expect(result, expected);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,14 @@ const b = a == Object();
|
|||
''');
|
||||
}
|
||||
|
||||
test_equal_double_object_language219() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
// @dart = 2.19
|
||||
const a = 0.1;
|
||||
const b = a == Object();
|
||||
''');
|
||||
}
|
||||
|
||||
test_equal_int_object() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
const a = 0;
|
||||
|
@ -54,8 +62,48 @@ const b = a == Object();
|
|||
''');
|
||||
}
|
||||
|
||||
test_equal_userClass_int() async {
|
||||
test_equal_userClass_int_hasEqEq() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
bool operator ==(other) => false;
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 87, 6),
|
||||
]);
|
||||
}
|
||||
|
||||
test_equal_userClass_int_hasHashCode() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
int get hashCode => 0;
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 76, 6),
|
||||
]);
|
||||
}
|
||||
|
||||
test_equal_userClass_int_hasPrimitiveEquality() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a == 0;
|
||||
''');
|
||||
}
|
||||
|
||||
test_equal_userClass_int_language219() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart = 2.19
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
@ -63,7 +111,7 @@ class A {
|
|||
const a = A();
|
||||
const b = a == 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 51, 6),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 67, 6),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -74,6 +122,14 @@ const b = a != Object();
|
|||
''');
|
||||
}
|
||||
|
||||
test_notEqual_double_object_language219() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
// @dart = 2.19
|
||||
const a = 0.1;
|
||||
const b = a != Object();
|
||||
''');
|
||||
}
|
||||
|
||||
test_notEqual_int_object() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
const a = 0;
|
||||
|
@ -106,8 +162,48 @@ const b = a != Object();
|
|||
''');
|
||||
}
|
||||
|
||||
test_notEqual_userClass_int() async {
|
||||
test_notEqual_userClass_int_hasEqEq() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
bool operator ==(other) => false;
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a != 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 87, 6),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notEqual_userClass_int_hasHashCode() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
int get hashCode => 0;
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a != 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 76, 6),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notEqual_userClass_int_hasPrimitiveEquality() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const b = a != 0;
|
||||
''');
|
||||
}
|
||||
|
||||
test_notEqual_userClass_int_language219() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart = 2.19
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
|
@ -115,7 +211,7 @@ class A {
|
|||
const a = A();
|
||||
const b = a != 0;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 51, 6),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 67, 6),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,8 +177,6 @@ method<T>(o) {
|
|||
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
|
||||
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
|
||||
case const Object() == 2: // Error
|
||||
// ^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL_NUM_STRING
|
||||
// ^
|
||||
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
|
||||
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
|
||||
|
@ -243,4 +241,4 @@ method<T>(o) {
|
|||
// [analyzer] COMPILE_TIME_ERROR.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION
|
||||
// [cfe] Not a constant expression.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue