Skip to content

Commit

Permalink
Revert "Bugfix swift5 code generation 2966 (#7301)" and provide a better
Browse files Browse the repository at this point in the history
fix for the stackoverflow issue
  • Loading branch information
wing328 committed Dec 2, 2020
1 parent 634c4c0 commit c9200f1
Show file tree
Hide file tree
Showing 23 changed files with 86 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public Swift5ClientCodegen() {
cliOptions.add(new CliOption(POD_DOCUMENTATION_URL,
"Documentation URL used for Podspec"));
cliOptions.add(new CliOption(READONLY_PROPERTIES, "Make properties "
+ "readonly (default: false)"));
+ "readonly (default: false)"));
cliOptions.add(new CliOption(SWIFT_USE_API_NAMESPACE,
"Flag to make all the API classes inner-class "
+ "of {{projectName}}API"));
Expand Down Expand Up @@ -997,15 +997,15 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) {
for (CodegenParameter cp : operation.allParams) {
cp.vendorExtensions.put("x-swift-example", constructExampleCode(cp, modelMaps, new ExampleCodeGenerationContext()));
cp.vendorExtensions.put("x-swift-example", constructExampleCode(cp, modelMaps, new HashSet()));
}
}
return objs;
}

public String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, ExampleCodeGenerationContext context) {
public String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
if (codegenParameter.isArray) { // array
return "[" + constructExampleCode(codegenParameter.items, modelMaps, context) + "]";
return "[" + constructExampleCode(codegenParameter.items, modelMaps, visitedModels) + "]";
} else if (codegenParameter.isMap) { // TODO: map, file type
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenParameter.dataType)) { // primitive type
Expand Down Expand Up @@ -1035,17 +1035,23 @@ public String constructExampleCode(CodegenParameter codegenParameter, HashMap<St
} else { // model
// look up the model
if (modelMaps.containsKey(codegenParameter.dataType)) {
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps, context);
if (visitedModels.contains(modelMaps.get(codegenParameter.dataType))) {
// recursive/self-referencing model, simply return nil to avoid stackoverflow
return "nil";
} else {
visitedModels.add(modelMaps.get(codegenParameter.dataType));
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps, visitedModels);
}
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenParameter.dataType);
return "TODO";
}
}
}

private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, ExampleCodeGenerationContext context) {
public String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
if (codegenProperty.isArray) { // array
return "[" + constructExampleCode(codegenProperty.items, modelMaps, context) + "]";
return "[" + constructExampleCode(codegenProperty.items, modelMaps, visitedModels) + "]";
} else if (codegenProperty.isMap) { // TODO: map, file type
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenProperty.dataType)) { // primitive type
Expand Down Expand Up @@ -1075,59 +1081,28 @@ private String constructExampleCode(CodegenProperty codegenProperty, HashMap<Str
} else {
// look up the model
if (modelMaps.containsKey(codegenProperty.dataType)) {
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, context);
if (visitedModels.contains(modelMaps.get(codegenProperty.dataType))) {
// recursive/self-referencing model, simply return nil to avoid stackoverflow
return "nil";
} else {
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, visitedModels);
}
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenProperty.dataType);
return "\"TODO\"";
}
}
}

