[analyzer] Refactor visitConstructorReference and tests in the const evaluator.
Change-Id: I24eb2a2daa3bd7437dfdc5ab2f4fed4899209fbb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308260
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 185fc9d..5454748 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -732,10 +732,10 @@
}
@override
- Constant? visitConstructorReference(ConstructorReference node) {
+ Constant visitConstructorReference(ConstructorReference node) {
var constructorFunctionType = node.typeOrThrow;
if (constructorFunctionType is! FunctionType) {
- return null;
+ return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT);
}
var classType = constructorFunctionType.returnType as InterfaceType;
var typeArguments = classType.typeArguments;
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 591dd59..bfc62b5 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -368,259 +368,6 @@
_assertHasPrimitiveEqualityTrue('v');
}
- test_identical_constructorReference_aliasIsNotGeneric() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC = C<int>;
-const a = identical(MyC.new, C<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_differentBound() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T extends num> = C<T>;
-const a = identical(MyC.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_differentCount() async {
- await resolveTestCode('''
-class C<T, U> {}
-typedef MyC<T> = C<T, int>;
-const a = identical(MyC.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_differentCount2() async {
- await resolveTestCode('''
-class C<T, U> {}
-typedef MyC<T> = C;
-const a = identical(MyC.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_differentOrder() async {
- await resolveTestCode('''
-class C<T, U> {}
-typedef MyC<T, U> = C<U, T>;
-const a = identical(MyC.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_instantiated() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T extends num> = C<T>;
-const a = identical(MyC<int>.new, C<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsNotProperRename_mixedInstantiations() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T extends num> = C<T>;
-const a = identical(MyC<int>.new, (MyC.new)<int>);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_aliasIsProperRename_instantiated() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T> = C<T>;
-const a = identical(MyC<int>.new, MyC<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsProperRename_mixedInstantiations() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T> = C<T>;
-const a = identical(MyC<int>.new, (MyC.new)<int>);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_dynamic() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T extends Object?> = C<T>;
-const a = identical(MyC<int>.new, MyC<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_futureOr() async {
- await resolveTestCode('''
-class C<T extends num> {}
-typedef MyC<T extends FutureOr<num>> = C<T>;
-const a = identical(MyC<int>.new, MyC<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_aliasIsProperRename_uninstantiated() async {
- await resolveTestCode('''
-class C<T> {}
-typedef MyC<T> = C<T>;
-const a = identical(MyC.new, MyC.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_explicitTypeArgs_differentClasses() async {
- await resolveTestCode('''
-class C<T> {}
-class D<T> {}
-const a = identical(C<int>.new, D<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_explicitTypeArgs_differentConstructors() async {
- await resolveTestCode('''
-class C<T> {
- C();
- C.named();
-}
-const a = identical(C<int>.new, C<int>.named);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_explicitTypeArgs_differentTypeArgs() async {
- await resolveTestCode('''
-class C<T> {}
-const a = identical(C<int>.new, C<String>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_explicitTypeArgs_sameElement() async {
- await resolveTestCode('''
-class C<T> {}
-const a = identical(C<int>.new, C<int>.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_inferredTypeArgs_sameElement() async {
- await resolveTestCode('''
-class C<T> {}
-const C<int> Function() c1 = C.new;
-const c2 = C<int>.new;
-const a = identical(c1, c2);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_notInstantiated_differentClasses() async {
- await resolveTestCode('''
-class C<T> {}
-class D<T> {}
-const a = identical(C.new, D.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_notInstantiated_differentConstructors() async {
- await resolveTestCode('''
-class C<T> {
- C();
- C.named();
-}
-const a = identical(C.new, C.named);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
- test_identical_constructorReference_notInstantiated_sameElement() async {
- await resolveTestCode('''
-class C<T> {}
-const a = identical(C.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(true),
- );
- }
-
- test_identical_constructorReference_onlyOneHasTypeArgs() async {
- await resolveTestCode('''
-class C<T> {}
-const a = identical(C<int>.new, C.new);
-''');
- expect(
- _evaluateConstant('a'),
- _boolValue(false),
- );
- }
-
test_identical_functionReference_explicitTypeArgs_differentElements() async {
await resolveTestCode('''
void foo<T>(T a) {}
@@ -994,6 +741,260 @@
]);
}
+ test_visitConstructorReference_identical_aliasIsNotGeneric() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC = C<int>;
+const a = identical(MyC.new, C<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_differentBound() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T extends num> = C<T>;
+const a = identical(MyC.new, C.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_differentCount() async {
+ await assertNoErrorsInCode('''
+class C<T, U> {}
+typedef MyC<T> = C<T, int>;
+const a = identical(MyC.new, C.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_differentCount2() async {
+ await assertNoErrorsInCode('''
+class C<T, U> {}
+typedef MyC<T> = C;
+const a = identical(MyC.new, C.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_differentOrder() async {
+ await assertNoErrorsInCode('''
+class C<T, U> {}
+typedef MyC<T, U> = C<U, T>;
+const a = identical(MyC.new, C.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_instantiated() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T extends num> = C<T>;
+const a = identical(MyC<int>.new, C<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsNotProperRename_mixedInstantiations() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T extends num> = C<T>;
+const a = identical(MyC<int>.new, (MyC.new)<int>);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsProperRename_instantiated() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T> = C<T>;
+const a = identical(MyC<int>.new, MyC<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsProperRename_mixedInstantiations() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T> = C<T>;
+const a = identical(MyC<int>.new, (MyC.new)<int>);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsProperRename_mutualSubtypes_dynamic() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T extends Object?> = C<T>;
+const a = identical(MyC<int>.new, MyC<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsProperRename_mutualSubtypes_futureOr() async {
+ await assertNoErrorsInCode('''
+import 'dart:async';
+class C<T extends FutureOr<num>> {}
+typedef MyC<T extends num> = C<T>;
+const a = identical(MyC<int>.new, MyC<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_aliasIsProperRename_uninstantiated() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+typedef MyC<T> = C<T>;
+const a = identical(MyC.new, MyC.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_explicitTypeArgs_differentClasses() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+class D<T> {}
+const a = identical(C<int>.new, D<int>.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_explicitTypeArgs_differentConstructors() async {
+ await assertNoErrorsInCode('''
+class C<T> {
+ C();
+ C.named();
+}
+const a = identical(C<int>.new, C<int>.named);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_explicitTypeArgs_differentTypeArgs() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+const a = identical(C<int>.new, C<String>.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_explicitTypeArgs_sameElement() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+const a = identical(C<int>.new, C<int>.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_inferredTypeArgs_sameElement() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+const C<int> Function() c1 = C.new;
+const c2 = C<int>.new;
+const a = identical(c1, c2);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_notInstantiated_differentClasses() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+class D<T> {}
+const a = identical(C.new, D.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_notInstantiated_differentConstructors() async {
+ await assertNoErrorsInCode('''
+class C<T> {
+ C();
+ C.named();
+}
+const a = identical(C.new, C.named);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_notInstantiated_sameElement() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+const a = identical(C.new, C.new);
+''');
+ _assertValue('a', r'''
+bool true
+ variable: self::@variable::a
+''');
+ }
+
+ test_visitConstructorReference_identical_onlyOneHasTypeArgs() async {
+ await assertNoErrorsInCode('''
+class C<T> {}
+const a = identical(C<int>.new, C.new);
+''');
+ _assertValue('a', r'''
+bool false
+ variable: self::@variable::a
+''');
+ }
+
test_visitFunctionReference_explicitTypeArgs_complexExpression() async {
await resolveTestCode('''
const b = true;