Skip to content

Swift4: make generated models structs instead of classes #7345

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

Merged
merged 6 commits into from
Jan 25, 2018
Merged
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 @@ -710,8 +710,38 @@ public String toEnumName(CodegenProperty property) {

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
return postProcessModelsEnum(objs);
Map<String, Object> postProcessedModelsEnum = postProcessModelsEnum(objs);

// We iterate through the list of models, and also iterate through each of the
// properties for each model. For each property, if:
//
// CodegenProperty.name != CodegenProperty.baseName
//
// then we set
//
// CodegenProperty.vendorExtensions["x-codegen-escaped-property-name"] = true
//
// Also, if any property in the model has x-codegen-escaped-property-name=true, then we mark:
//
// CodegenModel.vendorExtensions["x-codegen-has-escaped-property-names"] = true
//
List<Object> models = (List<Object>) postProcessedModelsEnum.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
boolean modelHasPropertyWithEscapedName = false;
for (CodegenProperty prop : cm.allVars) {
if (!prop.name.equals(prop.baseName)) {
prop.vendorExtensions.put("x-codegen-escaped-property-name", true);
modelHasPropertyWithEscapedName = true;
}
}
if (modelHasPropertyWithEscapedName) {
cm.vendorExtensions.put("x-codegen-has-escaped-property-names", true);
}
}

return postProcessedModelsEnum;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

