[analyzer] Dot shorthands: Report error when instantiating abstract class.
This CL reports `INSTANTIATE_ABSTRACT_CLASS` when we are trying to instantiate an abstract class (with a non-factory constructor).
co19 tests and unit tests passing.
Bug: https://github.com/dart-lang/sdk/issues/59835
Change-Id: I5eded14f558d528265d82fd63cc0af3d9b052eac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426682
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
diff --git a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
index b4f6c94..6f1ca34 100644
--- a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
@@ -73,12 +73,12 @@
// TODO(kallentu): Support other context types
if (dotShorthandContextType is InterfaceTypeImpl) {
+ InterfaceElementImpl2? contextElement = dotShorthandContextType.element3;
// This branch will be true if we're resolving an explicitly marked
// const constructor invocation. It's completely unresolved, unlike a
// rewritten [DotShorthandConstructorInvocation] that resulted from
// resolving a [DotShorthandInvocation].
if (node.element == null) {
- var contextElement = dotShorthandContextType.element3;
if (contextElement.getNamedConstructor2(node.constructorName.name)
case ConstructorElementImpl2 element?
when element.isAccessibleIn2(_resolver.definingLibrary)) {
@@ -93,7 +93,15 @@
}
var typeArguments = node.typeArguments;
- if (typeArguments != null) {
+ if (contextElement is ClassElementImpl2 && contextElement.isAbstract) {
+ var constructorElement = node.element;
+ if (constructorElement != null && !constructorElement.isFactory) {
+ _resolver.errorReporter.atNode(
+ node,
+ CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS,
+ );
+ }
+ } else if (typeArguments != null) {
_resolver.errorReporter.atNode(
typeArguments,
CompileTimeErrorCode
diff --git a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart
index a90caa7..362f233b4 100644
--- a/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/dot_shorthand_constructor_invocation_test.dart
@@ -18,6 +18,52 @@
@reflectiveTest
class DotShorthandConstructorInvocationResolutionTest
extends PubPackageResolutionTest {
+ test_abstract_instantiation() async {
+ await assertErrorsInCode(
+ r'''
+Function getFunction() {
+ return .new();
+}
+''',
+ [error(CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, 34, 6)],
+ );
+ }
+
+ test_abstract_instantiation_factory() async {
+ await assertNoErrorsInCode(r'''
+void main() async {
+ var iter = [1, 2];
+ await for (var x in .fromIterable(iter)) {
+ print(x);
+ }
+}
+''');
+
+ var node = findNode.singleDotShorthandConstructorInvocation;
+ assertResolvedNodeText(node, r'''
+DotShorthandConstructorInvocation
+ period: .
+ constructorName: SimpleIdentifier
+ token: fromIterable
+ element: ConstructorMember
+ baseElement: dart:async::@fragment::dart:async/stream.dart::@class::Stream::@constructor::fromIterable#element
+ substitution: {T: int}
+ staticType: null
+ argumentList: ArgumentList
+ leftParenthesis: (
+ arguments
+ SimpleIdentifier
+ token: iter
+ correspondingParameter: ParameterMember
+ baseElement: dart:async::@fragment::dart:async/stream.dart::@class::Stream::@constructor::fromIterable::@parameter::data#element
+ substitution: {T: int}
+ element: iter@26
+ staticType: List<int>
+ rightParenthesis: )
+ staticType: Stream<int>
+''');
+ }
+
test_chain_method() async {
await assertNoErrorsInCode(r'''
class C {