From 07fff59cf4f449d347bfbd9844910fe0b8803916 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Fri, 30 May 2025 14:14:22 +0100 Subject: [PATCH] Change InlineArray sugar separator `x` -> `of` --- .../Sources/SyntaxSupport/KeywordSpec.swift | 3 -- .../Sources/SyntaxSupport/TypeNodes.swift | 6 +-- .../ValidateSyntaxNodes.swift | 5 ++- Sources/SwiftParser/TokenPrecedence.swift | 1 - Sources/SwiftParser/Types.swift | 14 +++---- Sources/SwiftSyntax/generated/Keyword.swift | 10 ----- .../generated/raw/RawSyntaxValidation.swift | 2 +- .../syntaxNodes/SyntaxNodesGHI.swift | 10 ++--- .../SwiftParserTest/ExpressionTypeTests.swift | 40 +++++++++---------- Tests/SwiftParserTest/TypeTests.swift | 32 +++++++-------- 10 files changed, 55 insertions(+), 68 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index a0e6730e18d..eeb66ea4b56 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -276,7 +276,6 @@ public enum Keyword: CaseIterable { case `while` case willSet case wrt - case x case yield public var spec: KeywordSpec { @@ -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") } diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index 3d65755fa45..ab81dde2a2d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -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", @@ -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", diff --git a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift index d2eceb9334f..164b1505895 100644 --- a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift +++ b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift @@ -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'" ), ] ) diff --git a/Sources/SwiftParser/TokenPrecedence.swift b/Sources/SwiftParser/TokenPrecedence.swift index c0a9a04bd08..2879548d56c 100644 --- a/Sources/SwiftParser/TokenPrecedence.swift +++ b/Sources/SwiftParser/TokenPrecedence.swift @@ -345,7 +345,6 @@ enum TokenPrecedence: Comparable { .visibility, .weak, .wrt, - .x, .unsafe: self = .exprKeyword #if RESILIENT_LIBRARIES diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 58eacfa59b9..68a6428ef49 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -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() @@ -879,18 +879,18 @@ extension Parser.Lookahead { return false } - // We must have at least '[ x', which cannot be any other + // We must have at least '[ 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 { @@ -898,7 +898,7 @@ extension Parser.Lookahead { 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 } diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index 3a848bf62b7..aedba46b9f1 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -222,19 +222,10 @@ public enum Keyword: UInt8, Hashable, Sendable { case `while` case willSet case wrt - @_spi(ExperimentalLanguageFeatures) - case x case yield @_spi(RawSyntax) public init?(_ text: SyntaxText) { switch text.count { - case 1: - switch text { - case "x": - self = .x - default: - return nil - } case 2: switch text { case "as": @@ -964,7 +955,6 @@ public enum Keyword: UInt8, Hashable, Sendable { "while", "willSet", "wrt", - "x", "yield", ] diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 182d2d0aeba..4eb22f87384 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -1748,7 +1748,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawGenericArgumentSyntax.self)) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.keyword("x")])) + assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.keyword("of")])) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 7, verify(layout[7], as: RawGenericArgumentSyntax.self)) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index b61d7b799ca..b6eec06d4b0 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -4373,7 +4373,7 @@ public struct InitializerDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _LeafDe // MARK: - InlineArrayTypeSyntax -/// An inline array type `[3 x Int]`, sugar for `InlineArray<3, Int>`. +/// An inline array type `[3 of Int]`, sugar for `InlineArray<3, Int>`. /// /// - Note: Requires experimental feature `inlineArrayTypeSugar`. /// @@ -4381,7 +4381,7 @@ public struct InitializerDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _LeafDe /// /// - `leftSquare`: `[` /// - `count`: ``GenericArgumentSyntax`` -/// - `separator`: `x` +/// - `separator`: `of` /// - `element`: ``GenericArgumentSyntax`` /// - `rightSquare`: `]` @_spi(ExperimentalLanguageFeatures) @@ -4412,7 +4412,7 @@ public struct InlineArrayTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTy _ unexpectedBetweenLeftSquareAndCount: UnexpectedNodesSyntax? = nil, count: GenericArgumentSyntax, _ unexpectedBetweenCountAndSeparator: UnexpectedNodesSyntax? = nil, - separator: TokenSyntax = .keyword(.x), + separator: TokenSyntax = .keyword(.of), _ unexpectedBetweenSeparatorAndElement: UnexpectedNodesSyntax? = nil, element: GenericArgumentSyntax, _ unexpectedBetweenElementAndRightSquare: UnexpectedNodesSyntax? = nil, @@ -4491,7 +4491,7 @@ public struct InlineArrayTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTy /// 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]`. public var count: GenericArgumentSyntax { get { return Syntax(self).child(at: 3)!.cast(GenericArgumentSyntax.self) @@ -4512,7 +4512,7 @@ public struct InlineArrayTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTy /// ### Tokens /// - /// For syntax trees generated by the parser, this is guaranteed to be `x`. + /// For syntax trees generated by the parser, this is guaranteed to be `of`. public var separator: TokenSyntax { get { return Syntax(self).child(at: 5)!.cast(TokenSyntax.self) diff --git a/Tests/SwiftParserTest/ExpressionTypeTests.swift b/Tests/SwiftParserTest/ExpressionTypeTests.swift index 5def6ec1241..f9f6587dbe4 100644 --- a/Tests/SwiftParserTest/ExpressionTypeTests.swift +++ b/Tests/SwiftParserTest/ExpressionTypeTests.swift @@ -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 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 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( diff --git a/Tests/SwiftParserTest/TypeTests.swift b/Tests/SwiftParserTest/TypeTests.swift index 2d317551c14..4ab3316b6b7 100644 --- a/Tests/SwiftParserTest/TypeTests.swift +++ b/Tests/SwiftParserTest/TypeTests.swift @@ -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("_"))) ) ) @@ -804,7 +804,7 @@ final class InlineArrayTypeTests: ParserTestCase { """ S<[ 3 - 1️⃣x + 1️⃣of Int ]>() """, @@ -815,7 +815,7 @@ final class InlineArrayTypeTests: ParserTestCase { assertParse( """ S<[3 - 1️⃣x + 1️⃣of Int ]>() """, @@ -826,23 +826,23 @@ 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 ]>() """ ) @@ -850,17 +850,17 @@ final class InlineArrayTypeTests: ParserTestCase { 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", @@ -868,12 +868,12 @@ final class InlineArrayTypeTests: ParserTestCase { fixIts: ["insert ']'"] ) ], - fixedSource: "[3 x Int]" + fixedSource: "[3 of Int]" ) } func testEllipsis() { - // Make sure this isn't parsed as ' x ' - assertParse("[x...x]") + // Make sure this isn't parsed as ' of ' + assertParse("[x...of]") } }