[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`
This commit is contained in:
Peter Leibiger 2021-08-04 08:25:26 +02:00 committed by GitHub
parent 98e4eb708f
commit ccd23ec75a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 8 deletions

View File

@ -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<Uint8List>" 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<String, Object> 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<String, Object> 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<String> imports = v == null ? Sets.newHashSet() : ((Set<String>) v);
imports.addAll(rewriteImports(Sets.newHashSet(type), true));
return imports;
});
}
private Set<String> rewriteImports(Set<String> originalImports, boolean isModel) {
Set<String> resultImports = Sets.newHashSet();
for (String modelImport : originalImports) {

View File

@ -2,7 +2,7 @@
{{#isMultipart}}
_bodyData = FormData.fromMap(<String, dynamic>{
{{#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}}

View File

@ -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}}

View File

@ -110,14 +110,26 @@ part 'serializers.g.dart';
User,
])
Serializers serializers = (_$serializers.toBuilder()
..addBuilderFactory(
const FullType(BuiltList, [FullType(String)]),
() => ListBuilder<String>(),
)
..addBuilderFactory(
const FullType(BuiltMap, [FullType(String), FullType(String)]),
() => MapBuilder<String, String>(),
)
..addBuilderFactory(
const FullType(BuiltList, [FullType(String)]),
() => ListBuilder<String>(),
)
..addBuilderFactory(
const FullType(BuiltSet, [FullType(Pet)]),
() => SetBuilder<Pet>(),
)
..addBuilderFactory(
const FullType(BuiltSet, [FullType(String)]),
() => SetBuilder<String>(),
)
..addBuilderFactory(
const FullType(BuiltList, [FullType(Pet)]),
() => ListBuilder<Pet>(),