[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;