Skip to content

Commit

Permalink
fix(dynamite)!: Do not assume subtypes of someOfs are always nullable
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <[email protected]>
  • Loading branch information
provokateurin committed Aug 27, 2024
1 parent 2a48f06 commit 96329db
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 144 deletions.
2 changes: 1 addition & 1 deletion packages/dynamite/lib/src/builder/generate_ofs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ Iterable<Spec> generateSomeOf(
final buffer = StringBuffer();
for (final field in fields.entries) {
final result = field.key;
final dartName = result.nullableName;
final dartName = result.asNullable.nullableName;
final fieldName = field.value;

buffer.write('''
Expand Down
2 changes: 1 addition & 1 deletion packages/dynamite/lib/src/builder/resolve_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void _generateProperty(
}

if (result is TypeResultSomeOf && result.isSingleValue) {
b.returns = refer(result.dartType.name);
b.returns = refer(result.dartType.nullableName);
} else {
b.returns = refer(result.nullableName);
}
Expand Down
4 changes: 1 addition & 3 deletions packages/dynamite/lib/src/builder/resolve_ofs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ TypeResult resolveSomeOf(State state, json_schema.JsonSchema schema) {
return resolveType(
state,
schema.rebuild((b) {
b
..identifier = '$identifier$index'
..nullable = true;
b.identifier = '$identifier$index';
}),
);
}).toBuiltSet();
Expand Down
7 changes: 7 additions & 0 deletions packages/dynamite/lib/src/models/type_result/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ class TypeResultBase extends TypeResult {

return TypeResultBase(dartName, nullable: nullable);
}

@override
TypeResultBase get asNullable => TypeResultBase(
className,
nullable: true,
isTypeDef: isTypeDef,
);
}
8 changes: 8 additions & 0 deletions packages/dynamite/lib/src/models/type_result/enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ class TypeResultEnum extends TypeResult {

@override
int get hashCode => className.hashCode + subType.hashCode;

@override
TypeResultEnum get asNullable => TypeResultEnum(
className,
subType,
nullable: true,
isTypeDef: isTypeDef,
);
}
9 changes: 9 additions & 0 deletions packages/dynamite/lib/src/models/type_result/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,13 @@ class TypeResultList extends TypeResult {

@override
int get hashCode => className.hashCode + generics.hashCode + subType.hashCode;

@override
TypeResultList get asNullable => TypeResultList(
className,
subType,
nullable: true,
isTypeDef: isTypeDef,
builderName: builderName,
);
}
9 changes: 9 additions & 0 deletions packages/dynamite/lib/src/models/type_result/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,13 @@ class TypeResultMap extends TypeResult {

@override
int get hashCode => className.hashCode + generics.hashCode + subType.hashCode;

@override
TypeResultMap get asNullable => TypeResultMap(
className,
subType,
nullable: true,
isTypeDef: isTypeDef,
builderName: builderName,
);
}
8 changes: 8 additions & 0 deletions packages/dynamite/lib/src/models/type_result/object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@ class TypeResultObject extends TypeResult {
isTypeDef: isTypeDef,
);
}

@override
TypeResultObject get asNullable => TypeResultObject(
className,
generics: generics,
nullable: true,
isTypeDef: isTypeDef,
);
}
20 changes: 17 additions & 3 deletions packages/dynamite/lib/src/models/type_result/some_of.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ abstract class TypeResultSomeOf extends TypeResult {
@override
TypeResult get dartType {
if (isSingleValue) {
return optimizedSubTypes.single;
return nullable ? optimizedSubTypes.single.asNullable : optimizedSubTypes.single;
}

final record = optimizedSubTypes.map((type) {
final dartType = type.nullableName;
final dartType = type.asNullable.nullableName;
final dartName = toDartName(dartType);

return '$dartType $dartName';
Expand Down Expand Up @@ -77,7 +77,7 @@ abstract class TypeResultSomeOf extends TypeResult {
final optimizeNum = subTypes.where(_isNumber).length >= 2;

if (optimizeNum) {
optimized.add(TypeResultBase('num', nullable: true));
optimized.add(TypeResultBase('num'));
}

optimized.addAll(
Expand Down Expand Up @@ -131,6 +131,13 @@ class TypeResultAnyOf extends TypeResultSomeOf {

@override
int get hashCode => className.hashCode + generics.hashCode + dartType.hashCode;

@override
TypeResultAnyOf get asNullable => TypeResultAnyOf(
className,
subTypes: subTypes,
nullable: true,
);
}

class TypeResultOneOf extends TypeResultSomeOf {
Expand All @@ -153,4 +160,11 @@ class TypeResultOneOf extends TypeResultSomeOf {

@override
int get hashCode => className.hashCode + generics.hashCode + dartType.hashCode;

@override
TypeResultOneOf get asNullable => TypeResultOneOf(
className,
subTypes: subTypes,
nullable: true,
);
}
2 changes: 2 additions & 0 deletions packages/dynamite/lib/src/models/type_result/type_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ sealed class TypeResult {
};
}

TypeResult get asNullable;

@override
bool operator ==(Object other) => other is TypeResult && other.className == className && other.generics == generics;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,66 +23,72 @@ typedef OneOfIntDoubleOther = ({num? $num, String? string});

/// One of with an integer, double and other value.
typedef AnyOfIntDoubleOther = ({num? $num, String? string});
typedef OneValueSomeOfInObject_IntDoubleString = ({num? $num, String? string});
typedef OneOfInObject_IntDoubleOther = ({num? $num, String? string});
typedef OneOfInObject_IntDoubleOtherRequired = ({num? $num, String? string});

/// Object with someOfs that only contain a single value (or are optimized to such).
/// Should use the single member directly.
@BuiltValue(instantiable: false)
sealed class $OneValueSomeOfInObjectInterface {
sealed class $OneOfInObjectInterface {
@BuiltValueField(wireName: 'OneValue')
int get oneValue;
int? get oneValue;
@BuiltValueField(wireName: 'OneValueRequired')
int get oneValueRequired;
@BuiltValueField(wireName: 'IntDouble')
num get intDouble;
@BuiltValueField(wireName: 'IntDoubleString')
OneValueSomeOfInObject_IntDoubleString? get intDoubleString;
num? get intDouble;
@BuiltValueField(wireName: 'IntDoubleRequired')
num get intDoubleRequired;
@BuiltValueField(wireName: 'IntDoubleOther')
OneOfInObject_IntDoubleOther? get intDoubleOther;
@BuiltValueField(wireName: 'IntDoubleOtherRequired')
OneOfInObject_IntDoubleOtherRequired get intDoubleOtherRequired;

/// Rebuilds the instance.
///
/// The result is the same as this instance but with [updates] applied.
/// [updates] is a function that takes a builder [$OneValueSomeOfInObjectInterfaceBuilder].
$OneValueSomeOfInObjectInterface rebuild(void Function($OneValueSomeOfInObjectInterfaceBuilder) updates);
/// [updates] is a function that takes a builder [$OneOfInObjectInterfaceBuilder].
$OneOfInObjectInterface rebuild(void Function($OneOfInObjectInterfaceBuilder) updates);

/// Converts the instance to a builder [$OneValueSomeOfInObjectInterfaceBuilder].
$OneValueSomeOfInObjectInterfaceBuilder toBuilder();
/// Converts the instance to a builder [$OneOfInObjectInterfaceBuilder].
$OneOfInObjectInterfaceBuilder toBuilder();
@BuiltValueHook(initializeBuilder: true)
static void _defaults($OneValueSomeOfInObjectInterfaceBuilder b) {}
static void _defaults($OneOfInObjectInterfaceBuilder b) {}
@BuiltValueHook(finalizeBuilder: true)
static void _validate($OneValueSomeOfInObjectInterfaceBuilder b) {
b.intDoubleString?.validateOneOf();
static void _validate($OneOfInObjectInterfaceBuilder b) {
b.intDoubleOther?.validateOneOf();
b.intDoubleOtherRequired?.validateOneOf();
}
}

/// Object with someOfs that only contain a single value (or are optimized to such).
/// Should use the single member directly.
abstract class OneValueSomeOfInObject
implements $OneValueSomeOfInObjectInterface, Built<OneValueSomeOfInObject, OneValueSomeOfInObjectBuilder> {
/// Creates a new OneValueSomeOfInObject object using the builder pattern.
factory OneValueSomeOfInObject([void Function(OneValueSomeOfInObjectBuilder)? b]) = _$OneValueSomeOfInObject;
abstract class OneOfInObject implements $OneOfInObjectInterface, Built<OneOfInObject, OneOfInObjectBuilder> {
/// Creates a new OneOfInObject object using the builder pattern.
factory OneOfInObject([void Function(OneOfInObjectBuilder)? b]) = _$OneOfInObject;

const OneValueSomeOfInObject._();
const OneOfInObject._();

/// Creates a new object from the given [json] data.
///
/// Use [toJson] to serialize it back into json.
factory OneValueSomeOfInObject.fromJson(Map<String, dynamic> json) =>
_$jsonSerializers.deserializeWith(serializer, json)!;
factory OneOfInObject.fromJson(Map<String, dynamic> json) => _$jsonSerializers.deserializeWith(serializer, json)!;

/// Parses this object into a json like map.
///
/// Use the fromJson factory to revive it again.
Map<String, dynamic> toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>;

/// Serializer for OneValueSomeOfInObject.
static Serializer<OneValueSomeOfInObject> get serializer => _$oneValueSomeOfInObjectSerializer;
/// Serializer for OneOfInObject.
static Serializer<OneOfInObject> get serializer => _$oneOfInObjectSerializer;

@BuiltValueHook(initializeBuilder: true)
static void _defaults(OneValueSomeOfInObjectBuilder b) {
$OneValueSomeOfInObjectInterface._defaults(b);
static void _defaults(OneOfInObjectBuilder b) {
$OneOfInObjectInterface._defaults(b);
}

@BuiltValueHook(finalizeBuilder: true)
static void _validate(OneValueSomeOfInObjectBuilder b) {
$OneValueSomeOfInObjectInterface._validate(b);
static void _validate(OneOfInObjectBuilder b) {
$OneOfInObjectInterface._validate(b);
}
}

Expand Down Expand Up @@ -110,17 +116,31 @@ extension $AnyOfIntDoubleOtherExtension on AnyOfIntDoubleOther {
static AnyOfIntDoubleOther fromJson(Object? json) => $b6d67dc2a96424d2f407f8e51557f3deExtension._fromJson(json);
}

/// Serialization extension for `OneValueSomeOfInObject_IntDoubleString`.
extension $OneValueSomeOfInObject_IntDoubleStringExtension on OneValueSomeOfInObject_IntDoubleString {
/// Serializer for OneValueSomeOfInObject_IntDoubleString.
/// Serialization extension for `OneOfInObject_IntDoubleOther`.
extension $OneOfInObject_IntDoubleOtherExtension on OneOfInObject_IntDoubleOther {
/// Serializer for OneOfInObject_IntDoubleOther.
@BuiltValueSerializer(custom: true)
static Serializer<OneValueSomeOfInObject_IntDoubleString> get serializer =>
static Serializer<OneOfInObject_IntDoubleOther> get serializer =>
$b6d67dc2a96424d2f407f8e51557f3deExtension._serializer;

/// Creates a new object from the given [json] data.
///
/// Use `toJson` to serialize it back into json.
static OneValueSomeOfInObject_IntDoubleString fromJson(Object? json) =>
static OneOfInObject_IntDoubleOther fromJson(Object? json) =>
$b6d67dc2a96424d2f407f8e51557f3deExtension._fromJson(json);
}

/// Serialization extension for `OneOfInObject_IntDoubleOtherRequired`.
extension $OneOfInObject_IntDoubleOtherRequiredExtension on OneOfInObject_IntDoubleOtherRequired {
/// Serializer for OneOfInObject_IntDoubleOtherRequired.
@BuiltValueSerializer(custom: true)
static Serializer<OneOfInObject_IntDoubleOtherRequired> get serializer =>
$b6d67dc2a96424d2f407f8e51557f3deExtension._serializer;

/// Creates a new object from the given [json] data.
///
/// Use `toJson` to serialize it back into json.
static OneOfInObject_IntDoubleOtherRequired fromJson(Object? json) =>
$b6d67dc2a96424d2f407f8e51557f3deExtension._fromJson(json);
}

Expand Down Expand Up @@ -215,8 +235,8 @@ class _$b6d67dc2a96424d2f407f8e51557f3deSerializer implements PrimitiveSerialize
final Serializers $serializers = _$serializers;
final Serializers _$serializers = (Serializers().toBuilder()
..add($b6d67dc2a96424d2f407f8e51557f3deExtension._serializer)
..addBuilderFactory(const FullType(OneValueSomeOfInObject), OneValueSomeOfInObjectBuilder.new)
..add(OneValueSomeOfInObject.serializer))
..addBuilderFactory(const FullType(OneOfInObject), OneOfInObjectBuilder.new)
..add(OneOfInObject.serializer))
.build();

/// Serializer for all values in this library.
Expand Down
Loading

0 comments on commit 96329db

Please sign in to comment.