Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,14 @@ String _validateMethod(String className, Set<UniversalType> types) {
return funcBuffer.toString();
}

String _factories(UniversalComponentClass dataClass, String className,
bool useMultipartFile, bool includeIfNull, String? fallbackUnion,
{required bool isUnion}) {
String _factories(
UniversalComponentClass dataClass,
String className,
bool useMultipartFile,
bool includeIfNull,
String? fallbackUnion, {
required bool isUnion,
}) {
if (!isUnion) {
return '''
const factory $className(${dataClass.parameters.isNotEmpty ? '{' : ''}${_parametersToString(dataClass.parameters, useMultipartFile, includeIfNull)}${dataClass.parameters.isNotEmpty ? '\n }' : ''}) = _$className;''';
Expand All @@ -196,12 +201,18 @@ String _factories(UniversalComponentClass dataClass, String className,
final factories = <String>[];
for (final discriminatorValue
in dataClass.discriminator!.discriminatorValueToRefMapping.keys) {
final discriminator = dataClass.discriminator!;
final discriminatorRef =
discriminator.discriminatorValueToRefMapping[discriminatorValue]!;

final (protectedName, _) = protectName(discriminatorValue, isMethod: true);
final factoryName = protectedName!.toCamel;
final discriminatorRef = dataClass
.discriminator!.discriminatorValueToRefMapping[discriminatorValue]!;

final factoryParameters =
dataClass.discriminator!.refProperties[discriminatorRef]!;
discriminator.refProperties[discriminatorRef]!.where((e) {
return e.jsonKey != discriminator.jsonKey;
}).toSet();

final unionItemClassName = className + discriminatorValue.toPascal;

factories.add('''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ String _generateDiscriminatedUnionTemplate(

// Generate sealed base class
final baseClass = '''
@JsonSerializable(createFactory: false)
@JsonSerializable(createFactory: false, createToJson: false)
sealed class $className {
const $className();

Expand Down Expand Up @@ -295,6 +295,12 @@ String _generateDiscriminatedWrapperClasses(
bool useMultipartFile,
bool includeIfNull,
String? fallbackUnion) {
// Build default mapping literal: { WrapperType: 'DiscriminatorValue', ... }
final discriminatorsByVariant =
discriminator.discriminatorValueToRefMapping.map((key, val) {
return MapEntry(val, key);
});

final wrappers =
discriminator.discriminatorValueToRefMapping.entries.map((entry) {
final variantName = entry.value;
Expand All @@ -303,23 +309,43 @@ String _generateDiscriminatedWrapperClasses(
discriminator.refProperties[variantName] ?? <UniversalType>{};

// Generate direct properties
final directProperties = properties
.map((prop) =>
' @override\n final ${_renameUnionTypes(prop.toSuitableType(ProgrammingLanguage.dart, useMultipartFile: useMultipartFile))} ${prop.name};')
.join('\n');
final directProperties = properties.map((prop) {
final dataType = _renameUnionTypes(prop.toSuitableType(
ProgrammingLanguage.dart,
useMultipartFile: useMultipartFile));
if (prop.jsonKey == discriminator.jsonKey) {
final jsonKey = "JsonKey(includeToJson: true, name: '${prop.jsonKey}')";

var val = '"${discriminatorsByVariant[variantName]}"';
if (prop.enumType != null) {
val = '$dataType.fromJson($val)';
}

return ' @$jsonKey\n @override\n $dataType get ${prop.name} => $val;';
} else {
return ' @override\n final $dataType ${prop.name};';
}
}).join('\n');

// Generate constructor parameters
final constructorParams =
properties.map((prop) => ' required this.${prop.name},').join('\n');
properties.whereNot((prop) => prop.jsonKey == discriminator.jsonKey);

var constructor = ' const $wrapperClassName(';
if (constructorParams.isNotEmpty) {
final constructorParamsStr = constructorParams
.map((prop) => ' ${_required(prop)}this.${prop.name},')
.join('\n');
constructor += '{\n$constructorParamsStr\n }';
}
constructor += ');';

return '''
@JsonSerializable()
class $wrapperClassName extends $className implements $variantName {
$directProperties

const $wrapperClassName({
$constructorParams
});
$constructor

factory $wrapperClassName.fromJson(Map<String, dynamic> json) =>
_\$${wrapperClassName}FromJson(json);
Expand Down Expand Up @@ -355,7 +381,7 @@ String _generateUndiscriminatedWrapperClasses(

// Generate constructor parameters
final constructorParams =
properties.map((prop) => ' required this.${prop.name},').join('\n');
properties.map((prop) => ' ${_required(prop)}this.${prop.name},').join('\n');

// Inline synthesized variants (variantX) should not implement any interface
final isInline = variantName.toLowerCase().startsWith('variant');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ typedef Discriminator = ({
/// The name of the property that is used to discriminate the oneOf variants
String propertyName,

/// This is the equivalent to [UniversalType.jsonKey]
String jsonKey,

/// The mapping of the property value to the ref
Map<String, String> discriminatorValueToRefMapping,

Expand Down
3 changes: 3 additions & 0 deletions swagger_parser/lib/src/parser/parser/open_api_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,8 @@ class OpenApiParser {
return null;
}

final jsonKey = discriminatorRaw[_propertyNameConst] as String;

final propertyName = discriminatorRaw[_propertyNameConst] as String;
final refMappingRaw = discriminatorRaw[_mappingConst];
if (refMappingRaw is! Map) {
Expand All @@ -2157,6 +2159,7 @@ class OpenApiParser {
}

return (
jsonKey: jsonKey,
propertyName: propertyName,
discriminatorValueToRefMapping: cleanedRefMapping,
// This property is populated by the parser after all the data classes are created
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading