Skip to content

Commit 875a130

Browse files
johnniwintherCommit Queue
authored andcommitted
[_fe_analyzer_shared] Support extension types in macro metadata
Change-Id: I91d4a2837285583ec8c05f0f8f3c4c906f861411 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391402 Reviewed-by: Jens Johansen <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 9e28e19 commit 875a130

File tree

11 files changed

+530
-12
lines changed

11 files changed

+530
-12
lines changed

pkg/_fe_analyzer_shared/lib/src/metadata/proto.dart

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,110 @@ class GenericClassProto extends Proto {
516516
}
517517
}
518518

519+
/// A [reference] to an extension type.
520+
///
521+
/// The [Proto] includes the [scope] of the extension type, which is used to
522+
/// resolve access to constructors and static members on the extension type.
523+
class ExtensionTypeProto extends Proto {
524+
final ExtensionTypeReference reference;
525+
final TypeDeclarationScope scope;
526+
527+
ExtensionTypeProto(this.reference, this.scope);
528+
529+
@override
530+
String toString() => 'ExtensionTypeProto($reference)';
531+
532+
@override
533+
Proto access(String? name) {
534+
if (name == null) {
535+
return this;
536+
}
537+
if (name == 'new') {
538+
name = '';
539+
}
540+
return scope.lookup(name);
541+
}
542+
543+
@override
544+
Proto instantiate(List<TypeAnnotation>? typeArguments) {
545+
return typeArguments != null
546+
? new GenericExtensionTypeProto(reference, scope, typeArguments)
547+
: this;
548+
}
549+
550+
@override
551+
Proto invoke(List<Argument>? arguments) {
552+
return arguments != null ? access('new').invoke(arguments) : this;
553+
}
554+
555+
@override
556+
Expression toExpression() {
557+
return new TypeLiteral(toTypeAnnotation());
558+
}
559+
560+
@override
561+
TypeAnnotation toTypeAnnotation() => new NamedTypeAnnotation(reference);
562+
563+
@override
564+
Proto? resolve() => null;
565+
}
566+
567+
/// A [reference] to an extension type instantiated with [typeArguments].
568+
///
569+
/// The [Proto] includes the [scope] of the extension type, which is used to
570+
/// resolve access to constructors on the class.
571+
class GenericExtensionTypeProto extends Proto {
572+
final ExtensionTypeReference reference;
573+
final TypeDeclarationScope scope;
574+
final List<TypeAnnotation> typeArguments;
575+
576+
GenericExtensionTypeProto(this.reference, this.scope, this.typeArguments);
577+
578+
@override
579+
String toString() => 'GenericExtensionTypeProto($reference,$typeArguments)';
580+
581+
@override
582+
Proto access(String? name) {
583+
if (name == null) {
584+
return this;
585+
}
586+
if (name == 'new') {
587+
name = '';
588+
}
589+
return scope.lookup(name, typeArguments);
590+
}
591+
592+
@override
593+
Proto instantiate(List<TypeAnnotation>? typeArguments) {
594+
return typeArguments != null
595+
? throw new UnimplementedError('GenericExtensionTypeProto.instantiate')
596+
: this;
597+
}
598+
599+
@override
600+
Proto invoke(List<Argument>? arguments) {
601+
return arguments != null ? access('new').invoke(arguments) : this;
602+
}
603+
604+
@override
605+
Expression toExpression() {
606+
return new TypeLiteral(toTypeAnnotation());
607+
}
608+
609+
@override
610+
TypeAnnotation toTypeAnnotation() =>
611+
new NamedTypeAnnotation(reference, typeArguments);
612+
613+
@override
614+
Proto? resolve() {
615+
List<TypeAnnotation>? newTypeArguments =
616+
typeArguments.resolve((a) => a.resolve());
617+
return newTypeArguments == null
618+
? null
619+
: new GenericExtensionTypeProto(reference, scope, newTypeArguments);
620+
}
621+
}
622+
519623
/// A [reference] to a typedef.
520624
///
521625
/// The [Proto] includes the [scope] of the typedef, which is used to resolve
@@ -990,23 +1094,23 @@ class InstanceAccessProto extends Proto {
9901094
if (name == null) {
9911095
return this;
9921096
}
993-
throw new UnimplementedError('InstanceAccessProto.access');
1097+
throw new UnimplementedError('$this.access');
9941098
}
9951099

9961100
@override
9971101
Proto instantiate(List<TypeAnnotation>? typeArguments) {
9981102
if (typeArguments == null) {
9991103
return this;
10001104
}
1001-
throw new UnimplementedError('InstanceAccessProto.instantiate');
1105+
throw new UnimplementedError('$this.instantiate');
10021106
}
10031107

10041108
@override
10051109
Proto invoke(List<Argument>? arguments) {
10061110
if (arguments == null) {
10071111
return this;
10081112
}
1009-
throw new UnimplementedError('InstanceAccessProto.invoke');
1113+
throw new UnimplementedError('$this.invoke');
10101114
}
10111115

