Skip to content

Commit

Permalink
fill out all the fields for AugmentResponse, update everything
Browse files Browse the repository at this point in the history
  • Loading branch information
jakemac53 committed Oct 17, 2024
1 parent 1166d91 commit e94930d
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 36 deletions.
30 changes: 27 additions & 3 deletions pkgs/_analyzer_macros/lib/macro_implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,34 @@ class AnalyzerMacroExecutionResult
static Future<AnalyzerMacroExecutionResult> dartModelToInjected(
macros_api_v1.MacroTarget target, AugmentResponse augmentResponse) async {
final declarations = <macros_api_v1.DeclarationCode>[];
for (final augmentation in augmentResponse.augmentations) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
if (augmentResponse.typeAugmentations.isNotEmpty) {
// TODO: Handle multiple type augmentations, or augmentations where the
// target is itself a member of a type and not the type.
final entry = augmentResponse.typeAugmentations.entries.single;
if (entry.key != target.qualifiedName.name) {
throw UnimplementedError(
'Type augmentations are only implemented when the type is the '
'target of the augmentation.');
}
for (final augmentation in entry.value) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
}
}

if (augmentResponse.enumValueAugmentations.isNotEmpty) {
throw UnimplementedError('Enum value augmentations are not implemented');
}
if (augmentResponse.extendsTypeAugmentations.isNotEmpty ||
augmentResponse.interfaceAugmentations.isNotEmpty ||
augmentResponse.mixinAugmentations.isNotEmpty) {
throw UnimplementedError('Type augmentations are not implemented');
}
if (augmentResponse.libraryAugmentations.isNotEmpty ||
augmentResponse.newTypeNames.isNotEmpty) {
throw UnimplementedError('Library augmentations are not implemented');
}

return AnalyzerMacroExecutionResult(target, declarations);
}

Expand Down
30 changes: 27 additions & 3 deletions pkgs/_cfe_macros/lib/macro_implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,34 @@ class CfeMacroExecutionResult implements macros_api_v1.MacroExecutionResult {
static Future<CfeMacroExecutionResult> dartModelToInjected(
macros_api_v1.MacroTarget target, AugmentResponse augmentResponse) async {
final declarations = <macros_api_v1.DeclarationCode>[];
for (final augmentation in augmentResponse.augmentations) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
if (augmentResponse.typeAugmentations.isNotEmpty) {
// TODO: Handle multiple type augmentations, or augmentations where the
// target is itself a member of a type and not the type.
final entry = augmentResponse.typeAugmentations.entries.single;
if (entry.key != target.qualifiedName.name) {
throw UnimplementedError(
'Type augmentations are only implemented when the type is the '
'target of the augmentation.');
}
for (final augmentation in entry.value) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
}
}

if (augmentResponse.enumValueAugmentations.isNotEmpty) {
throw UnimplementedError('Enum value augmentations are not implemented');
}
if (augmentResponse.extendsTypeAugmentations.isNotEmpty ||
augmentResponse.interfaceAugmentations.isNotEmpty ||
augmentResponse.mixinAugmentations.isNotEmpty) {
throw UnimplementedError('Type augmentations are not implemented');
}
if (augmentResponse.libraryAugmentations.isNotEmpty ||
augmentResponse.newTypeNames.isNotEmpty) {
throw UnimplementedError('Library augmentations are not implemented');
}

return CfeMacroExecutionResult(target, declarations);
}

Expand Down
2 changes: 1 addition & 1 deletion pkgs/_macro_client/lib/macro_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class MacroClient {
'Unexpected phase ${augmentRequest.phase}, '
'expected 1, 2, or 3.')
} ??
AugmentResponse(augmentations: []),
AugmentResponse(),
requestId: hostRequest.id)));
}
default:
Expand Down
22 changes: 12 additions & 10 deletions pkgs/_macro_host/test/macro_host_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ void main() {
phase: 2,
target: QualifiedName(
name: 'Foo', uri: 'package:foo/foo.dart'))),
Scope.macro.run(() => AugmentResponse(augmentations: [
Augmentation(code: [Code.string('int get x => 3;')])
])));
Scope.macro.run(() => AugmentResponse()
..typeAugmentations['Foo'] = [
Augmentation(code: [Code.string('int get x => 3;')])
]));
});

