Skip to content

Commit 8936b6e

Browse files
authored
Merge pull request #1164 from kimdv/kimdv/fix-spacing
Fix spacing around `<`, `>`, `*`, `!` and `?`
2 parents 50a322c + a3ef115 commit 8936b6e

File tree

10 files changed

+394
-38
lines changed

10 files changed

+394
-38
lines changed

CodeGeneration/Sources/SyntaxSupport/gyb_generated/TokenSpec.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ public let SYNTAX_TOKENS: [TokenSpec] = [
261261
PunctuatorSpec(name: "RightBrace", kind: "r_brace", text: "}"),
262262
PunctuatorSpec(name: "LeftSquareBracket", kind: "l_square", text: "["),
263263
PunctuatorSpec(name: "RightSquareBracket", kind: "r_square", text: "]"),
264-
PunctuatorSpec(name: "LeftAngle", kind: "l_angle", text: "<", requiresLeadingSpace: true, requiresTrailingSpace: true),
265-
PunctuatorSpec(name: "RightAngle", kind: "r_angle", text: ">", requiresLeadingSpace: true, requiresTrailingSpace: true),
264+
PunctuatorSpec(name: "LeftAngle", kind: "l_angle", text: "<"),
265+
PunctuatorSpec(name: "RightAngle", kind: "r_angle", text: ">"),
266266
PunctuatorSpec(name: "Period", kind: "period", text: "."),
267267
PunctuatorSpec(name: "Comma", kind: "comma", text: ",", requiresTrailingSpace: true),
268268
PunctuatorSpec(name: "Ellipsis", kind: "ellipsis", text: "..."),
@@ -275,8 +275,8 @@ public let SYNTAX_TOKENS: [TokenSpec] = [
275275
PunctuatorSpec(name: "Arrow", kind: "arrow", text: "->", requiresLeadingSpace: true, requiresTrailingSpace: true),
276276
PunctuatorSpec(name: "Backtick", kind: "backtick", text: "`"),
277277
PunctuatorSpec(name: "Backslash", kind: "backslash", text: "\\"),
278-
PunctuatorSpec(name: "ExclamationMark", kind: "exclaim_postfix", text: "!"),
279-
PunctuatorSpec(name: "PostfixQuestionMark", kind: "question_postfix", text: "?"),
278+
PunctuatorSpec(name: "ExclamationMark", kind: "exclaim_postfix", text: "!", requiresTrailingSpace: true),
279+
PunctuatorSpec(name: "PostfixQuestionMark", kind: "question_postfix", text: "?", requiresTrailingSpace: true),
280280
PunctuatorSpec(name: "InfixQuestionMark", kind: "question_infix", text: "?"),
281281
PunctuatorSpec(name: "StringQuote", kind: "string_quote", text: "\"", classification: "StringLiteral"),
282282
PunctuatorSpec(name: "SingleQuote", kind: "single_quote", text: "\'", classification: "StringLiteral"),

CodeGeneration/Sources/generate-swiftsyntax/templates/basicformat/BasicFormatFile.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ let basicFormatFile = SourceFile {
122122
}
123123

124124
FunctionDecl("open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool") {
125+
SwitchStmt("""
126+
switch (token.previousToken(viewMode: .sourceAccurate)?.tokenKind, token.tokenKind) {
127+
case (.leftParen, .spacedBinaryOperator):
128+
return false
129+
default:
130+
break
131+
}
132+
""")
133+
125134
SwitchStmt(expression: Expr("token.tokenKind")) {
126135
for token in SYNTAX_TOKENS {
127136
if token.requiresLeadingSpace {
@@ -146,12 +155,19 @@ let basicFormatFile = SourceFile {
146155

147156
SwitchStmt("""
148157
switch (token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind) {
149-
case (.asKeyword, .exclamationMark),
150-
(.asKeyword, .postfixQuestionMark),
151-
(.initKeyword, .leftParen),
152-
(.initKeyword, .postfixQuestionMark),
153-
(.tryKeyword, .exclamationMark),
154-
(.tryKeyword, .postfixQuestionMark):
158+
case (.asKeyword, .exclamationMark), // Ensures there is not space in `as!`
159+
(.asKeyword, .postfixQuestionMark), // Ensures there is not space in `as?`
160+
(.exclamationMark, .leftParen), // Ensures there is not space in `myOptionalClosure!()`
161+
(.exclamationMark, .period), // Ensures there is not space in `myOptionalBar!.foo()`
162+
(.initKeyword, .leftParen), // Ensures there is not space in `init()`
163+
(.initKeyword, .postfixQuestionMark), // Ensures there is not space in `init?`
164+
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()`
165+
(.postfixQuestionMark, .rightAngle), // Ensures there is not space in `ContiguousArray<RawSyntax?>`
166+
(.postfixQuestionMark, .rightParen), // Ensures there is not space in `myOptionalClosure?()`
167+
(.tryKeyword, .exclamationMark), // Ensures there is not space in `try!`
168+
(.tryKeyword, .postfixQuestionMark): // Ensures there is not space in `try?`
169+
return false
170+
case (.spacedBinaryOperator, .comma):
155171
return false
156172
default:
157173
break

Sources/SwiftBasicFormat/generated/BasicFormat.swift

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ open class BasicFormat: SyntaxRewriter {
136136
}
137137

138138
open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool {
139+
switch (token.previousToken(viewMode: .sourceAccurate)?.tokenKind, token.tokenKind) {
140+
case (.leftParen, .spacedBinaryOperator):
141+
return false
142+
default:
143+
break
144+
}
139145
switch token.tokenKind {
140146
case .inKeyword:
141147
return true
@@ -145,10 +151,6 @@ open class BasicFormat: SyntaxRewriter {
145151
return true
146152
case .leftBrace:
147153
return true
148-
case .leftAngle:
149-
return true
150-
case .rightAngle:
151-
return true
152154
case .equal:
153155
return true
154156
case .arrow:
@@ -166,12 +168,19 @@ open class BasicFormat: SyntaxRewriter {
166168
return false
167169
}
168170
switch (token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind) {
169-
case (.asKeyword, .exclamationMark),
170-
(.asKeyword, .postfixQuestionMark),
171-
(.initKeyword, .leftParen),
172-
(.initKeyword, .postfixQuestionMark),
173-
(.tryKeyword, .exclamationMark),
174-
(.tryKeyword, .postfixQuestionMark):
171+
case (.asKeyword, .exclamationMark), // Ensures there is not space in `as!`
172+
(.asKeyword, .postfixQuestionMark), // Ensures there is not space in `as?`
173+
(.exclamationMark, .leftParen), // Ensures there is not space in `myOptionalClosure!()`
174+
(.exclamationMark, .period), // Ensures there is not space in `myOptionalBar!.foo()`
175+
(.initKeyword, .leftParen), // Ensures there is not space in `init()`
176+
(.initKeyword, .postfixQuestionMark), // Ensures there is not space in `init?`
177+
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()`
178+
(.postfixQuestionMark, .rightAngle), // Ensures there is not space in `ContiguousArray<RawSyntax?>`
179+
(.postfixQuestionMark, .rightParen), // Ensures there is not space in `myOptionalClosure?()`
180+
(.tryKeyword, .exclamationMark), // Ensures there is not space in `try!`
181+
(.tryKeyword, .postfixQuestionMark): // Ensures there is not space in `try?`
182+
return false
183+
case (.spacedBinaryOperator, .comma):
175184
return false
176185
default:
177186
break
@@ -267,10 +276,6 @@ open class BasicFormat: SyntaxRewriter {
267276
return true
268277
case .wildcardKeyword:
269278
return true
270-
case .leftAngle:
271-
return true
272-
case .rightAngle:
273-
return true
274279
case .comma:
275280
return true
276281
case .colon:
@@ -279,6 +284,10 @@ open class BasicFormat: SyntaxRewriter {
279284
return true
280285
case .arrow:
281286
return true
287+
case .exclamationMark:
288+
return true
289+
case .postfixQuestionMark:
290+
return true
282291
case .poundKeyPathKeyword:
283292
return true
284293
case .poundLineKeyword:

Sources/SwiftSyntax/gyb_generated/SyntaxFactory.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9039,17 +9039,17 @@ public enum SyntaxFactory {
90399039
}
90409040
@available(*, deprecated, message: "Use TokenSyntax.leftAngleToken instead")
90419041
public static func makeLeftAngleToken(
9042-
leadingTrivia: Trivia = .space,
9043-
trailingTrivia: Trivia = .space
9042+
leadingTrivia: Trivia = [],
9043+
trailingTrivia: Trivia = []
90449044
) -> TokenSyntax {
90459045
return makeToken(.leftAngle, presence: .present,
90469046
leadingTrivia: leadingTrivia,
90479047
trailingTrivia: trailingTrivia)
90489048
}
90499049
@available(*, deprecated, message: "Use TokenSyntax.rightAngleToken instead")
90509050
public static func makeRightAngleToken(
9051-
leadingTrivia: Trivia = .space,
9052-
trailingTrivia: Trivia = .space
9051+
leadingTrivia: Trivia = [],
9052+
trailingTrivia: Trivia = []
90539053
) -> TokenSyntax {
90549054
return makeToken(.rightAngle, presence: .present,
90559055
leadingTrivia: leadingTrivia,
@@ -9166,7 +9166,7 @@ public enum SyntaxFactory {
91669166
@available(*, deprecated, message: "Use TokenSyntax.exclamationMarkToken instead")
91679167
public static func makeExclamationMarkToken(
91689168
leadingTrivia: Trivia = [],
9169-
trailingTrivia: Trivia = []
9169+
trailingTrivia: Trivia = .space
91709170
) -> TokenSyntax {
91719171
return makeToken(.exclamationMark, presence: .present,
91729172
leadingTrivia: leadingTrivia,
@@ -9175,7 +9175,7 @@ public enum SyntaxFactory {
91759175
@available(*, deprecated, message: "Use TokenSyntax.postfixQuestionMarkToken instead")
91769176
public static func makePostfixQuestionMarkToken(
91779177
leadingTrivia: Trivia = [],
9178-
trailingTrivia: Trivia = []
9178+
trailingTrivia: Trivia = .space
91799179
) -> TokenSyntax {
91809180
return makeToken(.postfixQuestionMark, presence: .present,
91819181
leadingTrivia: leadingTrivia,

Tests/SwiftSyntaxBuilderTest/DoStmtTests.swift

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,104 @@ final class DoStmtTests: XCTestCase {
6464
"""
6565
)
6666
}
67+
68+
func testDoStmtWithExclamationMark() {
69+
let buildable = DoStmt(
70+
body: CodeBlock(statementsBuilder: {
71+
TryExpr(questionOrExclamationMark: .exclamationMark, expression: FunctionCallExpr(callee: ExprSyntax("a.b")))
72+
}),
73+
catchClauses: [
74+
CatchClause(
75+
CatchItemList {
76+
CatchItem(pattern: PatternSyntax("Error1"))
77+
CatchItem(pattern: PatternSyntax("Error2"))
78+
}
79+
) {
80+
FunctionCallExpr(callee: ExprSyntax("print")) {
81+
TupleExprElement(expression: StringLiteralExpr(content: "Known error"))
82+
}
83+
},
84+
CatchClause(
85+
CatchItemList {
86+
CatchItem(
87+
pattern: PatternSyntax("Error3"),
88+
whereClause: WhereClause(guardResult: MemberAccessExpr(base: "error", name: "isError4"))
89+
)
90+
}
91+
) {
92+
ThrowStmt(expression: MemberAccessExpr(base: "Error4", name: "error3"))
93+
},
94+
CatchClause {
95+
FunctionCallExprSyntax(callee: ExprSyntax("print")) {
96+
TupleExprElementSyntax(expression: Expr("error"))
97+
}
98+
},
99+
]
100+
)
101+
102+
AssertBuildResult(
103+
buildable,
104+
"""
105+
do {
106+
try! a.b()
107+
} catch Error1, Error2 {
108+
print("Known error")
109+
} catch Error3 where error.isError4 {
110+
throw Error4.error3
111+
} catch {
112+
print(error)
113+
}
114+
"""
115+
)
116+
}
117+
118+
func testDoStmtWithPostfixQuestionMark() {
119+
let buildable = DoStmt(
120+
body: CodeBlock(statementsBuilder: {
121+
TryExpr(questionOrExclamationMark: .postfixQuestionMark, expression: FunctionCallExpr(callee: ExprSyntax("a.b")))
122+
}),
123+
catchClauses: [
124+
CatchClause(
125+
CatchItemList {
126+
CatchItem(pattern: PatternSyntax("Error1"))
127+
CatchItem(pattern: PatternSyntax("Error2"))
128+
}
129+
) {
130+
FunctionCallExpr(callee: ExprSyntax("print")) {
131+
TupleExprElement(expression: StringLiteralExpr(content: "Known error"))
132+
}
133+
},
134+
CatchClause(
135+
CatchItemList {
136+
CatchItem(
137+
pattern: PatternSyntax("Error3"),
138+
whereClause: WhereClause(guardResult: MemberAccessExpr(base: "error", name: "isError4"))
139+
)
140+
}
141+
) {
142+
ThrowStmt(expression: MemberAccessExpr(base: "Error4", name: "error3"))
143+
},
144+
CatchClause {
145+
FunctionCallExprSyntax(callee: ExprSyntax("print")) {
146+
TupleExprElementSyntax(expression: Expr("error"))
147+
}
148+
},
149+
]
150+
)
151+
152+
AssertBuildResult(
153+
buildable,
154+
"""
155+
do {
156+
try? a.b()
157+
} catch Error1, Error2 {
158+
print("Known error")
159+
} catch Error3 where error.isError4 {
160+
throw Error4.error3
161+
} catch {
162+
print(error)
163+
}
164+
"""
165+
)
166+
}
67167
}

0 commit comments

Comments
 (0)