10121116
@override

pkg/_fe_analyzer_shared/lib/src/metadata/references.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ abstract class ExtensionReference extends Reference {
5959
String toString() => 'ExtensionReference(${name})';
6060
}
6161

62+
abstract class ExtensionTypeReference extends Reference {
63+
String get name;
64+
65+
@override
66+
String toString() => 'ExtensionTypeReference(${name})';
67+
}
68+
6269
abstract class FunctionTypeParameterReference extends Reference {
6370
String get name;
6471

pkg/_fe_analyzer_shared/lib/src/metadata/scope.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,42 @@ abstract base class BaseExtensionScope implements TypeDeclarationScope {
7575
}
7676
}
7777

78+
/// Base implementation for creating a [TypeDeclarationScope] for an extension
79+
/// type.
80+
abstract base class BaseExtensionTypeScope implements TypeDeclarationScope {
81+
ExtensionTypeReference get extensionTypeReference;
82+
83+
Proto createConstructorProto(List<TypeAnnotation>? typeArguments,
84+
ConstructorReference constructorReference) {
85+
return new ConstructorProto(extensionTypeReference,
86+
typeArguments ?? const [], constructorReference);
87+
}
88+
89+
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
90+
T? member, Proto Function(T, String) memberToProto) {
91+
if (member == null) {
92+
if (typeArguments != null) {
93+
return new UnresolvedAccess(
94+
new GenericExtensionTypeProto(
95+
extensionTypeReference, this, typeArguments),
96+
name);
97+
} else {
98+
return new UnresolvedAccess(
99+
new ExtensionTypeProto(extensionTypeReference, this), name);
100+
}
101+
} else {
102+
if (typeArguments != null) {
103+
return new InvalidAccessProto(
104+
new GenericExtensionTypeProto(
105+
extensionTypeReference, this, typeArguments),
106+
name);
107+
} else {
108+
return memberToProto(member, name);
109+
}
110+
}
111+
}
112+
}
113+
78114
/// Base implementation for creating a [TypeDeclarationScope] for a typedef.
79115
abstract base class BaseTypedefScope implements TypeDeclarationScope {
80116
TypedefReference get typedefReference;

pkg/_fe_analyzer_shared/lib/src/testing/metadata_helper.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class Writer {
168168
_write(expression.name);
169169
_write(')');
170170
case TypeLiteral():
171-
_write('NullAwarePropertyGet(');
171+
_write('TypeLiteral(');
172172
_typeAnnotationToText(expression.typeAnnotation);
173173
_write(')');
174174
case ParenthesizedExpression():
@@ -286,6 +286,8 @@ class Writer {
286286
_write(reference.name);
287287
case ExtensionReference():
288288
_write(reference.name);
289+
case ExtensionTypeReference():
290+
_write(reference.name);
289291
case FunctionTypeParameterReference():
290292
_write(reference.name);
291293
}
@@ -622,6 +624,15 @@ class Writer {
622624
_write('ExtensionProto(');
623625
_referenceToText(proto.reference);
624626
_write(')');
627+
case ExtensionTypeProto():
628+
_write('ExtensionTypeProto(');
629+
_referenceToText(proto.reference);
630+
_write(')');
631+
case GenericExtensionTypeProto():
632+
_write('GenericExtensionTypeProto(');
633+
_referenceToText(proto.reference);
634+
_typeArgumentsToText(proto.typeArguments);
635+
_write(')');
625636
case TypedefProto():
626637
_write('TypedefProto(');
627638
_referenceToText(proto.reference);

pkg/_fe_analyzer_shared/test/metadata/data/access/main.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void access3() {}
4848

4949
@Helper(Class)
5050
/*member: access4:
51-
NullAwarePropertyGet(Class)*/
51+
TypeLiteral(Class)*/
5252
void access4() {}
5353

5454
@Helper(Class.new)
@@ -93,7 +93,7 @@ void access12() {}
9393

9494
@Helper(self.Class)
9595
/*member: access13:
96-
NullAwarePropertyGet(Class)*/
96+
TypeLiteral(Class)*/
9797
void access13() {}
9898

9999
@Helper(self.Class.new)
@@ -123,7 +123,7 @@ void access18() {}
123123

124124
@Helper(dynamic)
125125
/*member: access19:
126-
NullAwarePropertyGet(dynamic)*/
126+
TypeLiteral(dynamic)*/
127127
void access19() {}
128128

129129
@Helper(Alias.new)
@@ -178,7 +178,7 @@ void access29() {}
178178

179179
@Helper(dynamic)
180180
/*member: access30:
181-
NullAwarePropertyGet(dynamic)*/
181+
TypeLiteral(dynamic)*/
182182
void access30() {}
183183

184184
@Helper(self.Alias.new)

0 commit comments

Comments
 (0)