test('hosts a macro, responds to queries', () async {
Expand All @@ -67,13 +68,14 @@ void main() {
phase: 3,
target: QualifiedName(
uri: 'package:foo/foo.dart', name: 'Foo'))),
Scope.macro.run(() => AugmentResponse(augmentations: [
Augmentation(code: [
Code.string(
'// {"uris":{"package:foo/foo.dart":{"scopes":{"Foo":{'
'"members":{},"properties":{"isClass":true}}}}}}')
])
])));
Scope.macro.run(() => AugmentResponse()
..typeAugmentations['Foo'] = [
Augmentation(code: [
Code.string(
'// {"uris":{"package:foo/foo.dart":{"scopes":{"Foo":{'
'"members":{},"properties":{"isClass":true}}}}}}')
])
]));
});

test('hosts two macros', () async {
Expand Down
8 changes: 5 additions & 3 deletions pkgs/_test_macros/lib/declare_x_macro.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ class DeclareXImplementation implements ClassDeclarationsMacro {
Host host, AugmentRequest request) async {
// TODO(davidmorgan): make the host only run in the phases requested so
// that this is not needed.
if (request.phase != 2) return AugmentResponse(augmentations: []);
if (request.phase != 2) return AugmentResponse();

// TODO(davidmorgan): still need to pass through the augment target.
return AugmentResponse(
augmentations: [Augmentation(code: expandTemplate('int get x => 3;'))]);
return AugmentResponse()
..typeAugmentations[request.target.name] = [
Augmentation(code: expandTemplate('int get x => 3;'))
];
}
}
16 changes: 9 additions & 7 deletions pkgs/_test_macros/lib/json_codable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ class JsonCodableImplementation
Future<AugmentResponse> buildDeclarationsForClass(
Host host, AugmentRequest request) async {
final target = request.target;
return AugmentResponse(augmentations: [
Augmentation(code: expandTemplate('''
return AugmentResponse()
..typeAugmentations[request.target.name] = [
Augmentation(code: expandTemplate('''
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external ${target.name}.fromJson($_jsonMapType json);
// external $_jsonMapType toJson();
'''))
]);
];
}

@override
Expand All @@ -49,10 +50,11 @@ class JsonCodableImplementation
// TODO(davidmorgan): put `extends` information directly in `Interface`.
final superclassName = MacroScope.current.typeSystem.supertypeOf(target);

return AugmentResponse(augmentations: [
await _generateFromJson(host, model, target, superclassName, clazz),
await _generateToJson(host, model, target, superclassName, clazz)
]);
return AugmentResponse()
..typeAugmentations[request.target.name] = [
await _generateFromJson(host, model, target, superclassName, clazz),
await _generateToJson(host, model, target, superclassName, clazz)
];
}

Future<Augmentation> _generateFromJson(
Expand Down
7 changes: 4 additions & 3 deletions pkgs/_test_macros/lib/query_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class QueryClassImplementation implements ClassDefinitionsMacro {
final model = await host.query(Query(
target: request.target,
));
return AugmentResponse(augmentations: [
Augmentation(code: expandTemplate('// ${json.encode(model)}'))
]);
return AugmentResponse()
..typeAugmentations[request.target.name] = [
Augmentation(code: expandTemplate('// ${json.encode(model)}'))
];
}
}
42 changes: 39 additions & 3 deletions pkgs/macro_service/lib/src/macro_service.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,51 @@ extension type AugmentRequest.fromJson(Map<String, Object?> node)
/// Macro's response to an [AugmentRequest]: the resulting augmentations.
extension type AugmentResponse.fromJson(Map<String, Object?> node)
implements Object {
AugmentResponse()
: this.fromJson({
AugmentResponse({
List<Augmentation>? libraryAugmentations,
List<String>? newTypeNames,
}) : this.fromJson({
'enumValueAugmentations': {},
'extendsTypeAugmentations': {},
'interfaceAugmentations': {},
if (libraryAugmentations != null)
'libraryAugmentations': libraryAugmentations,
'mixinAugmentations': {},
if (newTypeNames != null) 'newTypeNames': newTypeNames,
'typeAugmentations': {},
});

/// Augmentations representing new enum values to add, indexed by name of the enum.
/// Any augmentations to enum values that should be applied to an enum as a result of executing a macro, indexed by the name of the enum.
Map<String, List<Augmentation>> get enumValueAugmentations =>
(node['enumValueAugmentations'] as Map)
.deepCast<String, List<Augmentation>>((v) => (v as List).cast());

/// Any extends clauses that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.
Map<String, List<Augmentation>> get extendsTypeAugmentations =>
(node['extendsTypeAugmentations'] as Map)
.deepCast<String, List<Augmentation>>((v) => (v as List).cast());

/// Any interfaces that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.
Map<String, List<Augmentation>> get interfaceAugmentations =>
(node['interfaceAugmentations'] as Map)
.deepCast<String, List<Augmentation>>((v) => (v as List).cast());

/// Any augmentations that should be applied to the library as a result of executing a macro.
List<Augmentation> get libraryAugmentations =>
(node['libraryAugmentations'] as List).cast();

/// Any mixins that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.
Map<String, List<Augmentation>> get mixinAugmentations =>
(node['mixinAugmentations'] as Map)
.deepCast<String, List<Augmentation>>((v) => (v as List).cast());

/// The names of any new types declared in [libraryAugmentations].
List<String> get newTypeNames => (node['newTypeNames'] as List).cast();

/// Any augmentations that should be applied to a class as a result of executing a macro, indexed by the name of the class.
Map<String, List<Augmentation>> get typeAugmentations =>
(node['typeAugmentations'] as Map)
.deepCast<String, List<Augmentation>>((v) => (v as List).cast());
}

/// Request could not be handled.
Expand Down
56 changes: 55 additions & 1 deletion schemas/macro_service.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,61 @@
"properties": {
"enumValueAugmentations": {
"type": "object",
"description": "Augmentations representing new enum values to add, indexed by name of the enum.",
"description": "Any augmentations to enum values that should be applied to an enum as a result of executing a macro, indexed by the name of the enum.",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "file:dart_model.schema.json#/$defs/Augmentation"
}
}
},
"extendsTypeAugmentations": {
"type": "object",
"description": "Any extends clauses that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "file:dart_model.schema.json#/$defs/Augmentation"
}
}
},
"interfaceAugmentations": {
"type": "object",
"description": "Any interfaces that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "file:dart_model.schema.json#/$defs/Augmentation"
}
}
},
"libraryAugmentations": {
"type": "array",
"description": "Any augmentations that should be applied to the library as a result of executing a macro.",
"items": {
"$ref": "file:dart_model.schema.json#/$defs/Augmentation"
}
},
"mixinAugmentations": {
"type": "object",
"description": "Any mixins that should be added to types as a result of executing a macro, indexed by the name of the augmented type declaration.",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "file:dart_model.schema.json#/$defs/Augmentation"
}
}
},
"newTypeNames": {
"type": "array",
"description": "The names of any new types declared in [libraryAugmentations].",
"items": {
"type": "string"
}
},
"typeAugmentations": {
"type": "object",
"description": "Any augmentations that should be applied to a class as a result of executing a macro, indexed by the name of the class.",
"additionalProperties": {
"type": "array",
"items": {
Expand Down
38 changes: 36 additions & 2 deletions tool/dart_model_generator/lib/definitions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,42 @@ static QualifiedName parse(String string) {
Property('enumValueAugmentations',
type: 'Map<List<Augmentation>>',
description:
'Augmentations representing new enum values to add, '
'indexed by name of the enum.'),
'Any augmentations to enum values that should be applied '
'to an enum as a result of executing a macro, indexed by '
'the name of the enum.'),
Property('extendsTypeAugmentations',
type: 'Map<List<Augmentation>>',
description:
'Any extends clauses that should be added to types as a '
'result of executing a macro, indexed by the name '
'of the augmented type declaration.'),
Property('interfaceAugmentations',
type: 'Map<List<Augmentation>>',
description:
'Any interfaces that should be added to types as a '
'result of executing a macro, indexed by the name '
'of the augmented type declaration.'),
Property('libraryAugmentations',
type: 'List<Augmentation>',
description:
'Any augmentations that should be applied to the library '
'as a result of executing a macro.'),
Property('mixinAugmentations',
type: 'Map<List<Augmentation>>',
description:
'Any mixins that should be added to types as a result of '
'executing a macro, indexed by the name of the '
'augmented type declaration.'),
Property('newTypeNames',
type: 'List<String>',
description: 'The names of any new types declared in '
'[libraryAugmentations].'),
Property('typeAugmentations',
type: 'Map<List<Augmentation>>',
description:
'Any augmentations that should be applied to a class as '
'a result of executing a macro, indexed by the '
'name of the class.'),
]),
Definition.clazz('ErrorResponse',
description: 'Request could not be handled.',
Expand Down

0 comments on commit e94930d

Please sign in to comment.