Skip to content

Commit 25cbfdc

Browse files
authored
[native_assets_cli] Refactor overrides in syntax classes (#2160)
This PR refactors field overrides in the syntax generator. The analysis of overrides is now done on the `PropertyInfo` and `DartType` rather than on the `JsonSchema`. If a field is overridden with a more specific type, generate the more specific type in the default constructor and pass it to the more general parameter in the super constructor invocation. (See the single change in the generated file.)
1 parent 05cf603 commit 25cbfdc

File tree

4 files changed

+116
-18
lines changed

4 files changed

+116
-18
lines changed

pkgs/json_syntax_generator/lib/src/generator/normal_class_generator.dart

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,19 @@ static const ${tagProperty}Value = '$tagValue';
142142
final thisClassProperty = classInfo.getProperty(propertyName);
143143

144144
if (superClassProperty != null) {
145-
if (!classInfo.isTaggedUnion) {
146-
final propertyName = superClassProperty.name;
147-
result.add('required super.$propertyName');
145+
if (propertyName != classInfo.superclass?.taggedUnionProperty) {
146+
if (thisClassProperty != null &&
147+
superClassProperty.type != thisClassProperty.type) {
148+
// More specific type on this class so emit normal parameter.
149+
// Must be passed to super constructor call.
150+
final dartType = thisClassProperty.type;
151+
final propertyName = thisClassProperty.name;
152+
result.add('required $dartType $propertyName');
153+
} else {
154+
// Same type on this class, emit super parameter.
155+
final propertyName = superClassProperty.name;
156+
result.add('required super.$propertyName');
157+
}
148158
}
149159
} else {
150160
final dartType = thisClassProperty!.type;
@@ -155,15 +165,40 @@ static const ${tagProperty}Value = '$tagValue';
155165
return result;
156166
}
157167

158-
/// The only super constructor call parameter is for tagged unions.
168+
/// Generates super constructor calls.
169+
///
170+
/// * For tagged unions, the tagged union value.
171+
/// * For parameters that have a more specific type in the subclass a simple
172+
/// forwarding.
159173
///
160174
/// All other parameters are already set by `super.paramName`.
161175
List<String> _generateDefaultConstructorSuperArguments() {
162-
if (!classInfo.isTaggedUnion || classInfo.superclass == null) return [];
176+
final superclass = classInfo.superclass;
177+
if (superclass == null) return [];
163178

164-
final taggedUnionProperty = classInfo.superclass!.taggedUnionProperty;
179+
final result = <String>[];
180+
181+
final taggedUnionProperty = superclass.taggedUnionProperty;
165182
final taggedUnionValue = classInfo.taggedUnionValue;
166-
return ["$taggedUnionProperty: '$taggedUnionValue'"];
183+
if (taggedUnionValue != null && taggedUnionProperty != null) {
184+
result.add("$taggedUnionProperty: '$taggedUnionValue'");
185+
}
186+
187+
final propertyNames = _getAllPropertyNames();
188+
for (final propertyName in propertyNames) {
189+
final superClassProperty = superclass.getProperty(propertyName);
190+
final thisClassProperty = classInfo.getProperty(propertyName);
191+
192+
if (propertyName != classInfo.superclass?.taggedUnionProperty) {
193+
if (thisClassProperty != null &&
194+
superClassProperty != null &&
195+
superClassProperty.type != thisClassProperty.type) {
196+
final propertyName = thisClassProperty.name;
197+
result.add('$propertyName: $propertyName');
198+
}
199+
}
200+
}
201+
return result;
167202
}
168203

169204
/// Generates the setter calls for both [_generateDefaultConstructor] and

pkgs/json_syntax_generator/lib/src/model/dart_type.dart

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ sealed class DartType {
1515
return isNullable ? '$typeString?' : typeString;
1616
}
1717

18+
@override
19+
bool operator ==(Object other) =>
20+
identical(this, other) ||
21+
other is DartType && isNullable == other.isNullable;
22+
23+
@override
24+
int get hashCode => isNullable.hashCode;
25+
1826
String toNonNullableString();
1927
}
2028

@@ -28,22 +36,53 @@ sealed class SimpleDartType extends DartType {
2836

2937
@override
3038
String toNonNullableString() => typeName;
39+
40+
@override
41+
bool operator ==(Object other) =>
42+
super == other && other is SimpleDartType && typeName == other.typeName;
43+
44+
@override
45+
int get hashCode => Object.hash(super.hashCode, typeName);
3146
}
3247

3348
class StringDartType extends SimpleDartType {
3449
const StringDartType({required super.isNullable}) : super(typeName: 'String');
50+
51+
@override
52+
bool operator ==(Object other) => super == other && other is StringDartType;
53+
54+
@override
55+
int get hashCode => Object.hash(super.hashCode, 'String');
3556
}
3657

3758
class IntDartType extends SimpleDartType {
3859
const IntDartType({required super.isNullable}) : super(typeName: 'int');
60+
61+
@override
62+
bool operator ==(Object other) => super == other && other is IntDartType;
63+
64+
@override
65+
int get hashCode => Object.hash(super.hashCode, 'int');
3966
}
4067

4168
class BoolDartType extends SimpleDartType {
4269
const BoolDartType({required super.isNullable}) : super(typeName: 'bool');
70+
71+
@override
72+
bool operator ==(Object other) => super == other && other is BoolDartType;
73+
74+
@override
75+
int get hashCode => Object.hash(super.hashCode, 'bool');
4376
}
4477

4578
class ObjectDartType extends SimpleDartType {
4679
const ObjectDartType({required super.isNullable}) : super(typeName: 'Object');
80+
81+
@override
82+
bool operator ==(Object other) => super == other && other is ObjectDartType;
83+
84+
@override
85+
int get hashCode => Object.hash(super.hashCode, 'Object');
4786
}
4887

4988
class ClassDartType extends DartType {
@@ -53,6 +92,13 @@ class ClassDartType extends DartType {
5392

5493
@override
5594
String toNonNullableString() => classInfo.name;
95+
96+
@override
97+
bool operator ==(Object other) =>
98+
super == other && other is ClassDartType && classInfo == other.classInfo;
99+
100+
@override
101+
int get hashCode => Object.hash(super.hashCode, classInfo);
56102
}
57103

58104
/// The [ClassInfo] for the `JsonObject` base class.
@@ -65,6 +111,13 @@ class ListDartType extends DartType {
65111

66112
@override
67113
String toNonNullableString() => 'List<$itemType>';
114+
115+
@override
116+
bool operator ==(Object other) =>
117+
super == other && other is ListDartType && itemType == other.itemType;
118+
119+
@override
120+
int get hashCode => Object.hash(super.hashCode, itemType);
68121
}
69122

70123
class MapDartType extends DartType {
@@ -79,11 +132,27 @@ class MapDartType extends DartType {
79132

80133
@override
81134
String toNonNullableString() => 'Map<$keyType, $valueType>';
135+
136+
@override
137+
bool operator ==(Object other) =>
138+
super == other &&
139+
other is MapDartType &&
140+
keyType == other.keyType &&
141+
valueType == other.valueType;
142+
143+
@override
144+
int get hashCode => Object.hash(super.hashCode, keyType, valueType);
82145
}
83146

84147
class UriDartType extends DartType {
85148
const UriDartType({required super.isNullable});
86149

87150
@override
88151
String toNonNullableString() => 'Uri';
152+
153+
@override
154+
bool operator ==(Object other) => super == other && other is UriDartType;
155+
156+
@override
157+
int get hashCode => Object.hash(super.hashCode, 'Uri');
89158
}

pkgs/json_syntax_generator/lib/src/parser/schema_analyzer.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ class SchemaAnalyzer {
142142
superclass = _classes[superClassName] as NormalClassInfo;
143143
}
144144
}
145-
final superSchemas = schemas.superClassSchemas;
146145
final propertyKeys = schemas.propertyKeys;
147146
final settersPrivate = !publicSetters.contains(typeName);
148147

@@ -151,21 +150,16 @@ class SchemaAnalyzer {
151150
final propertySchemas = schemas.property(propertyKey);
152151
final required = schemas.propertyRequired(propertyKey);
153152
final allowEnum = !schemas.generateSubClasses;
154-
final parentPropertySchemas = superSchemas?.property(propertyKey);
155153
final dartType = _analyzeDartType(
156154
propertyKey,
157155
propertySchemas,
158156
required,
159157
allowEnum: allowEnum,
160158
);
161159
final fieldName = _snakeToCamelCase(propertyKey);
162-
final isOverride =
163-
parentPropertySchemas != null &&
164-
(parentPropertySchemas?.type != null ||
165-
propertySchemas.className != null);
166-
if (parentPropertySchemas == null ||
167-
parentPropertySchemas.className != propertySchemas.className ||
168-
propertySchemas.type != parentPropertySchemas.type) {
160+
final parentDartType = superclass?.getProperty(fieldName)?.type;
161+
final isOverride = parentDartType != null;
162+
if (parentDartType == null || parentDartType != dartType) {
169163
properties.add(
170164
PropertyInfo(
171165
name: fieldName,

pkgs/native_assets_cli/lib/src/hooks/syntax.g.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ class BuildInput extends HookInput {
9898
BuildInput.fromJson(super.json, {super.path}) : super.fromJson();
9999

100100
BuildInput({
101-
required super.config,
101+
required BuildConfig config,
102102
required Map<String, Map<String, Object?>>? dependencyMetadata,
103103
required super.outDir,
104104
required super.outDirShared,
105105
required super.outFile,
106106
required super.packageName,
107107
required super.packageRoot,
108108
required super.version,
109-
}) : super() {
109+
}) : super(config: config) {
110110
_dependencyMetadata = dependencyMetadata;
111111
json.sortOnKey();
112112
}

0 commit comments

Comments
 (0)