Skip to content

Commit 1b99100

Browse files
jakemac53Commit Queue
authored and
Commit Queue
committed
Add API for resolving any identifier in the final macro phase.
- Rename declarationOf to typeDeclarationOf. - Add declarationOf api for general declarations. - Tighten the type of typeDeclarationOf in the final phase to avoid unnecessary casts in user code. - Refactor message handling a bit to unify the error handling. Bug: dart-lang/language#3216 Change-Id: Ia61da19374abec77853d37e110a08f7dfe0d3b10 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314280 Commit-Queue: Jake Macdonald <[email protected]> Auto-Submit: Jake Macdonald <[email protected]> Reviewed-by: Bob Nystrom <[email protected]>
1 parent 4893acd commit 1b99100

File tree

11 files changed

+334
-316
lines changed

11 files changed

+334
-316
lines changed

pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ abstract interface class DeclarationPhaseIntrospector
9090
///
9191
/// In the definition phase, this will return [IntrospectableType] instances
9292
/// for all type definitions which can have members (ie: not type aliases).
93-
Future<TypeDeclaration> declarationOf(covariant Identifier identifier);
93+
Future<TypeDeclaration> typeDeclarationOf(covariant Identifier identifier);
9494
}
9595

9696
/// The API used by [Macro]s to contribute new (non-type)
@@ -123,6 +123,16 @@ abstract interface class EnumDeclarationBuilder
123123
/// phase (and later).
124124
abstract interface class DefinitionPhaseIntrospector
125125
implements DeclarationPhaseIntrospector {
126+
/// Resolves any [identifier] to its [Declaration].
127+
///
128+
/// This will return [IntrospectableType] instances for type declarations.
129+
Future<Declaration> declarationOf(covariant Identifier identifier);
130+
131+
/// Resolves an [identifier] referring to a type to its [IntrospectableType]
132+
/// declaration.
133+
@override
134+
Future<IntrospectableType> typeDeclarationOf(covariant Identifier identifier);
135+
126136
/// Infers a real type annotation for [omittedType].
127137
///
128138
/// If no type could be inferred, then a type annotation representing the

pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ abstract class DeclarationBuilderBase extends TypeBuilderBase
7373
super.parentLibraryAugmentations});
7474

7575
@override
76-
Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) =>
77-
introspector.declarationOf(identifier);
76+
Future<TypeDeclaration> typeDeclarationOf(IdentifierImpl identifier) =>
77+
introspector.typeDeclarationOf(identifier);
7878

7979
@override
8080
Future<List<ConstructorDeclaration>> constructorsOf(
@@ -160,13 +160,21 @@ class DefinitionBuilderBase extends DeclarationBuilderBase
160160
super.parentLibraryAugmentations,
161161
});
162162

163+
@override
164+
Future<Declaration> declarationOf(Identifier identifier) =>
165+
introspector.declarationOf(identifier);
166+
163167
@override
164168
Future<TypeAnnotation> inferType(OmittedTypeAnnotationImpl omittedType) =>
165169
introspector.inferType(omittedType);
166170

167171
@override
168172
Future<List<Declaration>> topLevelDeclarationsOf(Library library) =>
169173
introspector.topLevelDeclarationsOf(library);
174+
175+
@override
176+
Future<IntrospectableType> typeDeclarationOf(Identifier identifier) =>
177+
introspector.typeDeclarationOf(identifier);
170178
}
171179

172180
class TypeDefinitionBuilderImpl extends DefinitionBuilderBase

pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart

Lines changed: 196 additions & 250 deletions
Large diffs are not rendered by default.

pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -500,23 +500,32 @@ class TypeIntrospectorRequest extends IntrospectionRequest {
500500
}
501501
}
502502

