Skip to content
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

Java equals() should evaluate primitives first #244

Merged
merged 1 commit into from
Aug 28, 2019
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
24 changes: 12 additions & 12 deletions Examples/Java/Sources/Everything.java
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,20 @@ public boolean equals(Object o) {
return false;
}
Everything that = (Everything) o;
return Objects.equals(this.arrayProp, that.arrayProp) &&
Objects.equals(this.booleanProp, that.booleanProp) &&
return Objects.equals(this.unsignedShortEnum, that.unsignedShortEnum) &&
Objects.equals(this.unsignedIntEnum, that.unsignedIntEnum) &&
Objects.equals(this.unsignedCharEnum, that.unsignedCharEnum) &&
Objects.equals(this.stringEnum, that.stringEnum) &&
Objects.equals(this.shortEnum, that.shortEnum) &&
Objects.equals(this.numberProp, that.numberProp) &&
Objects.equals(this.nsuintegerEnum, that.nsuintegerEnum) &&
Objects.equals(this.nsintegerEnum, that.nsintegerEnum) &&
Objects.equals(this.intProp, that.intProp) &&
Objects.equals(this.intEnum, that.intEnum) &&
Objects.equals(this.charEnum, that.charEnum) &&
Objects.equals(this.booleanProp, that.booleanProp) &&
Objects.equals(this.arrayProp, that.arrayProp) &&
Objects.equals(this.dateProp, that.dateProp) &&
Objects.equals(this.intEnum, that.intEnum) &&
Objects.equals(this.intProp, that.intProp) &&
Objects.equals(this.listPolymorphicValues, that.listPolymorphicValues) &&
Objects.equals(this.listWithListAndOtherModelValues, that.listWithListAndOtherModelValues) &&
Objects.equals(this.listWithMapAndOtherModelValues, that.listWithMapAndOtherModelValues) &&
Expand All @@ -347,22 +355,14 @@ public boolean equals(Object o) {
Objects.equals(this.mapWithObjectValues, that.mapWithObjectValues) &&
Objects.equals(this.mapWithOtherModelValues, that.mapWithOtherModelValues) &&
Objects.equals(this.mapWithPrimitiveValues, that.mapWithPrimitiveValues) &&
Objects.equals(this.nsintegerEnum, that.nsintegerEnum) &&
Objects.equals(this.nsuintegerEnum, that.nsuintegerEnum) &&
Objects.equals(this.numberProp, that.numberProp) &&
Objects.equals(this.otherModelProp, that.otherModelProp) &&
Objects.equals(this.polymorphicProp, that.polymorphicProp) &&
Objects.equals(this.setProp, that.setProp) &&
Objects.equals(this.setPropWithOtherModelValues, that.setPropWithOtherModelValues) &&
Objects.equals(this.setPropWithPrimitiveValues, that.setPropWithPrimitiveValues) &&
Objects.equals(this.setPropWithValues, that.setPropWithValues) &&
Objects.equals(this.shortEnum, that.shortEnum) &&
Objects.equals(this.stringEnum, that.stringEnum) &&
Objects.equals(this.stringProp, that.stringProp) &&
Objects.equals(this.type, that.type) &&
Objects.equals(this.unsignedCharEnum, that.unsignedCharEnum) &&
Objects.equals(this.unsignedIntEnum, that.unsignedIntEnum) &&
Objects.equals(this.unsignedShortEnum, that.unsignedShortEnum) &&
Objects.equals(this.uriProp, that.uriProp);
}

Expand Down
6 changes: 3 additions & 3 deletions Examples/Java/Sources/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ public boolean equals(Object o) {
return false;
}
Image that = (Image) o;
return Objects.equals(this.height, that.height) &&
Objects.equals(this.url, that.url) &&
Objects.equals(this.width, that.width);
return Objects.equals(this.width, that.width) &&
Objects.equals(this.height, that.height) &&
Objects.equals(this.url, that.url);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions Examples/Java/Sources/Pin.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ public boolean equals(Object o) {
return false;
}
Pin that = (Pin) o;
return Objects.equals(this.attribution, that.attribution) &&
return Objects.equals(this.inStock, that.inStock) &&
Objects.equals(this.attribution, that.attribution) &&
Objects.equals(this.attributionObjects, that.attributionObjects) &&
Objects.equals(this.board, that.board) &&
Objects.equals(this.color, that.color) &&
Expand All @@ -160,7 +161,6 @@ public boolean equals(Object o) {
Objects.equals(this.description, that.description) &&
Objects.equals(this.uid, that.uid) &&
Objects.equals(this.image, that.image) &&
Objects.equals(this.inStock, that.inStock) &&
Objects.equals(this.link, that.link) &&
Objects.equals(this.media, that.media) &&
Objects.equals(this.note, that.note) &&
Expand Down
4 changes: 2 additions & 2 deletions Examples/Java/Sources/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ public boolean equals(Object o) {
return false;
}
User that = (User) o;
return Objects.equals(this.bio, that.bio) &&
return Objects.equals(this.emailFrequency, that.emailFrequency) &&
Objects.equals(this.bio, that.bio) &&
Objects.equals(this.counts, that.counts) &&
Objects.equals(this.createdAt, that.createdAt) &&
Objects.equals(this.emailFrequency, that.emailFrequency) &&
Objects.equals(this.firstName, that.firstName) &&
Objects.equals(this.uid, that.uid) &&
Objects.equals(this.image, that.image) &&
Expand Down
6 changes: 3 additions & 3 deletions Examples/Java/Sources/VariableSubtitution.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ public boolean equals(Object o) {
return false;
}
VariableSubtitution that = (VariableSubtitution) o;
return Objects.equals(this.allocProp, that.allocProp) &&
Objects.equals(this.copyProp, that.copyProp) &&
return Objects.equals(this.newProp, that.newProp) &&
Objects.equals(this.mutableCopyProp, that.mutableCopyProp) &&
Objects.equals(this.newProp, that.newProp);
Objects.equals(this.copyProp, that.copyProp) &&
Objects.equals(this.allocProp, that.allocProp);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion Sources/Core/JSADTExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension JSModelRenderer {
case .array(itemType: _): return "Array<*>"
case .set(itemType: _): return "Set<*>"
case .map(valueType: .none): return "{}"
case let .map(valueType: .some(valueType)) where valueType.isObjCPrimitiveType:
case let .map(valueType: .some(valueType)) where valueType.isPrimitiveType:
return "{ +[string]: number } /* \(valueType.debugDescription) */"
case let .map(valueType: .some(valueType)):
return "{ +[string]: \(adtCaseTypeName(valueType)) }"
Expand Down
6 changes: 3 additions & 3 deletions Sources/Core/JSFileRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ extension JSFileRenderer {
switch schema.schema {
case .array(itemType: .none):
return "Array<*>"
case let .array(itemType: .some(itemType)) where itemType.isObjCPrimitiveType:
case let .array(itemType: .some(itemType)) where itemType.isPrimitiveType:
// JS primitive types are represented as number
return "Array<number /* \(itemType.debugDescription) */>"
case let .array(itemType: .some(itemType)):
return "Array<\(typeFromSchema(param, itemType.nonnullProperty()))>"
case .set(itemType: .none):
return "Array<*>"
case let .set(itemType: .some(itemType)) where itemType.isObjCPrimitiveType:
case let .set(itemType: .some(itemType)) where itemType.isPrimitiveType:
return "Array<number /* \(itemType.debugDescription)> */>"
case let .set(itemType: .some(itemType)):
return "Array<\(typeFromSchema(param, itemType.nonnullProperty()))>"
case .map(valueType: .none):
return "{}"
case let .map(valueType: .some(valueType)) where valueType.isObjCPrimitiveType:
case let .map(valueType: .some(valueType)) where valueType.isPrimitiveType:
return "{ +[string]: number } /* \(valueType.debugDescription) */"
case let .map(valueType: .some(valueType)):
return "{ +[string]: \(typeFromSchema(param, valueType.nonnullProperty())) }"
Expand Down
4 changes: 3 additions & 1 deletion Sources/Core/JavaModelRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ public struct JavaModelRenderer: JavaFileRenderer {
}

func renderModelEquals() -> JavaIR.Method {
let bodyEquals = transitiveProperties.map { param, _ in
let bodyEquals = transitiveProperties.sorted { arg1, _ in
arg1.1.schema.isPrimitiveType
}.map { param, _ in
"Objects.equals(this." + Languages.java.snakeCaseToPropertyName(param) + ", that." + Languages.java.snakeCaseToPropertyName(param) + ")"
}.joined(separator: " &&\n")

Expand Down
6 changes: 3 additions & 3 deletions Sources/Core/ObjCFileRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ extension ObjCFileRenderer {
switch schema.schema {
case .array(itemType: .none):
return "NSArray *"
case let .array(itemType: .some(itemType)) where itemType.isObjCPrimitiveType:
case let .array(itemType: .some(itemType)) where itemType.isPrimitiveType:
// Objective-C primitive types are represented as NSNumber
return "NSArray<NSNumber /* \(itemType.debugDescription) */ *> *"
case let .array(itemType: .some(itemType)):
return "NSArray<\(typeFromSchema(param, itemType.nonnullProperty()))> *"
case .set(itemType: .none):
return "NSSet *"
case let .set(itemType: .some(itemType)) where itemType.isObjCPrimitiveType:
case let .set(itemType: .some(itemType)) where itemType.isPrimitiveType:
return "NSSet<NSNumber /*> \(itemType.debugDescription) */ *> *"
case let .set(itemType: .some(itemType)):
return "NSSet<\(typeFromSchema(param, itemType.nonnullProperty()))> *"
case .map(valueType: .none):
return "NSDictionary *"
case let .map(valueType: .some(valueType)) where valueType.isObjCPrimitiveType:
case let .map(valueType: .some(valueType)) where valueType.isPrimitiveType:
return "NSDictionary<NSString *, NSNumber /* \(valueType.debugDescription) */ *> *"
case let .map(valueType: .some(valueType)):
return "NSDictionary<NSString *, \(typeFromSchema(param, valueType.nonnullProperty()))> *"
Expand Down
6 changes: 3 additions & 3 deletions Sources/Core/ObjCModelRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ public struct ObjCModelRenderer: ObjCFileRenderer {
let adtRoots = properties.flatMap { (param, prop) -> [ObjCIR.Root] in
switch prop.schema {
case let .oneOf(types: possibleTypes):
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isObjCPrimitiveType ? nil : .nullable) }
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isPrimitiveType ? nil : .nullable) }
return adtRootsForSchema(property: param, schemas: objProps)
case let .array(itemType: .some(itemType)):
switch itemType {
case let .oneOf(types: possibleTypes):
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isObjCPrimitiveType ? nil : .nullable) }
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isPrimitiveType ? nil : .nullable) }
return adtRootsForSchema(property: param, schemas: objProps)
default: return []
}
case let .map(valueType: .some(additionalProperties)):
switch additionalProperties {
case let .oneOf(types: possibleTypes):
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isObjCPrimitiveType ? nil : .nullable) }
let objProps = possibleTypes.map { SchemaObjectProperty(schema: $0, nullability: $0.isPrimitiveType ? nil : .nullable) }
return adtRootsForSchema(property: param, schemas: objProps)
default: return []
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Core/ObjectiveCDictionaryExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension ObjCModelRenderer {
!schema.schema.isBoolean()
}.map { (param, schemaObj) -> String in
ObjCIR.ifStmt("_" + "\(self.dirtyPropertiesIVarName).\(dirtyPropertyOption(propertyName: param, className: self.className))") { [
schemaObj.schema.isObjCPrimitiveType ?
schemaObj.schema.isPrimitiveType ?
self.renderAddToDictionaryStatement(.ivar(param), schemaObj.schema, dictionary) :
ObjCIR.ifElseStmt("_\(Languages.objectiveC.snakeCaseToPropertyName(param)) != nil") { [
self.renderAddToDictionaryStatement(.ivar(param), schemaObj.schema, dictionary),
Expand Down Expand Up @@ -202,7 +202,7 @@ extension ObjCFileRenderer {
}
let currentResult = "result\(counter)"
let currentObj = "obj\(counter)"
let itemClass = itemType.isObjCPrimitiveType ? "id" : typeFromSchema(param, itemType.nonnullProperty())
let itemClass = itemType.isPrimitiveType ? "id" : typeFromSchema(param, itemType.nonnullProperty())
return [
"__auto_type items\(counter) = \(propIVarName);",
"\(CollectionClass.array.mutableName()) *\(currentResult) = [\(CollectionClass.array.mutableName()) \(CollectionClass.array.initializer())items\(counter).count];",
Expand Down
2 changes: 1 addition & 1 deletion Sources/Core/ObjectiveCEqualityExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ extension ObjCFileRenderer {

// Performance optimization - compare primitives before resorting to more expensive `isEqual` calls
let sortedProps = properties.sorted { arg1, _ in
arg1.1.schema.isObjCPrimitiveType
arg1.1.schema.isPrimitiveType
}

let propReturnStmts = sortedProps.map { param, prop -> String in
Expand Down
9 changes: 0 additions & 9 deletions Sources/Core/ObjectiveCIR.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,6 @@ extension SchemaObjectRoot {
}

extension Schema {
var isObjCPrimitiveType: Bool {
switch self {
case .boolean, .integer, .enumT, .float:
return true
default:
return false
}
}

func memoryAssignmentType() -> ObjCMemoryAssignmentType {
switch self {
// Use copy for any string, date, url etc.
Expand Down
6 changes: 3 additions & 3 deletions Sources/Core/ObjectiveCInitExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ extension ObjCModelRenderer {
let currentResult = "result\(counter)"
let currentTmp = "tmp\(counter)"
let currentObj = "obj\(counter)"
if itemType.isObjCPrimitiveType {
if itemType.isPrimitiveType {
return [
"\(propertyToAssign) = \(rawObjectName);",
]
Expand All @@ -104,7 +104,7 @@ extension ObjCModelRenderer {
let currentTmp = "tmp\(counter)"
let currentObj = "obj\(counter)"

if itemType.isObjCPrimitiveType {
if itemType.isPrimitiveType {
return [
"NSArray *items = \(rawObjectName);",
"\(propertyToAssign) = [NSSet setWithArray:items];",
Expand All @@ -125,7 +125,7 @@ extension ObjCModelRenderer {
] },
"\(propertyToAssign) = \(currentResult);",
]
case let .map(valueType: .some(valueType)) where valueType.isObjCPrimitiveType == false:
case let .map(valueType: .some(valueType)) where valueType.isPrimitiveType == false:
let currentResult = "result\(counter)"
let currentItems = "items\(counter)"
let (currentKey, currentObj, currentStop) = ("key\(counter)", "obj\(counter)", "stop\(counter)")
Expand Down
11 changes: 10 additions & 1 deletion Sources/Core/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ public indirect enum Schema {
case oneOf(types: [Schema]) // ADT
case enumT(EnumType)
case reference(with: URLSchemaReference)

var isPrimitiveType: Bool {
switch self {
case .boolean, .integer, .enumT, .float:
return true
default:
return false
}
}
}

typealias Property = (Parameter, SchemaObjectProperty)
Expand Down Expand Up @@ -306,7 +315,7 @@ extension Schema {
}
return (key, schemaOpt)
}.map { name, optSchema in optSchema.map {
(name, SchemaObjectProperty(schema: $0, nullability: $0.isObjCPrimitiveType ? nil : requiredProps.contains(name) ? .nonnull : .nullable))
(name, SchemaObjectProperty(schema: $0, nullability: $0.isPrimitiveType ? nil : requiredProps.contains(name) ? .nonnull : .nullable))
}
}
let lifted: [Property]? = optTuples.reduce([], { (build: [Property]?, tupleOption: Property?) -> [Property]? in
Expand Down