Skip to content

Commit 91aaff8

Browse files
committed
Merge branch 'main' of https://github.com/apple/swift-syntax into package-attr
2 parents 10e8853 + 3ac962d commit 91aaff8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+906
-10272
lines changed

CodeGeneration/Sources/SyntaxSupport/Child.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ public enum ChildKind {
3232
/// The child is a collection of `kind`.
3333
case collection(kind: String, collectionElementName: String)
3434
/// The child is a token that matches one of the given `choices`.
35-
case token(choices: [TokenChoice])
35+
/// If `requiresLeadingSpace` or `requiresTrailingSpace` is not `nil`, it
36+
/// overrides the default leading/trailing space behavior of the token.
37+
case token(choices: [TokenChoice], requiresLeadingSpace: Bool? = nil, requiresTrailingSpace: Bool? = nil)
3638

3739
public var isNodeChoices: Bool {
3840
if case .nodeChoices = self {
@@ -67,7 +69,7 @@ public class Child {
6769
return "syntax"
6870
case .collection(kind: let kind, collectionElementName: _):
6971
return kind
70-
case .token(choices: let choices):
72+
case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _):
7173
if choices.count == 1 {
7274
switch choices.first! {
7375
case .keyword: return "KeywordToken"

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public let KEYWORDS: [KeywordSpec] = [
112112
KeywordSpec("cType"),
113113
KeywordSpec("default", isLexerClassified: true),
114114
KeywordSpec("defer", isLexerClassified: true, requiresTrailingSpace: true),
115-
KeywordSpec("deinit", isLexerClassified: true, requiresTrailingSpace: true),
115+
KeywordSpec("deinit", isLexerClassified: true),
116116
KeywordSpec("deprecated"),
117117
KeywordSpec("derivative"),
118118
KeywordSpec("didSet"),
@@ -146,7 +146,7 @@ public let KEYWORDS: [KeywordSpec] = [
146146
KeywordSpec("in", isLexerClassified: true, requiresLeadingSpace: true, requiresTrailingSpace: true),
147147
KeywordSpec("indirect"),
148148
KeywordSpec("infix"),
149-
KeywordSpec("init", isLexerClassified: true, requiresTrailingSpace: true),
149+
KeywordSpec("init", isLexerClassified: true),
150150
KeywordSpec("inline"),
151151
KeywordSpec("inout", isLexerClassified: true, requiresTrailingSpace: true),
152152
KeywordSpec("internal", isLexerClassified: true, requiresTrailingSpace: true),

CodeGeneration/Sources/SyntaxSupport/gyb_generated/AttributeNodes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ public let ATTRIBUTE_NODES: [Node] = [
618618
kind: "Syntax",
619619
children: [
620620
Child(name: "ForLabel",
621-
kind: .token(choices: [.keyword(text: "for")])),
621+
kind: .token(choices: [.keyword(text: "for")], requiresTrailingSpace: false)),
622622
Child(name: "Colon",
623623
kind: .token(choices: [.token(tokenKind: "ColonToken")])),
624624
Child(name: "Declname",

CodeGeneration/Sources/SyntaxSupport/gyb_generated/AvailabilityNodes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public let AVAILABILITY_NODES: [Node] = [
2626
Child(name: "Entry",
2727
kind: .nodeChoices(choices: [
2828
Child(name: "Token",
29-
kind: .token(choices: [.token(tokenKind: "BinaryOperatorToken"), .token(tokenKind: "IdentifierToken")])),
29+
kind: .token(choices: [.token(tokenKind: "BinaryOperatorToken"), .token(tokenKind: "IdentifierToken")], requiresLeadingSpace: false, requiresTrailingSpace: false)),
3030
Child(name: "AvailabilityVersionRestriction",
3131
kind: .node(kind: "AvailabilityVersionRestriction")),
3232
Child(name: "AvailabilityLabeledArgument",

CodeGeneration/Sources/SyntaxSupport/gyb_generated/ExprNodes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public let EXPR_NODES: [Node] = [
5252
Child(name: "TryKeyword",
5353
kind: .token(choices: [.keyword(text: "try")])),
5454
Child(name: "QuestionOrExclamationMark",
55-
kind: .token(choices: [.token(tokenKind: "PostfixQuestionMarkToken"), .token(tokenKind: "ExclamationMarkToken")]),
55+
kind: .token(choices: [.token(tokenKind: "PostfixQuestionMarkToken"), .token(tokenKind: "ExclamationMarkToken")], requiresTrailingSpace: true),
5656
isOptional: true),
5757
Child(name: "Expression",
5858
kind: .node(kind: "Expr"))
@@ -284,7 +284,7 @@ public let EXPR_NODES: [Node] = [
284284
Child(name: "Content",
285285
kind: .nodeChoices(choices: [
286286
Child(name: "Colon",
287-
kind: .token(choices: [.token(tokenKind: "ColonToken")])),
287+
kind: .token(choices: [.token(tokenKind: "ColonToken")], requiresTrailingSpace: false)),
288288
Child(name: "Elements",
289289
kind: .node(kind: "DictionaryElementList"))
290290
]),

CodeGeneration/Sources/SyntaxSupport/gyb_helpers/utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,13 @@ def make_swift_child(child, spaces):
5959
mapped_choices = [f'.token(tokenKind: "{choice.name}Token")' for (choice, text) in child.token_choices if text is None]
6060
mapped_choices += [f'.keyword(text: "{text}")' for (choice, text) in child.token_choices if text is not None]
6161
joined_choices = ', '.join(mapped_choices)
62-
kind = f'.token(choices: [{joined_choices}])'
62+
token_arguments = [f'choices: [{joined_choices}]']
63+
if child.requires_leading_space is not None:
64+
token_arguments += ['requiresLeadingSpace: ' + ('true' if child.requires_leading_space else 'false')]
65+
if child.requires_trailing_space is not None:
66+
token_arguments += ['requiresTrailingSpace: ' + ('true' if child.requires_trailing_space else 'false')]
67+
arguments = ', '.join(token_arguments)
68+
kind = f'.token({arguments})'
6369
elif child.collection_element_name:
6470
kind = f'.collection(kind: "{child.syntax_kind}", collectionElementName: "{child.collection_element_name}")'
6571
elif child.node_choices:

CodeGeneration/Sources/Utils/SyntaxBuildableChild.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public extension Child {
4747

4848
var defaultInitialization: ExprSyntax? {
4949
switch kind {
50-
case .token(choices: let choices):
50+
case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _):
5151
if choices.count == 1, case .keyword(text: let text) = choices.first {
5252
var textChoice = text
5353
if textChoice == "init" {
@@ -66,7 +66,7 @@ public extension Child {
6666
/// `assert` statement that verifies the variable with name var_name and of type
6767
/// `TokenSyntax` contains one of the supported text options. Otherwise return `nil`.
6868
func generateAssertStmtTextChoices(varName: String) -> FunctionCallExprSyntax? {
69-
guard case .token(choices: let choices) = kind else {
69+
guard case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _) = kind else {
7070
return nil
7171
}
7272

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

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,40 @@ import SwiftSyntaxBuilder
1515
import SyntaxSupport
1616
import Utils
1717

18+
extension Child {
19+
var requiresLeadingSpace: Bool? {
20+
switch self.kind {
21+
case .token(choices: _, requiresLeadingSpace: let requiresLeadingSpace, requiresTrailingSpace: _):
22+
return requiresLeadingSpace
23+
case .nodeChoices(choices: let choices):
24+
for choice in choices {
25+
if let requiresLeadingSpace = choice.requiresLeadingSpace {
26+
return requiresLeadingSpace
27+
}
28+
}
29+
default:
30+
break
31+
}
32+
return nil
33+
}
34+
35+
var requiresTrailingSpace: Bool? {
36+
switch self.kind {
37+
case .token(choices: _, requiresLeadingSpace: _, requiresTrailingSpace: let requiresTrailingSpace):
38+
return requiresTrailingSpace
39+
case .nodeChoices(choices: let choices):
40+
for choice in choices {
41+
if let requiresTrailingSpace = choice.requiresTrailingSpace {
42+
return requiresTrailingSpace
43+
}
44+
}
45+
default:
46+
break
47+
}
48+
return nil
49+
}
50+
}
51+
1852
let basicFormatFile = SourceFileSyntax {
1953
DeclSyntax(
2054
"""
@@ -126,14 +160,34 @@ let basicFormatFile = SourceFileSyntax {
126160
}
127161
}
128162

163+
try FunctionDeclSyntax(
164+
"""
165+
/// If this returns a value that is not `nil`, it overrides the default
166+
/// leading space behavior of a token.
167+
open func requiresLeadingSpace(_ keyPath: AnyKeyPath) -> Bool?
168+
"""
169+
) {
170+
try SwitchStmtSyntax("switch keyPath") {
171+
for node in SYNTAX_NODES where !node.isBase {
172+
for child in node.children {
173+
if let requiresLeadingSpace = child.requiresLeadingSpace {
174+
SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") {
175+
StmtSyntax("return \(literal: requiresLeadingSpace)")
176+
}
177+
}
178+
}
179+
}
180+
SwitchCaseSyntax("default:") {
181+
StmtSyntax("return nil")
182+
}
183+
}
184+
}
185+
129186
try FunctionDeclSyntax("open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool") {
130187
StmtSyntax(
131188
"""
132-
switch (token.previousToken(viewMode: .sourceAccurate)?.tokenKind, token.tokenKind) {
133-
case (.leftParen, .binaryOperator): // Ensures there is no space in @available(*, deprecated)
134-
return false
135-
default:
136-
break
189+
if let keyPath = getKeyPath(token), let requiresLeadingSpace = requiresLeadingSpace(keyPath) {
190+
return requiresLeadingSpace
137191
}
138192
"""
139193
)
@@ -157,17 +211,34 @@ let basicFormatFile = SourceFileSyntax {
157211
}
158212
}
159213

214+
try FunctionDeclSyntax(
215+
"""
216+
/// If this returns a value that is not `nil`, it overrides the default
217+
/// trailing space behavior of a token.
218+
open func requiresTrailingSpace(_ keyPath: AnyKeyPath) -> Bool?
219+
"""
220+
) {
221+
try SwitchStmtSyntax("switch keyPath") {
222+
for node in SYNTAX_NODES where !node.isBase {
223+
for child in node.children {
224+
if let requiresTrailingSpace = child.requiresTrailingSpace {
225+
SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") {
226+
StmtSyntax("return \(literal: requiresTrailingSpace)")
227+
}
228+
}
229+
}
230+
}
231+
SwitchCaseSyntax("default:") {
232+
StmtSyntax("return nil")
233+
}
234+
}
235+
}
236+
160237
try FunctionDeclSyntax("open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool") {
161238
StmtSyntax(
162239
"""
163-
switch (token.tokenKind, token.parent?.kind) {
164-
case (.colon, .dictionaryExpr): // Ensures there is not space in `[:]`
165-
return false
166-
case (.exclamationMark, .tryExpr), // Ensures there is a space in `try! foo`
167-
(.postfixQuestionMark, .tryExpr): // Ensures there is a space in `try? foo`
168-
return true
169-
default:
170-
break
240+
if let keyPath = getKeyPath(token), let requiresTrailingSpace = requiresTrailingSpace(keyPath) {
241+
return requiresTrailingSpace
171242
}
172243
"""
173244
)
@@ -179,14 +250,11 @@ let basicFormatFile = SourceFileSyntax {
179250
(.keyword(.as), .postfixQuestionMark), // Ensures there is not space in `as?`
180251
(.exclamationMark, .leftParen), // Ensures there is not space in `myOptionalClosure!()`
181252
(.exclamationMark, .period), // Ensures there is not space in `myOptionalBar!.foo()`
182-
(.keyword(.`init`), .leftParen), // Ensures there is not space in `init()`
183-
(.keyword(.`init`), .postfixQuestionMark), // Ensures there is not space in `init?`
184-
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()`
253+
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()` or `myOptionalClosure?()`s
185254
(.postfixQuestionMark, .rightAngle), // Ensures there is not space in `ContiguousArray<RawSyntax?>`
186255
(.postfixQuestionMark, .rightParen), // Ensures there is not space in `myOptionalClosure?()`
187256
(.keyword(.try), .exclamationMark), // Ensures there is not space in `try!`
188-
(.keyword(.try), .postfixQuestionMark), // Ensures there is not space in `try?`
189-
(.binaryOperator, .comma): // Ensures there is no space in `@available(*, deprecated)`
257+
(.keyword(.try), .postfixQuestionMark): // Ensures there is not space in `try?`:
190258
return false
191259
default:
192260
break
@@ -215,7 +283,7 @@ let basicFormatFile = SourceFileSyntax {
215283

216284
DeclSyntax(
217285
"""
218-
private func getKeyPath(_ node: Syntax) -> AnyKeyPath? {
286+
private func getKeyPath<T: SyntaxProtocol>(_ node: T) -> AnyKeyPath? {
219287
guard let parent = node.parent else {
220288
return nil
221289
}

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxVisitorFile.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,6 @@ let syntaxVisitorFile = SourceFileSyntax {
3232
try! ClassDeclSyntax("open class SyntaxVisitor") {
3333
DeclSyntax("public let viewMode: SyntaxTreeViewMode")
3434

35-
DeclSyntax(
36-
"""
37-
@available(*, deprecated, message: "Use init(viewMode:) instead")
38-
public convenience init() {
39-
self.init(viewMode: .sourceAccurate)
40-
}
41-
"""
42-
)
43-
4435
DeclSyntax(
4536
"""
4637
public init(viewMode: SyntaxTreeViewMode) {

Package.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ let package = Package(
6767
"CMakeLists.txt",
6868
"Raw/RawSyntaxNodes.swift.gyb",
6969
"Raw/RawSyntaxValidation.swift.gyb",
70-
"SyntaxFactory.swift.gyb",
7170
"SyntaxNodes.swift.gyb.template",
7271
],
7372
swiftSettings: swiftSyntaxSwiftSettings

Sources/SwiftBasicFormat/generated/BasicFormat.swift

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

139-
open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool {
140-
switch (token.previousToken(viewMode: .sourceAccurate)?.tokenKind, token.tokenKind) {
141-
case (.leftParen, .binaryOperator): // Ensures there is no space in @available(*, deprecated)
139+
/// If this returns a value that is not `nil`, it overrides the default
140+
/// leading space behavior of a token.
141+
open func requiresLeadingSpace(_ keyPath: AnyKeyPath) -> Bool? {
142+
switch keyPath {
143+
case \AvailabilityArgumentSyntax.entry:
142144
return false
143145
default:
144-
break
146+
return nil
147+
}
148+
}
149+
150+
open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool {
151+
if let keyPath = getKeyPath(token), let requiresLeadingSpace = requiresLeadingSpace(keyPath) {
152+
return requiresLeadingSpace
145153
}
146154
switch token.tokenKind {
147155
case .leftBrace:
@@ -163,29 +171,37 @@ open class BasicFormat: SyntaxRewriter {
163171
}
164172
}
165173

166-
open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool {
167-
switch (token.tokenKind, token.parent?.kind) {
168-
case (.colon, .dictionaryExpr): // Ensures there is not space in `[:]`
174+
/// If this returns a value that is not `nil`, it overrides the default
175+
/// trailing space behavior of a token.
176+
open func requiresTrailingSpace(_ keyPath: AnyKeyPath) -> Bool? {
177+
switch keyPath {
178+
case \AvailabilityArgumentSyntax.entry:
169179
return false
170-
case (.exclamationMark, .tryExpr), // Ensures there is a space in `try! foo`
171-
(.postfixQuestionMark, .tryExpr): // Ensures there is a space in `try? foo`
180+
case \DictionaryExprSyntax.content:
181+
return false
182+
case \DynamicReplacementArgumentsSyntax.forLabel:
183+
return false
184+
case \TryExprSyntax.questionOrExclamationMark:
172185
return true
173186
default:
174-
break
187+
return nil
188+
}
189+
}
190+
191+
open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool {
192+
if let keyPath = getKeyPath(token), let requiresTrailingSpace = requiresTrailingSpace(keyPath) {
193+
return requiresTrailingSpace
175194
}
176195
switch (token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind) {
177196
case (.keyword(.as), .exclamationMark), // Ensures there is not space in `as!`
178197
(.keyword(.as), .postfixQuestionMark), // Ensures there is not space in `as?`
179198
(.exclamationMark, .leftParen), // Ensures there is not space in `myOptionalClosure!()`
180199
(.exclamationMark, .period), // Ensures there is not space in `myOptionalBar!.foo()`
181-
(.keyword(.`init`), .leftParen), // Ensures there is not space in `init()`
182-
(.keyword(.`init`), .postfixQuestionMark), // Ensures there is not space in `init?`
183-
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()`
200+
(.postfixQuestionMark, .leftParen), // Ensures there is not space in `init?()` or `myOptionalClosure?()`s
184201
(.postfixQuestionMark, .rightAngle), // Ensures there is not space in `ContiguousArray<RawSyntax?>`
185202
(.postfixQuestionMark, .rightParen), // Ensures there is not space in `myOptionalClosure?()`
186203
(.keyword(.try), .exclamationMark), // Ensures there is not space in `try!`
187-
(.keyword(.try), .postfixQuestionMark), // Ensures there is not space in `try?`
188-
(.binaryOperator, .comma): // Ensures there is no space in `@available(*, deprecated)`
204+
(.keyword(.try), .postfixQuestionMark): // Ensures there is not space in `try?`:
189205
return false
190206
default:
191207
break
@@ -233,8 +249,6 @@ open class BasicFormat: SyntaxRewriter {
233249
return true
234250
case .keyword(.`defer`):
235251
return true
236-
case .keyword(.`deinit`):
237-
return true
238252
case .keyword(.`else`):
239253
return true
240254
case .keyword(.`enum`):
@@ -257,8 +271,6 @@ open class BasicFormat: SyntaxRewriter {
257271
return true
258272
case .keyword(.`in`):
259273
return true
260-
case .keyword(.`init`):
261-
return true
262274
case .keyword(.`inout`):
263275
return true
264276
case .keyword(.`internal`):
@@ -310,7 +322,7 @@ open class BasicFormat: SyntaxRewriter {
310322
}
311323
}
312324

313-
private func getKeyPath(_ node: Syntax) -> AnyKeyPath? {
325+
private func getKeyPath<T: SyntaxProtocol>(_ node: T) -> AnyKeyPath? {
314326
guard let parent = node.parent else {
315327
return nil
316328
}

Sources/SwiftParser/Attributes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ extension Parser {
874874

875875
extension Parser {
876876
mutating func parsePackageAttributeArguments() -> RawPackageAttributeArgumentsSyntax {
877-
// Parsing package description
877+
// Parsing package location
878878
let (unexpectedBeforeLocationLabel, locationLabel) = self.expectAny([.keyword(.id), .keyword(.path), .keyword(.url)], default: .keyword(.id))
879879
let (unexpectedBeforeLocationColon, locationColon) = self.expect(.colon)
880880
let location = self.parseStringLiteral()

0 commit comments

Comments
 (0)