503-
/// A request to get a [TypeDeclaration] for a [StaticType].
503+
/// A request to get a [Declaration] for an [identifier].
504+
///
505+
/// Used for both the `typeDeclarationOf` and `declarationOf` requests. A cast
506+
/// is done on the client side to ensure only [TypeDeclaration]s are returned
507+
/// from `typeDeclarationOf`.
504508
class DeclarationOfRequest extends IntrospectionRequest {
505509
final IdentifierImpl identifier;
510+
final MessageType kind;
506511

507-
DeclarationOfRequest(this.identifier, super.introspector,
508-
{required super.serializationZoneId});
512+
DeclarationOfRequest(this.identifier, this.kind, super.introspector,
513+
{required super.serializationZoneId})
514+
: assert(kind == MessageType.typeDeclarationOfRequest ||
515+
kind == MessageType.declarationOfRequest);
509516

510517
/// When deserializing we have already consumed the message type, so we don't
511518
/// consume it again.
512519
DeclarationOfRequest.deserialize(
513-
super.deserializer, super.serializationZoneId)
514-
: identifier = RemoteInstance.deserialize(deserializer),
520+
super.deserializer, super.serializationZoneId, this.kind)
521+
: assert(kind == MessageType.typeDeclarationOfRequest ||
522+
kind == MessageType.declarationOfRequest),
523+
identifier = RemoteInstance.deserialize(deserializer),
515524
super.deserialize();
516525

517526
@override
518527
void serialize(Serializer serializer) {
519-
serializer.addInt(MessageType.declarationOfRequest.index);
528+
serializer.addInt(kind.index);
520529
identifier.serialize(serializer);
521530
super.serialize(serializer);
522531
}
@@ -686,9 +695,9 @@ final class ClientDeclarationPhaseIntrospector
686695
}
687696

688697
@override
689-
Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) async {
698+
Future<TypeDeclaration> typeDeclarationOf(IdentifierImpl identifier) async {
690699
DeclarationOfRequest request = new DeclarationOfRequest(
691-
identifier, remoteInstance,
700+
identifier, MessageType.typeDeclarationOfRequest, remoteInstance,
692701
serializationZoneId: serializationZoneId);
693702
return _handleResponse<TypeDeclaration>(await _sendRequest(request));
694703
}
@@ -731,6 +740,14 @@ final class ClientDefinitionPhaseIntrospector
731740
ClientDefinitionPhaseIntrospector(super._sendRequest,
732741
{required super.remoteInstance, required super.serializationZoneId});
733742

743+
@override
744+
Future<Declaration> declarationOf(IdentifierImpl identifier) async {
745+
DeclarationOfRequest request = new DeclarationOfRequest(
746+
identifier, MessageType.declarationOfRequest, remoteInstance,
747+
serializationZoneId: serializationZoneId);
748+
return _handleResponse<Declaration>(await _sendRequest(request));
749+
}
750+
734751
@override
735752
Future<TypeAnnotation> inferType(
736753
OmittedTypeAnnotationImpl omittedType) async {
@@ -747,6 +764,15 @@ final class ClientDefinitionPhaseIntrospector
747764
return _handleResponse<DeclarationList>(await _sendRequest(request))
748765
.declarations;
749766
}
767+
768+
@override
769+
Future<IntrospectableType> typeDeclarationOf(
770+
IdentifierImpl identifier) async {
771+
DeclarationOfRequest request = new DeclarationOfRequest(
772+
identifier, MessageType.typeDeclarationOfRequest, remoteInstance,
773+
serializationZoneId: serializationZoneId);
774+
return _handleResponse<IntrospectableType>(await _sendRequest(request));
775+
}
750776
}
751777

752778
/// An exception that occurred remotely, the exception object and stack trace
@@ -803,5 +829,6 @@ enum MessageType {
803829
response,
804830
staticType,
805831
topLevelDeclarationsOfRequest,
832+
typeDeclarationOfRequest,
806833
typesOfRequest,
807834
}

pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,20 @@ Future<void> checkClassDeclaration(ClassDeclaration declaration,
127127
TypeDeclaration? superclass = declaration.superclass == null
128128
? null
129129
: await introspector
130-
.declarationOf(declaration.superclass!.identifier);
130+
.typeDeclarationOf(declaration.superclass!.identifier);
131131
expect(
132132
expected.superclass, superclass?.identifier.name, '$name.superclass');
133133
if (superclass is ClassDeclaration) {
134134
TypeDeclaration? superSuperclass = superclass.superclass == null
135135
? null
136136
: await introspector
137-
.declarationOf(superclass.superclass!.identifier);
137+
.typeDeclarationOf(superclass.superclass!.identifier);
138138
expect(expected.superSuperclass, superSuperclass?.identifier.name,
139139
'$name.superSuperclass');
140140
}
141141
List<TypeDeclaration> mixins = [
142142
for (NamedTypeAnnotation mixin in declaration.mixins)
143-
await introspector.declarationOf(mixin.identifier),
143+
await introspector.typeDeclarationOf(mixin.identifier),
144144
];
145145
expect(expected.mixins.length, mixins.length, '$name.mixins.length');
146146
for (int i = 0; i < mixins.length; i++) {
@@ -150,7 +150,7 @@ Future<void> checkClassDeclaration(ClassDeclaration declaration,
150150

151151
List<TypeDeclaration> interfaces = [
152152
for (NamedTypeAnnotation interface in declaration.interfaces)
153-
await introspector.declarationOf(interface.identifier),
153+
await introspector.typeDeclarationOf(interface.identifier),
154154
];
155155
expect(expected.interfaces.length, interfaces.length,
156156
'$name.interfaces.length');
@@ -263,13 +263,13 @@ Future<void> checkTypeDeclarationResolver(
263263
{bool expectThrows = false}) async {
264264
if (expectThrows) {
265265
await throws(() async {
266-
await introspector.declarationOf(identifier);
266+
await introspector.typeDeclarationOf(identifier);
267267
}, '$name from $identifier',
268268
expectedError: (e) => e is! ArgumentError
269269
? 'Expected ArgumentError, got ${e.runtimeType}: $e'
270270
: null);
271271
} else {
272-
TypeDeclaration result = await introspector.declarationOf(identifier);
272+
TypeDeclaration result = await introspector.typeDeclarationOf(identifier);
273273
expect(name, result.identifier.name, '$name from $identifier');
274274
}
275275
}

pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class SimpleMacro
107107
@override
108108
FutureOr<void> buildDeclarationsForEnumValue(
109109
EnumValueDeclaration value, EnumDeclarationBuilder builder) async {
110-
final parent = await builder.declarationOf(value.definingEnum);
110+
final parent = await builder.typeDeclarationOf(value.definingEnum);
111111
builder.declareInType(DeclarationCode.fromParts([
112112
parent.identifier,
113113
' ${value.identifier.name}ToString() => ',
@@ -256,7 +256,7 @@ class SimpleMacro
256256
@override
257257
FutureOr<void> buildDefinitionForEnumValue(
258258
EnumValueDeclaration value, EnumValueDefinitionBuilder builder) async {
259-
final parent = await builder.declarationOf(value.definingEnum)
259+
final parent = await builder.typeDeclarationOf(value.definingEnum)
260260
as IntrospectableEnumDeclaration;
261261
final constructor = (await builder.constructorsOf(parent)).first;
262262
final parts = [
@@ -302,8 +302,7 @@ class SimpleMacro
302302
await buildDefinitionForFunction(method, builder);
303303

304304
// Test the type declaration resolver
305-
var parentClass =
306-
await builder.declarationOf(method.definingType) as IntrospectableType;
305+
var parentClass = await builder.typeDeclarationOf(method.definingType);
307306
// Should be able to find ourself in the methods of the parent class.
308307
(await builder.methodsOf(parentClass))
309308
.singleWhere((m) => m.identifier == method.identifier);
@@ -315,22 +314,22 @@ class SimpleMacro
315314
// Test the class introspector
316315
if (parentClass is IntrospectableClassDeclaration) {
317316
superClass =
318-
(await builder.declarationOf(parentClass.superclass!.identifier));
319-
interfaces.addAll(await Future.wait(parentClass.interfaces
320-
.map((interface) => builder.declarationOf(interface.identifier))));
317+
(await builder.typeDeclarationOf(parentClass.superclass!.identifier));
318+
interfaces.addAll(await Future.wait(parentClass.interfaces.map(
319+
(interface) => builder.typeDeclarationOf(interface.identifier))));
321320
mixins.addAll(await Future.wait(parentClass.mixins
322-
.map((mixins) => builder.declarationOf(mixins.identifier))));
321+
.map((mixins) => builder.typeDeclarationOf(mixins.identifier))));
323322
} else if (parentClass is IntrospectableMixinDeclaration) {
324-
superclassConstraints.addAll(await Future.wait(parentClass
325-
.superclassConstraints
326-
.map((interface) => builder.declarationOf(interface.identifier))));
327-
interfaces.addAll(await Future.wait(parentClass.interfaces
328-
.map((interface) => builder.declarationOf(interface.identifier))));
323+
superclassConstraints.addAll(await Future.wait(
324+
parentClass.superclassConstraints.map(
325+
(interface) => builder.typeDeclarationOf(interface.identifier))));
326+
interfaces.addAll(await Future.wait(parentClass.interfaces.map(
327+
(interface) => builder.typeDeclarationOf(interface.identifier))));
329328
} else if (parentClass is IntrospectableEnumDeclaration) {
330-
interfaces.addAll(await Future.wait(parentClass.interfaces
331-
.map((interface) => builder.declarationOf(interface.identifier))));
329+
interfaces.addAll(await Future.wait(parentClass.interfaces.map(
330+
(interface) => builder.typeDeclarationOf(interface.identifier))));
332331
mixins.addAll(await Future.wait(parentClass.mixins
333-
.map((mixins) => builder.declarationOf(mixins.identifier))));
332+
.map((mixins) => builder.typeDeclarationOf(mixins.identifier))));
334333
}
335334
var fields = (await builder.fieldsOf(parentClass));
336335
var methods = (await builder.methodsOf(parentClass));

pkg/_fe_analyzer_shared/test/macros/util.dart

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class TestDeclarationPhaseIntrospector extends TestTypePhaseIntrospector
2929
final Map<IntrospectableType, List<MethodDeclaration>> methods;
3030
final Map<Library, List<TypeDeclaration>> libraryTypes;
3131
final Map<Identifier, StaticType> staticTypes;
32-
final Map<Identifier, TypeDeclaration> typeDeclarations;
32+
final Map<Identifier, Declaration> identifierDeclarations;
3333

3434
TestDeclarationPhaseIntrospector(
3535
{required this.constructors,
@@ -38,12 +38,13 @@ class TestDeclarationPhaseIntrospector extends TestTypePhaseIntrospector
3838
required this.methods,
3939
required this.libraryTypes,
4040
required this.staticTypes,
41-
required this.typeDeclarations});
41+
required this.identifierDeclarations});
4242

4343
@override
44-
Future<TypeDeclaration> declarationOf(covariant Identifier identifier) async {
45-
var declaration = typeDeclarations[identifier];
46-
if (declaration != null) return declaration;
44+
Future<TypeDeclaration> typeDeclarationOf(
45+
covariant Identifier identifier) async {
46+
var declaration = identifierDeclarations[identifier];
47+
if (declaration != null) return declaration as TypeDeclaration;
4748
throw 'No declaration found for ${identifier.name}';
4849
}
4950

@@ -113,17 +114,23 @@ class TestDefinitionsPhaseIntrospector extends TestDeclarationPhaseIntrospector
113114
required super.methods,
114115
required super.libraryTypes,
115116
required super.staticTypes,
116-
required super.typeDeclarations});
117+
required super.identifierDeclarations});
118+
@override
119+
Future<Declaration> declarationOf(Identifier identifier) async =>
120+
identifierDeclarations[identifier]!;
117121

