Skip to content

Change InlineArray sugar separator x -> of #3088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ public enum Keyword: CaseIterable {
case `while`
case willSet
case wrt
case x
case yield

public var spec: KeywordSpec {
Expand Down Expand Up @@ -685,8 +684,6 @@ public enum Keyword: CaseIterable {
return KeywordSpec("willSet")
case .wrt:
return KeywordSpec("wrt")
case .x:
return KeywordSpec("x", experimentalFeature: .inlineArrayTypeSugar)
case .yield:
return KeywordSpec("yield")
}
Expand Down
6 changes: 3 additions & 3 deletions CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public let TYPE_NODES: [Node] = [
base: .type,
experimentalFeature: .inlineArrayTypeSugar,
nameForDiagnostics: "inline array type",
documentation: "An inline array type `[3 x Int]`, sugar for `InlineArray<3, Int>`.",
documentation: "An inline array type `[3 of Int]`, sugar for `InlineArray<3, Int>`.",
children: [
Child(
name: "leftSquare",
Expand All @@ -317,12 +317,12 @@ public let TYPE_NODES: [Node] = [
documentation: """
The `count` argument for the inline array type.

- Note: In semantically valid Swift code, this is always an integer or a wildcard type, e.g `_` in `[_ x Int]`.
- Note: In semantically valid Swift code, this is always an integer or a wildcard type, e.g `_` in `[_ of Int]`.
"""
),
Child(
name: "separator",
kind: .token(choices: [.keyword(.x)])
kind: .token(choices: [.keyword(.of)])
),
Child(
name: "element",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,11 @@ class ValidateSyntaxNodes: XCTestCase {
message:
"child 'defaultKeyword' has a single keyword as its only token choice and is followed by a colon. It should thus be named 'defaultLabel'"
),
// 'separator' is more descriptive than 'xKeyword'
// 'separator' is more descriptive than 'ofKeyword'
ValidationFailure(
node: .inlineArrayType,
message: "child 'separator' has a single keyword as its only token choice and should thus be named 'xKeyword'"
message:
"child 'separator' has a single keyword as its only token choice and should thus be named 'ofKeyword'"
),
]
)
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftParser/TokenPrecedence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ enum TokenPrecedence: Comparable {
.visibility,
.weak,
.wrt,
.x,
.unsafe:
self = .exprKeyword
#if RESILIENT_LIBRARIES
Expand Down
14 changes: 7 additions & 7 deletions Sources/SwiftParser/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,11 @@ extension Parser {
precondition(self.experimentalFeatures.contains(.inlineArrayTypeSugar))

// We allow both values and types here and for the element type for
// better recovery in cases where the user writes e.g '[Int x 3]'.
// better recovery in cases where the user writes e.g '[Int of 3]'.
let count = self.parseGenericArgumentType()

let (unexpectedBeforeSeparator, separator) = self.expect(
TokenSpec(.x, allowAtStartOfLine: false)
TokenSpec(.of, allowAtStartOfLine: false)
)

let element = self.parseGenericArgumentType()
Expand Down Expand Up @@ -879,26 +879,26 @@ extension Parser.Lookahead {
return false
}

// We must have at least '[<type-or-integer> x', which cannot be any other
// We must have at least '[<type-or-integer> of', which cannot be any other
// kind of expression or type. We specifically look for both types and
// integers for better recovery in e.g cases where the user writes e.g
// '[Int x 2]'. We only do type-scalar since variadics would be ambiguous
// e.g 'Int...x'.
// '[Int of 2]'. We only do type-scalar since variadics would be ambiguous
// e.g 'Int...of'.
guard self.canParseTypeScalar() || self.canParseIntegerLiteral() else {
return false
}

// We don't currently allow multi-line since that would require
// disambiguation with array literals.
return self.consume(if: TokenSpec(.x, allowAtStartOfLine: false)) != nil
return self.consume(if: TokenSpec(.of, allowAtStartOfLine: false)) != nil
}

mutating func canParseInlineArrayTypeBody() -> Bool {
guard self.canParseStartOfInlineArrayTypeBody() else {
return false
}
// Note we look for both types and integers for better recovery in e.g cases
// where the user writes e.g '[Int x 2]'.
// where the user writes e.g '[Int of 2]'.
guard self.canParseGenericArgument() else {
return false
}
Expand Down
10 changes: 0 additions & 10 deletions Sources/SwiftSyntax/generated/Keyword.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 20 additions & 20 deletions Tests/SwiftParserTest/ExpressionTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,26 @@ final class ExpressionTypeTests: ParserTestCase {
// Make sure we can handle cases where the type is spelled first in
// an InlineArray sugar type.
let cases: [UInt: String] = [
#line: "[3 x Int]",
#line: "[[3 x Int]]",
#line: "[[Int x 3]]",
#line: "[_ x Int]",
#line: "[Int x Int]",
#line: "[@escaping () -> Int x Int]",
#line: "[Int.Type x Int]",
#line: "[sending P & Q x Int]",
#line: "[(some P & Q) -> Int x Int]",
#line: "[~P x Int]",
#line: "[(Int, String) x Int]",
#line: "[G<T> x Int]",
#line: "[[3 x Int] x Int]",
#line: "[[Int] x Int]",
#line: "[_ x Int]",
#line: "[_? x Int]",
#line: "[_?x Int]",
#line: "[_! x Int]",
#line: "[_!x Int]",
#line: "[Int?x Int]",
#line: "[3 of Int]",
#line: "[[3 of Int]]",
#line: "[[Int of 3]]",
#line: "[_ of Int]",
#line: "[Int of Int]",
#line: "[@escaping () -> Int of Int]",
#line: "[Int.Type of Int]",
#line: "[sending P & Q of Int]",
#line: "[(some P & Q) -> Int of Int]",
#line: "[~P of Int]",
#line: "[(Int, String) of Int]",
#line: "[G<T> of Int]",
#line: "[[3 of Int] of Int]",
#line: "[[Int] of Int]",
#line: "[_ of Int]",
#line: "[_? of Int]",
#line: "[_?of Int]",
#line: "[_! of Int]",
#line: "[_!of Int]",
#line: "[Int?of Int]",
]
for (line, type) in cases {
assertParse(
Expand Down
32 changes: 16 additions & 16 deletions Tests/SwiftParserTest/TypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -781,18 +781,18 @@ final class InlineArrayTypeTests: ParserTestCase {

func testBasic() {
assertParse(
"[3 x Int]",
"[3 of Int]",
substructure: InlineArrayTypeSyntax(
count: .init(argument: .expr("3")),
separator: .keyword(.x),
separator: .keyword(.of),
element: .init(argument: .type(TypeSyntax("Int")))
)
)
assertParse(
"[Int x _]",
"[Int of _]",
substructure: InlineArrayTypeSyntax(
count: .init(argument: .type(TypeSyntax("Int"))),
separator: .keyword(.x),
separator: .keyword(.of),
element: .init(argument: .type(TypeSyntax("_")))
)
)
Expand All @@ -804,7 +804,7 @@ final class InlineArrayTypeTests: ParserTestCase {
"""
S<[
3
1️⃣x
1️⃣of
Int
]>()
""",
Expand All @@ -815,7 +815,7 @@ final class InlineArrayTypeTests: ParserTestCase {
assertParse(
"""
S<[3
1️⃣x
1️⃣of
Int
]>()
""",
Expand All @@ -826,54 +826,54 @@ final class InlineArrayTypeTests: ParserTestCase {
assertParse(
"""
S<[3
1️⃣x Int]>()
1️⃣of Int]>()
""",
diagnostics: [
DiagnosticSpec(message: "unexpected code 'x Int' in array")
DiagnosticSpec(message: "unexpected code 'of Int' in array")
]
)
// These are okay.
assertParse(
"""
S<[3 x
S<[3 of
Int]>()
"""
)
assertParse(
"""
S<[
3 x Int
3 of Int
]>()
"""
)
}

func testDiagnostics() {
assertParse(
"2️⃣[3 x1️⃣",
"2️⃣[3 of1️⃣",
diagnostics: [
DiagnosticSpec(
message: "expected element type and ']' to end inline array type",
fixIts: ["insert element type and ']'"]
)
],
fixedSource: "[3 x <#type#>]"
fixedSource: "[3 of <#type#>]"
)
assertParse(
"ℹ️[3 x Int1️⃣",
"ℹ️[3 of Int1️⃣",
diagnostics: [
DiagnosticSpec(
message: "expected ']' to end inline array type",
notes: [NoteSpec(message: "to match this opening '['")],
fixIts: ["insert ']'"]
)
],
fixedSource: "[3 x Int]"
fixedSource: "[3 of Int]"
)
}

func testEllipsis() {
// Make sure this isn't parsed as '<variadic-type> x <missing type>'
assertParse("[x...x]")
// Make sure this isn't parsed as '<variadic-type> of <missing type>'
assertParse("[x...of]")
}
}