From ccd23ec75acd080e3b8d05b047d922a84a2696d4 Mon Sep 17 00:00:00 2001 From: Peter Leibiger Date: Wed, 4 Aug 2021 08:25:26 +0200 Subject: [PATCH] [dart-dio] Fix parameter generation problems (#10061) * fix parameter with list of `MultipartFile` being generated as single `MultipartFile` * generate serializer factories for all container params, not only body params * fix compilation errors when `skipFormModel=false` --- .../languages/DartDioNextClientCodegen.java | 35 +++++++++++++++---- .../built_value/serialize.mustache | 2 +- .../built_value/serializers.mustache | 4 ++- .../lib/src/serializers.dart | 12 +++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioNextClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioNextClientCodegen.java index cf93047eda2..895a5559e68 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioNextClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioNextClientCodegen.java @@ -20,6 +20,7 @@ import com.google.common.collect.Sets; import io.swagger.v3.oas.models.media.Schema; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; +import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.meta.features.ClientModificationFeature; @@ -317,13 +318,23 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen { for (CodegenOperation op : operationList) { for (CodegenParameter param : op.allParams) { if (((op.isMultipart && param.isFormParam) || param.isBodyParam) && (param.isBinary || param.isFile)) { - param.baseType = "MultipartFile"; - param.dataType = "MultipartFile"; + param.dataType = param.dataType.replace("Uint8List", "MultipartFile"); + param.baseType = param.baseType.replace("Uint8List", "MultipartFile"); op.imports.add("MultipartFile"); + + if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) { + boolean skipFormModel = Boolean.parseBoolean(GlobalSettings.getProperty(CodegenConstants.SKIP_FORM_MODEL, "true")); + if (param.isFormParam && param.isContainer && !skipFormModel) { + // Because of skipFormModel=false, there is a model class generated which has + // "BuiltList" as property and it requires the correct + // serializer imports to be added in order to compile. + addBuiltValueSerializerImport("Uint8List"); + } + } } } - // the MultipartFile handling above changes the type of some parameters from + // The MultipartFile handling above changes the type of some parameters from // `UInt8List`, the default for files, to `MultipartFile`. // // The following block removes the required import for Uint8List if it is no @@ -335,8 +346,10 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen { op.imports.remove("Uint8List"); } - for (CodegenParameter param : op.bodyParams) { - if (param.isContainer) { + for (CodegenParameter param : op.allParams) { + // Generate serializer factories for all container type parameters. + // But skip binary and file parameters, JSON serializers don't make sense there. + if (param.isContainer && !(param.isBinary || param.isFile )) { final Map serializer = new HashMap<>(); serializer.put("isArray", param.isArray); serializer.put("uniqueItems", param.uniqueItems); @@ -351,7 +364,9 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen { resultImports.add("package:" + pubName + "/src/api_util.dart"); } - if (op.returnContainer != null) { + // Generate serializer factories for response types. + // But skip binary and file response, JSON serializers don't make sense there. + if (op.returnContainer != null && !(op.isResponseBinary || op.isResponseFile)) { final Map serializer = new HashMap<>(); serializer.put("isArray", Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer)); serializer.put("uniqueItems", op.uniqueItems); @@ -367,6 +382,14 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen { return objs; } + private void addBuiltValueSerializerImport(String type) { + additionalProperties.compute("builtValueSerializerImports", (k, v) -> { + Set imports = v == null ? Sets.newHashSet() : ((Set) v); + imports.addAll(rewriteImports(Sets.newHashSet(type), true)); + return imports; + }); + } + private Set rewriteImports(Set originalImports, boolean isModel) { Set resultImports = Sets.newHashSet(); for (String modelImport : originalImports) { diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serialize.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serialize.mustache index 60dcd1773ba..d876fe2979b 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serialize.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serialize.mustache @@ -2,7 +2,7 @@ {{#isMultipart}} _bodyData = FormData.fromMap({ {{#formParams}} - {{^required}}{{^isNullable}}if ({{{paramName}}} != null) {{/isNullable}}{{/required}}r'{{{baseName}}}': {{#isFile}}{{{paramName}}}{{/isFile}}{{^isFile}}encodeFormParameter(_serializers, {{{paramName}}}, const FullType({{^isContainer}}{{{baseType}}}{{/isContainer}}{{#isContainer}}Built{{#isMap}}Map{{/isMap}}{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{baseType}}})]{{/isContainer}})){{/isFile}}, + {{^required}}{{^isNullable}}if ({{{paramName}}} != null) {{/isNullable}}{{/required}}r'{{{baseName}}}': {{#isFile}}{{{paramName}}}{{#isArray}}.toList(){{/isArray}}{{/isFile}}{{^isFile}}encodeFormParameter(_serializers, {{{paramName}}}, const FullType({{^isContainer}}{{{baseType}}}{{/isContainer}}{{#isContainer}}Built{{#isMap}}Map{{/isMap}}{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{baseType}}})]{{/isContainer}})){{/isFile}}, {{/formParams}} }); {{/isMultipart}} diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache index 10925bc1112..e1f3dbe1df5 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache @@ -11,7 +11,9 @@ import 'package:{{pubName}}/src/model/date.dart';{{/useDateLibCore}} {{#useDateLibTimeMachine}}import 'package:time_machine/time_machine.dart'; import 'package:{{pubName}}/src/offset_date_serializer.dart';{{/useDateLibTimeMachine}} {{#models}}{{#model}}import 'package:{{pubName}}/src/model/{{classFilename}}.dart'; -{{/model}}{{/models}} +{{/model}}{{/models}}{{#builtValueSerializerImports}}import '{{{.}}}'; +{{/builtValueSerializerImports}} + part 'serializers.g.dart'; @SerializersFor([{{#models}}{{#model}} diff --git a/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/serializers.dart b/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/serializers.dart index 52ea4eb7a19..1b807addf9e 100644 --- a/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/serializers.dart +++ b/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/lib/src/serializers.dart @@ -110,14 +110,26 @@ part 'serializers.g.dart'; User, ]) Serializers serializers = (_$serializers.toBuilder() + ..addBuilderFactory( + const FullType(BuiltList, [FullType(String)]), + () => ListBuilder(), + ) ..addBuilderFactory( const FullType(BuiltMap, [FullType(String), FullType(String)]), () => MapBuilder(), ) + ..addBuilderFactory( + const FullType(BuiltList, [FullType(String)]), + () => ListBuilder(), + ) ..addBuilderFactory( const FullType(BuiltSet, [FullType(Pet)]), () => SetBuilder(), ) + ..addBuilderFactory( + const FullType(BuiltSet, [FullType(String)]), + () => SetBuilder(), + ) ..addBuilderFactory( const FullType(BuiltList, [FullType(Pet)]), () => ListBuilder(),