118122
@override
119123
Future<TypeAnnotation> inferType(
120124
TestOmittedTypeAnnotation omittedType) async =>
121125
omittedType.inferredType!;
122126

123127
@override
124-
Future<List<Declaration>> topLevelDeclarationsOf(
125-
covariant Library library) async =>
128+
Future<List<Declaration>> topLevelDeclarationsOf(Library library) async =>
126129
libraryDeclarations[library]!;
130+
131+
@override
132+
Future<IntrospectableType> typeDeclarationOf(Identifier identifier) async =>
133+
(await super.typeDeclarationOf(identifier)) as IntrospectableType;
127134
}
128135

129136
/// Knows its inferred type ahead of time.
@@ -493,7 +500,7 @@ class Fixtures {
493500
type: stringType,
494501
definingType: myClassType.identifier,
495502
isStatic: false);
496-
static final myInterface = ClassDeclarationImpl(
503+
static final myInterface = IntrospectableClassDeclarationImpl(
497504
id: RemoteInstance.uniqueId,
498505
identifier: myInterfaceType.identifier,
499506
library: Fixtures.library,
@@ -525,7 +532,7 @@ class Fixtures {
525532
typeParameters: [],
526533
definingType: myClassType.identifier,
527534
isStatic: false);
528-
static final mySuperclass = ClassDeclarationImpl(
535+
static final mySuperclass = IntrospectableClassDeclarationImpl(
529536
id: RemoteInstance.uniqueId,
530537
identifier: mySuperclassType.identifier,
531538
library: Fixtures.library,
@@ -648,12 +655,18 @@ class Fixtures {
648655
stringType.identifier:
649656
TestNamedStaticType(stringType.identifier, 'dart:core', []),
650657
myClass.identifier: myClassStaticType,
651-
}, typeDeclarations: {
658+
}, identifierDeclarations: {
652659
myClass.identifier: myClass,
653660
myEnum.identifier: myEnum,
654661
mySuperclass.identifier: mySuperclass,
655662
myInterface.identifier: myInterface,
656-
myMixin.identifier: myMixin
663+
myMixin.identifier: myMixin,
664+
myConstructor.identifier: myConstructor,
665+
myEnumConstructor.identifier: myEnumConstructor,
666+
for (EnumValueDeclaration value in myEnumValues) value.identifier: value,
667+
myField.identifier: myField,
668+
myMixinMethod.identifier: myMixinMethod,
669+
myMethod.identifier: myMethod,
657670
});
658671

659672
static final testDefinitionPhaseIntrospector =
@@ -674,5 +687,6 @@ class Fixtures {
674687
},
675688
libraryTypes: testDeclarationPhaseIntrospector.libraryTypes,
676689
staticTypes: testDeclarationPhaseIntrospector.staticTypes,
677-
typeDeclarations: testDeclarationPhaseIntrospector.typeDeclarations);
690+
identifierDeclarations:
691+
testDeclarationPhaseIntrospector.identifierDeclarations);
678692
}