open class {{classname}}: {{#parent}}{{{parent}}}{{/parent}}{{^parent}}Codable{{/parent}} {
public struct {{classname}}: Codable {

{{#vars}}
{{#allVars}}
{{#isEnum}}
{{> modelInlineEnumDeclaration}}
{{/isEnum}}
{{/vars}}
{{#vars}}
{{/allVars}}
{{#allVars}}
{{#isEnum}}
{{#description}}/** {{description}} */
{{/description}}public var {{name}}: {{{datatypeWithEnum}}}{{^required}}?{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}
Expand All @@ -20,7 +20,7 @@ open class {{classname}}: {{#parent}}{{{parent}}}{{/parent}}{{^parent}}Codable{{
}
}{{/vendorExtensions.x-swift-optional-scalar}}{{/objcCompatible}}
{{/isEnum}}
{{/vars}}
{{/allVars}}

{{#additionalPropertiesType}}
public var additionalProperties: [String:{{{additionalPropertiesType}}}] = [:]
Expand All @@ -37,47 +37,39 @@ open class {{classname}}: {{#parent}}{{{parent}}}{{/parent}}{{^parent}}Codable{{
additionalProperties[key] = newValue
}
}
{{/additionalPropertiesType}}

{{^parent}}{{#hasVars}}
public init({{#vars}}{{name}}: {{{datatypeWithEnum}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/vars}}) {
{{#vars}}
self.{{name}} = {{name}}
{{/vars}}
}
{{/hasVars}}{{/parent}}

// Encodable protocol methods

public {{#parent}}override {{/parent}}func encode(to encoder: Encoder) throws {
public func encode(to encoder: Encoder) throws {

var container = encoder.container(keyedBy: String.self)

{{#vars}}
{{#allVars}}
try container.encode{{^required}}IfPresent{{/required}}({{{name}}}, forKey: "{{{baseName}}}")
{{/vars}}
{{#additionalPropertiesType}}
{{/allVars}}
try container.encodeMap(additionalProperties)
{{/additionalPropertiesType}}
}

// Decodable protocol methods

public required init(from decoder: Decoder) throws {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: String.self)

{{#vars}}
{{#allVars}}
{{name}} = try container.decode{{^required}}IfPresent{{/required}}({{{datatypeWithEnum}}}.self, forKey: "{{{baseName}}}")
{{/vars}}
{{#additionalPropertiesType}}
{{/allVars}}
var nonAdditionalPropertyKeys = Set<String>()
{{#vars}}
{{#allVars}}
nonAdditionalPropertyKeys.insert("{{{baseName}}}")
{{/vars}}
{{/allVars}}
additionalProperties = try container.decodeMap({{{additionalPropertiesType}}}.self, excludedKeys: nonAdditionalPropertyKeys)
{{/additionalPropertiesType}}
{{#parent}}
try super.init(from: decoder)
{{/parent}}
}

{{/additionalPropertiesType}}
{{^additionalPropertiesType}}{{#vendorExtensions.x-codegen-has-escaped-property-names}}
public enum CodingKeys: String, CodingKey { {{#allVars}}
case {{name}}{{#vendorExtensions.x-codegen-escaped-property-name}} = "{{{baseName}}}"{{/vendorExtensions.x-codegen-escaped-property-name}}{{/allVars}}
}
{{/vendorExtensions.x-codegen-has-escaped-property-names}}{{/additionalPropertiesType}}

}
91 changes: 91 additions & 0 deletions modules/swagger-codegen/src/test/resources/2_0/swift4Test.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@
"for": {
"description": "This property name is a reserved word in most languages, including Swift 4.",
"type": "string"
},
"normalName": {
"description": "This model object property name should be unchanged from the JSON property name.",
"type": "string"
}
}
},
Expand Down Expand Up @@ -370,6 +374,93 @@
"additionalProperties": {
"type": "string"
}
},
"SampleBase": {
"type": "object",
"description": "This is an base class object from which other classes will derive.",
"properties": {
"baseClassStringProp": {
"type": "string"
},
"baseClassIntegerProp": {
"type": "integer",
"format": "int32"
}
}
},
"SampleSubClass": {
"description": "This is an subclass defived from the SampleBase class.",
"allOf": [
{
"$ref": "#/definitions/SampleBase"
},
{
"type": "object",
"properties": {
"subClassStringProp": {
"type": "string"
},
"subClassIntegerProp": {
"type": "integer",
"format": "int32"
}
}
}
]
},
"BaseCard": {
"type": "object",
"description": "This is a base card object which uses a 'cardType' discriminator.",
"x-unit-tests": ["B45"],
"discriminator": "cardType",
"required": [
"cardType"
],
"properties": {
"cardType": {
"type": "string"
}
}
},
"PersonCard": {
"description": "This is an card object for a Person derived from BaseCard.",
"x-unit-tests": ["B45"],
"allOf": [
{
"$ref": "#/definitions/BaseCard"
},
{
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
}
]
},
"PlaceCard": {
"description": "This is an card object for a Person derived from BaseCard.",
"x-unit-tests": ["B45"],
"allOf": [
{
"$ref": "#/definitions/BaseCard"
},
{
"type": "object",
"properties": {
"placeName": {
"type": "string"
},
"placeAddress": {
"type": "string"
}
}
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.3.0-SNAPSHOT
2.4.0-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// AnotherfakeAPI.swift
// AnotherFakeAPI.swift
//
// Generated by swagger-codegen
// https://github.com/swagger-api/swagger-codegen
Expand All @@ -10,7 +10,7 @@ import Alamofire



open class AnotherfakeAPI {
open class AnotherFakeAPI {
/**
To test special tags

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,17 @@ import Foundation



open class AdditionalPropertiesClass: Codable {
public struct AdditionalPropertiesClass: Codable {

public var mapProperty: [String:String]?
public var mapOfMapProperty: [String:[String:String]]?



public init(mapProperty: [String:String]?, mapOfMapProperty: [String:[String:String]]?) {
self.mapProperty = mapProperty
self.mapOfMapProperty = mapOfMapProperty
public enum CodingKeys: String, CodingKey {
case mapProperty = "map_property"
case mapOfMapProperty = "map_of_map_property"
}


// Encodable protocol methods

public func encode(to encoder: Encoder) throws {

var container = encoder.container(keyedBy: String.self)

try container.encodeIfPresent(mapProperty, forKey: "map_property")
try container.encodeIfPresent(mapOfMapProperty, forKey: "map_of_map_property")
}

// Decodable protocol methods

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: String.self)

mapProperty = try container.decodeIfPresent([String:String].self, forKey: "map_property")
mapOfMapProperty = try container.decodeIfPresent([String:[String:String]].self, forKey: "map_of_map_property")
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,12 @@ import Foundation



open class Animal: Codable {
public struct Animal: Codable {

public var className: String
public var color: String?



public init(className: String, color: String?) {
self.className = className
self.color = color
}


// Encodable protocol methods

public func encode(to encoder: Encoder) throws {

var container = encoder.container(keyedBy: String.self)

try container.encode(className, forKey: "className")
try container.encodeIfPresent(color, forKey: "color")
}

// Decodable protocol methods

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: String.self)

className = try container.decode(String.self, forKey: "className")
color = try container.decodeIfPresent(String.self, forKey: "color")
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,13 @@ import Foundation



open class ApiResponse: Codable {
public struct ApiResponse: Codable {

public var code: Int?
public var type: String?
public var message: String?



public init(code: Int?, type: String?, message: String?) {
self.code = code
self.type = type
self.message = message
}


// Encodable protocol methods

public func encode(to encoder: Encoder) throws {

var container = encoder.container(keyedBy: String.self)

try container.encodeIfPresent(code, forKey: "code")
try container.encodeIfPresent(type, forKey: "type")
try container.encodeIfPresent(message, forKey: "message")
}

// Decodable protocol methods

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: String.self)

code = try container.decodeIfPresent(Int.self, forKey: "code")
type = try container.decodeIfPresent(String.self, forKey: "type")
message = try container.decodeIfPresent(String.self, forKey: "message")
}
}

Loading