Store resolution for abstract class constructor invocation.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: I8973a93550cb7718070a478c26747c88176f60f7
Reviewed-on: https://dart-review.googlesource.com/64160
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index 3c88c1a..9d1f172 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -971,20 +971,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_newWithAbstractClass() async {
- return super.test_newWithAbstractClass_generic();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_newWithAbstractClass_generic() async {
- return super.test_newWithAbstractClass_generic();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_newWithInvalidTypeParameters() async {
return super.test_newWithInvalidTypeParameters();
}
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index 411efa9..174f423 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -37,20 +37,6 @@
@override
@failingTest
- test_async_star_method_propagation() async {
- // Bad state: No type information for Stream at 124
- await super.test_async_star_method_propagation();
- }
-
- @override
- @failingTest
- test_async_star_propagation() async {
- // Bad state: No type information for Stream at 105
- await super.test_async_star_propagation();
- }
-
- @override
- @failingTest
test_constrainedByBounds2() async {
// Expected: InterfaceTypeImpl:<int>
await super.test_constrainedByBounds2();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 692e703..d0951ad 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2971,6 +2971,74 @@
assertType(aRef, 'int');
}
+ test_invalid_instanceCreation_abstract() async {
+ addTestFile(r'''
+abstract class C<T> {
+ C(T a);
+ C.named(T a);
+ C.named2();
+}
+var a = 0;
+var b = true;
+main() {
+ new C(a);
+ new C.named(b);
+ new C<double>.named2();
+}
+''');
+ await resolveTestFile();
+ expect(result.errors, isNotEmpty);
+
+ var c = findElement.class_('C');
+
+ {
+ var creation = findNode.instanceCreation('new C(a)');
+ assertType(creation, 'C<int>');
+
+ ConstructorName constructorName = creation.constructorName;
+ expect(constructorName.name, isNull);
+
+ TypeName type = constructorName.type;
+ expect(type.typeArguments, isNull);
+ assertElement(type.name, c);
+ assertType(type.name, useCFE ? 'C<int>' : 'C<dynamic>');
+
+ SimpleIdentifier aRef = creation.argumentList.arguments[0];
+ assertElement(aRef, findElement.topGet('a'));
+ assertType(aRef, 'int');
+ }
+
+ {
+ var creation = findNode.instanceCreation('new C.named(b)');
+ assertType(creation, 'C<bool>');
+
+ ConstructorName constructorName = creation.constructorName;
+ expect(constructorName.name.name, 'named');
+
+ TypeName type = constructorName.type;
+ expect(type.typeArguments, isNull);
+ assertElement(type.name, c);
+ assertType(type.name, useCFE ? 'C<bool>' : 'C<dynamic>');
+
+ SimpleIdentifier bRef = creation.argumentList.arguments[0];
+ assertElement(bRef, findElement.topGet('b'));
+ assertType(bRef, 'bool');
+ }
+
+ {
+ var creation = findNode.instanceCreation('new C<double>.named2()');
+ assertType(creation, 'C<double>');
+
+ ConstructorName constructorName = creation.constructorName;
+ expect(constructorName.name.name, 'named2');
+
+ TypeName type = constructorName.type;
+ assertTypeArguments(type.typeArguments, [doubleType]);
+ assertElement(type.name, c);
+ assertType(type.name, 'C<double>');
+ }
+ }
+
test_invalid_methodInvocation_simpleIdentifier() async {
addTestFile(r'''
int foo = 0;
@@ -7552,6 +7620,15 @@
CompilationUnitElement get unitElement => result.unit.element;
+ ClassElement class_(String name) {
+ for (var class_ in unitElement.types) {
+ if (class_.name == name) {
+ return class_;
+ }
+ }
+ fail('Not found class: $name');
+ }
+
FieldElement field(String name) {
for (var type in unitElement.types) {
for (var field in type.fields) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index ddbf2dd..f9430d9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2966,13 +2966,17 @@
// Not found. Reported below.
} else if (b.isConstructor) {
if (type.isAbstract) {
- return new SyntheticExpressionJudgment(evaluateArgumentsBefore(
- arguments,
- buildAbstractClassInstantiationError(
- fasta.templateAbstractClassInstantiation
- .withArguments(type.name),
- type.name,
- nameToken.charOffset)));
+ return new InvalidConstructorInvocationJudgment(
+ evaluateArgumentsBefore(
+ arguments,
+ buildAbstractClassInstantiationError(
+ fasta.templateAbstractClassInstantiation
+ .withArguments(type.name),
+ type.name,
+ nameToken.charOffset)),
+ target,
+ arguments)
+ ..fileOffset = charOffset;
}
}
if (target is Constructor ||
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index b54ec64..b3c17bb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2819,19 +2819,22 @@
kernel.Expression desugared, this.constructor, this.arguments)
: super(desugared);
+ ArgumentsJudgment get argumentJudgments => arguments;
+
@override
Expression infer<Expression, Statement, Initializer, Type>(
ShadowTypeInferrer inferrer,
Factory<Expression, Statement, Initializer, Type> factory,
DartType typeContext) {
- for (var argument in arguments.positional) {
- inferrer.inferExpression(factory, argument, const UnknownType(), true);
- }
- for (var argument in arguments.named) {
- inferrer.inferExpression(
- factory, argument.value, const UnknownType(), true);
- }
- inferredType = constructor.enclosingClass.rawType;
+ var calleeType = constructor.function.functionType;
+ var inferenceResult = inferrer.inferInvocation(
+ factory,
+ typeContext,
+ fileOffset,
+ calleeType,
+ computeConstructorReturnType(constructor),
+ argumentJudgments);
+ this.inferredType = inferenceResult.type;
inferrer.listener.constructorInvocation(
this, arguments.fileOffset, constructor, inferredType);
return super.infer(inferrer, factory, typeContext);