pkg/analyzer/lib/src/summary2/macro_application.dart

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -498,18 +498,6 @@ class _DeclarationPhaseIntrospector extends _TypePhaseIntrospector
498498
throw UnimplementedError();
499499
}
500500

501-
@override
502-
Future<macro.TypeDeclaration> declarationOf(
503-
covariant IdentifierImpl identifier,
504-
) async {
505-
final element = identifier.element;
506-
if (element is ClassElementImpl) {
507-
return declarationBuilder.fromElement.classElement(element);
508-
} else {
509-
throw ArgumentError('element: $element');
510-
}
511-
}
512-
513501
@override
514502
Future<List<macro.FieldDeclaration>> fieldsOf(
515503
covariant macro.IntrospectableType type,
@@ -536,6 +524,18 @@ class _DeclarationPhaseIntrospector extends _TypePhaseIntrospector
536524
return _StaticTypeImpl(typeSystem, dartType);
537525
}
538526

527+
@override
528+
Future<macro.TypeDeclaration> typeDeclarationOf(
529+
covariant IdentifierImpl identifier,
530+
) async {
531+
final element = identifier.element;
532+
if (element is ClassElementImpl) {
533+
return declarationBuilder.fromElement.classElement(element);
534+
} else {
535+
throw ArgumentError('element: $element');
536+
}
537+
}
538+
539539
@override
540540
Future<List<macro.TypeDeclaration>> typesOf(covariant macro.Library library) {
541541
// TODO: implement typesOf

0 commit comments

Comments
 (0)