Skip to content

Commit 3a582ee

Browse files
committed
Add support for optional return types
1 parent 7770ffa commit 3a582ee

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

Sources/existentialannotator/Annotator.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,22 @@ final class Annotator: SyntaxRewriter {
126126
return node
127127
}
128128
let currentTypeWithoutAnyKeyword = node.returnType
129-
let typeWithAnyKeyword = withExistentialAny(currentTypeWithoutAnyKeyword)
130-
.withTrailingTrivia([.spaces(1)])
129+
130+
var typeWithAnyKeyword: TypeSyntax {
131+
if let lastToken = currentTypeWithoutAnyKeyword.lastToken, lastToken.isOptionalNotation {
132+
let typeString = "(\(withExistentialAny(currentTypeWithoutAnyKeyword.rawStringRepresentation)))\(lastToken.description)"
133+
return TypeSyntax(stringLiteral: typeString)
134+
}
135+
return withExistentialAny(currentTypeWithoutAnyKeyword)
136+
.withTrailingTrivia([.spaces(1)])
137+
}
131138

132139
let modifiedNode = node.withReturnType(typeWithAnyKeyword)
133140
return modifiedNode
134141
}
135142

136143
private func isOptional(tokens: TokenSequence) -> (isOptional: Bool, optionalNotation: String) {
137-
let token = tokens.first(where: {
138-
$0.tokenKind == .postfixQuestionMark || $0.tokenKind == .exclamationMark
139-
})
144+
let token = tokens.first(where: { $0.isOptionalNotation })
140145
let notation = token?.description ?? ""
141146
let isOptional = !notation.isEmpty
142147
return (isOptional: isOptional, optionalNotation: notation)
@@ -166,3 +171,9 @@ extension VariableDeclSyntax {
166171
return description.contains("[\(type)]")
167172
}
168173
}
174+
175+
private extension TokenSyntax {
176+
var isOptionalNotation: Bool {
177+
tokenKind == .postfixQuestionMark || tokenKind == .exclamationMark
178+
}
179+
}

Tests/existentialannotatorTests/ExistentialAnnotatorTests.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,28 @@ final class ExistentialAnnotatorTests: XCTestCase {
511511
XCTAssertEqual(annotated.description, expected)
512512
}
513513

514-
func testThatExistentialIsAnnotatedWhenUsedInCollection() throws {
514+
func testThatExistentialIsAnnotatedWhenUsedAsOptionalReturnType() throws {
515+
let exampleFile = #"""
516+
private func getValue(forKey key: String) -> NSCoding? {
517+
return "some key"
518+
}
519+
"""#
520+
521+
let sut = Annotator(protocols: ["NSCoding"])
522+
let parsedSource = try SyntaxParser.parse(source: exampleFile)
523+
524+
let annotated = sut.visit(parsedSource)
525+
526+
let expected = #"""
527+
private func getValue(forKey key: String) -> (any NSCoding)? {
528+
return "some key"
529+
}
530+
"""#
531+
532+
XCTAssertEqual(annotated.description, expected)
533+
}
534+
535+
func testThatExistentialIsAnnotatedWhenUsedInArray() throws {
515536
let exampleFile = #"""
516537
struct MyType {
517538
let responses: [Decodable]

0 commit comments

Comments
 (0)