1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 12:06:26 +00:00

Extension types. It is not an error to invoke members of nullable extension type.

1. It is not allowed to write a nullable type in `implements`.
2. Any methods of the extension type itself are OK to invoke.

I start to doubt what is the meaning of isNonNullable() to extension types.
For now I will add a workaround, to be reconsidered if isNonNullable() is
clarified.

Change-Id: I8a9543a6b0e942ae4de3ce673eeee1aa9b0a5230
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319862
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-08-10 20:14:57 +00:00 committed by Commit Queue
parent 3c75002cee
commit 00b59bd878
4 changed files with 65 additions and 1 deletions

View File

@ -11,6 +11,10 @@ import 'package:collection/collection.dart';
import 'package:meta/meta_meta.dart';
extension DartTypeExtension on DartType {
bool get isExtensionType {
return element is ExtensionTypeElement;
}
/// If `this` is an [InterfaceType] that is an instantiation of an extension
/// type, returns its representation type erasure. Otherwise, returns self.
DartType get representationTypeErasureOrSelf {

View File

@ -92,7 +92,8 @@ class TypePropertyResolver {
}
if (_isNonNullableByDefault &&
_typeSystem.isPotentiallyNullable(receiverType)) {
_typeSystem.isPotentiallyNullable(receiverType) &&
!receiverType.isExtensionType) {
_lookupInterfaceType(_typeProvider.objectType);
if (_hasGetterOrSetter) {
return _toResult();

View File

@ -817,6 +817,37 @@ extension type A(int it) {
void foo() {}
}
void f(A a) {
a.foo();
}
''');
final node = findNode.singleMethodInvocation;
assertResolvedNodeText(node, r'''
MethodInvocation
target: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: A
operator: .
methodName: SimpleIdentifier
token: foo
staticElement: self::@extensionType::A::@method::foo
staticType: void Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: void Function()
staticType: void
''');
}
test_hasReceiver_interfaceType_extensionType_declared_nullableRepresentation() async {
await assertNoErrorsInCode(r'''
extension type A(int? it) {
void foo() {}
}
void f(A a) {
a.foo();
}

View File

@ -549,6 +549,34 @@ extension type A(int it) {
int get foo => 0;
}
void f(A a) {
a.foo;
}
''');
final node = findNode.singlePrefixedIdentifier;
assertResolvedNodeText(node, r'''
PrefixedIdentifier
prefix: SimpleIdentifier
token: a
staticElement: self::@function::f::@parameter::a
staticType: A
period: .
identifier: SimpleIdentifier
token: foo
staticElement: self::@extensionType::A::@getter::foo
staticType: int
staticElement: self::@extensionType::A::@getter::foo
staticType: int
''');
}
test_ofExtensionType_read_nullableRepresentation() async {
await assertNoErrorsInCode(r'''
extension type A(int? it) {
int get foo => 0;
}
void f(A a) {
a.foo;
}