Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add builder classes, make them the only parameter to macro methods #115

Merged
merged 13 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 53 additions & 47 deletions goldens/foo/lib/json_codable_test.analyzer.augmentations
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import 'package:foo/json_codable_test.dart' as prefix1;
augment class A {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external A.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment A.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
boolField = json[r'boolField'] as prefix0.bool,
stringField = json[r'stringField'] as prefix0.String,
intField = json[r'intField'] as prefix0.int,
doubleField = json[r'doubleField'] as prefix0.double,
numField = json[r'numField'] as prefix0.num,
listOfSerializableField = [for (final item in json[r'listOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
setOfSerializableField = {for (final item in json[r'setOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
mapOfSerializableField = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfSerializableField'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)};

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment A.fromJson(json)
: boolField = json[r'boolField'] as prefix0.bool,
stringField = json[r'stringField'] as prefix0.String,
intField = json[r'intField'] as prefix0.int,
doubleField = json[r'doubleField'] as prefix0.double,
numField = json[r'numField'] as prefix0.num,
listOfSerializableField = [for (final item in json[r'listOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
setOfSerializableField = {for (final item in json[r'setOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
mapOfSerializableField = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfSerializableField'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)};
augment toJson() {
final json = <prefix0.String, prefix0.Object?>{};
json[r'boolField'] = boolField;
json[r'stringField'] = stringField;
Expand All @@ -36,19 +37,20 @@ json[r'mapOfSerializableField'] = {for (final prefix0.MapEntry(:key, :value) in
augment class B {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external B.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment B.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
nullableBoolField = json[r'nullableBoolField'] as prefix0.bool?,
nullableStringField = json[r'nullableStringField'] as prefix0.String?,
nullableIntField = json[r'nullableIntField'] as prefix0.int?,
nullableDoubleField = json[r'nullableDoubleField'] as prefix0.double?,
nullableNumField = json[r'nullableNumField'] as prefix0.num?,
nullableListOfSerializableField = json[r'nullableListOfSerializableField'] == null ? null : [for (final item in json[r'nullableListOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
nullableSetOfSerializableField = json[r'nullableSetOfSerializableField'] == null ? null : {for (final item in json[r'nullableSetOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
nullableMapOfSerializableField = json[r'nullableMapOfSerializableField'] == null ? null : {for (final prefix0.MapEntry(:key, :value) in (json[r'nullableMapOfSerializableField'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)};

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment B.fromJson(json)
: nullableBoolField = json[r'nullableBoolField'] as prefix0.bool?,
nullableStringField = json[r'nullableStringField'] as prefix0.String?,
nullableIntField = json[r'nullableIntField'] as prefix0.int?,
nullableDoubleField = json[r'nullableDoubleField'] as prefix0.double?,
nullableNumField = json[r'nullableNumField'] as prefix0.num?,
nullableListOfSerializableField = json[r'nullableListOfSerializableField'] == null ? null : [for (final item in json[r'nullableListOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
nullableSetOfSerializableField = json[r'nullableSetOfSerializableField'] == null ? null : {for (final item in json[r'nullableSetOfSerializableField'] as prefix0.List<prefix0.Object?>) prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
nullableMapOfSerializableField = json[r'nullableMapOfSerializableField'] == null ? null : {for (final prefix0.MapEntry(:key, :value) in (json[r'nullableMapOfSerializableField'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)};
augment toJson() {
final json = <prefix0.String, prefix0.Object?>{};
if (nullableBoolField != null) {
json[r'nullableBoolField'] = nullableBoolField;
Expand Down Expand Up @@ -82,12 +84,13 @@ json[r'nullableMapOfSerializableField'] = nullableMapOfSerializableField == null
augment class C {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external C.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment C.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
x = json[r'x'] as prefix0.int;

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment C.fromJson(json)
: x = json[r'x'] as prefix0.int;
augment toJson() {
final json = <prefix0.String, prefix0.Object?>{};
json[r'x'] = x;

Expand All @@ -98,13 +101,14 @@ json[r'x'] = x;
augment class D {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external D.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment D.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
y = json[r'y'] as prefix0.String,
super.fromJson(json);

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment D.fromJson(json)
: y = json[r'y'] as prefix0.String,
super.fromJson(json);
augment toJson() {
final json = super.toJson();
json[r'y'] = y;

Expand All @@ -115,20 +119,21 @@ json[r'y'] = y;
augment class E {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external E.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment E.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
listOfNullableInts = [for (final item in json[r'listOfNullableInts'] as prefix0.List<prefix0.Object?>) item as prefix0.int?],
listOfNullableSerializables = [for (final item in json[r'listOfNullableSerializables'] as prefix0.List<prefix0.Object?>) item == null ? null : prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
listOfNullableMapsOfNullableInts = [for (final item in json[r'listOfNullableMapsOfNullableInts'] as prefix0.List<prefix0.Object?>) item == null ? null : {for (final prefix0.MapEntry(:key, :value) in (item as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?}],
setOfNullableInts = {for (final item in json[r'setOfNullableInts'] as prefix0.List<prefix0.Object?>) item as prefix0.int?},
setOfNullableSerializables = {for (final item in json[r'setOfNullableSerializables'] as prefix0.List<prefix0.Object?>) item == null ? null : prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
setOfNullableMapsOfNullableInts = {for (final item in json[r'setOfNullableMapsOfNullableInts'] as prefix0.List<prefix0.Object?>) item == null ? null : {for (final prefix0.MapEntry(:key, :value) in (item as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?}},
mapOfNullableInts = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableInts'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?},
mapOfNullableSerializables = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableSerializables'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value == null ? null : prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)},
mapOfNullableSetsOfNullableInts = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableSetsOfNullableInts'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value == null ? null : {for (final item in value as prefix0.List<prefix0.Object?>) item as prefix0.int?}};

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment E.fromJson(json)
: listOfNullableInts = [for (final item in json[r'listOfNullableInts'] as prefix0.List<prefix0.Object?>) item as prefix0.int?],
listOfNullableSerializables = [for (final item in json[r'listOfNullableSerializables'] as prefix0.List<prefix0.Object?>) item == null ? null : prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)],
listOfNullableMapsOfNullableInts = [for (final item in json[r'listOfNullableMapsOfNullableInts'] as prefix0.List<prefix0.Object?>) item == null ? null : {for (final prefix0.MapEntry(:key, :value) in (item as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?}],
setOfNullableInts = {for (final item in json[r'setOfNullableInts'] as prefix0.List<prefix0.Object?>) item as prefix0.int?},
setOfNullableSerializables = {for (final item in json[r'setOfNullableSerializables'] as prefix0.List<prefix0.Object?>) item == null ? null : prefix1.C.fromJson(item as prefix0.Map<prefix0.String, prefix0.Object?>)},
setOfNullableMapsOfNullableInts = {for (final item in json[r'setOfNullableMapsOfNullableInts'] as prefix0.List<prefix0.Object?>) item == null ? null : {for (final prefix0.MapEntry(:key, :value) in (item as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?}},
mapOfNullableInts = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableInts'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value as prefix0.int?},
mapOfNullableSerializables = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableSerializables'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value == null ? null : prefix1.C.fromJson(value as prefix0.Map<prefix0.String, prefix0.Object?>)},
mapOfNullableSetsOfNullableInts = {for (final prefix0.MapEntry(:key, :value) in (json[r'mapOfNullableSetsOfNullableInts'] as prefix0.Map<prefix0.String, prefix0.Object?>).entries) key: value == null ? null : {for (final item in value as prefix0.List<prefix0.Object?>) item as prefix0.int?}};
augment toJson() {
final json = <prefix0.String, prefix0.Object?>{};
json[r'listOfNullableInts'] = [for (final item in listOfNullableInts) item];
json[r'listOfNullableSerializables'] = [for (final item in listOfNullableSerializables) item == null ? null : item.toJson()];
Expand All @@ -147,12 +152,13 @@ json[r'mapOfNullableSetsOfNullableInts'] = {for (final prefix0.MapEntry(:key, :
augment class F {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external F.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);

// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external prefix0.Map<prefix0.String, prefix0.Object?> toJson();

augment F.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json) :
fieldWithDollarSign$ = json[r'fieldWithDollarSign$'] as prefix0.int;

augment prefix0.Map<prefix0.String, prefix0.Object?> toJson() {
augment F.fromJson(json)
: fieldWithDollarSign$ = json[r'fieldWithDollarSign$'] as prefix0.int;
augment toJson() {
final json = <prefix0.String, prefix0.Object?>{};
json[r'fieldWithDollarSign$'] = fieldWithDollarSign$;

Expand Down
34 changes: 19 additions & 15 deletions pkgs/_analyzer_macros/lib/macro_implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,20 +168,28 @@ class AnalyzerMacroExecutionResult
macros_api_v1.MacroTarget target, AugmentResponse augmentResponse) async {
final declarations = <macros_api_v1.DeclarationCode>[];
if (augmentResponse.typeAugmentations?.isNotEmpty == true) {
// 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)));
// TODO: Handle targets that are not interfaces, or test that this works
// already.
for (final entry in augmentResponse.typeAugmentations!.entries) {
jakemac53 marked this conversation as resolved.
Show resolved Hide resolved
if (entry.key != target.qualifiedName.name) {
throw UnimplementedError(
'Type augmentations are only implemented when the type is the '
'target of the augmentation, expected '
'${target.qualifiedName.name} but got ${entry.key}');
}
for (final augmentation in entry.value) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
}
}
}

for (final augmentation
in augmentResponse.libraryAugmentations ?? const <Augmentation>[]) {
declarations.add(macros_api_v1.DeclarationCode.fromParts(
await _resolveNames(augmentation.code)));
}

if (augmentResponse.enumValueAugmentations?.isNotEmpty == true) {
throw UnimplementedError('Enum value augmentations are not implemented');
}
Expand All @@ -190,10 +198,6 @@ class AnalyzerMacroExecutionResult
augmentResponse.mixinAugmentations?.isNotEmpty == true) {
throw UnimplementedError('Type augmentations are not implemented');
}
if (augmentResponse.libraryAugmentations?.isNotEmpty == true ||
augmentResponse.newTypeNames?.isNotEmpty == true) {
throw UnimplementedError('Library augmentations are not implemented');
}

return AnalyzerMacroExecutionResult(target, declarations);
}
Expand Down
5 changes: 5 additions & 0 deletions pkgs/_macro_client/lib/macro_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ class MacroClient {
}
}

/// Interface for the remote Host API for macros to query against.
abstract class Host {
Future<Model> query(Query query);
}

/// [Host] that is connected to a remote macro host.
///
/// Wraps `MacroClient` exposing just what should be available to the macro.
Expand Down
Loading