Skip to content

Commit 18d9af7

Browse files
committed
Fix trailing space on as keyword
1 parent eb117dc commit 18d9af7

File tree

5 files changed

+133
-13
lines changed

5 files changed

+133
-13
lines changed

CodeGeneration/Sources/generate-swiftbasicformat/BasicFormatFile.swift

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ let basicFormatFile = SourceFile {
5252
open override func visit(_ node: TokenSyntax) -> TokenSyntax {
5353
var leadingTrivia = node.leadingTrivia
5454
var trailingTrivia = node.trailingTrivia
55-
if requiresLeadingSpace(node.tokenKind) && leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
55+
if requiresLeadingSpace(node) && leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
5656
leadingTrivia += .space
5757
}
58-
if requiresTrailingSpace(node.tokenKind) && trailingTrivia.isEmpty {
58+
if requiresTrailingSpace(node) && trailingTrivia.isEmpty {
5959
trailingTrivia += .space
6060
}
6161
if let keyPath = getKeyPath(Syntax(node)), requiresLeadingNewline(keyPath), !(leadingTrivia.first?.isNewline ?? false) {
@@ -121,8 +121,8 @@ let basicFormatFile = SourceFile {
121121
}
122122
}
123123

124-
FunctionDecl("open func requiresLeadingSpace(_ tokenKind: TokenKind) -> Bool") {
125-
SwitchStmt(expression: Expr("tokenKind")) {
124+
FunctionDecl("open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool") {
125+
SwitchStmt(expression: Expr("token.tokenKind")) {
126126
for token in SYNTAX_TOKENS {
127127
if token.requiresLeadingSpace {
128128
SwitchCase("case .\(raw: token.swiftKind):") {
@@ -136,8 +136,66 @@ let basicFormatFile = SourceFile {
136136
}
137137
}
138138

139-
FunctionDecl("open func requiresTrailingSpace(_ tokenKind: TokenKind) -> Bool") {
140-
SwitchStmt(expression: Expr("tokenKind")) {
139+
FunctionDecl("open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool") {
140+
SwitchStmt(expression: Expr("(token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind)")) {
141+
SwitchCase(
142+
label: .case(SwitchCaseLabel {
143+
CaseItem(
144+
pattern: TuplePattern {
145+
TuplePatternElement(
146+
pattern: EnumCasePattern(
147+
period: .period,
148+
caseName: .identifier("asKeyword"))
149+
)
150+
TuplePatternElement(
151+
pattern: EnumCasePattern(
152+
period: .period,
153+
caseName: .identifier("exclamationMark"))
154+
)
155+
},
156+
trailingComma: .comma)
157+
158+
CaseItem(
159+
leadingTrivia: [.newlines(1)],
160+
pattern: TuplePattern {
161+
TuplePatternElement(
162+
pattern: EnumCasePattern(
163+
period: .period,
164+
caseName: .identifier("asKeyword"))
165+
)
166+
TuplePatternElement(
167+
pattern: EnumCasePattern(
168+
period: .period,
169+
caseName: .identifier("postfixQuestionMark"))
170+
)
171+
},
172+
trailingComma: .comma)
173+
174+
CaseItem(
175+
leadingTrivia: [.newlines(1)],
176+
pattern: TuplePattern {
177+
TuplePatternElement(
178+
pattern: EnumCasePattern(
179+
period: .period,
180+
caseName: .identifier("initKeyword"))
181+
)
182+
TuplePatternElement(
183+
pattern: EnumCasePattern(
184+
period: .period,
185+
caseName: .identifier("postfixQuestionMark"))
186+
)
187+
})
188+
})
189+
) {
190+
ReturnStmt("return false")
191+
}
192+
193+
SwitchCase("default:") {
194+
BreakStmt()
195+
}
196+
}
197+
198+
SwitchStmt(expression: Expr("token.tokenKind")) {
141199
for token in SYNTAX_TOKENS {
142200
if token.requiresTrailingSpace {
143201
SwitchCase("case .\(raw: token.swiftKind):") {

Sources/SwiftBasicFormat/generated/BasicFormat.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ open class BasicFormat: SyntaxRewriter {
4848
open override func visit(_ node: TokenSyntax) -> TokenSyntax {
4949
var leadingTrivia = node.leadingTrivia
5050
var trailingTrivia = node.trailingTrivia
51-
if requiresLeadingSpace(node.tokenKind) && leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
51+
if requiresLeadingSpace(node) && leadingTrivia.isEmpty && lastRewrittenToken?.trailingTrivia.isEmpty != false {
5252
leadingTrivia += .space
5353
}
54-
if requiresTrailingSpace(node.tokenKind) && trailingTrivia.isEmpty {
54+
if requiresTrailingSpace(node) && trailingTrivia.isEmpty {
5555
trailingTrivia += .space
5656
}
5757
if let keyPath = getKeyPath(Syntax(node)), requiresLeadingNewline(keyPath), !(leadingTrivia.first?.isNewline ?? false) {
@@ -113,8 +113,8 @@ open class BasicFormat: SyntaxRewriter {
113113
}
114114
}
115115

116-
open func requiresLeadingSpace(_ tokenKind: TokenKind) -> Bool {
117-
switch tokenKind {
116+
open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool {
117+
switch token.tokenKind {
118118
case .whereKeyword:
119119
return true
120120
case .catchKeyword:
@@ -136,8 +136,16 @@ open class BasicFormat: SyntaxRewriter {
136136
}
137137
}
138138

139-
open func requiresTrailingSpace(_ tokenKind: TokenKind) -> Bool {
140-
switch tokenKind {
139+
open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool {
140+
switch (token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind) {
141+
case (.asKeyword, .exclamationMark),
142+
(.asKeyword, .postfixQuestionMark),
143+
(.initKeyword, .postfixQuestionMark):
144+
return false
145+
default:
146+
break
147+
}
148+
switch token.tokenKind {
141149
case .associatedtypeKeyword:
142150
return true
143151
case .classKeyword:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import XCTest
14+
import SwiftSyntax
15+
import SwiftSyntaxBuilder
16+
17+
final class InitializerDeclTests: XCTestCase {
18+
func testInitializerDecl() {
19+
let builder = InitializerDecl("""
20+
public init?(errorCode: Int) {
21+
guard errorCode > 0 else { return nil }
22+
self.code = errorCode
23+
}
24+
""")
25+
26+
print(builder.formatted().description)
27+
28+
AssertBuildResult(builder, """
29+
public init?(errorCode: Int) {
30+
guard errorCode > 0 else {
31+
return nil
32+
}
33+
self.code = errorCode
34+
}
35+
""")
36+
}
37+
}

Tests/SwiftSyntaxBuilderTest/MemberAccessTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import SwiftSyntaxBuilder
1616

1717
final class MemberAccessTests: XCTestCase {
1818
func testMemberAccessExprConvenienceInitializers() {
19-
let builder = MemberAccessExpr( base: "Foo", name: "bar")
19+
let builder = MemberAccessExpr(base: "Foo", name: "bar")
2020
AssertBuildResult(builder, "Foo.bar")
2121
}
2222
}

Tests/SwiftSyntaxBuilderTest/ReturnStmsTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,21 @@ final class ReturnStmtTests: XCTestCase {
2424
""")
2525
}
2626

27+
func testReturnStmtwithAsKeyword() {
28+
let testCases: [UInt: (ReturnStmt, String)] = [
29+
#line: (ReturnStmt("return self.asProtocol(SyntaxProtocol.self) as? DeclSyntaxProtocol"),
30+
"return self.asProtocol(SyntaxProtocol.self) as? DeclSyntaxProtocol"),
31+
#line: (ReturnStmt("return 0 as! String"),
32+
"return 0 as! String"),
33+
#line: (ReturnStmt("return 0 as Double"),
34+
"return 0 as Double"),
35+
#line: (ReturnStmt("return !myBool"),
36+
"return !myBool")
37+
]
38+
39+
for (line, testCase) in testCases {
40+
let (builder, expected) = testCase
41+
AssertBuildResult(builder, expected, line: line)
42+
}
43+
}
2744
}

0 commit comments

Comments
 (0)