From 2b73e522778f6958d33b26a438b23eca01cdf7ae Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 24 Sep 2024 10:56:33 -0700 Subject: [PATCH 01/10] Introduce genericArgumentType and parse integer generics --- .../Sources/SyntaxSupport/GenericNodes.swift | 4 +- .../SyntaxSupport/SyntaxNodeKind.swift | 1 + .../Sources/SyntaxSupport/TypeNodes.swift | 23 +- Sources/SwiftParser/Declarations.swift | 260 ++++++++++-------- Sources/SwiftParser/Types.swift | 73 ++++- .../SyntaxKindNameForDiagnostics.swift | 2 + .../generated/SwiftSyntax.md | 1 + .../generated/ChildNameForKeyPath.swift | 6 + .../RenamedChildrenCompatibility.swift | 12 +- .../generated/SyntaxAnyVisitor.swift | 8 + .../generated/SyntaxBaseNodes.swift | 5 +- .../SwiftSyntax/generated/SyntaxEnum.swift | 6 + .../SwiftSyntax/generated/SyntaxKind.swift | 3 + .../generated/SyntaxRewriter.swift | 13 + .../SwiftSyntax/generated/SyntaxVisitor.swift | 18 ++ .../generated/raw/RawSyntaxNodesGHI.swift | 100 ++++++- .../generated/raw/RawSyntaxNodesQRS.swift | 12 +- .../generated/raw/RawSyntaxNodesTUVWXYZ.swift | 2 +- .../generated/raw/RawSyntaxValidation.swift | 12 +- .../syntaxNodes/SyntaxNodesGHI.swift | 164 ++++++++++- .../syntaxNodes/SyntaxNodesQRS.swift | 16 +- .../MacroReplacement.swift | 6 +- Tests/SwiftParserTest/DeclarationTests.swift | 5 +- Tests/SwiftParserTest/PatternTests.swift | 2 +- Tests/SwiftParserTest/StatementTests.swift | 6 +- Tests/SwiftParserTest/TypeMemberTests.swift | 2 +- Tests/SwiftParserTest/TypeTests.swift | 6 +- .../SwiftParserTest/ValueGenericsTests.swift | 143 ++++++++++ .../GenericDisambiguationTests.swift | 16 +- 29 files changed, 754 insertions(+), 173 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift index 99a37a8b352..becc4fbcbb8 100644 --- a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift @@ -334,7 +334,7 @@ public let GENERIC_NODES: [Node] = [ children: [ Child( name: "leftType", - kind: .node(kind: .type), + kind: .node(kind: .genericArgumentType), nameForDiagnostics: "left-hand type" ), Child( @@ -343,7 +343,7 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "rightType", - kind: .node(kind: .type), + kind: .node(kind: .genericArgumentType), nameForDiagnostics: "right-hand type" ), ], diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift index aca5c52aa86..a5a96cf5e1d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift @@ -142,6 +142,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon case genericArgument case genericArgumentClause case genericArgumentList + case genericArgumentType case genericParameter case genericParameterClause case genericParameterList diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index fb88fa18776..d75af9beb2b 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -257,7 +257,7 @@ public let TYPE_NODES: [Node] = [ children: [ Child( name: "argument", - kind: .node(kind: .type) + kind: .node(kind: .genericArgumentType) ), Child( name: "trailingComma", @@ -652,4 +652,25 @@ public let TYPE_NODES: [Node] = [ nameForDiagnostics: nil, elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier] ), + + Node( + kind: .genericArgumentType, + base: .type, + nameForDiagnostics: "generic argument type", + children: [ + Child( + name: "value", + kind: .nodeChoices(choices: [ + Child( + name: "type", + kind: .node(kind: .type) + ), + Child( + name: "expr", + kind: .node(kind: .expr) + ) + ]) + ) + ] + ) ] diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 6d8845d52a0..dcd3784b88e 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -532,16 +532,17 @@ extension Parser { var keepGoing: RawTokenSyntax? = nil var loopProgress = LoopProgressCondition() repeat { - let firstType = self.parseType() - guard !firstType.is(RawMissingTypeSyntax.self) else { + let firstArgument = self.parseGenericArgumentType() + + guard !firstArgument.value.raw.is(RawMissingTypeSyntax.self) else { keepGoing = self.consume(if: .comma) elements.append( RawGenericRequirementSyntax( requirement: .sameTypeRequirement( RawSameTypeRequirementSyntax( - leftType: RawMissingTypeSyntax(arena: self.arena), + leftType: firstArgument, equal: missingToken(.binaryOperator, text: "=="), - rightType: RawMissingTypeSyntax(arena: self.arena), + rightType: firstArgument, arena: self.arena ) ), @@ -552,137 +553,164 @@ extension Parser { continue } - enum ExpectedTokenKind: TokenSpecSet { - case colon - case binaryOperator - case postfixOperator - case prefixOperator - - init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { - switch (lexeme.rawTokenKind, lexeme.tokenText) { - case (.colon, _): self = .colon - case (.binaryOperator, "=="): self = .binaryOperator - case (.postfixOperator, "=="): self = .postfixOperator - case (.prefixOperator, "=="): self = .prefixOperator - default: return nil + let requirement: RawGenericRequirementSyntax.Requirement + + switch RawGenericArgumentTypeSyntax.Value(firstArgument.value.raw)! { + // If the first argument is an expression, then we have to have a same + // type requirement. We do not allow conformance requirements like + // '123: Protocol' or layout constraints on expressions. + case .expr: + let (unexpectedBeforeEqual, equal) = self.expect( + anyIn: SameTypeRequirementSyntax.EqualOptions.self, + default: .binaryOperator + ) + let secondArgument = self.parseGenericArgumentType() + requirement = .sameTypeRequirement( + RawSameTypeRequirementSyntax( + leftType: firstArgument, + unexpectedBeforeEqual, + equal: equal, + rightType: secondArgument, + arena: self.arena + ) + ) + + // Otherwise, this can be a conformance, same type, or layout constraint. + case .type(let firstType): + enum ExpectedTokenKind: TokenSpecSet { + case colon + case binaryOperator + case postfixOperator + case prefixOperator + + init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { + switch (lexeme.rawTokenKind, lexeme.tokenText) { + case (.colon, _): self = .colon + case (.binaryOperator, "=="): self = .binaryOperator + case (.postfixOperator, "=="): self = .postfixOperator + case (.prefixOperator, "=="): self = .prefixOperator + default: return nil + } } - } - var spec: TokenSpec { - switch self { - case .colon: return .colon - case .binaryOperator: return .binaryOperator - case .postfixOperator: return .postfixOperator - case .prefixOperator: return .prefixOperator + var spec: TokenSpec { + switch self { + case .colon: return .colon + case .binaryOperator: return .binaryOperator + case .postfixOperator: return .postfixOperator + case .prefixOperator: return .prefixOperator + } } } - } - let requirement: RawGenericRequirementSyntax.Requirement - switch self.at(anyIn: ExpectedTokenKind.self) { - case (.colon, let handle)?: - let colon = self.eat(handle) - // A conformance-requirement. - if let (layoutSpecifier, handle) = self.at(anyIn: LayoutRequirementSyntax.LayoutSpecifierOptions.self) { - // Parse a layout constraint. - let specifier = self.eat(handle) - - let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax? - let leftParen: RawTokenSyntax? - let size: RawTokenSyntax? - let comma: RawTokenSyntax? - let alignment: RawTokenSyntax? - let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax? - let rightParen: RawTokenSyntax? - - var hasArguments: Bool { - switch layoutSpecifier { - case ._Trivial, - ._TrivialAtMost, - ._TrivialStride: - return true - - case ._UnknownLayout, - ._RefCountedObject, - ._NativeRefCountedObject, - ._Class, - ._NativeClass, - ._BridgeObject: - return false + switch self.at(anyIn: ExpectedTokenKind.self) { + case (.colon, let handle)?: + let colon = self.eat(handle) + // A conformance-requirement. + if let (layoutSpecifier, handle) = self.at(anyIn: LayoutRequirementSyntax.LayoutSpecifierOptions.self) { + // Parse a layout constraint. + let specifier = self.eat(handle) + + let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax? + let leftParen: RawTokenSyntax? + let size: RawTokenSyntax? + let comma: RawTokenSyntax? + let alignment: RawTokenSyntax? + let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax? + let rightParen: RawTokenSyntax? + + var hasArguments: Bool { + switch layoutSpecifier { + case ._Trivial, + ._TrivialAtMost, + ._TrivialStride: + return true + + case ._UnknownLayout, + ._RefCountedObject, + ._NativeRefCountedObject, + ._Class, + ._NativeClass, + ._BridgeObject: + return false + } } - } - // Unlike the other layout constraints, _Trivial's argument list - // is optional. - if hasArguments && (layoutSpecifier != ._Trivial || self.at(.leftParen)) { - (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen) - size = self.expectWithoutRecovery(.integerLiteral) - comma = self.consume(if: .comma) - if comma != nil { - alignment = self.expectWithoutRecovery(.integerLiteral) + // Unlike the other layout constraints, _Trivial's argument list + // is optional. + if hasArguments && (layoutSpecifier != ._Trivial || self.at(.leftParen)) { + (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen) + size = self.expectWithoutRecovery(.integerLiteral) + comma = self.consume(if: .comma) + if comma != nil { + alignment = self.expectWithoutRecovery(.integerLiteral) + } else { + alignment = nil + } + (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen) } else { + unexpectedBeforeLeftParen = nil + leftParen = nil + size = nil + comma = nil alignment = nil + unexpectedBeforeRightParen = nil + rightParen = nil } - (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen) + + requirement = .layoutRequirement( + RawLayoutRequirementSyntax( + type: firstType, + colon: colon, + layoutSpecifier: specifier, + unexpectedBeforeLeftParen, + leftParen: leftParen, + size: size, + comma: comma, + alignment: alignment, + unexpectedBeforeRightParen, + rightParen: rightParen, + arena: self.arena + ) + ) } else { - unexpectedBeforeLeftParen = nil - leftParen = nil - size = nil - comma = nil - alignment = nil - unexpectedBeforeRightParen = nil - rightParen = nil + // Parse the protocol or composition. + let secondType = self.parseType() + requirement = .conformanceRequirement( + RawConformanceRequirementSyntax( + leftType: firstType, + colon: colon, + rightType: secondType, + arena: self.arena + ) + ) } - - requirement = .layoutRequirement( - RawLayoutRequirementSyntax( - type: firstType, - colon: colon, - layoutSpecifier: specifier, - unexpectedBeforeLeftParen, - leftParen: leftParen, - size: size, - comma: comma, - alignment: alignment, - unexpectedBeforeRightParen, - rightParen: rightParen, + case (.binaryOperator, let handle)?, + (.postfixOperator, let handle)?, + (.prefixOperator, let handle)?: + let equal = self.eat(handle) + let secondArgument = self.parseGenericArgumentType() + requirement = .sameTypeRequirement( + RawSameTypeRequirementSyntax( + leftType: firstArgument, + equal: equal, + rightType: secondArgument, arena: self.arena ) ) - } else { - // Parse the protocol or composition. - let secondType = self.parseType() - requirement = .conformanceRequirement( - RawConformanceRequirementSyntax( - leftType: firstType, - colon: colon, - rightType: secondType, + case nil: + requirement = .sameTypeRequirement( + RawSameTypeRequirementSyntax( + leftType: firstArgument, + equal: RawTokenSyntax(missing: .binaryOperator, text: "==", arena: self.arena), + rightType: RawGenericArgumentTypeSyntax( + value: .type(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))), + arena: self.arena + ), arena: self.arena ) ) } - case (.binaryOperator, let handle)?, - (.postfixOperator, let handle)?, - (.prefixOperator, let handle)?: - let equal = self.eat(handle) - let secondType = self.parseType() - requirement = .sameTypeRequirement( - RawSameTypeRequirementSyntax( - leftType: firstType, - equal: equal, - rightType: secondType, - arena: self.arena - ) - ) - case nil: - requirement = .sameTypeRequirement( - RawSameTypeRequirementSyntax( - leftType: firstType, - equal: RawTokenSyntax(missing: .binaryOperator, text: "==", arena: self.arena), - rightType: RawMissingTypeSyntax(arena: self.arena), - arena: self.arena - ) - ) } keepGoing = self.consume(if: .comma) diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 16198f9bad2..373b1cd899e 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -416,14 +416,16 @@ extension Parser { var keepGoing: RawTokenSyntax? = nil var loopProgress = LoopProgressCondition() repeat { - let type = self.parseType() - if arguments.isEmpty && type.is(RawMissingTypeSyntax.self) { + let argument = self.parseGenericArgumentType() + + if arguments.isEmpty, argument.value.raw.is(RawMissingTypeSyntax.self) { break } + keepGoing = self.consume(if: .comma) arguments.append( RawGenericArgumentSyntax( - argument: type, + argument: argument, trailingComma: keepGoing, arena: self.arena ) @@ -446,6 +448,20 @@ extension Parser { arena: self.arena ) } + + mutating func parseGenericArgumentType() -> RawGenericArgumentTypeSyntax { + if let valueType = self.parseValueType() { + return RawGenericArgumentTypeSyntax( + value: .expr(valueType), + arena: self.arena + ) + } else { + return RawGenericArgumentTypeSyntax( + value: .type(self.parseType()), + arena: self.arena + ) + } + } } extension Parser { @@ -685,9 +701,22 @@ extension Parser.Lookahead { switch self.currentToken { case TokenSpec(.Any): self.consumeAnyToken() - case TokenSpec(.prefixOperator) where self.currentToken.tokenText == "~": - self.consumeAnyToken() - fallthrough + case TokenSpec(.prefixOperator): + // '~Copyable' + if self.currentToken.tokenText == "~" { + self.consumeAnyToken() + fallthrough + } + + // '-123' for value generics. + if self.currentToken.tokenText == "-", + self.peek(isAt: .integerLiteral) { + self.consumeAnyToken() + self.consumeAnyToken() + return true + } + + return false case TokenSpec(.Self), TokenSpec(.identifier): guard self.canParseTypeIdentifier() else { return false @@ -1106,6 +1135,38 @@ extension Parser { } } +extension Parser { + mutating func parseValueType() -> RawExprSyntax? { + // Eat any '-' preceding integer literals. + var minusSign: RawTokenSyntax? = nil + if self.currentToken.tokenText == "-", + self.peek(isAt: .integerLiteral) { + minusSign = self.consumeIfContextualPunctuator("-", remapping: .prefixOperator) + } + + // Attempt to parse values first. Right now the only value that can be parsed + // as a type are integers. + if let integerLiteral = self.consume(if: .integerLiteral) { + let integerExpr = RawIntegerLiteralExprSyntax( + literal: integerLiteral, + arena: self.arena + ) + + guard let minusSign else { + return RawExprSyntax(integerExpr) + } + + return RawExprSyntax(RawPrefixOperatorExprSyntax( + operator: minusSign, + expression: integerExpr, + arena: self.arena + )) + } + + return nil + } +} + extension Lexer.Lexeme { var isGenericTypeDisambiguatingToken: Bool { switch self.rawTokenKind { diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 4006f445c54..09b42bb4722 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -197,6 +197,8 @@ extension SyntaxKind { return "generic argument clause" case .genericArgument: return "generic argument" + case .genericArgumentType: + return "generic argument type" case .genericParameterClause: return "generic parameter clause" case .genericParameter: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index 10a71a658da..31434ac59b4 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -180,6 +180,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- - - - diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 31a6ac2cac5..cd4f8cf9713 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -1529,6 +1529,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "trailingComma" case \GenericArgumentSyntax.unexpectedAfterTrailingComma: return "unexpectedAfterTrailingComma" + case \GenericArgumentTypeSyntax.unexpectedBeforeValue: + return "unexpectedBeforeValue" + case \GenericArgumentTypeSyntax.value: + return "value" + case \GenericArgumentTypeSyntax.unexpectedAfterValue: + return "unexpectedAfterValue" case \GenericParameterClauseSyntax.unexpectedBeforeLeftAngle: return "unexpectedBeforeLeftAngle" case \GenericParameterClauseSyntax.leftAngle: diff --git a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift index fb3cd840904..b04d8c83913 100644 --- a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift +++ b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift @@ -3450,7 +3450,7 @@ extension GenericArgumentSyntax { } @available(*, deprecated, renamed: "argument") - public var argumentType: TypeSyntax { + public var argumentType: GenericArgumentTypeSyntax { get { return argument } @@ -3474,7 +3474,7 @@ extension GenericArgumentSyntax { public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeArgumentType: UnexpectedNodesSyntax? = nil, - argumentType: some TypeSyntaxProtocol, + argumentType: GenericArgumentTypeSyntax, _ unexpectedBetweenArgumentTypeAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax? = nil, _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, @@ -6615,7 +6615,7 @@ extension SameTypeRequirementSyntax { } @available(*, deprecated, renamed: "leftType") - public var leftTypeIdentifier: TypeSyntax { + public var leftTypeIdentifier: GenericArgumentTypeSyntax { get { return leftType } @@ -6655,7 +6655,7 @@ extension SameTypeRequirementSyntax { } @available(*, deprecated, renamed: "rightType") - public var rightTypeIdentifier: TypeSyntax { + public var rightTypeIdentifier: GenericArgumentTypeSyntax { get { return rightType } @@ -6679,11 +6679,11 @@ extension SameTypeRequirementSyntax { public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeLeftTypeIdentifier: UnexpectedNodesSyntax? = nil, - leftTypeIdentifier: some TypeSyntaxProtocol, + leftTypeIdentifier: GenericArgumentTypeSyntax, _ unexpectedBetweenLeftTypeIdentifierAndEqualityToken: UnexpectedNodesSyntax? = nil, equalityToken: TokenSyntax, _ unexpectedBetweenEqualityTokenAndRightTypeIdentifier: UnexpectedNodesSyntax? = nil, - rightTypeIdentifier: some TypeSyntaxProtocol, + rightTypeIdentifier: GenericArgumentTypeSyntax, _ unexpectedAfterRightTypeIdentifier: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index 6b4a238d8cf..c7ff5c95a9a 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -1022,6 +1022,14 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: GenericArgumentTypeSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: GenericArgumentTypeSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: GenericParameterClauseSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index 4341ca1bc2f..7a9e8cd7f31 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -1371,6 +1371,7 @@ extension Syntax { /// - ``CompositionTypeSyntax`` /// - ``DictionaryTypeSyntax`` /// - ``FunctionTypeSyntax`` +/// - ``GenericArgumentTypeSyntax`` /// - ``IdentifierTypeSyntax`` /// - ``ImplicitlyUnwrappedOptionalTypeSyntax`` /// - ``MemberTypeSyntax`` @@ -1419,7 +1420,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { public init?(_ node: __shared some SyntaxProtocol) { switch node.raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .genericArgumentType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: self._syntaxNode = node._syntaxNode default: return nil @@ -1450,6 +1451,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { .node(CompositionTypeSyntax.self), .node(DictionaryTypeSyntax.self), .node(FunctionTypeSyntax.self), + .node(GenericArgumentTypeSyntax.self), .node(IdentifierTypeSyntax.self), .node(ImplicitlyUnwrappedOptionalTypeSyntax.self), .node(MemberTypeSyntax.self), @@ -1637,6 +1639,7 @@ extension Syntax { .node(GenericArgumentClauseSyntax.self), .node(GenericArgumentListSyntax.self), .node(GenericArgumentSyntax.self), + .node(GenericArgumentTypeSyntax.self), .node(GenericParameterClauseSyntax.self), .node(GenericParameterListSyntax.self), .node(GenericParameterSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index fef31916caa..e73ccc578f2 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -138,6 +138,7 @@ public enum SyntaxEnum: Sendable { case genericArgumentClause(GenericArgumentClauseSyntax) case genericArgumentList(GenericArgumentListSyntax) case genericArgument(GenericArgumentSyntax) + case genericArgumentType(GenericArgumentTypeSyntax) case genericParameterClause(GenericParameterClauseSyntax) case genericParameterList(GenericParameterListSyntax) case genericParameter(GenericParameterSyntax) @@ -561,6 +562,8 @@ extension Syntax { return .genericArgumentList(GenericArgumentListSyntax(self)!) case .genericArgument: return .genericArgument(GenericArgumentSyntax(self)!) + case .genericArgumentType: + return .genericArgumentType(GenericArgumentTypeSyntax(self)!) case .genericParameterClause: return .genericParameterClause(GenericParameterClauseSyntax(self)!) case .genericParameterList: @@ -1264,6 +1267,7 @@ public enum TypeSyntaxEnum { case compositionType(CompositionTypeSyntax) case dictionaryType(DictionaryTypeSyntax) case functionType(FunctionTypeSyntax) + case genericArgumentType(GenericArgumentTypeSyntax) case identifierType(IdentifierTypeSyntax) case implicitlyUnwrappedOptionalType(ImplicitlyUnwrappedOptionalTypeSyntax) case memberType(MemberTypeSyntax) @@ -1294,6 +1298,8 @@ extension TypeSyntax { return .dictionaryType(DictionaryTypeSyntax(self)!) case .functionType: return .functionType(FunctionTypeSyntax(self)!) + case .genericArgumentType: + return .genericArgumentType(GenericArgumentTypeSyntax(self)!) case .identifierType: return .identifierType(IdentifierTypeSyntax(self)!) case .implicitlyUnwrappedOptionalType: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index e8efa17158f..7c004a3bb0b 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -138,6 +138,7 @@ public enum SyntaxKind: Sendable { case genericArgumentClause case genericArgumentList case genericArgument + case genericArgumentType case genericParameterClause case genericParameterList case genericParameter @@ -686,6 +687,8 @@ public enum SyntaxKind: Sendable { return GenericArgumentListSyntax.self case .genericArgument: return GenericArgumentSyntax.self + case .genericArgumentType: + return GenericArgumentTypeSyntax.self case .genericParameterClause: return GenericParameterClauseSyntax.self case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index ade68592503..f47fb257be9 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -949,6 +949,13 @@ open class SyntaxRewriter { return visitChildren(node._syntaxNode).cast(GenericArgumentSyntax.self) } + /// Visit a ``GenericArgumentTypeSyntax``. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: GenericArgumentTypeSyntax) -> TypeSyntax { + return TypeSyntax(visitChildren(node._syntaxNode).cast(GenericArgumentTypeSyntax.self)) + } + /// Visit a ``GenericParameterClauseSyntax``. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -2671,6 +2678,10 @@ open class SyntaxRewriter { return { self.visitImpl(&$0, GenericArgumentSyntax.self, self.visit) } + case .genericArgumentType: + return { + self.visitImpl(&$0, GenericArgumentTypeSyntax.self, self.visit) + } case .genericParameterClause: return { self.visitImpl(&$0, GenericParameterClauseSyntax.self, self.visit) @@ -3573,6 +3584,8 @@ open class SyntaxRewriter { return visitImpl(&node, GenericArgumentListSyntax.self, visit) case .genericArgument: return visitImpl(&node, GenericArgumentSyntax.self, visit) + case .genericArgumentType: + return visitImpl(&node, GenericArgumentTypeSyntax.self, visit) case .genericParameterClause: return visitImpl(&node, GenericParameterClauseSyntax.self, visit) case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index 67092f4ac60..2ee383e0eda 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -1484,6 +1484,18 @@ open class SyntaxVisitor { open func visitPost(_ node: GenericArgumentSyntax) { } + /// Visiting ``GenericArgumentTypeSyntax`` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: GenericArgumentTypeSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting ``GenericArgumentTypeSyntax`` and its descendants. + /// - node: the node we just finished visiting. + open func visitPost(_ node: GenericArgumentTypeSyntax) { + } + /// Visiting ``GenericParameterClauseSyntax`` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -4015,6 +4027,10 @@ open class SyntaxVisitor { return { self.visitImpl(&$0, GenericArgumentSyntax.self, self.visit, self.visitPost) } + case .genericArgumentType: + return { + self.visitImpl(&$0, GenericArgumentTypeSyntax.self, self.visit, self.visitPost) + } case .genericParameterClause: return { self.visitImpl(&$0, GenericParameterClauseSyntax.self, self.visit, self.visitPost) @@ -4921,6 +4937,8 @@ open class SyntaxVisitor { visitImpl(&node, GenericArgumentListSyntax.self, visit, visitPost) case .genericArgument: visitImpl(&node, GenericArgumentSyntax.self, visit, visitPost) + case .genericArgumentType: + visitImpl(&node, GenericArgumentTypeSyntax.self, visit, visitPost) case .genericParameterClause: visitImpl(&node, GenericParameterClauseSyntax.self, visit, visitPost) case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift index d9ae3a324d8..80992f6406d 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift @@ -175,7 +175,7 @@ public struct RawGenericArgumentSyntax: RawSyntaxNodeProtocol { public init( _ unexpectedBeforeArgument: RawUnexpectedNodesSyntax? = nil, - argument: some RawTypeSyntaxNodeProtocol, + argument: RawGenericArgumentTypeSyntax, _ unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? = nil, trailingComma: RawTokenSyntax?, _ unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? = nil, @@ -197,8 +197,8 @@ public struct RawGenericArgumentSyntax: RawSyntaxNodeProtocol { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var argument: RawTypeSyntax { - layoutView.children[1].map(RawTypeSyntax.init(raw:))! + public var argument: RawGenericArgumentTypeSyntax { + layoutView.children[1].map(RawGenericArgumentTypeSyntax.init(raw:))! } public var unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? { @@ -214,6 +214,100 @@ public struct RawGenericArgumentSyntax: RawSyntaxNodeProtocol { } } +@_spi(RawSyntax) +public struct RawGenericArgumentTypeSyntax: RawTypeSyntaxNodeProtocol { + public enum Value: RawSyntaxNodeProtocol { + case type(RawTypeSyntax) + case expr(RawExprSyntax) + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + RawTypeSyntax.isKindOf(raw) || RawExprSyntax.isKindOf(raw) + } + + public var raw: RawSyntax { + switch self { + case .type(let node): + return node.raw + case .expr(let node): + return node.raw + } + } + + public init?(_ node: __shared some RawSyntaxNodeProtocol) { + if let node = node.as(RawTypeSyntax.self) { + self = .type(node) + } else if let node = node.as(RawExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public init(type: some RawTypeSyntaxNodeProtocol) { + self = .type(RawTypeSyntax(type)) + } + + public init(expr: some RawExprSyntaxNodeProtocol) { + self = .expr(RawExprSyntax(expr)) + } + } + + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .genericArgumentType + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: some RawSyntaxNodeProtocol) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeValue: RawUnexpectedNodesSyntax? = nil, + value: Value, + _ unexpectedAfterValue: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .genericArgumentType, uninitializedCount: 3, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeValue?.raw + layout[1] = value.raw + layout[2] = unexpectedAfterValue?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeValue: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var value: RawSyntax { + layoutView.children[1]! + } + + public var unexpectedAfterValue: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + @_spi(RawSyntax) public struct RawGenericParameterClauseSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift index a2574cdd83e..a4ebdadf08c 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift @@ -386,11 +386,11 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { public init( _ unexpectedBeforeLeftType: RawUnexpectedNodesSyntax? = nil, - leftType: some RawTypeSyntaxNodeProtocol, + leftType: RawGenericArgumentTypeSyntax, _ unexpectedBetweenLeftTypeAndEqual: RawUnexpectedNodesSyntax? = nil, equal: RawTokenSyntax, _ unexpectedBetweenEqualAndRightType: RawUnexpectedNodesSyntax? = nil, - rightType: some RawTypeSyntaxNodeProtocol, + rightType: RawGenericArgumentTypeSyntax, _ unexpectedAfterRightType: RawUnexpectedNodesSyntax? = nil, arena: __shared SyntaxArena ) { @@ -412,8 +412,8 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var leftType: RawTypeSyntax { - layoutView.children[1].map(RawTypeSyntax.init(raw:))! + public var leftType: RawGenericArgumentTypeSyntax { + layoutView.children[1].map(RawGenericArgumentTypeSyntax.init(raw:))! } public var unexpectedBetweenLeftTypeAndEqual: RawUnexpectedNodesSyntax? { @@ -428,8 +428,8 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var rightType: RawTypeSyntax { - layoutView.children[5].map(RawTypeSyntax.init(raw:))! + public var rightType: RawGenericArgumentTypeSyntax { + layoutView.children[5].map(RawGenericArgumentTypeSyntax.init(raw:))! } public var unexpectedAfterRightType: RawUnexpectedNodesSyntax? { diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift index 4a2489c4ba0..e3870bbb6ce 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift @@ -1501,7 +1501,7 @@ public struct RawTypeSyntax: RawTypeSyntaxNodeProtocol { public static func isKindOf(_ raw: RawSyntax) -> Bool { switch raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .genericArgumentType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: return true default: return false diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index a5430c16f4a..950d172948d 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -1335,10 +1335,16 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { case .genericArgument: assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTypeSyntax.self)) + assertNoError(kind, 1, verify(layout[1], as: RawGenericArgumentTypeSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + case .genericArgumentType: + assert(layout.count == 3) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertAnyHasNoError(kind, 1, [ + verify(layout[1], as: RawSyntax.self)]) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) case .genericParameterClause: assert(layout.count == 9) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) @@ -2261,11 +2267,11 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { case .sameTypeRequirement: assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTypeSyntax.self)) + assertNoError(kind, 1, verify(layout[1], as: RawGenericArgumentTypeSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.binaryOperator), .tokenKind(.prefixOperator), .tokenKind(.postfixOperator)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawTypeSyntax.self)) + assertNoError(kind, 5, verify(layout[5], as: RawGenericArgumentTypeSyntax.self)) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) case .sequenceExpr: assert(layout.count == 3) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index 435fb46b38d..aa0705f64aa 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -194,7 +194,7 @@ public struct GenericArgumentClauseSyntax: SyntaxProtocol, SyntaxHashable, _Leaf /// ### Children /// -/// - `argument`: ``TypeSyntax`` +/// - `argument`: ``GenericArgumentTypeSyntax`` /// - `trailingComma`: `,`? /// /// ### Contained in @@ -216,7 +216,7 @@ public struct GenericArgumentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntax public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeArgument: UnexpectedNodesSyntax? = nil, - argument: some TypeSyntaxProtocol, + argument: GenericArgumentTypeSyntax, _ unexpectedBetweenArgumentAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax? = nil, _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, @@ -258,9 +258,9 @@ public struct GenericArgumentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntax } } - public var argument: TypeSyntax { + public var argument: GenericArgumentTypeSyntax { get { - return Syntax(self).child(at: 1)!.cast(TypeSyntax.self) + return Syntax(self).child(at: 1)!.cast(GenericArgumentTypeSyntax.self) } set(value) { self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) @@ -306,6 +306,162 @@ public struct GenericArgumentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntax ]) } +// MARK: - GenericArgumentTypeSyntax + +/// ### Children +/// +/// - `value`: (``TypeSyntax`` | ``ExprSyntax``) +/// +/// ### Contained in +/// +/// - ``GenericArgumentSyntax``.``GenericArgumentSyntax/argument`` +/// - ``SameTypeRequirementSyntax``.``SameTypeRequirementSyntax/leftType`` +/// - ``SameTypeRequirementSyntax``.``SameTypeRequirementSyntax/rightType`` +public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyntaxNodeProtocol { + public enum Value: SyntaxChildChoices, SyntaxHashable { + case type(TypeSyntax) + case expr(ExprSyntax) + + public var _syntaxNode: Syntax { + switch self { + case .type(let node): + return node._syntaxNode + case .expr(let node): + return node._syntaxNode + } + } + + public init(_ node: some TypeSyntaxProtocol) { + self = .type(TypeSyntax(node)) + } + + public init(_ node: some ExprSyntaxProtocol) { + self = .expr(ExprSyntax(node)) + } + + public init?(_ node: __shared some SyntaxProtocol) { + if let node = node.as(TypeSyntax.self) { + self = .type(node) + } else if let node = node.as(ExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public static var structure: SyntaxNodeStructure { + return .choices([.node(TypeSyntax.self), .node(ExprSyntax.self)]) + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + public func `is`(_ syntaxType: (some TypeSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + public func `is`(_ syntaxType: (some ExprSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + } + + public let _syntaxNode: Syntax + + public init?(_ node: __shared some SyntaxProtocol) { + guard node.raw.kind == .genericArgumentType else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// - Parameters: + /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeValue: UnexpectedNodesSyntax? = nil, + value: Value, + _ unexpectedAfterValue: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + self = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeValue, value, unexpectedAfterValue))) { (arena, _) in + let layout: [RawSyntax?] = [unexpectedBeforeValue?.raw, value.raw, unexpectedAfterValue?.raw] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.genericArgumentType, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + ) + return Syntax.forRoot(raw, rawNodeArena: arena).cast(Self.self) + } + } + + public var unexpectedBeforeValue: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 0, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + } + } + + public var value: Value { + get { + return Syntax(self).child(at: 1)!.cast(Value.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + } + } + + public var unexpectedAfterValue: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + } + } + + public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforeValue, \Self.value, \Self.unexpectedAfterValue]) +} + // MARK: - GenericParameterClauseSyntax /// The parameter clause that defines the generic parameters. diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift index 87750e981a9..7d24e1faec5 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift @@ -626,9 +626,9 @@ public struct ReturnStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyn /// ### Children /// -/// - `leftType`: ``TypeSyntax`` +/// - `leftType`: ``GenericArgumentTypeSyntax`` /// - `equal`: (`` | `` | ``) -/// - `rightType`: ``TypeSyntax`` +/// - `rightType`: ``GenericArgumentTypeSyntax`` /// /// ### Contained in /// @@ -649,11 +649,11 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeLeftType: UnexpectedNodesSyntax? = nil, - leftType: some TypeSyntaxProtocol, + leftType: GenericArgumentTypeSyntax, _ unexpectedBetweenLeftTypeAndEqual: UnexpectedNodesSyntax? = nil, equal: TokenSyntax, _ unexpectedBetweenEqualAndRightType: UnexpectedNodesSyntax? = nil, - rightType: some TypeSyntaxProtocol, + rightType: GenericArgumentTypeSyntax, _ unexpectedAfterRightType: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { @@ -697,9 +697,9 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy } } - public var leftType: TypeSyntax { + public var leftType: GenericArgumentTypeSyntax { get { - return Syntax(self).child(at: 1)!.cast(TypeSyntax.self) + return Syntax(self).child(at: 1)!.cast(GenericArgumentTypeSyntax.self) } set(value) { self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(SameTypeRequirementSyntax.self) @@ -739,9 +739,9 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy } } - public var rightType: TypeSyntax { + public var rightType: GenericArgumentTypeSyntax { get { - return Syntax(self).child(at: 5)!.cast(TypeSyntax.self) + return Syntax(self).child(at: 5)!.cast(GenericArgumentTypeSyntax.self) } set(value) { self = Syntax(self).replacingChild(at: 5, with: Syntax(value), arena: SyntaxArena()).cast(SameTypeRequirementSyntax.self) diff --git a/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift b/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift index 23961c8ec5c..f778eb62e4d 100644 --- a/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift +++ b/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift @@ -262,13 +262,13 @@ private final class MacroExpansionRewriter: SyntaxRewriter { let parameterReplacements: [DeclReferenceExprSyntax: Int] let arguments: [ExprSyntax] let genericParameterReplacements: [GenericArgumentSyntax: Int] - let genericArguments: [TypeSyntax] + let genericArguments: [GenericArgumentTypeSyntax] init( parameterReplacements: [DeclReferenceExprSyntax: Int], arguments: [ExprSyntax], genericReplacements: [GenericArgumentSyntax: Int], - genericArguments: [TypeSyntax] + genericArguments: [GenericArgumentTypeSyntax] ) { self.parameterReplacements = parameterReplacements self.arguments = arguments @@ -331,7 +331,7 @@ extension MacroDeclSyntax { }, uniquingKeysWith: { l, r in l } ) - let genericArguments: [TypeSyntax] = + let genericArguments: [GenericArgumentTypeSyntax] = genericArgumentList?.arguments.map { $0.argument } ?? [] let rewriter = MacroExpansionRewriter( diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index 345ca2739e9..6e643f99779 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -2715,8 +2715,9 @@ final class DeclarationTests: ParserTestCase { genericArgumentClause: GenericArgumentClauseSyntax( arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: - IdentifierTypeSyntax(name: .identifier("T")) + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("T")))) + ) ) ]) ) diff --git a/Tests/SwiftParserTest/PatternTests.swift b/Tests/SwiftParserTest/PatternTests.swift index a55e76a19ec..a379149c5cb 100644 --- a/Tests/SwiftParserTest/PatternTests.swift +++ b/Tests/SwiftParserTest/PatternTests.swift @@ -27,7 +27,7 @@ final class PatternTests: ParserTestCase { expression: DeclReferenceExprSyntax(baseName: .identifier("E")), genericArgumentClause: GenericArgumentClauseSyntax( arguments: .init([ - .init(argument: IdentifierTypeSyntax(name: .identifier("Int"))) + .init(argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("Int")))))) ]) ) ), diff --git a/Tests/SwiftParserTest/StatementTests.swift b/Tests/SwiftParserTest/StatementTests.swift index cd82807bb01..628ed538d82 100644 --- a/Tests/SwiftParserTest/StatementTests.swift +++ b/Tests/SwiftParserTest/StatementTests.swift @@ -376,10 +376,10 @@ final class StatementTests: ParserTestCase { leftAngle: .leftAngleToken(), arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: OptionalTypeSyntax( + argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(OptionalTypeSyntax( wrappedType: IdentifierTypeSyntax(name: .identifier("String")), questionMark: .postfixQuestionMarkToken() - ) + )))) ) ]), rightAngle: .rightAngleToken() @@ -398,7 +398,7 @@ final class StatementTests: ParserTestCase { leftAngle: .leftAngleToken(), arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: IdentifierTypeSyntax(name: .keyword(.Any)) + argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .keyword(.Any))))) ) ]), rightAngle: .rightAngleToken() diff --git a/Tests/SwiftParserTest/TypeMemberTests.swift b/Tests/SwiftParserTest/TypeMemberTests.swift index 9e0e123ccc1..12376df16a8 100644 --- a/Tests/SwiftParserTest/TypeMemberTests.swift +++ b/Tests/SwiftParserTest/TypeMemberTests.swift @@ -150,7 +150,7 @@ final class TypeMemberTests: ParserTestCase { \.genericArgumentClause, GenericArgumentClauseSyntax( arguments: .init([ - GenericArgumentSyntax(argument: IdentifierTypeSyntax(name: .identifier("W"))) + GenericArgumentSyntax(argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("W")))))) ]) ) ), diff --git a/Tests/SwiftParserTest/TypeTests.swift b/Tests/SwiftParserTest/TypeTests.swift index 0e8bd40d38f..68a02322a47 100644 --- a/Tests/SwiftParserTest/TypeTests.swift +++ b/Tests/SwiftParserTest/TypeTests.swift @@ -260,8 +260,10 @@ final class TypeTests: ParserTestCase { genericArgumentClause: GenericArgumentClauseSyntax( arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: IdentifierTypeSyntax( - name: .identifier("Foo") + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax( + name: .identifier("Foo") + ))) ) ) ]) diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index 482522a58a7..91d0120900b 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -102,4 +102,147 @@ final class ValueGenericsTests: ParserTestCase { """ ) } + + func testIntegers() { + assertParse( + """ + let x: 1️⃣123 + """, + diagnostics: [ + DiagnosticSpec( + message: "expected type in type annotation", + fixIts: ["insert type"] + ), + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ) + ], + fixedSource: """ + let x: <#type#> = 123 + """ + ) + + assertParse( + """ + let x: Generic<123> + """ + ) + + // FIXME?: We can't parse this either in the old parser or the swift-syntax one. + assertParse( + """ + let x: Generic1️⃣<-123> + """, + diagnostics: [ + DiagnosticSpec( + message: "extraneous code '<-123>' at top level" + ) + ] + ) + + assertParse( + """ + typealias One = 1️⃣1 + """, + diagnostics: [ + DiagnosticSpec( + message: "expected type in typealias declaration", + fixIts: ["insert type"] + ) + ], + fixedSource: """ + typealias One = <#type#>1 + """ + ) + + assertParse( + """ + extension Vector where N == 123 {} + """ + ) + + assertParse( + """ + extension Vector where 123 == N {} + """ + ) + + assertParse( + """ + extension Vector where N == -123 {} + """ + ) + + assertParse( + """ + extension Vector where -123 == N {} + """ + ) + + assertParse( + """ + extension Vector where N: 1️⃣123 {} + """, + diagnostics: [ + DiagnosticSpec( + message: "expected type in conformance requirement", + fixIts: ["insert type"] + ), + DiagnosticSpec( + message: "unexpected code '123' in extension" + ) + ], + fixedSource: """ + extension Vector where N: <#type#> 123 {} + """ + ) + + assertParse( + """ + extension Vector where N: 1️⃣-123 {} + """, + diagnostics: [ + DiagnosticSpec( + message: "expected type in conformance requirement", + fixIts: ["insert type"] + ), + DiagnosticSpec( + message: "unexpected code '-123' in extension" + ) + ], + fixedSource: """ + extension Vector where N: <#type#> -123 {} + """ + ) + + // FIXME: Not the best diagnostic + assertParse( + """ + extension Vector where 1231️⃣: N {} + """, + diagnostics: [ + DiagnosticSpec( + message: "expected ':' or '==' to indicate a conformance or same-type requirement" + ), + DiagnosticSpec( + message: "unexpected code ': N' in extension" + ) + ] + ) + + assertParse( + """ + extension Vector where -1231️⃣: N {} + """, + diagnostics: [ + DiagnosticSpec( + message: "expected ':' or '==' to indicate a conformance or same-type requirement" + ), + DiagnosticSpec( + message: "unexpected code ': N' in extension" + ) + ] + ) + } } diff --git a/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift b/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift index 98d5849cfd8..7ad687ac723 100644 --- a/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift +++ b/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift @@ -91,11 +91,15 @@ final class GenericDisambiguationTests: ParserTestCase { """, substructure: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: IdentifierTypeSyntax(name: .identifier("b")), + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))) + ), trailingComma: .commaToken() ), GenericArgumentSyntax( - argument: IdentifierTypeSyntax(name: .identifier("c")) + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) + ) ), ]) ) @@ -109,11 +113,15 @@ final class GenericDisambiguationTests: ParserTestCase { """, substructure: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: IdentifierTypeSyntax(name: .identifier("b")), + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))) + ), trailingComma: .commaToken() ), GenericArgumentSyntax( - argument: IdentifierTypeSyntax(name: .identifier("c")) + argument: GenericArgumentTypeSyntax( + value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) + ) ), ]) ) From 6d7dcee2f22000129020be414687580e135b2157 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 17 Oct 2024 10:18:46 -0700 Subject: [PATCH 02/10] Use node choices instead of new node type --- .../SyntaxSupport/ExperimentalFeatures.swift | 3 + .../Sources/SyntaxSupport/GenericNodes.swift | 32 ++- .../SyntaxSupport/SyntaxNodeKind.swift | 1 - .../Sources/SyntaxSupport/TypeNodes.swift | 35 ++- Release Notes/601.md | 24 +++ Sources/SwiftParser/Declarations.swift | 37 ++-- Sources/SwiftParser/Types.swift | 40 ++-- .../generated/ExperimentalFeatures.swift | 3 + .../SyntaxKindNameForDiagnostics.swift | 2 - .../generated/SwiftSyntax.md | 1 - .../generated/ChildNameForKeyPath.swift | 6 - .../RenamedChildrenCompatibility.swift | 12 +- .../generated/SyntaxAnyVisitor.swift | 8 - .../generated/SyntaxBaseNodes.swift | 5 +- .../SwiftSyntax/generated/SyntaxEnum.swift | 6 - .../SwiftSyntax/generated/SyntaxKind.swift | 3 - .../generated/SyntaxRewriter.swift | 13 -- .../SwiftSyntax/generated/SyntaxVisitor.swift | 18 -- .../generated/raw/RawSyntaxNodesGHI.swift | 110 +++------- .../generated/raw/RawSyntaxNodesQRS.swift | 92 +++++++- .../generated/raw/RawSyntaxNodesTUVWXYZ.swift | 2 +- .../generated/raw/RawSyntaxValidation.swift | 15 +- .../syntaxNodes/SyntaxNodesGHI.swift | 204 ++++++------------ .../syntaxNodes/SyntaxNodesQRS.swift | 200 ++++++++++++++++- .../MacroReplacement.swift | 6 +- Tests/SwiftParserTest/DeclarationTests.swift | 4 +- Tests/SwiftParserTest/PatternTests.swift | 2 +- Tests/SwiftParserTest/StatementTests.swift | 14 +- Tests/SwiftParserTest/TypeMemberTests.swift | 2 +- Tests/SwiftParserTest/TypeTests.swift | 10 +- .../SwiftParserTest/ValueGenericsTests.swift | 10 +- .../GenericDisambiguationTests.swift | 16 +- 32 files changed, 538 insertions(+), 398 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift index 35fadbc0f2f..b0b1f36226d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift @@ -19,6 +19,7 @@ public enum ExperimentalFeature: String, CaseIterable { case nonescapableTypes case trailingComma case coroutineAccessors + case valueGenerics /// The name of the feature, which is used in the doc comment. public var featureName: String { @@ -35,6 +36,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "trailing comma" case .coroutineAccessors: return "CoroutineAccessors" + case .valueGenerics: + return "ValueGenerics" } } diff --git a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift index becc4fbcbb8..a54368b8dd6 100644 --- a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift @@ -334,8 +334,20 @@ public let GENERIC_NODES: [Node] = [ children: [ Child( name: "leftType", - kind: .node(kind: .genericArgumentType), - nameForDiagnostics: "left-hand type" + kind: .nodeChoices(choices: [ + Child( + name: "type", + kind: .node(kind: .type) + ), + Child( + name: "expr", + kind: .node(kind: .expr), + experimentalFeature: .valueGenerics + ), + ]), + nameForDiagnostics: "left-hand type", + documentation: + "The left hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics." ), Child( name: "equal", @@ -343,8 +355,20 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "rightType", - kind: .node(kind: .genericArgumentType), - nameForDiagnostics: "right-hand type" + kind: .nodeChoices(choices: [ + Child( + name: "type", + kind: .node(kind: .type) + ), + Child( + name: "expr", + kind: .node(kind: .expr), + experimentalFeature: .valueGenerics + ), + ]), + nameForDiagnostics: "right-hand type", + documentation: + "The right hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics." ), ], childHistory: [ diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift index a5a96cf5e1d..aca5c52aa86 100644 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift @@ -142,7 +142,6 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon case genericArgument case genericArgumentClause case genericArgumentList - case genericArgumentType case genericParameter case genericParameterClause case genericParameterList diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index d75af9beb2b..ac5b1a8f8a4 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -257,7 +257,19 @@ public let TYPE_NODES: [Node] = [ children: [ Child( name: "argument", - kind: .node(kind: .genericArgumentType) + kind: .nodeChoices(choices: [ + Child( + name: "type", + kind: .node(kind: .type) + ), + Child( + name: "expr", + kind: .node(kind: .expr), + experimentalFeature: .valueGenerics + ), + ]), + documentation: + "The argument type for a generic argument. This can either be a regular type argument or an expression for value generics." ), Child( name: "trailingComma", @@ -652,25 +664,4 @@ public let TYPE_NODES: [Node] = [ nameForDiagnostics: nil, elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier] ), - - Node( - kind: .genericArgumentType, - base: .type, - nameForDiagnostics: "generic argument type", - children: [ - Child( - name: "value", - kind: .nodeChoices(choices: [ - Child( - name: "type", - kind: .node(kind: .type) - ), - Child( - name: "expr", - kind: .node(kind: .expr) - ) - ]) - ) - ] - ) ] diff --git a/Release Notes/601.md b/Release Notes/601.md index 2f1d6264698..6e4a0b0c8d3 100644 --- a/Release Notes/601.md +++ b/Release Notes/601.md @@ -2,6 +2,18 @@ ## New APIs +- `SameTypeRequirementSyntax` has a new `RightType` nested type. + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + +- `SameTypeRequirementSyntax` has a new `LeftType` nested type. + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + +- `GenericArgumentSynax` has a new `Argument` nested type. + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + - `GenericParameterSyntax` now has a new `specifier` property. - Description: With the introduction of value generics, generic parameters can now be optionally preceded by either a `let` or an `each`. The `specifier` property captures the token representing which one was parsed. - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2785 @@ -54,6 +66,18 @@ ## API-Incompatible Changes +- `SameTypeRequirementSyntax.rightType` has changed types from `TypeSyntax` to `SameTypeRequirementSyntax.RightType` + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + +- `SameTypeRequirementSyntax.leftType` has changed types from `TypeSyntax` to `SameTypeRequirementSyntax.LeftType` + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + +- `GenericArgumentSyntax.argument` has changed types from `TypeSyntax` to `GenericArgumentSyntax.Argument` + - Description: The Swift parser can now parse values as types in certain situations, so the new type reflects the possibility of the argument being either an `ExprSyntax` or a `TypeSyntax`. + - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2859 + - Moved `Radix` and `IntegerLiteralExprSyntax.radix` from `SwiftRefactor` to `SwiftSyntax`. - Description: Allows retrieving the radix value from the `literal.text`. - Issue: https://github.com/apple/swift-syntax/issues/405 diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index dcd3784b88e..8b68c484eca 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #if swift(>=6) -@_spi(RawSyntax) internal import SwiftSyntax +@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax #else -@_spi(RawSyntax) import SwiftSyntax +@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftSyntax #endif extension DeclarationModifier { @@ -524,6 +524,22 @@ extension Parser { return self.at(prefix: ">") } + mutating func parseSameTypeLeftType() -> RawSameTypeRequirementSyntax.LeftType { + if let valueType = self.parseValueType() { + return .expr(valueType) + } else { + return .type(self.parseType()) + } + } + + mutating func parseSameTypeRightType() -> RawSameTypeRequirementSyntax.RightType { + if let valueType = self.parseValueType() { + return .expr(valueType) + } else { + return .type(self.parseType()) + } + } + mutating func parseGenericWhereClause() -> RawGenericWhereClauseSyntax { let (unexpectedBeforeWhereKeyword, whereKeyword) = self.expect(.keyword(.where)) @@ -532,9 +548,9 @@ extension Parser { var keepGoing: RawTokenSyntax? = nil var loopProgress = LoopProgressCondition() repeat { - let firstArgument = self.parseGenericArgumentType() + let firstArgument = self.parseSameTypeLeftType() - guard !firstArgument.value.raw.is(RawMissingTypeSyntax.self) else { + guard !firstArgument.raw.is(RawMissingTypeSyntax.self) else { keepGoing = self.consume(if: .comma) elements.append( RawGenericRequirementSyntax( @@ -542,7 +558,7 @@ extension Parser { RawSameTypeRequirementSyntax( leftType: firstArgument, equal: missingToken(.binaryOperator, text: "=="), - rightType: firstArgument, + rightType: .type(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))), arena: self.arena ) ), @@ -555,7 +571,7 @@ extension Parser { let requirement: RawGenericRequirementSyntax.Requirement - switch RawGenericArgumentTypeSyntax.Value(firstArgument.value.raw)! { + switch firstArgument { // If the first argument is an expression, then we have to have a same // type requirement. We do not allow conformance requirements like // '123: Protocol' or layout constraints on expressions. @@ -564,7 +580,7 @@ extension Parser { anyIn: SameTypeRequirementSyntax.EqualOptions.self, default: .binaryOperator ) - let secondArgument = self.parseGenericArgumentType() + let secondArgument = self.parseSameTypeRightType() requirement = .sameTypeRequirement( RawSameTypeRequirementSyntax( leftType: firstArgument, @@ -689,7 +705,7 @@ extension Parser { (.postfixOperator, let handle)?, (.prefixOperator, let handle)?: let equal = self.eat(handle) - let secondArgument = self.parseGenericArgumentType() + let secondArgument = self.parseSameTypeRightType() requirement = .sameTypeRequirement( RawSameTypeRequirementSyntax( leftType: firstArgument, @@ -703,10 +719,7 @@ extension Parser { RawSameTypeRequirementSyntax( leftType: firstArgument, equal: RawTokenSyntax(missing: .binaryOperator, text: "==", arena: self.arena), - rightType: RawGenericArgumentTypeSyntax( - value: .type(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))), - arena: self.arena - ), + rightType: .type(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))), arena: self.arena ) ) diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 373b1cd899e..02abca08374 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -418,7 +418,7 @@ extension Parser { repeat { let argument = self.parseGenericArgumentType() - if arguments.isEmpty, argument.value.raw.is(RawMissingTypeSyntax.self) { + if arguments.isEmpty, argument.raw.is(RawMissingTypeSyntax.self) { break } @@ -449,17 +449,11 @@ extension Parser { ) } - mutating func parseGenericArgumentType() -> RawGenericArgumentTypeSyntax { + mutating func parseGenericArgumentType() -> RawGenericArgumentSyntax.Argument { if let valueType = self.parseValueType() { - return RawGenericArgumentTypeSyntax( - value: .expr(valueType), - arena: self.arena - ) + return .expr(valueType) } else { - return RawGenericArgumentTypeSyntax( - value: .type(self.parseType()), - arena: self.arena - ) + return .type(self.parseType()) } } } @@ -710,7 +704,8 @@ extension Parser.Lookahead { // '-123' for value generics. if self.currentToken.tokenText == "-", - self.peek(isAt: .integerLiteral) { + self.peek(isAt: .integerLiteral) + { self.consumeAnyToken() self.consumeAnyToken() return true @@ -1137,10 +1132,17 @@ extension Parser { extension Parser { mutating func parseValueType() -> RawExprSyntax? { + // If the 'ValueGenerics' experimental feature hasn't been added, then don't + // attempt to parse values as types. + guard self.experimentalFeatures.contains(.valueGenerics) else { + return nil + } + // Eat any '-' preceding integer literals. var minusSign: RawTokenSyntax? = nil - if self.currentToken.tokenText == "-", - self.peek(isAt: .integerLiteral) { + if self.atContextualPunctuator("-"), + self.peek(isAt: .integerLiteral) + { minusSign = self.consumeIfContextualPunctuator("-", remapping: .prefixOperator) } @@ -1156,11 +1158,13 @@ extension Parser { return RawExprSyntax(integerExpr) } - return RawExprSyntax(RawPrefixOperatorExprSyntax( - operator: minusSign, - expression: integerExpr, - arena: self.arena - )) + return RawExprSyntax( + RawPrefixOperatorExprSyntax( + operator: minusSign, + expression: integerExpr, + arena: self.arena + ) + ) } return nil diff --git a/Sources/SwiftParser/generated/ExperimentalFeatures.swift b/Sources/SwiftParser/generated/ExperimentalFeatures.swift index 63fe9639d8f..24aa8dce00b 100644 --- a/Sources/SwiftParser/generated/ExperimentalFeatures.swift +++ b/Sources/SwiftParser/generated/ExperimentalFeatures.swift @@ -41,4 +41,7 @@ extension Parser.ExperimentalFeatures { /// Whether to enable the parsing of CoroutineAccessors. public static let coroutineAccessors = Self (rawValue: 1 << 5) + + /// Whether to enable the parsing of ValueGenerics. + public static let valueGenerics = Self (rawValue: 1 << 6) } diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 09b42bb4722..4006f445c54 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -197,8 +197,6 @@ extension SyntaxKind { return "generic argument clause" case .genericArgument: return "generic argument" - case .genericArgumentType: - return "generic argument type" case .genericParameterClause: return "generic parameter clause" case .genericParameter: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index 31434ac59b4..10a71a658da 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -180,7 +180,6 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - -- - - - diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index cd4f8cf9713..31a6ac2cac5 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -1529,12 +1529,6 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "trailingComma" case \GenericArgumentSyntax.unexpectedAfterTrailingComma: return "unexpectedAfterTrailingComma" - case \GenericArgumentTypeSyntax.unexpectedBeforeValue: - return "unexpectedBeforeValue" - case \GenericArgumentTypeSyntax.value: - return "value" - case \GenericArgumentTypeSyntax.unexpectedAfterValue: - return "unexpectedAfterValue" case \GenericParameterClauseSyntax.unexpectedBeforeLeftAngle: return "unexpectedBeforeLeftAngle" case \GenericParameterClauseSyntax.leftAngle: diff --git a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift index b04d8c83913..c0b55967d15 100644 --- a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift +++ b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift @@ -3450,7 +3450,7 @@ extension GenericArgumentSyntax { } @available(*, deprecated, renamed: "argument") - public var argumentType: GenericArgumentTypeSyntax { + public var argumentType: Argument { get { return argument } @@ -3474,7 +3474,7 @@ extension GenericArgumentSyntax { public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeArgumentType: UnexpectedNodesSyntax? = nil, - argumentType: GenericArgumentTypeSyntax, + argumentType: Argument, _ unexpectedBetweenArgumentTypeAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax? = nil, _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, @@ -6615,7 +6615,7 @@ extension SameTypeRequirementSyntax { } @available(*, deprecated, renamed: "leftType") - public var leftTypeIdentifier: GenericArgumentTypeSyntax { + public var leftTypeIdentifier: LeftType { get { return leftType } @@ -6655,7 +6655,7 @@ extension SameTypeRequirementSyntax { } @available(*, deprecated, renamed: "rightType") - public var rightTypeIdentifier: GenericArgumentTypeSyntax { + public var rightTypeIdentifier: RightType { get { return rightType } @@ -6679,11 +6679,11 @@ extension SameTypeRequirementSyntax { public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeLeftTypeIdentifier: UnexpectedNodesSyntax? = nil, - leftTypeIdentifier: GenericArgumentTypeSyntax, + leftTypeIdentifier: LeftType, _ unexpectedBetweenLeftTypeIdentifierAndEqualityToken: UnexpectedNodesSyntax? = nil, equalityToken: TokenSyntax, _ unexpectedBetweenEqualityTokenAndRightTypeIdentifier: UnexpectedNodesSyntax? = nil, - rightTypeIdentifier: GenericArgumentTypeSyntax, + rightTypeIdentifier: RightType, _ unexpectedAfterRightTypeIdentifier: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index c7ff5c95a9a..6b4a238d8cf 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -1022,14 +1022,6 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } - override open func visit(_ node: GenericArgumentTypeSyntax) -> SyntaxVisitorContinueKind { - return visitAny(node._syntaxNode) - } - - override open func visitPost(_ node: GenericArgumentTypeSyntax) { - visitAnyPost(node._syntaxNode) - } - override open func visit(_ node: GenericParameterClauseSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index 7a9e8cd7f31..4341ca1bc2f 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -1371,7 +1371,6 @@ extension Syntax { /// - ``CompositionTypeSyntax`` /// - ``DictionaryTypeSyntax`` /// - ``FunctionTypeSyntax`` -/// - ``GenericArgumentTypeSyntax`` /// - ``IdentifierTypeSyntax`` /// - ``ImplicitlyUnwrappedOptionalTypeSyntax`` /// - ``MemberTypeSyntax`` @@ -1420,7 +1419,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { public init?(_ node: __shared some SyntaxProtocol) { switch node.raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .genericArgumentType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: self._syntaxNode = node._syntaxNode default: return nil @@ -1451,7 +1450,6 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { .node(CompositionTypeSyntax.self), .node(DictionaryTypeSyntax.self), .node(FunctionTypeSyntax.self), - .node(GenericArgumentTypeSyntax.self), .node(IdentifierTypeSyntax.self), .node(ImplicitlyUnwrappedOptionalTypeSyntax.self), .node(MemberTypeSyntax.self), @@ -1639,7 +1637,6 @@ extension Syntax { .node(GenericArgumentClauseSyntax.self), .node(GenericArgumentListSyntax.self), .node(GenericArgumentSyntax.self), - .node(GenericArgumentTypeSyntax.self), .node(GenericParameterClauseSyntax.self), .node(GenericParameterListSyntax.self), .node(GenericParameterSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index e73ccc578f2..fef31916caa 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -138,7 +138,6 @@ public enum SyntaxEnum: Sendable { case genericArgumentClause(GenericArgumentClauseSyntax) case genericArgumentList(GenericArgumentListSyntax) case genericArgument(GenericArgumentSyntax) - case genericArgumentType(GenericArgumentTypeSyntax) case genericParameterClause(GenericParameterClauseSyntax) case genericParameterList(GenericParameterListSyntax) case genericParameter(GenericParameterSyntax) @@ -562,8 +561,6 @@ extension Syntax { return .genericArgumentList(GenericArgumentListSyntax(self)!) case .genericArgument: return .genericArgument(GenericArgumentSyntax(self)!) - case .genericArgumentType: - return .genericArgumentType(GenericArgumentTypeSyntax(self)!) case .genericParameterClause: return .genericParameterClause(GenericParameterClauseSyntax(self)!) case .genericParameterList: @@ -1267,7 +1264,6 @@ public enum TypeSyntaxEnum { case compositionType(CompositionTypeSyntax) case dictionaryType(DictionaryTypeSyntax) case functionType(FunctionTypeSyntax) - case genericArgumentType(GenericArgumentTypeSyntax) case identifierType(IdentifierTypeSyntax) case implicitlyUnwrappedOptionalType(ImplicitlyUnwrappedOptionalTypeSyntax) case memberType(MemberTypeSyntax) @@ -1298,8 +1294,6 @@ extension TypeSyntax { return .dictionaryType(DictionaryTypeSyntax(self)!) case .functionType: return .functionType(FunctionTypeSyntax(self)!) - case .genericArgumentType: - return .genericArgumentType(GenericArgumentTypeSyntax(self)!) case .identifierType: return .identifierType(IdentifierTypeSyntax(self)!) case .implicitlyUnwrappedOptionalType: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index 7c004a3bb0b..e8efa17158f 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -138,7 +138,6 @@ public enum SyntaxKind: Sendable { case genericArgumentClause case genericArgumentList case genericArgument - case genericArgumentType case genericParameterClause case genericParameterList case genericParameter @@ -687,8 +686,6 @@ public enum SyntaxKind: Sendable { return GenericArgumentListSyntax.self case .genericArgument: return GenericArgumentSyntax.self - case .genericArgumentType: - return GenericArgumentTypeSyntax.self case .genericParameterClause: return GenericParameterClauseSyntax.self case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index f47fb257be9..ade68592503 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -949,13 +949,6 @@ open class SyntaxRewriter { return visitChildren(node._syntaxNode).cast(GenericArgumentSyntax.self) } - /// Visit a ``GenericArgumentTypeSyntax``. - /// - Parameter node: the node that is being visited - /// - Returns: the rewritten node - open func visit(_ node: GenericArgumentTypeSyntax) -> TypeSyntax { - return TypeSyntax(visitChildren(node._syntaxNode).cast(GenericArgumentTypeSyntax.self)) - } - /// Visit a ``GenericParameterClauseSyntax``. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -2678,10 +2671,6 @@ open class SyntaxRewriter { return { self.visitImpl(&$0, GenericArgumentSyntax.self, self.visit) } - case .genericArgumentType: - return { - self.visitImpl(&$0, GenericArgumentTypeSyntax.self, self.visit) - } case .genericParameterClause: return { self.visitImpl(&$0, GenericParameterClauseSyntax.self, self.visit) @@ -3584,8 +3573,6 @@ open class SyntaxRewriter { return visitImpl(&node, GenericArgumentListSyntax.self, visit) case .genericArgument: return visitImpl(&node, GenericArgumentSyntax.self, visit) - case .genericArgumentType: - return visitImpl(&node, GenericArgumentTypeSyntax.self, visit) case .genericParameterClause: return visitImpl(&node, GenericParameterClauseSyntax.self, visit) case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index 2ee383e0eda..67092f4ac60 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -1484,18 +1484,6 @@ open class SyntaxVisitor { open func visitPost(_ node: GenericArgumentSyntax) { } - /// Visiting ``GenericArgumentTypeSyntax`` specifically. - /// - Parameter node: the node we are visiting. - /// - Returns: how should we continue visiting. - open func visit(_ node: GenericArgumentTypeSyntax) -> SyntaxVisitorContinueKind { - return .visitChildren - } - - /// The function called after visiting ``GenericArgumentTypeSyntax`` and its descendants. - /// - node: the node we just finished visiting. - open func visitPost(_ node: GenericArgumentTypeSyntax) { - } - /// Visiting ``GenericParameterClauseSyntax`` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -4027,10 +4015,6 @@ open class SyntaxVisitor { return { self.visitImpl(&$0, GenericArgumentSyntax.self, self.visit, self.visitPost) } - case .genericArgumentType: - return { - self.visitImpl(&$0, GenericArgumentTypeSyntax.self, self.visit, self.visitPost) - } case .genericParameterClause: return { self.visitImpl(&$0, GenericParameterClauseSyntax.self, self.visit, self.visitPost) @@ -4937,8 +4921,6 @@ open class SyntaxVisitor { visitImpl(&node, GenericArgumentListSyntax.self, visit, visitPost) case .genericArgument: visitImpl(&node, GenericArgumentSyntax.self, visit, visitPost) - case .genericArgumentType: - visitImpl(&node, GenericArgumentTypeSyntax.self, visit, visitPost) case .genericParameterClause: visitImpl(&node, GenericParameterClauseSyntax.self, visit, visitPost) case .genericParameterList: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift index 80992f6406d..e9972b6df1a 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift @@ -146,78 +146,10 @@ public struct RawGenericArgumentListSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) public struct RawGenericArgumentSyntax: RawSyntaxNodeProtocol { - @_spi(RawSyntax) - public var layoutView: RawSyntaxLayoutView { - return raw.layoutView! - } - - public static func isKindOf(_ raw: RawSyntax) -> Bool { - return raw.kind == .genericArgument - } - - public var raw: RawSyntax - - init(raw: RawSyntax) { - precondition(Self.isKindOf(raw)) - self.raw = raw - } - - private init(unchecked raw: RawSyntax) { - self.raw = raw - } - - public init?(_ other: some RawSyntaxNodeProtocol) { - guard Self.isKindOf(other.raw) else { - return nil - } - self.init(unchecked: other.raw) - } - - public init( - _ unexpectedBeforeArgument: RawUnexpectedNodesSyntax? = nil, - argument: RawGenericArgumentTypeSyntax, - _ unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? = nil, - trailingComma: RawTokenSyntax?, - _ unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? = nil, - arena: __shared SyntaxArena - ) { - let raw = RawSyntax.makeLayout( - kind: .genericArgument, uninitializedCount: 5, arena: arena) { layout in - layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeArgument?.raw - layout[1] = argument.raw - layout[2] = unexpectedBetweenArgumentAndTrailingComma?.raw - layout[3] = trailingComma?.raw - layout[4] = unexpectedAfterTrailingComma?.raw - } - self.init(unchecked: raw) - } - - public var unexpectedBeforeArgument: RawUnexpectedNodesSyntax? { - layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) - } - - public var argument: RawGenericArgumentTypeSyntax { - layoutView.children[1].map(RawGenericArgumentTypeSyntax.init(raw:))! - } - - public var unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? { - layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) - } - - public var trailingComma: RawTokenSyntax? { - layoutView.children[3].map(RawTokenSyntax.init(raw:)) - } - - public var unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? { - layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) - } -} - -@_spi(RawSyntax) -public struct RawGenericArgumentTypeSyntax: RawTypeSyntaxNodeProtocol { - public enum Value: RawSyntaxNodeProtocol { + public enum Argument: RawSyntaxNodeProtocol { case type(RawTypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) case expr(RawExprSyntax) public static func isKindOf(_ raw: RawSyntax) -> Bool { @@ -247,6 +179,8 @@ public struct RawGenericArgumentTypeSyntax: RawTypeSyntaxNodeProtocol { self = .type(RawTypeSyntax(type)) } + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) public init(expr: some RawExprSyntaxNodeProtocol) { self = .expr(RawExprSyntax(expr)) } @@ -258,7 +192,7 @@ public struct RawGenericArgumentTypeSyntax: RawTypeSyntaxNodeProtocol { } public static func isKindOf(_ raw: RawSyntax) -> Bool { - return raw.kind == .genericArgumentType + return raw.kind == .genericArgument } public var raw: RawSyntax @@ -280,32 +214,44 @@ public struct RawGenericArgumentTypeSyntax: RawTypeSyntaxNodeProtocol { } public init( - _ unexpectedBeforeValue: RawUnexpectedNodesSyntax? = nil, - value: Value, - _ unexpectedAfterValue: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeArgument: RawUnexpectedNodesSyntax? = nil, + argument: Argument, + _ unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? = nil, + trailingComma: RawTokenSyntax?, + _ unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? = nil, arena: __shared SyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .genericArgumentType, uninitializedCount: 3, arena: arena) { layout in + kind: .genericArgument, uninitializedCount: 5, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeValue?.raw - layout[1] = value.raw - layout[2] = unexpectedAfterValue?.raw + layout[0] = unexpectedBeforeArgument?.raw + layout[1] = argument.raw + layout[2] = unexpectedBetweenArgumentAndTrailingComma?.raw + layout[3] = trailingComma?.raw + layout[4] = unexpectedAfterTrailingComma?.raw } self.init(unchecked: raw) } - public var unexpectedBeforeValue: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeArgument: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var value: RawSyntax { + public var argument: RawSyntax { layoutView.children[1]! } - public var unexpectedAfterValue: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenArgumentAndTrailingComma: RawUnexpectedNodesSyntax? { layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } + + public var trailingComma: RawTokenSyntax? { + layoutView.children[3].map(RawTokenSyntax.init(raw:)) + } + + public var unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } } @_spi(RawSyntax) diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift index a4ebdadf08c..fb8d2038f1a 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift @@ -357,6 +357,86 @@ public struct RawReturnStmtSyntax: RawStmtSyntaxNodeProtocol { @_spi(RawSyntax) public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { + public enum LeftType: RawSyntaxNodeProtocol { + case type(RawTypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + case expr(RawExprSyntax) + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + RawTypeSyntax.isKindOf(raw) || RawExprSyntax.isKindOf(raw) + } + + public var raw: RawSyntax { + switch self { + case .type(let node): + return node.raw + case .expr(let node): + return node.raw + } + } + + public init?(_ node: __shared some RawSyntaxNodeProtocol) { + if let node = node.as(RawTypeSyntax.self) { + self = .type(node) + } else if let node = node.as(RawExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public init(type: some RawTypeSyntaxNodeProtocol) { + self = .type(RawTypeSyntax(type)) + } + + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public init(expr: some RawExprSyntaxNodeProtocol) { + self = .expr(RawExprSyntax(expr)) + } + } + + public enum RightType: RawSyntaxNodeProtocol { + case type(RawTypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + case expr(RawExprSyntax) + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + RawTypeSyntax.isKindOf(raw) || RawExprSyntax.isKindOf(raw) + } + + public var raw: RawSyntax { + switch self { + case .type(let node): + return node.raw + case .expr(let node): + return node.raw + } + } + + public init?(_ node: __shared some RawSyntaxNodeProtocol) { + if let node = node.as(RawTypeSyntax.self) { + self = .type(node) + } else if let node = node.as(RawExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public init(type: some RawTypeSyntaxNodeProtocol) { + self = .type(RawTypeSyntax(type)) + } + + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public init(expr: some RawExprSyntaxNodeProtocol) { + self = .expr(RawExprSyntax(expr)) + } + } + @_spi(RawSyntax) public var layoutView: RawSyntaxLayoutView { return raw.layoutView! @@ -386,11 +466,11 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { public init( _ unexpectedBeforeLeftType: RawUnexpectedNodesSyntax? = nil, - leftType: RawGenericArgumentTypeSyntax, + leftType: LeftType, _ unexpectedBetweenLeftTypeAndEqual: RawUnexpectedNodesSyntax? = nil, equal: RawTokenSyntax, _ unexpectedBetweenEqualAndRightType: RawUnexpectedNodesSyntax? = nil, - rightType: RawGenericArgumentTypeSyntax, + rightType: RightType, _ unexpectedAfterRightType: RawUnexpectedNodesSyntax? = nil, arena: __shared SyntaxArena ) { @@ -412,8 +492,8 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var leftType: RawGenericArgumentTypeSyntax { - layoutView.children[1].map(RawGenericArgumentTypeSyntax.init(raw:))! + public var leftType: RawSyntax { + layoutView.children[1]! } public var unexpectedBetweenLeftTypeAndEqual: RawUnexpectedNodesSyntax? { @@ -428,8 +508,8 @@ public struct RawSameTypeRequirementSyntax: RawSyntaxNodeProtocol { layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var rightType: RawGenericArgumentTypeSyntax { - layoutView.children[5].map(RawGenericArgumentTypeSyntax.init(raw:))! + public var rightType: RawSyntax { + layoutView.children[5]! } public var unexpectedAfterRightType: RawUnexpectedNodesSyntax? { diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift index e3870bbb6ce..4a2489c4ba0 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesTUVWXYZ.swift @@ -1501,7 +1501,7 @@ public struct RawTypeSyntax: RawTypeSyntaxNodeProtocol { public static func isKindOf(_ raw: RawSyntax) -> Bool { switch raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .genericArgumentType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .dictionaryType, .functionType, .identifierType, .implicitlyUnwrappedOptionalType, .memberType, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packElementType, .packExpansionType, .someOrAnyType, .suppressedType, .tupleType: return true default: return false diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 950d172948d..55706f39f4c 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -1335,16 +1335,11 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { case .genericArgument: assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawGenericArgumentTypeSyntax.self)) - assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) - assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - case .genericArgumentType: - assert(layout.count == 3) - assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertAnyHasNoError(kind, 1, [ verify(layout[1], as: RawSyntax.self)]) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) case .genericParameterClause: assert(layout.count == 9) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) @@ -2267,11 +2262,13 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { case .sameTypeRequirement: assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawGenericArgumentTypeSyntax.self)) + assertAnyHasNoError(kind, 1, [ + verify(layout[1], as: RawSyntax.self)]) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.binaryOperator), .tokenKind(.prefixOperator), .tokenKind(.postfixOperator)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawGenericArgumentTypeSyntax.self)) + assertAnyHasNoError(kind, 5, [ + verify(layout[5], as: RawSyntax.self)]) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) case .sequenceExpr: assert(layout.count == 3) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index aa0705f64aa..f71bcae8e42 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -194,132 +194,17 @@ public struct GenericArgumentClauseSyntax: SyntaxProtocol, SyntaxHashable, _Leaf /// ### Children /// -/// - `argument`: ``GenericArgumentTypeSyntax`` +/// - `argument`: (``TypeSyntax`` | ``ExprSyntax``) /// - `trailingComma`: `,`? /// /// ### Contained in /// /// - ``GenericArgumentListSyntax`` public struct GenericArgumentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProtocol { - public let _syntaxNode: Syntax - - public init?(_ node: __shared some SyntaxProtocol) { - guard node.raw.kind == .genericArgument else { - return nil - } - self._syntaxNode = node._syntaxNode - } - - /// - Parameters: - /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( - leadingTrivia: Trivia? = nil, - _ unexpectedBeforeArgument: UnexpectedNodesSyntax? = nil, - argument: GenericArgumentTypeSyntax, - _ unexpectedBetweenArgumentAndTrailingComma: UnexpectedNodesSyntax? = nil, - trailingComma: TokenSyntax? = nil, - _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, - trailingTrivia: Trivia? = nil - ) { - // Extend the lifetime of all parameters so their arenas don't get destroyed - // before they can be added as children of the new arena. - self = withExtendedLifetime((SyntaxArena(), ( - unexpectedBeforeArgument, - argument, - unexpectedBetweenArgumentAndTrailingComma, - trailingComma, - unexpectedAfterTrailingComma - ))) { (arena, _) in - let layout: [RawSyntax?] = [ - unexpectedBeforeArgument?.raw, - argument.raw, - unexpectedBetweenArgumentAndTrailingComma?.raw, - trailingComma?.raw, - unexpectedAfterTrailingComma?.raw - ] - let raw = RawSyntax.makeLayout( - kind: SyntaxKind.genericArgument, - from: layout, - arena: arena, - leadingTrivia: leadingTrivia, - trailingTrivia: trailingTrivia - ) - return Syntax.forRoot(raw, rawNodeArena: arena).cast(Self.self) - } - } - - public var unexpectedBeforeArgument: UnexpectedNodesSyntax? { - get { - return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) - } - set(value) { - self = Syntax(self).replacingChild(at: 0, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) - } - } - - public var argument: GenericArgumentTypeSyntax { - get { - return Syntax(self).child(at: 1)!.cast(GenericArgumentTypeSyntax.self) - } - set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) - } - } - - public var unexpectedBetweenArgumentAndTrailingComma: UnexpectedNodesSyntax? { - get { - return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) - } - set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) - } - } - - /// ### Tokens - /// - /// For syntax trees generated by the parser, this is guaranteed to be `,`. - public var trailingComma: TokenSyntax? { - get { - return Syntax(self).child(at: 3)?.cast(TokenSyntax.self) - } - set(value) { - self = Syntax(self).replacingChild(at: 3, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) - } - } - - public var unexpectedAfterTrailingComma: UnexpectedNodesSyntax? { - get { - return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) - } - set(value) { - self = Syntax(self).replacingChild(at: 4, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) - } - } - - public static let structure: SyntaxNodeStructure = .layout([ - \Self.unexpectedBeforeArgument, - \Self.argument, - \Self.unexpectedBetweenArgumentAndTrailingComma, - \Self.trailingComma, - \Self.unexpectedAfterTrailingComma - ]) -} - -// MARK: - GenericArgumentTypeSyntax - -/// ### Children -/// -/// - `value`: (``TypeSyntax`` | ``ExprSyntax``) -/// -/// ### Contained in -/// -/// - ``GenericArgumentSyntax``.``GenericArgumentSyntax/argument`` -/// - ``SameTypeRequirementSyntax``.``SameTypeRequirementSyntax/leftType`` -/// - ``SameTypeRequirementSyntax``.``SameTypeRequirementSyntax/rightType`` -public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyntaxNodeProtocol { - public enum Value: SyntaxChildChoices, SyntaxHashable { + public enum Argument: SyntaxChildChoices, SyntaxHashable { case type(TypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) case expr(ExprSyntax) public var _syntaxNode: Syntax { @@ -335,6 +220,8 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le self = .type(TypeSyntax(node)) } + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) public init(_ node: some ExprSyntaxProtocol) { self = .expr(ExprSyntax(node)) } @@ -378,6 +265,8 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le /// Checks if the current syntax node can be cast to the type conforming to the ``ExprSyntaxProtocol`` protocol. /// /// - Returns: `true` if the node can be cast, `false` otherwise. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) public func `is`(_ syntaxType: (some ExprSyntaxProtocol).Type) -> Bool { return self.as(syntaxType) != nil } @@ -385,6 +274,8 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le /// Attempts to cast the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. /// /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) public func `as`(_ syntaxType: S.Type) -> S? { return S.init(self) } @@ -393,6 +284,8 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le /// /// - Returns: An instance of the specialized type. /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! } @@ -401,7 +294,7 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le public let _syntaxNode: Syntax public init?(_ node: __shared some SyntaxProtocol) { - guard node.raw.kind == .genericArgumentType else { + guard node.raw.kind == .genericArgument else { return nil } self._syntaxNode = node._syntaxNode @@ -409,20 +302,35 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - argument: The argument type for a generic argument. This can either be a regular type argument or an expression for value generics. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeValue: UnexpectedNodesSyntax? = nil, - value: Value, - _ unexpectedAfterValue: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeArgument: UnexpectedNodesSyntax? = nil, + argument: Argument, + _ unexpectedBetweenArgumentAndTrailingComma: UnexpectedNodesSyntax? = nil, + trailingComma: TokenSyntax? = nil, + _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. - self = withExtendedLifetime((SyntaxArena(), (unexpectedBeforeValue, value, unexpectedAfterValue))) { (arena, _) in - let layout: [RawSyntax?] = [unexpectedBeforeValue?.raw, value.raw, unexpectedAfterValue?.raw] + self = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeArgument, + argument, + unexpectedBetweenArgumentAndTrailingComma, + trailingComma, + unexpectedAfterTrailingComma + ))) { (arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeArgument?.raw, + argument.raw, + unexpectedBetweenArgumentAndTrailingComma?.raw, + trailingComma?.raw, + unexpectedAfterTrailingComma?.raw + ] let raw = RawSyntax.makeLayout( - kind: SyntaxKind.genericArgumentType, + kind: SyntaxKind.genericArgument, from: layout, arena: arena, leadingTrivia: leadingTrivia, @@ -432,34 +340,62 @@ public struct GenericArgumentTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _Le } } - public var unexpectedBeforeValue: UnexpectedNodesSyntax? { + public var unexpectedBeforeArgument: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 0, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + self = Syntax(self).replacingChild(at: 0, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) } } - public var value: Value { + /// The argument type for a generic argument. This can either be a regular type argument or an expression for value generics. + public var argument: Argument { get { - return Syntax(self).child(at: 1)!.cast(Value.self) + return Syntax(self).child(at: 1)!.cast(Argument.self) } set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) } } - public var unexpectedAfterValue: UnexpectedNodesSyntax? { + public var unexpectedBetweenArgumentAndTrailingComma: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentTypeSyntax.self) + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) + } + } + + /// ### Tokens + /// + /// For syntax trees generated by the parser, this is guaranteed to be `,`. + public var trailingComma: TokenSyntax? { + get { + return Syntax(self).child(at: 3)?.cast(TokenSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) + } + } + + public var unexpectedAfterTrailingComma: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), arena: SyntaxArena()).cast(GenericArgumentSyntax.self) } } - public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforeValue, \Self.value, \Self.unexpectedAfterValue]) + public static let structure: SyntaxNodeStructure = .layout([ + \Self.unexpectedBeforeArgument, + \Self.argument, + \Self.unexpectedBetweenArgumentAndTrailingComma, + \Self.trailingComma, + \Self.unexpectedAfterTrailingComma + ]) } // MARK: - GenericParameterClauseSyntax diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift index 7d24e1faec5..add1bca1a9f 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift @@ -626,14 +626,194 @@ public struct ReturnStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyn /// ### Children /// -/// - `leftType`: ``GenericArgumentTypeSyntax`` +/// - `leftType`: (``TypeSyntax`` | ``ExprSyntax``) /// - `equal`: (`` | `` | ``) -/// - `rightType`: ``GenericArgumentTypeSyntax`` +/// - `rightType`: (``TypeSyntax`` | ``ExprSyntax``) /// /// ### Contained in /// /// - ``GenericRequirementSyntax``.``GenericRequirementSyntax/requirement`` public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProtocol { + public enum LeftType: SyntaxChildChoices, SyntaxHashable { + case type(TypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + case expr(ExprSyntax) + + public var _syntaxNode: Syntax { + switch self { + case .type(let node): + return node._syntaxNode + case .expr(let node): + return node._syntaxNode + } + } + + public init(_ node: some TypeSyntaxProtocol) { + self = .type(TypeSyntax(node)) + } + + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public init(_ node: some ExprSyntaxProtocol) { + self = .expr(ExprSyntax(node)) + } + + public init?(_ node: __shared some SyntaxProtocol) { + if let node = node.as(TypeSyntax.self) { + self = .type(node) + } else if let node = node.as(ExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public static var structure: SyntaxNodeStructure { + return .choices([.node(TypeSyntax.self), .node(ExprSyntax.self)]) + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + public func `is`(_ syntaxType: (some TypeSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func `is`(_ syntaxType: (some ExprSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + } + + public enum RightType: SyntaxChildChoices, SyntaxHashable { + case type(TypeSyntax) + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + case expr(ExprSyntax) + + public var _syntaxNode: Syntax { + switch self { + case .type(let node): + return node._syntaxNode + case .expr(let node): + return node._syntaxNode + } + } + + public init(_ node: some TypeSyntaxProtocol) { + self = .type(TypeSyntax(node)) + } + + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public init(_ node: some ExprSyntaxProtocol) { + self = .expr(ExprSyntax(node)) + } + + public init?(_ node: __shared some SyntaxProtocol) { + if let node = node.as(TypeSyntax.self) { + self = .type(node) + } else if let node = node.as(ExprSyntax.self) { + self = .expr(node) + } else { + return nil + } + } + + public static var structure: SyntaxNodeStructure { + return .choices([.node(TypeSyntax.self), .node(ExprSyntax.self)]) + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + public func `is`(_ syntaxType: (some TypeSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``TypeSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + + /// Checks if the current syntax node can be cast to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func `is`(_ syntaxType: (some ExprSyntaxProtocol).Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func `as`(_ syntaxType: S.Type) -> S? { + return S.init(self) + } + + /// Force-casts the current syntax node to the type conforming to the ``ExprSyntaxProtocol`` protocol. + /// + /// - Returns: An instance of the specialized type. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// - Note: Requires experimental feature `valueGenerics`. + @_spi(ExperimentalLanguageFeatures) + public func cast(_ syntaxType: S.Type) -> S { + return self.as(S.self)! + } + } + public let _syntaxNode: Syntax public init?(_ node: __shared some SyntaxProtocol) { @@ -645,15 +825,17 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - leftType: The left hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics. + /// - rightType: The right hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeLeftType: UnexpectedNodesSyntax? = nil, - leftType: GenericArgumentTypeSyntax, + leftType: LeftType, _ unexpectedBetweenLeftTypeAndEqual: UnexpectedNodesSyntax? = nil, equal: TokenSyntax, _ unexpectedBetweenEqualAndRightType: UnexpectedNodesSyntax? = nil, - rightType: GenericArgumentTypeSyntax, + rightType: RightType, _ unexpectedAfterRightType: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { @@ -697,9 +879,10 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy } } - public var leftType: GenericArgumentTypeSyntax { + /// The left hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics. + public var leftType: LeftType { get { - return Syntax(self).child(at: 1)!.cast(GenericArgumentTypeSyntax.self) + return Syntax(self).child(at: 1)!.cast(LeftType.self) } set(value) { self = Syntax(self).replacingChild(at: 1, with: Syntax(value), arena: SyntaxArena()).cast(SameTypeRequirementSyntax.self) @@ -739,9 +922,10 @@ public struct SameTypeRequirementSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy } } - public var rightType: GenericArgumentTypeSyntax { + /// The right hand side type for a same type requirement. This can either be a regular type argument or an expression for value generics. + public var rightType: RightType { get { - return Syntax(self).child(at: 5)!.cast(GenericArgumentTypeSyntax.self) + return Syntax(self).child(at: 5)!.cast(RightType.self) } set(value) { self = Syntax(self).replacingChild(at: 5, with: Syntax(value), arena: SyntaxArena()).cast(SameTypeRequirementSyntax.self) diff --git a/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift b/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift index f778eb62e4d..1f991daef70 100644 --- a/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift +++ b/Sources/SwiftSyntaxMacroExpansion/MacroReplacement.swift @@ -262,13 +262,13 @@ private final class MacroExpansionRewriter: SyntaxRewriter { let parameterReplacements: [DeclReferenceExprSyntax: Int] let arguments: [ExprSyntax] let genericParameterReplacements: [GenericArgumentSyntax: Int] - let genericArguments: [GenericArgumentTypeSyntax] + let genericArguments: [GenericArgumentSyntax.Argument] init( parameterReplacements: [DeclReferenceExprSyntax: Int], arguments: [ExprSyntax], genericReplacements: [GenericArgumentSyntax: Int], - genericArguments: [GenericArgumentTypeSyntax] + genericArguments: [GenericArgumentSyntax.Argument] ) { self.parameterReplacements = parameterReplacements self.arguments = arguments @@ -331,7 +331,7 @@ extension MacroDeclSyntax { }, uniquingKeysWith: { l, r in l } ) - let genericArguments: [GenericArgumentTypeSyntax] = + let genericArguments: [GenericArgumentSyntax.Argument] = genericArgumentList?.arguments.map { $0.argument } ?? [] let rewriter = MacroExpansionRewriter( diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index 6e643f99779..50a651948b2 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -2715,9 +2715,7 @@ final class DeclarationTests: ParserTestCase { genericArgumentClause: GenericArgumentClauseSyntax( arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("T")))) - ) + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("T")))) ) ]) ) diff --git a/Tests/SwiftParserTest/PatternTests.swift b/Tests/SwiftParserTest/PatternTests.swift index a379149c5cb..84bfb763183 100644 --- a/Tests/SwiftParserTest/PatternTests.swift +++ b/Tests/SwiftParserTest/PatternTests.swift @@ -27,7 +27,7 @@ final class PatternTests: ParserTestCase { expression: DeclReferenceExprSyntax(baseName: .identifier("E")), genericArgumentClause: GenericArgumentClauseSyntax( arguments: .init([ - .init(argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("Int")))))) + .init(argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("Int"))))) ]) ) ), diff --git a/Tests/SwiftParserTest/StatementTests.swift b/Tests/SwiftParserTest/StatementTests.swift index 628ed538d82..13da04c7c70 100644 --- a/Tests/SwiftParserTest/StatementTests.swift +++ b/Tests/SwiftParserTest/StatementTests.swift @@ -376,10 +376,14 @@ final class StatementTests: ParserTestCase { leftAngle: .leftAngleToken(), arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(OptionalTypeSyntax( - wrappedType: IdentifierTypeSyntax(name: .identifier("String")), - questionMark: .postfixQuestionMarkToken() - )))) + argument: .type( + TypeSyntax( + OptionalTypeSyntax( + wrappedType: IdentifierTypeSyntax(name: .identifier("String")), + questionMark: .postfixQuestionMarkToken() + ) + ) + ) ) ]), rightAngle: .rightAngleToken() @@ -398,7 +402,7 @@ final class StatementTests: ParserTestCase { leftAngle: .leftAngleToken(), arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .keyword(.Any))))) + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .keyword(.Any)))) ) ]), rightAngle: .rightAngleToken() diff --git a/Tests/SwiftParserTest/TypeMemberTests.swift b/Tests/SwiftParserTest/TypeMemberTests.swift index 12376df16a8..236e6af7ecb 100644 --- a/Tests/SwiftParserTest/TypeMemberTests.swift +++ b/Tests/SwiftParserTest/TypeMemberTests.swift @@ -150,7 +150,7 @@ final class TypeMemberTests: ParserTestCase { \.genericArgumentClause, GenericArgumentClauseSyntax( arguments: .init([ - GenericArgumentSyntax(argument: GenericArgumentTypeSyntax(value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("W")))))) + GenericArgumentSyntax(argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("W"))))) ]) ) ), diff --git a/Tests/SwiftParserTest/TypeTests.swift b/Tests/SwiftParserTest/TypeTests.swift index 68a02322a47..fa679445f37 100644 --- a/Tests/SwiftParserTest/TypeTests.swift +++ b/Tests/SwiftParserTest/TypeTests.swift @@ -260,10 +260,12 @@ final class TypeTests: ParserTestCase { genericArgumentClause: GenericArgumentClauseSyntax( arguments: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax( - name: .identifier("Foo") - ))) + argument: .type( + TypeSyntax( + IdentifierTypeSyntax( + name: .identifier("Foo") + ) + ) ) ) ]) diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index 91d0120900b..cac3c110f54 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -116,7 +116,7 @@ final class ValueGenericsTests: ParserTestCase { DiagnosticSpec( message: "expected '=' in variable", fixIts: ["insert '='"] - ) + ), ], fixedSource: """ let x: <#type#> = 123 @@ -191,7 +191,7 @@ final class ValueGenericsTests: ParserTestCase { ), DiagnosticSpec( message: "unexpected code '123' in extension" - ) + ), ], fixedSource: """ extension Vector where N: <#type#> 123 {} @@ -209,7 +209,7 @@ final class ValueGenericsTests: ParserTestCase { ), DiagnosticSpec( message: "unexpected code '-123' in extension" - ) + ), ], fixedSource: """ extension Vector where N: <#type#> -123 {} @@ -227,7 +227,7 @@ final class ValueGenericsTests: ParserTestCase { ), DiagnosticSpec( message: "unexpected code ': N' in extension" - ) + ), ] ) @@ -241,7 +241,7 @@ final class ValueGenericsTests: ParserTestCase { ), DiagnosticSpec( message: "unexpected code ': N' in extension" - ) + ), ] ) } diff --git a/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift b/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift index 7ad687ac723..925a007e567 100644 --- a/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift +++ b/Tests/SwiftParserTest/translated/GenericDisambiguationTests.swift @@ -91,15 +91,11 @@ final class GenericDisambiguationTests: ParserTestCase { """, substructure: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))) - ), + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))), trailingComma: .commaToken() ), GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) - ) + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) ), ]) ) @@ -113,15 +109,11 @@ final class GenericDisambiguationTests: ParserTestCase { """, substructure: GenericArgumentListSyntax([ GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))) - ), + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("b")))), trailingComma: .commaToken() ), GenericArgumentSyntax( - argument: GenericArgumentTypeSyntax( - value: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) - ) + argument: .type(TypeSyntax(IdentifierTypeSyntax(name: .identifier("c")))) ), ]) ) From 973fced8e1e99b1db7d53061ffda8035aeb8d948 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 21 Oct 2024 19:52:44 -0700 Subject: [PATCH 03/10] Update AddAsyncMacro.swift --- .../Implementation/Peer/AddAsyncMacro.swift | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift index 4e25660cff8..feb815852a8 100644 --- a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift +++ b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +@_spi(ExperimentalLanguageFeatures) import SwiftSyntax import SwiftSyntaxMacros @@ -71,12 +72,24 @@ public struct AddAsyncMacro: PeerMacro { let returnType = completionHandlerParameter.parameters.first?.type let isResultReturn = returnType?.children(viewMode: .all).first?.description == "Result" - let successReturnType = - if isResultReturn { - returnType!.as(IdentifierTypeSyntax.self)!.genericArgumentClause?.arguments.first!.argument - } else { - returnType + let successReturnType: TypeSyntax? + + if isResultReturn { + let argument = returnType!.as(IdentifierTypeSyntax.self)!.genericArgumentClause?.arguments.first!.argument + + switch argument { + case .some(.type(let type)): + successReturnType = type + + case .some(.expr(_)): + fatalError("expression not available here") + + case .none: + successReturnType = nil } + } else { + successReturnType = returnType + } // Remove completionHandler and comma from the previous parameter var newParameterList = funcDecl.signature.parameterClause.parameters From 22df21e462f3c8af71c6ed34e2ca6409439dcd90 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 22 Oct 2024 10:48:32 -0700 Subject: [PATCH 04/10] Parse negative integers in type arguments --- Sources/SwiftParser/Types.swift | 2 +- .../SwiftParserTest/ValueGenericsTests.swift | 53 ++++++++++++------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 02abca08374..2b0150fe616 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -368,7 +368,7 @@ extension Parser { let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) let generics: RawGenericArgumentClauseSyntax? - if self.atContextualPunctuator("<") { + if self.at(prefix: "<") { generics = self.parseGenericArguments() } else { generics = nil diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index cac3c110f54..cf6416fc39e 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +@_spi(ExperimentalLanguageFeatures) +import SwiftParser import SwiftSyntax import XCTest @@ -120,25 +122,22 @@ final class ValueGenericsTests: ParserTestCase { ], fixedSource: """ let x: <#type#> = 123 - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( """ let x: Generic<123> - """ + """, + experimentalFeatures: .valueGenerics ) - // FIXME?: We can't parse this either in the old parser or the swift-syntax one. assertParse( """ - let x: Generic1️⃣<-123> + let x: Generic<-321> """, - diagnostics: [ - DiagnosticSpec( - message: "extraneous code '<-123>' at top level" - ) - ] + experimentalFeatures: .valueGenerics ) assertParse( @@ -153,31 +152,36 @@ final class ValueGenericsTests: ParserTestCase { ], fixedSource: """ typealias One = <#type#>1 - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( """ extension Vector where N == 123 {} - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( """ extension Vector where 123 == N {} - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( """ extension Vector where N == -123 {} - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( """ extension Vector where -123 == N {} - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( @@ -195,7 +199,8 @@ final class ValueGenericsTests: ParserTestCase { ], fixedSource: """ extension Vector where N: <#type#> 123 {} - """ + """, + experimentalFeatures: .valueGenerics ) assertParse( @@ -213,7 +218,8 @@ final class ValueGenericsTests: ParserTestCase { ], fixedSource: """ extension Vector where N: <#type#> -123 {} - """ + """, + experimentalFeatures: .valueGenerics ) // FIXME: Not the best diagnostic @@ -228,7 +234,8 @@ final class ValueGenericsTests: ParserTestCase { DiagnosticSpec( message: "unexpected code ': N' in extension" ), - ] + ], + experimentalFeatures: .valueGenerics ) assertParse( @@ -242,7 +249,17 @@ final class ValueGenericsTests: ParserTestCase { DiagnosticSpec( message: "unexpected code ': N' in extension" ), - ] + ], + experimentalFeatures: .valueGenerics + ) + } + + func testNegativeInteger() { + assertParse( + """ + let x: Generic<-321> + """, + experimentalFeatures: .valueGenerics ) } } From 96c509a416d6a4683f244d4982d6b98d9016a062 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 22 Oct 2024 10:54:21 -0700 Subject: [PATCH 05/10] Update ValueGenericsTests.swift --- Tests/SwiftParserTest/ValueGenericsTests.swift | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index cf6416fc39e..96e410a096f 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -135,7 +135,7 @@ final class ValueGenericsTests: ParserTestCase { assertParse( """ - let x: Generic<-321> + let x: Generic<-123> """, experimentalFeatures: .valueGenerics ) @@ -222,7 +222,6 @@ final class ValueGenericsTests: ParserTestCase { experimentalFeatures: .valueGenerics ) - // FIXME: Not the best diagnostic assertParse( """ extension Vector where 1231️⃣: N {} @@ -253,13 +252,4 @@ final class ValueGenericsTests: ParserTestCase { experimentalFeatures: .valueGenerics ) } - - func testNegativeInteger() { - assertParse( - """ - let x: Generic<-321> - """, - experimentalFeatures: .valueGenerics - ) - } } From 22c107517125020c31b7310422b6019ae6fe2939 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 22 Oct 2024 10:57:12 -0700 Subject: [PATCH 06/10] Update OptionSetMacro.swift --- .../Implementation/ComplexMacros/OptionSetMacro.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Sources/MacroExamples/Implementation/ComplexMacros/OptionSetMacro.swift b/Examples/Sources/MacroExamples/Implementation/ComplexMacros/OptionSetMacro.swift index 5b7eed9de30..31fad649bb4 100644 --- a/Examples/Sources/MacroExamples/Implementation/ComplexMacros/OptionSetMacro.swift +++ b/Examples/Sources/MacroExamples/Implementation/ComplexMacros/OptionSetMacro.swift @@ -81,7 +81,7 @@ public struct OptionSetMacro { attachedTo decl: some DeclGroupSyntax, in context: some MacroExpansionContext, emitDiagnostics: Bool - ) -> (StructDeclSyntax, EnumDeclSyntax, TypeSyntax)? { + ) -> (StructDeclSyntax, EnumDeclSyntax, GenericArgumentSyntax.Argument)? { // Determine the name of the options enum. let optionsEnumName: String if case let .argumentList(arguments) = attribute.arguments, From 788f54280f162809c41664fed1e858e59c9228c2 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 24 Oct 2024 13:46:48 -0700 Subject: [PATCH 07/10] Use at(prefix:) when consuming generic arguments --- Sources/SwiftParser/Names.swift | 4 +- Sources/SwiftParser/Types.swift | 29 +++++----- .../SwiftParserTest/ValueGenericsTests.swift | 55 +++++++++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/Sources/SwiftParser/Names.swift b/Sources/SwiftParser/Names.swift index 7c9523190ac..98acb48243e 100644 --- a/Sources/SwiftParser/Names.swift +++ b/Sources/SwiftParser/Names.swift @@ -193,7 +193,7 @@ extension Parser { let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) let generics: RawGenericArgumentClauseSyntax? - if self.atContextualPunctuator("<") { + if self.at(prefix: "<") { generics = self.parseGenericArguments() } else { generics = nil @@ -229,7 +229,7 @@ extension Parser { default: .identifier ) let generics: RawGenericArgumentClauseSyntax? - if self.atContextualPunctuator("<") { + if self.at(prefix: "<") { generics = self.parseGenericArguments() } else { generics = nil diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 2b0150fe616..5bfc5160cc4 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -295,7 +295,7 @@ extension Parser { name = missingToken(.identifier) } let generics: RawGenericArgumentClauseSyntax? - if self.atContextualPunctuator("<") { + if self.at(prefix: "<") { generics = self.parseGenericArguments() } else { generics = nil @@ -702,15 +702,6 @@ extension Parser.Lookahead { fallthrough } - // '-123' for value generics. - if self.currentToken.tokenText == "-", - self.peek(isAt: .integerLiteral) - { - self.consumeAnyToken() - self.consumeAnyToken() - return true - } - return false case TokenSpec(.Self), TokenSpec(.identifier): guard self.canParseTypeIdentifier() else { @@ -861,7 +852,7 @@ extension Parser.Lookahead { } mutating func canParseAsGenericArgumentList() -> Bool { - guard self.atContextualPunctuator("<") else { + guard self.at(prefix: "<") else { return false } @@ -881,9 +872,21 @@ extension Parser.Lookahead { if !self.at(prefix: ">") { var loopProgress = LoopProgressCondition() repeat { - guard self.canParseType() else { - return false + // A generic argument can either be a type or an integer literal (who is + // optionally negative). + if self.canParseType() { + continue + } else if self.currentToken.tokenText == "-", + self.peek(isAt: .integerLiteral) + { + self.consumeAnyToken() + self.consumeAnyToken() + continue + } else if self.consume(if: .integerLiteral) != nil { + continue } + + return false // Parse the comma, if the list continues. } while self.consume(if: .comma) != nil && self.hasProgressed(&loopProgress) } diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index 96e410a096f..95b1d196949 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -139,7 +139,49 @@ final class ValueGenericsTests: ParserTestCase { """, experimentalFeatures: .valueGenerics ) + + assertParse( + """ + let x = Generic<123>.self + """, + experimentalFeatures: .valueGenerics + ) + + assertParse( + """ + let x = Generic<-123>.self + """, + experimentalFeatures: .valueGenerics + ) + + assertParse( + """ + let x = Generic<123, Int>.self + """, + experimentalFeatures: .valueGenerics + ) + + assertParse( + """ + let x = Generic<-123, Int>.self + """, + experimentalFeatures: .valueGenerics + ) + + assertParse( + """ + let x = Generic.self + """, + experimentalFeatures: .valueGenerics + ) + assertParse( + """ + let x: Generic.self + """, + experimentalFeatures: .valueGenerics + ) + assertParse( """ typealias One = 1️⃣1 @@ -251,5 +293,18 @@ final class ValueGenericsTests: ParserTestCase { ], experimentalFeatures: .valueGenerics ) + + assertParse( + "func foo() -> (1️⃣-1) X", + diagnostics: [ + DiagnosticSpec( + message: "expected type in tuple type", + fixIts: ["insert type"] + ), + DiagnosticSpec(message: "unexpected code '-1' in tuple type"), + ], + fixedSource: "func foo() -> (<#type#>-1) X", + experimentalFeatures: [.valueGenerics] + ) } } From 81f67aa1439e83512aece6645da71801bcf850ea Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 24 Oct 2024 14:40:43 -0700 Subject: [PATCH 08/10] We cannot parse generic arguments if there are none --- Sources/SwiftParser/Types.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 5bfc5160cc4..d758e53017a 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -852,7 +852,7 @@ extension Parser.Lookahead { } mutating func canParseAsGenericArgumentList() -> Bool { - guard self.at(prefix: "<") else { + guard self.at(prefix: "<"), !self.at(prefix: "<>") else { return false } From c372977e25a5b2b7198c0650c5ca36150f55fe06 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 24 Oct 2024 14:43:26 -0700 Subject: [PATCH 09/10] Throw error instead of fatalError --- .../MacroExamples/Implementation/Peer/AddAsyncMacro.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift index feb815852a8..f08daac2d98 100644 --- a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift +++ b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift @@ -82,7 +82,7 @@ public struct AddAsyncMacro: PeerMacro { successReturnType = type case .some(.expr(_)): - fatalError("expression not available here") + throw CustomError.message("Found unexpected value generic in Result type") case .none: successReturnType = nil From 864b1a0ae6e3d09af67818bd52ec82e63de6ec69 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 5 Nov 2024 09:19:31 -0800 Subject: [PATCH 10/10] formatting --- .../Implementation/Peer/AddAsyncMacro.swift | 3 +-- Sources/SwiftParser/Types.swift | 2 +- Tests/SwiftParserTest/ValueGenericsTests.swift | 11 +++++------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift index f08daac2d98..923f002c6c4 100644 --- a/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift +++ b/Examples/Sources/MacroExamples/Implementation/Peer/AddAsyncMacro.swift @@ -10,8 +10,7 @@ // //===----------------------------------------------------------------------===// -@_spi(ExperimentalLanguageFeatures) -import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) import SwiftSyntax import SwiftSyntaxMacros extension SyntaxCollection { diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index d758e53017a..ab61c1c2bb6 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -885,7 +885,7 @@ extension Parser.Lookahead { } else if self.consume(if: .integerLiteral) != nil { continue } - + return false // Parse the comma, if the list continues. } while self.consume(if: .comma) != nil && self.hasProgressed(&loopProgress) diff --git a/Tests/SwiftParserTest/ValueGenericsTests.swift b/Tests/SwiftParserTest/ValueGenericsTests.swift index 95b1d196949..cc0620b06d5 100644 --- a/Tests/SwiftParserTest/ValueGenericsTests.swift +++ b/Tests/SwiftParserTest/ValueGenericsTests.swift @@ -10,8 +10,7 @@ // //===----------------------------------------------------------------------===// -@_spi(ExperimentalLanguageFeatures) -import SwiftParser +@_spi(ExperimentalLanguageFeatures) import SwiftParser import SwiftSyntax import XCTest @@ -139,7 +138,7 @@ final class ValueGenericsTests: ParserTestCase { """, experimentalFeatures: .valueGenerics ) - + assertParse( """ let x = Generic<123>.self @@ -167,7 +166,7 @@ final class ValueGenericsTests: ParserTestCase { """, experimentalFeatures: .valueGenerics ) - + assertParse( """ let x = Generic.self @@ -181,7 +180,7 @@ final class ValueGenericsTests: ParserTestCase { """, experimentalFeatures: .valueGenerics ) - + assertParse( """ typealias One = 1️⃣1 @@ -293,7 +292,7 @@ final class ValueGenericsTests: ParserTestCase { ], experimentalFeatures: .valueGenerics ) - + assertParse( "func foo() -> (1️⃣-1) X", diagnostics: [