Skip to content

Commit 6f58795

Browse files
committed
Improve ValueType.simplified()
1 parent a587319 commit 6f58795

2 files changed

Lines changed: 43 additions & 7 deletions

File tree

ShapeScript/Types.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,14 @@ extension ValueType {
125125
func simplified() -> ValueType {
126126
switch self {
127127
case let .union(types):
128-
let types = types.sorted()
128+
let types = types.flatMap {
129+
switch $0.simplified() {
130+
case let .union(types):
131+
return types
132+
default:
133+
return [$0]
134+
}
135+
}.sorted()
129136
guard var result = types.first.map({ [$0] }) else {
130137
return self
131138
}
@@ -137,9 +144,15 @@ extension ValueType {
137144
result.append(type)
138145
}
139146
return result.count == 1 ? result[0] : .union(Set(result))
147+
case let .list(type):
148+
return .list(type.simplified())
149+
case let .tuple(types):
150+
return .tuple(types.map { $0.simplified() })
151+
case let .object(fields):
152+
return .object(fields.mapValues { $0.simplified() })
140153
case .any, .color, .texture, .material, .boolean, .font, .number, .radians,
141154
.halfturns, .vector, .size, .rotation, .string, .text, .path, .mesh,
142-
.polygon, .point, .range, .partialRange, .bounds, .tuple, .list, .object:
155+
.polygon, .point, .range, .partialRange, .bounds:
143156
return self
144157
}
145158
}

ShapeScriptTests/TypesystemTests.swift

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ final class TypesystemTests: XCTestCase {
506506
}
507507
}
508508
""")
509-
XCTAssertEqual(type.parameterType, .tuple([.union([.numberOrVector, .list(.any)]), .number]))
509+
XCTAssertEqual(type.parameterType, .tuple([.union([.number, .list(.any)]), .number]))
510510
XCTAssertEqual(type.returnType, .void)
511511
}
512512

@@ -521,9 +521,7 @@ final class TypesystemTests: XCTestCase {
521521
}
522522
}
523523
""")
524-
XCTAssertEqual(type.parameterType, .tuple([
525-
.union([.number, .list(.number), .texture]),
526-
]))
524+
XCTAssertEqual(type.parameterType, .tuple([.union([.numberOrVector, .texture]).simplified()]))
527525
XCTAssertEqual(type.returnType, .void)
528526
}
529527

@@ -683,7 +681,7 @@ final class TypesystemTests: XCTestCase {
683681
}
684682
"""
685683
let type = try blockType(in: input)
686-
XCTAssertEqual(type.childTypes, .union([.mesh, .number, .list(.number)]))
684+
XCTAssertEqual(type.childTypes, .union([.mesh, .numberOrVector]).simplified())
687685
XCTAssertEqual(type.returnType, .mesh)
688686

689687
// No arguments
@@ -779,6 +777,31 @@ final class TypesystemTests: XCTestCase {
779777
XCTAssertEqual(type, .any)
780778
}
781779

780+
func testUnionSubtypeSimplification() {
781+
XCTAssertEqual(ValueType.union([.number, .any]).simplified(), .any)
782+
XCTAssertEqual(ValueType.union([.any, .boolean]).simplified(), .any)
783+
XCTAssertEqual(ValueType.union([.list(.any), .list(.number)]).simplified(), .list(.any))
784+
}
785+
786+
func testNestedUnionSimplification() {
787+
XCTAssertEqual(
788+
ValueType.union([.boolean, .union([.number, .string])]).simplified(),
789+
.union([.boolean, .number, .string])
790+
)
791+
XCTAssertEqual(
792+
ValueType.list(.union([.number, .any])).simplified(),
793+
.list(.any)
794+
)
795+
XCTAssertEqual(
796+
ValueType.tuple([.union([.number, .any]), .union([.any, .boolean])]).simplified(),
797+
.tuple([.any, .any])
798+
)
799+
XCTAssertEqual(
800+
ValueType.object(["foo": .union([.number, .any]), "bar": .union([.any, .boolean])]).simplified(),
801+
.object(["foo": .any, "bar": .any])
802+
)
803+
}
804+
782805
// MARK: Type conversion
783806

784807
func testCastNumberToNumberTuple() {

0 commit comments

Comments
 (0)