mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +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:
parent
3c75002cee
commit
00b59bd878
|
@ -11,6 +11,10 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:meta/meta_meta.dart';
|
import 'package:meta/meta_meta.dart';
|
||||||
|
|
||||||
extension DartTypeExtension on DartType {
|
extension DartTypeExtension on DartType {
|
||||||
|
bool get isExtensionType {
|
||||||
|
return element is ExtensionTypeElement;
|
||||||
|
}
|
||||||
|
|
||||||
/// If `this` is an [InterfaceType] that is an instantiation of an extension
|
/// If `this` is an [InterfaceType] that is an instantiation of an extension
|
||||||
/// type, returns its representation type erasure. Otherwise, returns self.
|
/// type, returns its representation type erasure. Otherwise, returns self.
|
||||||
DartType get representationTypeErasureOrSelf {
|
DartType get representationTypeErasureOrSelf {
|
||||||
|
|
|
@ -92,7 +92,8 @@ class TypePropertyResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isNonNullableByDefault &&
|
if (_isNonNullableByDefault &&
|
||||||
_typeSystem.isPotentiallyNullable(receiverType)) {
|
_typeSystem.isPotentiallyNullable(receiverType) &&
|
||||||
|
!receiverType.isExtensionType) {
|
||||||
_lookupInterfaceType(_typeProvider.objectType);
|
_lookupInterfaceType(_typeProvider.objectType);
|
||||||
if (_hasGetterOrSetter) {
|
if (_hasGetterOrSetter) {
|
||||||
return _toResult();
|
return _toResult();
|
||||||
|
|
|
@ -817,6 +817,37 @@ extension type A(int it) {
|
||||||
void foo() {}
|
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) {
|
void f(A a) {
|
||||||
a.foo();
|
a.foo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,6 +549,34 @@ extension type A(int it) {
|
||||||
int get foo => 0;
|
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) {
|
void f(A a) {
|
||||||
a.foo;
|
a.foo;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue