Skip to content

Commit 358c7b7

Browse files
Adding successTypeIsOptional to Result type (#65)
1 parent ea84efa commit 358c7b7

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

Sources/SyntaxSparrow/Internal/Extensions/EntityType+Parsing.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@ import Foundation
99
import SwiftSyntax
1010

1111
extension EntityType {
12+
13+
var isClosure: Bool {
14+
switch self {
15+
case .closure:
16+
return true
17+
default:
18+
return false
19+
}
20+
}
21+
22+
var isTuple: Bool {
23+
switch self {
24+
case .closure:
25+
return true
26+
default:
27+
return false
28+
}
29+
}
30+
1231
var isVoid: Bool {
1332
switch self {
1433
case .void:

Sources/SyntaxSparrow/Internal/Resolvers/Syntax/ResultSemanticsResolver.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ struct ResultSemanticsResolver: SemanticsResolving {
4343
return EntityType(successType.argument)
4444
}
4545

46+
func resolveSuccessTypeIsOptional() -> Bool {
47+
guard
48+
let arguments = node.genericArgumentClause?.arguments,
49+
arguments.count == 2,
50+
let successType = arguments.first
51+
else {
52+
return false
53+
}
54+
return successType.resolveIsSyntaxOptional()
55+
}
56+
4657
func resolveFailureType() -> EntityType {
4758
guard
4859
let arguments = node.genericArgumentClause?.arguments,

Sources/SyntaxSparrow/Public/Semantics/Components/Result.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ public struct Result: Hashable, Equatable, CustomStringConvertible {
3737
/// For example, `Result<String, Error>?` has `isOptional` as `true`.
3838
public var isOptional: Bool { resolver.resolveIsOptional() }
3939

40+
/// Bool indicating whether the resolved `successType` property is optional.
41+
///
42+
/// For example:
43+
/// ```swift
44+
/// Result<String?, Error>
45+
/// Result<String, Error>
46+
/// ```
47+
/// - The `successType` is `.simple("String?")` and `outputIsOptional` is `true`
48+
/// - The `successType` is `.simple("String")` and `outputIsOptional` is `false`
49+
///
50+
/// **Note:** Value will be `false` when the `output` is `nil`
51+
public var successTypeIsOptional: Bool { resolver.resolveSuccessTypeIsOptional() }
52+
4053
// MARK: - Properties: Convenience
4154

4255
private(set) var resolver: ResultSemanticsResolver

Tests/SyntaxSparrowTests/Supporting Types/ResultTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,51 @@ final class ResultTests: XCTestCase {
2424
}
2525

2626
// MARK: - Tests
27+
28+
func test_successTypeIsOptional_willResolveExpectedFlag() throws {
29+
let source = #"""
30+
typealias Example = Result<String, Error>
31+
typealias Example = Result<String?, Error>
32+
typealias Example = Result<() -> Void, Error>
33+
typealias Example = Result<(() -> Void)?, Error>
34+
typealias Example = Result<(name: String, age: Int), Error>
35+
typealias Example = Result<(name: String, age: Int)?, Error>
36+
"""#
37+
instanceUnderTest.updateToSource(source)
38+
XCTAssertTrue(instanceUnderTest.isStale)
39+
instanceUnderTest.collectChildren()
40+
XCTAssertFalse(instanceUnderTest.isStale)
41+
XCTAssertEqual(instanceUnderTest.typealiases.count, 6)
42+
43+
let results = instanceUnderTest.typealiases.map(\.initializedType)
44+
45+
for i in 0..<4 {
46+
if case let EntityType.result(wrappedResult) = results[i] {
47+
switch i {
48+
case 0:
49+
XCTAssertEqual(wrappedResult.successType, .simple("String"))
50+
XCTAssertFalse(wrappedResult.successTypeIsOptional)
51+
case 1:
52+
XCTAssertEqual(wrappedResult.successType, .simple("String?"))
53+
XCTAssertTrue(wrappedResult.successTypeIsOptional)
54+
case 2:
55+
XCTAssertTrue(wrappedResult.successType.isClosure)
56+
XCTAssertFalse(wrappedResult.successTypeIsOptional)
57+
case 3:
58+
XCTAssertTrue(wrappedResult.successType.isClosure)
59+
XCTAssertTrue(wrappedResult.successTypeIsOptional)
60+
case 4:
61+
XCTAssertTrue(wrappedResult.successType.isTuple)
62+
XCTAssertFalse(wrappedResult.successTypeIsOptional)
63+
case 5:
64+
XCTAssertTrue(wrappedResult.successType.isTuple)
65+
XCTAssertTrue(wrappedResult.successTypeIsOptional)
66+
default:
67+
break
68+
}
69+
} else {
70+
XCTFail("Should have result object")
71+
}
72+
}
73+
}
2774
}

0 commit comments

Comments
 (0)