mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:09:04 +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 {
|
_substitution = substitution {
|
||||||
_dartObjectComputer = DartObjectComputer(
|
_dartObjectComputer = DartObjectComputer(
|
||||||
typeSystem,
|
typeSystem,
|
||||||
|
_library.featureSet,
|
||||||
_errorReporter,
|
_errorReporter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1566,11 +1567,12 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
|
||||||
/// class and for collecting errors during evaluation.
|
/// class and for collecting errors during evaluation.
|
||||||
class DartObjectComputer {
|
class DartObjectComputer {
|
||||||
final TypeSystemImpl _typeSystem;
|
final TypeSystemImpl _typeSystem;
|
||||||
|
final FeatureSet _featureSet;
|
||||||
|
|
||||||
/// The error reporter that we are using to collect errors.
|
/// The error reporter that we are using to collect errors.
|
||||||
final ErrorReporter _errorReporter;
|
final ErrorReporter _errorReporter;
|
||||||
|
|
||||||
DartObjectComputer(this._typeSystem, this._errorReporter);
|
DartObjectComputer(this._typeSystem, this._featureSet, this._errorReporter);
|
||||||
|
|
||||||
DartObjectImpl? add(BinaryExpression node, DartObjectImpl? leftOperand,
|
DartObjectImpl? add(BinaryExpression node, DartObjectImpl? leftOperand,
|
||||||
DartObjectImpl? rightOperand) {
|
DartObjectImpl? rightOperand) {
|
||||||
|
@ -1698,7 +1700,7 @@ class DartObjectComputer {
|
||||||
DartObjectImpl? rightOperand) {
|
DartObjectImpl? rightOperand) {
|
||||||
if (leftOperand != null && rightOperand != null) {
|
if (leftOperand != null && rightOperand != null) {
|
||||||
try {
|
try {
|
||||||
return leftOperand.equalEqual(_typeSystem, rightOperand);
|
return leftOperand.equalEqual(_typeSystem, _featureSet, rightOperand);
|
||||||
} on EvaluationException catch (exception) {
|
} on EvaluationException catch (exception) {
|
||||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||||
}
|
}
|
||||||
|
@ -1770,7 +1772,8 @@ class DartObjectComputer {
|
||||||
DartObjectImpl? rightOperand) {
|
DartObjectImpl? rightOperand) {
|
||||||
if (leftOperand != null && rightOperand != null) {
|
if (leftOperand != null && rightOperand != null) {
|
||||||
try {
|
try {
|
||||||
return leftOperand.lazyEqualEqual(_typeSystem, rightOperand);
|
return leftOperand.lazyEqualEqual(
|
||||||
|
_typeSystem, _featureSet, rightOperand);
|
||||||
} on EvaluationException catch (exception) {
|
} on EvaluationException catch (exception) {
|
||||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||||
}
|
}
|
||||||
|
@ -1878,7 +1881,7 @@ class DartObjectComputer {
|
||||||
DartObjectImpl? rightOperand) {
|
DartObjectImpl? rightOperand) {
|
||||||
if (leftOperand != null && rightOperand != null) {
|
if (leftOperand != null && rightOperand != null) {
|
||||||
try {
|
try {
|
||||||
return leftOperand.notEqual(_typeSystem, rightOperand);
|
return leftOperand.notEqual(_typeSystem, _featureSet, rightOperand);
|
||||||
} on EvaluationException catch (exception) {
|
} on EvaluationException catch (exception) {
|
||||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,7 +429,10 @@ class DartObjectImpl implements DartObject {
|
||||||
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||||
/// object of this kind.
|
/// object of this kind.
|
||||||
DartObjectImpl equalEqual(
|
DartObjectImpl equalEqual(
|
||||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
TypeSystemImpl typeSystem,
|
||||||
|
FeatureSet featureSet,
|
||||||
|
DartObjectImpl rightOperand,
|
||||||
|
) {
|
||||||
if (isNull || rightOperand.isNull) {
|
if (isNull || rightOperand.isNull) {
|
||||||
return DartObjectImpl(
|
return DartObjectImpl(
|
||||||
typeSystem,
|
typeSystem,
|
||||||
|
@ -439,12 +442,22 @@ class DartObjectImpl implements DartObject {
|
||||||
: BoolState.FALSE_STATE,
|
: BoolState.FALSE_STATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (isBoolNumStringOrNull) {
|
if (featureSet.isEnabled(Feature.patterns)) {
|
||||||
return DartObjectImpl(
|
if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
|
||||||
typeSystem,
|
return DartObjectImpl(
|
||||||
typeSystem.typeProvider.boolType,
|
typeSystem,
|
||||||
state.equalEqual(typeSystem, rightOperand.state),
|
typeSystem.typeProvider.boolType,
|
||||||
);
|
state.equalEqual(typeSystem, rightOperand.state),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isBoolNumStringOrNull) {
|
||||||
|
return DartObjectImpl(
|
||||||
|
typeSystem,
|
||||||
|
typeSystem.typeProvider.boolType,
|
||||||
|
state.equalEqual(typeSystem, rightOperand.state),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw EvaluationException(
|
throw EvaluationException(
|
||||||
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
|
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
|
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||||
/// object of this kind.
|
/// object of this kind.
|
||||||
DartObjectImpl lazyEqualEqual(
|
DartObjectImpl lazyEqualEqual(
|
||||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
TypeSystemImpl typeSystem,
|
||||||
|
FeatureSet featureSet,
|
||||||
|
DartObjectImpl rightOperand,
|
||||||
|
) {
|
||||||
if (isNull || rightOperand.isNull) {
|
if (isNull || rightOperand.isNull) {
|
||||||
return DartObjectImpl(
|
return DartObjectImpl(
|
||||||
typeSystem,
|
typeSystem,
|
||||||
|
@ -608,12 +624,22 @@ class DartObjectImpl implements DartObject {
|
||||||
: BoolState.FALSE_STATE,
|
: BoolState.FALSE_STATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (isBoolNumStringOrNull) {
|
if (featureSet.isEnabled(Feature.patterns)) {
|
||||||
return DartObjectImpl(
|
if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
|
||||||
typeSystem,
|
return DartObjectImpl(
|
||||||
typeSystem.typeProvider.boolType,
|
typeSystem,
|
||||||
state.lazyEqualEqual(typeSystem, rightOperand.state),
|
typeSystem.typeProvider.boolType,
|
||||||
);
|
state.equalEqual(typeSystem, rightOperand.state),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isBoolNumStringOrNull) {
|
||||||
|
return DartObjectImpl(
|
||||||
|
typeSystem,
|
||||||
|
typeSystem.typeProvider.boolType,
|
||||||
|
state.equalEqual(typeSystem, rightOperand.state),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw EvaluationException(
|
throw EvaluationException(
|
||||||
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
|
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
|
/// Throws an [EvaluationException] if the operator is not appropriate for an
|
||||||
/// object of this kind.
|
/// object of this kind.
|
||||||
DartObjectImpl notEqual(
|
DartObjectImpl notEqual(
|
||||||
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
|
TypeSystemImpl typeSystem,
|
||||||
return equalEqual(typeSystem, rightOperand).logicalNot(typeSystem);
|
FeatureSet featureSet,
|
||||||
|
DartObjectImpl rightOperand,
|
||||||
|
) {
|
||||||
|
return equalEqual(typeSystem, featureSet, rightOperand)
|
||||||
|
.logicalNot(typeSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the result of converting this object to a 'String'.
|
/// Return the result of converting this object to a 'String'.
|
||||||
|
|
|
@ -29,6 +29,166 @@ main() {
|
||||||
@reflectiveTest
|
@reflectiveTest
|
||||||
class ConstantVisitorTest extends ConstantVisitorTestSupport
|
class ConstantVisitorTest extends ConstantVisitorTestSupport
|
||||||
with ConstantVisitorTestCases {
|
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 {
|
test_hasPrimitiveEquality_bool() async {
|
||||||
await assertNoErrorsInCode('''
|
await assertNoErrorsInCode('''
|
||||||
const v = true;
|
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 {
|
test_fieldInitializer_functionReference_withTypeParameter() async {
|
||||||
await resolveTestCode('''
|
await resolveTestCode('''
|
||||||
void g<U>(U a) {}
|
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 {
|
test_assertInitializer_simple_false() async {
|
||||||
await resolveTestCode('''
|
await resolveTestCode('''
|
||||||
class A {
|
class A {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// 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/nullability_suffix.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:analyzer/dart/element/type_provider.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 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||||
|
|
||||||
import '../../../generated/test_analysis_context.dart';
|
import '../../../generated/test_analysis_context.dart';
|
||||||
|
import '../../../util/feature_sets.dart';
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
defineReflectiveSuite(() {
|
defineReflectiveSuite(() {
|
||||||
|
@ -27,6 +29,7 @@ final Matcher throwsEvaluationException =
|
||||||
class DartObjectImplTest {
|
class DartObjectImplTest {
|
||||||
late final TypeProvider _typeProvider;
|
late final TypeProvider _typeProvider;
|
||||||
late final TypeSystemImpl _typeSystem;
|
late final TypeSystemImpl _typeSystem;
|
||||||
|
FeatureSet _featureSet = FeatureSets.latestWithExperiments;
|
||||||
|
|
||||||
void setUp() {
|
void setUp() {
|
||||||
var analysisContext = TestAnalysisContext();
|
var analysisContext = TestAnalysisContext();
|
||||||
|
@ -358,14 +361,29 @@ class DartObjectImplTest {
|
||||||
_assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
|
_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() {
|
void test_equalEqual_double_true() {
|
||||||
_assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
|
_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() {
|
void test_equalEqual_double_unknown() {
|
||||||
_assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
_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() {
|
void test_equalEqual_int_false() {
|
||||||
_assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
|
_assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
|
||||||
}
|
}
|
||||||
|
@ -378,7 +396,8 @@ class DartObjectImplTest {
|
||||||
_assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
|
_assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_equalEqual_list_empty() {
|
void test_equalEqual_list_error_language219() {
|
||||||
|
_featureSet = FeatureSets.language_2_19;
|
||||||
_assertEqualEqual(
|
_assertEqualEqual(
|
||||||
null,
|
null,
|
||||||
_listValue(_typeProvider.intType, []),
|
_listValue(_typeProvider.intType, []),
|
||||||
|
@ -386,15 +405,16 @@ class DartObjectImplTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_equalEqual_list_false() {
|
void test_equalEqual_list_true() {
|
||||||
_assertEqualEqual(
|
_assertEqualEqual(
|
||||||
null,
|
_boolValue(true),
|
||||||
_listValue(_typeProvider.intType, []),
|
_listValue(_typeProvider.intType, []),
|
||||||
_listValue(_typeProvider.intType, []),
|
_listValue(_typeProvider.intType, []),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_equalEqual_map_empty() {
|
void test_equalEqual_map_error_language219() {
|
||||||
|
_featureSet = FeatureSets.language_2_19;
|
||||||
_assertEqualEqual(
|
_assertEqualEqual(
|
||||||
null,
|
null,
|
||||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||||
|
@ -402,9 +422,9 @@ class DartObjectImplTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_equalEqual_map_false() {
|
void test_equalEqual_map_true() {
|
||||||
_assertEqualEqual(
|
_assertEqualEqual(
|
||||||
null,
|
_boolValue(true),
|
||||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||||
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
_mapValue(_typeProvider.intType, _typeProvider.stringType, []),
|
||||||
);
|
);
|
||||||
|
@ -1582,11 +1602,21 @@ class DartObjectImplTest {
|
||||||
_assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
|
_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));
|
_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));
|
_assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,6 +1624,11 @@ class DartObjectImplTest {
|
||||||
_assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
|
_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() {
|
void test_notEqual_int_false() {
|
||||||
_assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
|
_assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
|
||||||
}
|
}
|
||||||
|
@ -1996,10 +2031,10 @@ class DartObjectImplTest {
|
||||||
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
expect(() {
|
expect(() {
|
||||||
left.equalEqual(_typeSystem, right);
|
return left.equalEqual(_typeSystem, _featureSet, right);
|
||||||
}, throwsEvaluationException);
|
}, throwsEvaluationException);
|
||||||
} else {
|
} else {
|
||||||
DartObjectImpl result = left.equalEqual(_typeSystem, right);
|
DartObjectImpl result = left.equalEqual(_typeSystem, _featureSet, right);
|
||||||
expect(result, isNotNull);
|
expect(result, isNotNull);
|
||||||
expect(result, expected);
|
expect(result, expected);
|
||||||
}
|
}
|
||||||
|
@ -2189,10 +2224,10 @@ class DartObjectImplTest {
|
||||||
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
expect(() {
|
expect(() {
|
||||||
left.notEqual(_typeSystem, right);
|
left.notEqual(_typeSystem, _featureSet, right);
|
||||||
}, throwsEvaluationException);
|
}, throwsEvaluationException);
|
||||||
} else {
|
} else {
|
||||||
DartObjectImpl result = left.notEqual(_typeSystem, right);
|
DartObjectImpl result = left.notEqual(_typeSystem, _featureSet, right);
|
||||||
expect(result, isNotNull);
|
expect(result, isNotNull);
|
||||||
expect(result, expected);
|
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 {
|
test_equal_int_object() async {
|
||||||
await assertNoErrorsInCode(r'''
|
await assertNoErrorsInCode(r'''
|
||||||
const a = 0;
|
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'''
|
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 {
|
class A {
|
||||||
const A();
|
const A();
|
||||||
}
|
}
|
||||||
|
@ -63,7 +111,7 @@ class A {
|
||||||
const a = A();
|
const a = A();
|
||||||
const b = a == 0;
|
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 {
|
test_notEqual_int_object() async {
|
||||||
await assertNoErrorsInCode(r'''
|
await assertNoErrorsInCode(r'''
|
||||||
const a = 0;
|
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'''
|
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 {
|
class A {
|
||||||
const A();
|
const A();
|
||||||
}
|
}
|
||||||
|
@ -115,7 +211,7 @@ class A {
|
||||||
const a = A();
|
const a = A();
|
||||||
const b = a != 0;
|
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
|
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
|
||||||
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
|
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
|
||||||
case const Object() == 2: // Error
|
case const Object() == 2: // Error
|
||||||
// ^^^^^^^^^^^^^
|
|
||||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL_NUM_STRING
|
|
||||||
// ^
|
// ^
|
||||||
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
|
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
|
||||||
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
|
// [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
|
// [analyzer] COMPILE_TIME_ERROR.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION
|
||||||
// [cfe] Not a constant expression.
|
// [cfe] Not a constant expression.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue