-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recursively search for types during import type collection in deeply nested schemas #11221
Changes from all commits
12768ab
3910036
039e3e2
3613d54
61263ff
96a6ecd
ff4f9eb
68ec26e
005b382
9aeee78
5dd54d0
0181fdd
0a9d5b9
404e5b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
package org.openapitools.codegen; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Stream; | ||
|
||
import io.swagger.v3.oas.models.media.Schema; | ||
import org.openapitools.codegen.utils.ModelUtils; | ||
|
@@ -213,4 +217,51 @@ default void setTypeProperties(Schema p) { | |
setIsAnyType(true); | ||
} | ||
} | ||
|
||
/** | ||
* @return basic type - no generics supported. | ||
*/ | ||
default String getBaseType() { | ||
return null; | ||
}; | ||
|
||
/** | ||
* @return complex type that can contain type parameters - like {@code List<Items>} for Java | ||
*/ | ||
default String getComplexType() { | ||
return getBaseType(); | ||
}; | ||
|
||
/** | ||
* Recursively collect all necessary imports to include so that the type may be resolved. | ||
* | ||
* @param includeContainerTypes whether or not to include the container types in the returned imports. | ||
* @return all of the imports | ||
*/ | ||
default Set<String> getImports(boolean includeContainerTypes) { | ||
Set<String> imports = new HashSet<>(); | ||
if (this.getComposedSchemas() != null) { | ||
CodegenComposedSchemas composed = (CodegenComposedSchemas) this.getComposedSchemas(); | ||
List<CodegenProperty> allOfs = composed.getAllOf() == null ? Collections.emptyList() : composed.getAllOf(); | ||
List<CodegenProperty> oneOfs = composed.getOneOf() == null ? Collections.emptyList() : composed.getOneOf(); | ||
Stream<CodegenProperty> innerTypes = Stream.concat(allOfs.stream(), oneOfs.stream()); | ||
innerTypes.flatMap(cp -> cp.getImports(includeContainerTypes).stream()).forEach(s -> imports.add(s)); | ||
} else if (includeContainerTypes || !(this.getIsArray() || this.getIsMap())) { | ||
// this is our base case, add imports for referenced schemas | ||
// this can't be broken out as a separate if block because Typescript only generates union types as A | B | ||
// and would need to handle this differently | ||
imports.add(this.getComplexType()); | ||
imports.add(this.getBaseType()); | ||
spacether marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is for our base case, can you move it above our first composedschema if?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conversely, if I don't add baseType here, I get 130 changed sample files where key imports are removed. Some languages apparently need to import string - like in cpp they import |
||
} | ||
if (this.getItems() !=null && this.getIsArray()) { | ||
imports.addAll(this.getItems().getImports(includeContainerTypes)); | ||
} | ||
if (this.getAdditionalProperties() != null) { | ||
imports.addAll(this.getAdditionalProperties().getImports(includeContainerTypes)); | ||
} | ||
if (this.getVars() != null && !this.getVars().isEmpty()) { | ||
this.getVars().stream().flatMap(v -> v.getImports(includeContainerTypes).stream()).forEach(s -> imports.add(s)); | ||
} | ||
return imports; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
openapi: 3.0.1 | ||
info: | ||
title: Test additional properties with ref | ||
version: '1.0' | ||
servers: | ||
- url: 'http://localhost:8000/' | ||
paths: | ||
/ping: | ||
post: | ||
operationId: pingGet | ||
responses: | ||
default: | ||
description: default response | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
additionalProperties: | ||
type: object | ||
additionalProperties: | ||
type: object | ||
additionalProperties: | ||
"$ref": "#/components/schemas/Person" | ||
components: | ||
schemas: | ||
Person: | ||
type: object | ||
properties: | ||
lastName: | ||
type: string | ||
firstName: | ||
type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we not accepting container type imports here?
objects can be sent in parameters and properties of those objects can $ref to other models
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I leave this as true, 130 sample files are changed to include List, Set and Map-like imports that were already defined. This is because there seems to be an assumption to include such standard imports in the mustache templates already, and for some reason the duplicates aren't 'known about' in the codegen code. So I opted to optionally refrain from collecting those types. This could be changed later but for now is at least most consisten with what already is happening.