private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, ExampleCodeGenerationContext context) {
if (context.isTypeVisted(codegenModel.dataType)) {
String exampleCode = context.getExampleCode(codegenModel.dataType);
if (exampleCode != null) {
// Reuse already generated exampleCode
return exampleCode;
} else {
// Visited but no Example Code. Circuit Breaker --> No StackOverflow
return "{...}";
}
} else {
context.visitType(codegenModel.dataType);
String example = codegenModel.name + "(";
List<String> propertyExamples = new ArrayList<>();
for (CodegenProperty codegenProperty : codegenModel.vars) {
String propertyExample = constructExampleCode(codegenProperty, modelMaps, context);
propertyExamples.add(codegenProperty.name + ": " + propertyExample);
}
example += StringUtils.join(propertyExamples, ", ");
example += ")";

context.setExampleCode(codegenModel.dataType, example);
return example;
public String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
String example;
example = codegenModel.name + "(";
List<String> propertyExamples = new ArrayList<>();
for (CodegenProperty codegenProperty : codegenModel.vars) {
propertyExamples.add(codegenProperty.name + ": " + constructExampleCode(codegenProperty, modelMaps, visitedModels));
}
}

private static class ExampleCodeGenerationContext {

private Map<String, String> modelExampleCode = new HashMap<>();

public boolean isTypeVisted(String type) {
return modelExampleCode.containsKey(type);
}

public void visitType(String type) {
modelExampleCode.put(type, null);
}

public void setExampleCode(String type, String code) {
modelExampleCode.put(type, code);
}

public String getExampleCode(String type) {
return modelExampleCode.get(type);
}

example += StringUtils.join(propertyExamples, ", ");
example += ")";
return example;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.util.Arrays;
import java.util.List;


public class Swift5ClientCodegenTest {

Swift5ClientCodegen swiftCodegen = new Swift5ClientCodegen();
Expand Down Expand Up @@ -129,6 +128,32 @@ public void dateTest() {
Assert.assertEquals(op.bodyParam.dataType, "Date");
}

@Test(enabled = true)
public void testDefaultPodAuthors() throws Exception {
// Given

// When
swiftCodegen.processOpts();

// Then
final String podAuthors = (String) swiftCodegen.additionalProperties().get(Swift5ClientCodegen.POD_AUTHORS);
Assert.assertEquals(podAuthors, Swift5ClientCodegen.DEFAULT_POD_AUTHORS);
}

@Test(enabled = true)
public void testPodAuthors() throws Exception {
// Given
final String openAPIDevs = "OpenAPI Devs";
swiftCodegen.additionalProperties().put(Swift5ClientCodegen.POD_AUTHORS, openAPIDevs);

// When
swiftCodegen.processOpts();

// Then
final String podAuthors = (String) swiftCodegen.additionalProperties().get(Swift5ClientCodegen.POD_AUTHORS);
Assert.assertEquals(podAuthors, openAPIDevs);
}

@Test(description = "Bug example code generation", enabled = true)
public void crashSwift5ExampleCodeGenerationStackOverflowTest() throws IOException {
//final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/bugs/Swift5CodeGenerationStackOverflow#2966.yaml");
Expand Down Expand Up @@ -160,31 +185,4 @@ public void crashSwift5ExampleCodeGenerationStackOverflowTest() throws IOExcepti
}
}


@Test(enabled = true)
public void testDefaultPodAuthors() throws Exception {
// Given

// When
swiftCodegen.processOpts();

// Then
final String podAuthors = (String) swiftCodegen.additionalProperties().get(Swift5ClientCodegen.POD_AUTHORS);
Assert.assertEquals(podAuthors, Swift5ClientCodegen.DEFAULT_POD_AUTHORS);
}

@Test(enabled = true)
public void testPodAuthors() throws Exception {
// Given
final String openAPIDevs = "OpenAPI Devs";
swiftCodegen.additionalProperties().put(Swift5ClientCodegen.POD_AUTHORS, openAPIDevs);

// When
swiftCodegen.processOpts();

// Then
final String podAuthors = (String) swiftCodegen.additionalProperties().get(Swift5ClientCodegen.POD_AUTHORS);
Assert.assertEquals(podAuthors, openAPIDevs);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = FileSchemaTestClass(file: {...}, files: [{...}]) // FileSchemaTestClass |
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |

FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
guard error == nil else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add a new pet to the store
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Add a new pet to the store
PetAPI.addPet(body: body) { (response, error) in
Expand Down Expand Up @@ -275,7 +275,7 @@ Update an existing pet
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Update an existing pet
PetAPI.updatePet(body: body) { (response, error) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = FileSchemaTestClass(file: {...}, files: [{...}]) // FileSchemaTestClass |
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |

FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
guard error == nil else {
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/swift5/combineLibrary/docs/PetAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add a new pet to the store
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Add a new pet to the store
PetAPI.addPet(body: body) { (response, error) in
Expand Down Expand Up @@ -275,7 +275,7 @@ Update an existing pet
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Update an existing pet
PetAPI.updatePet(body: body) { (response, error) in
Expand Down
2 changes: 1 addition & 1 deletion samples/client/petstore/swift5/default/docs/FakeAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = FileSchemaTestClass(file: {...}, files: [{...}]) // FileSchemaTestClass |
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |

FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
guard error == nil else {
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/swift5/default/docs/PetAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add a new pet to the store
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Add a new pet to the store
PetAPI.addPet(body: body) { (response, error) in
Expand Down Expand Up @@ -275,7 +275,7 @@ Update an existing pet
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Update an existing pet
PetAPI.updatePet(body: body) { (response, error) in
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/swift5/deprecated/docs/PetAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Add a new pet to the store
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let pet = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let pet = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Add a new pet to the store
PetAPI.addPet(pet: pet) { (response, error) in
Expand Down Expand Up @@ -274,7 +274,7 @@ Update an existing pet
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let pet = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let pet = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Update an existing pet
PetAPI.updatePet(pet: pet) { (response, error) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = FileSchemaTestClass(file: {...}, files: [{...}]) // FileSchemaTestClass |
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |

FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
guard error == nil else {
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/swift5/nonPublicApi/docs/PetAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add a new pet to the store
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Add a new pet to the store
PetAPI.addPet(body: body) { (response, error) in
Expand Down Expand Up @@ -275,7 +275,7 @@ Update an existing pet
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = Pet(id: 123, category: {...}, name: "name_example", photoUrls: ["photoUrls_example"], tags: [{...}], status: "status_example") // Pet | Pet object that needs to be added to the store
let body = Pet(id: 123, category: Category(id: 123, name: "name_example"), name: "name_example", photoUrls: ["photoUrls_example"], tags: [Tag(id: 123, name: "name_example")], status: "status_example") // Pet | Pet object that needs to be added to the store

// Update an existing pet
PetAPI.updatePet(body: body) { (response, error) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
import PetstoreClient

let body = FileSchemaTestClass(file: {...}, files: [{...}]) // FileSchemaTestClass |
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |

FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
guard error == nil else {
Expand Down
Loading

0 comments on commit c9200f1

Please sign in to comment.