Skip to content

Commit

Permalink
@JsonCodable() supports super toJson and fromJson.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmorgan committed Oct 8, 2024
1 parent a3a5ec0 commit b584bbe
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 6 deletions.
188 changes: 188 additions & 0 deletions goldens/foo/lib/foo.analyzer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,85 @@
"scopes": {
"Foo": {
"members": {
"construct": {
"properties": {
"isAbstract": false,
"isConstructor": true,
"isGetter": false,
"isField": false,
"isMethod": false,
"isStatic": false
},
"requiredPositionalParameters": [
{
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
],
"optionalPositionalParameters": [],
"namedParameters": [
{
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
]
},
"construct2": {
"properties": {
"isAbstract": false,
"isConstructor": true,
"isGetter": false,
"isField": false,
"isMethod": false,
"isStatic": false
},
"requiredPositionalParameters": [
{
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
],
"optionalPositionalParameters": [
{
"type": "NullableTypeDesc",
"value": {
"inner": {
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "String"
},
"instantiation": []
}
}
}
}
],
"namedParameters": []
},
"bar": {
"properties": {
"isAbstract": false,
"isConstructor": false,
"isGetter": false,
"isField": true,
"isMethod": false,
Expand All @@ -22,14 +98,126 @@
"instantiation": []
}
}
},
"method": {
"properties": {
"isAbstract": false,
"isConstructor": false,
"isGetter": false,
"isField": false,
"isMethod": true,
"isStatic": false
},
"returnType": {
"type": "VoidTypeDesc"
},
"requiredPositionalParameters": [
{
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
],
"optionalPositionalParameters": [],
"namedParameters": [
{
"type": "NullableTypeDesc",
"value": {
"inner": {
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
}
}
]
},
"method2": {
"properties": {
"isAbstract": false,
"isConstructor": false,
"isGetter": false,
"isField": false,
"isMethod": true,
"isStatic": false
},
"returnType": {
"type": "NullableTypeDesc",
"value": {
"inner": {
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "package:foo/foo.dart",
"name": "Bar"
},
"instantiation": []
}
}
}
},
"requiredPositionalParameters": [
{
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "int"
},
"instantiation": []
}
}
],
"optionalPositionalParameters": [
{
"type": "NullableTypeDesc",
"value": {
"inner": {
"type": "NamedTypeDesc",
"value": {
"name": {
"uri": "dart:core",
"name": "String"
},
"instantiation": []
}
}
}
}
],
"namedParameters": []
}
}
},
"Bar": {
"members": {
"": {
"properties": {
"isAbstract": false,
"isConstructor": true,
"isGetter": false,
"isField": false,
"isMethod": false,
"isStatic": false
},
"requiredPositionalParameters": [],
"optionalPositionalParameters": [],
"namedParameters": []
},
"bar": {
"properties": {
"isAbstract": false,
"isConstructor": false,
"isGetter": false,
"isField": true,
"isMethod": false,
Expand Down
8 changes: 8 additions & 0 deletions goldens/foo/lib/foo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import 'package:_test_macros/query_class.dart';
@QueryClass()
class Foo {
final int bar = 3;

Foo.construct(int x, {required int y});
Foo.construct2(int x, [String? y]);

void method(int x, {int? y}) {}
Bar? method2(int x, [String? y]) {
return null;
}
}

@QueryClass()
Expand Down
17 changes: 17 additions & 0 deletions goldens/foo/lib/json_codable_test.analyzer.augmentations
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ json[r'x'] = x;
return json;
}

}
augment class D {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
// external D.fromJson(prefix0.Map<prefix0.String, prefix0.Object?> json);
// 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() {
final json = super.toJson();
json[r'y'] = y;

return json;
}

}
augment class E {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
Expand Down
10 changes: 6 additions & 4 deletions goldens/foo/lib/json_codable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ void main() {
expect(b.toJson(), isEmpty);
});

/* TODO(davidmorgan): make this test work.
test('class hierarchies', () {
var json = {
'x': 1,
Expand All @@ -118,7 +117,6 @@ void main() {

expect(d.toJson(), equals(json));
});
*/

test('collections of nullable objects', () {
var json = {
Expand Down Expand Up @@ -266,7 +264,6 @@ class C {
final int x;
}

/*
@JsonCodable()
class D extends C {
// TODO(davidmorgan): see https://github.com/dart-lang/macros/issues/80.
Expand All @@ -275,7 +272,6 @@ class D extends C {

final String y;
}
*/

@JsonCodable()
class E {
Expand Down Expand Up @@ -310,3 +306,9 @@ class F {

final int fieldWithDollarSign$;
}






63 changes: 63 additions & 0 deletions pkgs/_analyzer_macros/lib/query_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,53 @@ class AnalyzerQueryService implements QueryService {
..addInterfaceElement(clazz);

final interface = Interface();
for (final constructor in clazz.constructors) {
interface.members[constructor.name] = Member(
requiredPositionalParameters: constructor
.requiredPositionalParameters(types.translator, types.context),
optionalPositionalParameters: constructor
.optionalPositionalParameters(types.translator, types.context),
namedParameters:
constructor.namedParameters(types.translator, types.context),
properties: Properties(
isAbstract: constructor.isAbstract,
isConstructor: true,
isGetter: false,
isField: false,
isMethod: false,
isStatic: false,
));
}
for (final field in clazz.fields) {
interface.members[field.name] = Member(
properties: Properties(
isAbstract: field.isAbstract,
isConstructor: false,
isGetter: false,
isField: true,
isMethod: false,
isStatic: field.isStatic,
),
returnType: types.addDartType(field.type));
}
for (final method in clazz.methods) {
interface.members[method.name] = Member(
requiredPositionalParameters: method.requiredPositionalParameters(
types.translator, types.context),
optionalPositionalParameters: method.optionalPositionalParameters(
types.translator, types.context),
namedParameters:
method.namedParameters(types.translator, types.context),
properties: Properties(
isAbstract: method.isAbstract,
isConstructor: false,
isGetter: false,
isField: false,
isMethod: true,
isStatic: method.isStatic,
),
returnType: types.addDartType(method.returnType));
}
return Model(types: types.typeHierarchy)
..uris[uri] = (Library()..scopes[clazz.name] = interface);
}
Expand Down Expand Up @@ -105,3 +141,30 @@ class AnalyzerTypeHierarchy {
);
}
}

extension ExecutableElementExtension on ExecutableElement {
List<StaticTypeDesc> requiredPositionalParameters(
AnalyzerTypesToMacros translator, TypeTranslationContext context) {
return parameters
.where((p) => p.isRequiredPositional)
.map((p) => p.type.acceptWithArgument(translator, context))
.toList();
}

List<StaticTypeDesc> optionalPositionalParameters(
AnalyzerTypesToMacros translator, TypeTranslationContext context) {
return parameters
.where((p) => p.isOptionalPositional)
.map((p) => p.type.acceptWithArgument(translator, context))
.toList();
}

List<NamedFunctionTypeParameter> namedParameters(
AnalyzerTypesToMacros translator, TypeTranslationContext context) {
return parameters
.where((p) => p.isNamed)
.map((p) => p.type.acceptWithArgument(translator, context))
.cast<NamedFunctionTypeParameter>()
.toList();
}
}
Loading

0 comments on commit b584bbe

Please sign in to comment.