diff --git a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift index 3347cf8bb41..d960ec5db26 100644 --- a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift @@ -74,6 +74,11 @@ public let ATTRIBUTE_NODES: [Node] = [ // Special arguments for keyword decl name e.g. 'subscript(_:)', and availability arguments. kind: .node(kind: .specializeAttributeArgumentList) ), + Child( + name: "specializedArguments", + // Special arguments for generic where clause. + kind: .node(kind: .specializedAttributeArgument) + ), Child( name: "objCName", // Special arguments for Objective-C names. e.g. 'methodNameWithArg1:Arg2:' @@ -717,6 +722,19 @@ public let ATTRIBUTE_NODES: [Node] = [ ] ), + Node( + kind: .specializedAttributeArgument, + base: .syntax, + nameForDiagnostics: "argument to '@specialized", + documentation: "The generic where clause for the `@specialized` attribute", + children: [ + Child( + name: "genericWhereClause", + kind: .node(kind: .genericWhereClause) + ) + ] + ), + Node( kind: .specializeTargetFunctionArgument, base: .syntax, diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index 1a32f708965..a0e6730e18d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -104,6 +104,7 @@ public enum Keyword: CaseIterable { case _PackageDescription case _read case _RefCountedObject + case specialized case _specialize case _spi_available case _Trivial @@ -340,6 +341,8 @@ public enum Keyword: CaseIterable { return KeywordSpec("_read") case ._RefCountedObject: return KeywordSpec("_RefCountedObject") + case .specialized: + return KeywordSpec("specialized") case ._specialize: return KeywordSpec("_specialize") case ._spi_available: diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift index 6e50fe39500..98cd248e22b 100644 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift @@ -259,6 +259,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon case simpleStringLiteralSegmentList case someOrAnyType case sourceFile + case specializedAttributeArgument case specializeAttributeArgumentList case specializeAvailabilityArgument case specializeTargetFunctionArgument @@ -454,6 +455,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon case .someOrAnyType: return "constrainedSugarType" case .simpleTypeSpecifier: return "typeSpecifier" case .specializeAttributeArgumentList: return "specializeAttributeSpecList" + case .specializedAttributeArgument: return "specializedAttribute" case .specializeAvailabilityArgument: return "availabilityEntry" case .specializeTargetFunctionArgument: return "targetFunctionEntry" case .stringLiteralSegmentList: return "stringLiteralSegments" diff --git a/Sources/SwiftParser/Attributes.swift b/Sources/SwiftParser/Attributes.swift index c29fa786846..5946e76cdff 100644 --- a/Sources/SwiftParser/Attributes.swift +++ b/Sources/SwiftParser/Attributes.swift @@ -41,6 +41,7 @@ extension Parser { case _effects case _implements case _originallyDefinedIn + case specialized case _specialize case _spi_available case `rethrows` @@ -63,6 +64,7 @@ extension Parser { case TokenSpec(._effects): self = ._effects case TokenSpec(._implements): self = ._implements case TokenSpec(._originallyDefinedIn): self = ._originallyDefinedIn + case TokenSpec(.specialized): self = .specialized case TokenSpec(._specialize): self = ._specialize case TokenSpec(._spi_available): self = ._spi_available case TokenSpec(.`rethrows`): self = .rethrows @@ -89,6 +91,7 @@ extension Parser { case ._effects: return .keyword(._effects) case ._implements: return .keyword(._implements) case ._originallyDefinedIn: return .keyword(._originallyDefinedIn) + case .specialized: return .keyword(.specialized) case ._specialize: return .keyword(._specialize) case ._spi_available: return .keyword(._spi_available) case .`rethrows`: return .keyword(.rethrows) @@ -254,6 +257,10 @@ extension Parser { return parseAttribute(argumentMode: .optional) { parser in return (nil, .objCName(parser.parseObjectiveCSelector())) } + case .specialized: + return parseAttribute(argumentMode: .required) { parser in + return (nil, .specializedArguments(parser.parseSpecializedAttributeArgument())) + } case ._specialize: return parseAttribute(argumentMode: .required) { parser in return (nil, .specializeArguments(parser.parseSpecializeAttributeArgumentList())) @@ -645,6 +652,11 @@ extension Parser { } extension Parser { + mutating func parseSpecializedAttributeArgument() -> RawSpecializedAttributeArgumentSyntax { + let whereClause = self.parseGenericWhereClause() + return RawSpecializedAttributeArgumentSyntax(genericWhereClause: whereClause, arena: self.arena) + } + mutating func parseSpecializeAttributeArgumentList() -> RawSpecializeAttributeArgumentListSyntax { var elements = [RawSpecializeAttributeArgumentListSyntax.Element]() // Parse optional "exported" and "kind" labeled parameters. diff --git a/Sources/SwiftParser/TokenPrecedence.swift b/Sources/SwiftParser/TokenPrecedence.swift index 01fdbc06f78..c0a9a04bd08 100644 --- a/Sources/SwiftParser/TokenPrecedence.swift +++ b/Sources/SwiftParser/TokenPrecedence.swift @@ -267,6 +267,7 @@ enum TokenPrecedence: Comparable { ._effects, ._implements, ._originallyDefinedIn, + .specialized, ._specialize, ._spi_available, .abi, diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 9a9d00393e7..6c4448e9dbd 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -362,6 +362,8 @@ extension SyntaxKind { return "availability entry" case .specializeTargetFunctionArgument: return "attribute argument" + case .specializedAttributeArgument: + return "argument to '@specialized" case .stringLiteralExpr: return "string literal" case .structDecl: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index ee9216345d3..124109abadf 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -327,6 +327,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- ### Miscellaneous Syntax diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 802b6ae8003..079b4f842f3 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -2962,6 +2962,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "trailingComma" case \SpecializeTargetFunctionArgumentSyntax.unexpectedAfterTrailingComma: return "unexpectedAfterTrailingComma" + case \SpecializedAttributeArgumentSyntax.unexpectedBeforeGenericWhereClause: + return "unexpectedBeforeGenericWhereClause" + case \SpecializedAttributeArgumentSyntax.genericWhereClause: + return "genericWhereClause" + case \SpecializedAttributeArgumentSyntax.unexpectedAfterGenericWhereClause: + return "unexpectedAfterGenericWhereClause" case \StringLiteralExprSyntax.unexpectedBeforeOpeningPounds: return "unexpectedBeforeOpeningPounds" case \StringLiteralExprSyntax.openingPounds: diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index 6f049eb7936..3a848bf62b7 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -46,6 +46,7 @@ public enum Keyword: UInt8, Hashable, Sendable { case _PackageDescription case _read case _RefCountedObject + case specialized case _specialize case _spi_available case _Trivial @@ -601,6 +602,8 @@ public enum Keyword: UInt8, Hashable, Sendable { self = ._implements case "_noMetadata": self = ._noMetadata + case "specialized": + self = .specialized case "_specialize": self = ._specialize case "autoclosure": @@ -789,6 +792,7 @@ public enum Keyword: UInt8, Hashable, Sendable { "_PackageDescription", "_read", "_RefCountedObject", + "specialized", "_specialize", "_spi_available", "_Trivial", diff --git a/Sources/SwiftSyntax/generated/RenamedNodesCompatibility.swift b/Sources/SwiftSyntax/generated/RenamedNodesCompatibility.swift index d9eed528b19..3aa308c9fc1 100644 --- a/Sources/SwiftSyntax/generated/RenamedNodesCompatibility.swift +++ b/Sources/SwiftSyntax/generated/RenamedNodesCompatibility.swift @@ -178,6 +178,9 @@ public typealias SpecializeAttributeSpecListSyntax = SpecializeAttributeArgument @available(*, deprecated, renamed: "GenericSpecializationExprSyntax") public typealias SpecializeExprSyntax = GenericSpecializationExprSyntax +@available(*, deprecated, renamed: "SpecializedAttributeArgumentSyntax") +public typealias SpecializedAttributeSyntax = SpecializedAttributeArgumentSyntax + @available(*, deprecated, renamed: "StringLiteralSegmentListSyntax") public typealias StringLiteralSegmentsSyntax = StringLiteralSegmentListSyntax @@ -493,6 +496,11 @@ extension SyntaxKind { return .genericSpecializationExpr } + @available(*, deprecated, renamed: "SpecializedAttributeArgumentSyntax") + public static var specializedAttribute: Self { + return .specializedAttributeArgument + } + @available(*, deprecated, renamed: "StringLiteralSegmentListSyntax") public static var stringLiteralSegments: Self { return .stringLiteralSegmentList diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index 761e69e41d9..b8c4128e2d9 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -1983,6 +1983,14 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: SpecializedAttributeArgumentSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: SpecializedAttributeArgumentSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: StringLiteralExprSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index 8c1a8444f88..cf9cf32bbb7 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -1749,6 +1749,7 @@ extension Syntax { .node(SpecializeAttributeArgumentListSyntax.self), .node(SpecializeAvailabilityArgumentSyntax.self), .node(SpecializeTargetFunctionArgumentSyntax.self), + .node(SpecializedAttributeArgumentSyntax.self), .node(StringLiteralExprSyntax.self), .node(StringLiteralSegmentListSyntax.self), .node(StringSegmentSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index 5f70ddd32a8..629a783306d 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -265,6 +265,7 @@ public enum SyntaxEnum: Sendable { case specializeAttributeArgumentList(SpecializeAttributeArgumentListSyntax) case specializeAvailabilityArgument(SpecializeAvailabilityArgumentSyntax) case specializeTargetFunctionArgument(SpecializeTargetFunctionArgumentSyntax) + case specializedAttributeArgument(SpecializedAttributeArgumentSyntax) case stringLiteralExpr(StringLiteralExprSyntax) case stringLiteralSegmentList(StringLiteralSegmentListSyntax) case stringSegment(StringSegmentSyntax) @@ -800,6 +801,8 @@ extension Syntax { return .specializeAvailabilityArgument(SpecializeAvailabilityArgumentSyntax(self)!) case .specializeTargetFunctionArgument: return .specializeTargetFunctionArgument(SpecializeTargetFunctionArgumentSyntax(self)!) + case .specializedAttributeArgument: + return .specializedAttributeArgument(SpecializedAttributeArgumentSyntax(self)!) case .stringLiteralExpr: return .stringLiteralExpr(StringLiteralExprSyntax(self)!) case .stringLiteralSegmentList: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index f1d00716562..7c24764a8c0 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -265,6 +265,7 @@ public enum SyntaxKind: Sendable { case specializeAttributeArgumentList case specializeAvailabilityArgument case specializeTargetFunctionArgument + case specializedAttributeArgument case stringLiteralExpr case stringLiteralSegmentList case stringSegment @@ -925,6 +926,8 @@ public enum SyntaxKind: Sendable { return SpecializeAvailabilityArgumentSyntax.self case .specializeTargetFunctionArgument: return SpecializeTargetFunctionArgumentSyntax.self + case .specializedAttributeArgument: + return SpecializedAttributeArgumentSyntax.self case .stringLiteralExpr: return StringLiteralExprSyntax.self case .stringLiteralSegmentList: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index 06778189fb7..fce415516c9 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -1776,6 +1776,13 @@ open class SyntaxRewriter { return SpecializeTargetFunctionArgumentSyntax(unsafeCasting: visitChildren(node._syntaxNode)) } + /// Visit a ``SpecializedAttributeArgumentSyntax``. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: SpecializedAttributeArgumentSyntax) -> SpecializedAttributeArgumentSyntax { + return SpecializedAttributeArgumentSyntax(unsafeCasting: visitChildren(node._syntaxNode)) + } + /// Visit a ``StringLiteralExprSyntax``. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -3357,6 +3364,11 @@ open class SyntaxRewriter { Syntax(visit(SpecializeTargetFunctionArgumentSyntax(unsafeCasting: node))) } + @inline(never) + private func visitSpecializedAttributeArgumentSyntaxImpl(_ node: Syntax) -> Syntax { + Syntax(visit(SpecializedAttributeArgumentSyntax(unsafeCasting: node))) + } + @inline(never) private func visitStringLiteralExprSyntaxImpl(_ node: Syntax) -> Syntax { Syntax(visit(StringLiteralExprSyntax(unsafeCasting: node))) @@ -4111,6 +4123,8 @@ open class SyntaxRewriter { return self.visitSpecializeAvailabilityArgumentSyntaxImpl(_:) case .specializeTargetFunctionArgument: return self.visitSpecializeTargetFunctionArgumentSyntaxImpl(_:) + case .specializedAttributeArgument: + return self.visitSpecializedAttributeArgumentSyntaxImpl(_:) case .stringLiteralExpr: return self.visitStringLiteralExprSyntaxImpl(_:) case .stringLiteralSegmentList: @@ -4697,6 +4711,8 @@ open class SyntaxRewriter { return visitSpecializeAvailabilityArgumentSyntaxImpl(node) case .specializeTargetFunctionArgument: return visitSpecializeTargetFunctionArgumentSyntaxImpl(node) + case .specializedAttributeArgument: + return visitSpecializedAttributeArgumentSyntaxImpl(node) case .stringLiteralExpr: return visitStringLiteralExprSyntaxImpl(node) case .stringLiteralSegmentList: diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index d600655152f..d7a5c5b9b0f 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -2913,6 +2913,18 @@ open class SyntaxVisitor { open func visitPost(_ node: SpecializeTargetFunctionArgumentSyntax) { } + /// Visiting ``SpecializedAttributeArgumentSyntax`` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: SpecializedAttributeArgumentSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting ``SpecializedAttributeArgumentSyntax`` and its descendants. + /// - node: the node we just finished visiting. + open func visitPost(_ node: SpecializedAttributeArgumentSyntax) { + } + /// Visiting ``StringLiteralExprSyntax`` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -5438,6 +5450,14 @@ open class SyntaxVisitor { visitPost(SpecializeTargetFunctionArgumentSyntax(unsafeCasting: node)) } + @inline(never) + private func visitSpecializedAttributeArgumentSyntaxImpl(_ node: Syntax) { + if visit(SpecializedAttributeArgumentSyntax(unsafeCasting: node)) == .visitChildren { + visitChildren(node) + } + visitPost(SpecializedAttributeArgumentSyntax(unsafeCasting: node)) + } + @inline(never) private func visitStringLiteralExprSyntaxImpl(_ node: Syntax) { if visit(StringLiteralExprSyntax(unsafeCasting: node)) == .visitChildren { @@ -6342,6 +6362,8 @@ open class SyntaxVisitor { return self.visitSpecializeAvailabilityArgumentSyntaxImpl(_:) case .specializeTargetFunctionArgument: return self.visitSpecializeTargetFunctionArgumentSyntaxImpl(_:) + case .specializedAttributeArgument: + return self.visitSpecializedAttributeArgumentSyntaxImpl(_:) case .stringLiteralExpr: return self.visitStringLiteralExprSyntaxImpl(_:) case .stringLiteralSegmentList: @@ -6928,6 +6950,8 @@ open class SyntaxVisitor { self.visitSpecializeAvailabilityArgumentSyntaxImpl(node) case .specializeTargetFunctionArgument: self.visitSpecializeTargetFunctionArgumentSyntaxImpl(node) + case .specializedAttributeArgument: + self.visitSpecializedAttributeArgumentSyntaxImpl(node) case .stringLiteralExpr: self.visitStringLiteralExprSyntaxImpl(node) case .stringLiteralSegmentList: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesAB.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesAB.swift index 2c820290b8b..1dc419a7df4 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesAB.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesAB.swift @@ -1605,6 +1605,7 @@ public struct RawAttributeSyntax: RawSyntaxNodeProtocol { case argumentList(RawLabeledExprListSyntax) case availability(RawAvailabilityArgumentListSyntax) case specializeArguments(RawSpecializeAttributeArgumentListSyntax) + case specializedArguments(RawSpecializedAttributeArgumentSyntax) case objCName(RawObjCSelectorPieceListSyntax) case implementsArguments(RawImplementsAttributeArgumentsSyntax) case differentiableArguments(RawDifferentiableAttributeArgumentsSyntax) @@ -1617,7 +1618,7 @@ public struct RawAttributeSyntax: RawSyntaxNodeProtocol { case abiArguments(RawABIAttributeArgumentsSyntax) public static func isKindOf(_ raw: RawSyntax) -> Bool { - RawLabeledExprListSyntax.isKindOf(raw) || RawAvailabilityArgumentListSyntax.isKindOf(raw) || RawSpecializeAttributeArgumentListSyntax.isKindOf(raw) || RawObjCSelectorPieceListSyntax.isKindOf(raw) || RawImplementsAttributeArgumentsSyntax.isKindOf(raw) || RawDifferentiableAttributeArgumentsSyntax.isKindOf(raw) || RawDerivativeAttributeArgumentsSyntax.isKindOf(raw) || RawBackDeployedAttributeArgumentsSyntax.isKindOf(raw) || RawOriginallyDefinedInAttributeArgumentsSyntax.isKindOf(raw) || RawDynamicReplacementAttributeArgumentsSyntax.isKindOf(raw) || RawEffectsAttributeArgumentListSyntax.isKindOf(raw) || RawDocumentationAttributeArgumentListSyntax.isKindOf(raw) || RawABIAttributeArgumentsSyntax.isKindOf(raw) + RawLabeledExprListSyntax.isKindOf(raw) || RawAvailabilityArgumentListSyntax.isKindOf(raw) || RawSpecializeAttributeArgumentListSyntax.isKindOf(raw) || RawSpecializedAttributeArgumentSyntax.isKindOf(raw) || RawObjCSelectorPieceListSyntax.isKindOf(raw) || RawImplementsAttributeArgumentsSyntax.isKindOf(raw) || RawDifferentiableAttributeArgumentsSyntax.isKindOf(raw) || RawDerivativeAttributeArgumentsSyntax.isKindOf(raw) || RawBackDeployedAttributeArgumentsSyntax.isKindOf(raw) || RawOriginallyDefinedInAttributeArgumentsSyntax.isKindOf(raw) || RawDynamicReplacementAttributeArgumentsSyntax.isKindOf(raw) || RawEffectsAttributeArgumentListSyntax.isKindOf(raw) || RawDocumentationAttributeArgumentListSyntax.isKindOf(raw) || RawABIAttributeArgumentsSyntax.isKindOf(raw) } public var raw: RawSyntax { @@ -1628,6 +1629,8 @@ public struct RawAttributeSyntax: RawSyntaxNodeProtocol { return node.raw case .specializeArguments(let node): return node.raw + case .specializedArguments(let node): + return node.raw case .objCName(let node): return node.raw case .implementsArguments(let node): @@ -1658,6 +1661,8 @@ public struct RawAttributeSyntax: RawSyntaxNodeProtocol { self = .availability(node) } else if let node = node.as(RawSpecializeAttributeArgumentListSyntax.self) { self = .specializeArguments(node) + } else if let node = node.as(RawSpecializedAttributeArgumentSyntax.self) { + self = .specializedArguments(node) } else if let node = node.as(RawObjCSelectorPieceListSyntax.self) { self = .objCName(node) } else if let node = node.as(RawImplementsAttributeArgumentsSyntax.self) { diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift index e4313ae32a7..3092d21e457 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesQRS.swift @@ -1190,6 +1190,64 @@ public struct RawSpecializeTargetFunctionArgumentSyntax: RawSyntaxNodeProtocol { } } +@_spi(RawSyntax) +public struct RawSpecializedAttributeArgumentSyntax: RawSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .specializedAttributeArgument + } + + 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( + _ unexpectedBeforeGenericWhereClause: RawUnexpectedNodesSyntax? = nil, + genericWhereClause: RawGenericWhereClauseSyntax, + _ unexpectedAfterGenericWhereClause: RawUnexpectedNodesSyntax? = nil, + arena: __shared RawSyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .specializedAttributeArgument, uninitializedCount: 3, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeGenericWhereClause?.raw + layout[1] = genericWhereClause.raw + layout[2] = unexpectedAfterGenericWhereClause?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeGenericWhereClause: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var genericWhereClause: RawGenericWhereClauseSyntax { + layoutView.children[1].map(RawGenericWhereClauseSyntax.init(raw:))! + } + + public var unexpectedAfterGenericWhereClause: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + @_spi(RawSyntax) public struct RawStmtSyntax: RawStmtSyntaxNodeProtocol { @_spi(RawSyntax) diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 0ca5359f6e7..182d2d0aeba 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -2638,6 +2638,12 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) } + func validateSpecializedAttributeArgumentSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { + assert(layout.count == 3) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawGenericWhereClauseSyntax.self)) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + } func validateStringLiteralExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { assert(layout.count == 11) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) @@ -3606,6 +3612,8 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { validateSpecializeAvailabilityArgumentSyntax(kind: kind, layout: layout) case .specializeTargetFunctionArgument: validateSpecializeTargetFunctionArgumentSyntax(kind: kind, layout: layout) + case .specializedAttributeArgument: + validateSpecializedAttributeArgumentSyntax(kind: kind, layout: layout) case .stringLiteralExpr: validateStringLiteralExprSyntax(kind: kind, layout: layout) case .stringLiteralSegmentList: diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesAB.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesAB.swift index 6baae95f2e3..c36ad53e31d 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesAB.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesAB.swift @@ -3098,7 +3098,7 @@ public struct AttributeClauseFileSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy /// - `atSign`: `@` /// - `attributeName`: ``TypeSyntax`` /// - `leftParen`: `(`? -/// - `arguments`: (``LabeledExprListSyntax`` | ``AvailabilityArgumentListSyntax`` | ``SpecializeAttributeArgumentListSyntax`` | ``ObjCSelectorPieceListSyntax`` | ``ImplementsAttributeArgumentsSyntax`` | ``DifferentiableAttributeArgumentsSyntax`` | ``DerivativeAttributeArgumentsSyntax`` | ``BackDeployedAttributeArgumentsSyntax`` | ``OriginallyDefinedInAttributeArgumentsSyntax`` | ``DynamicReplacementAttributeArgumentsSyntax`` | ``EffectsAttributeArgumentListSyntax`` | ``DocumentationAttributeArgumentListSyntax`` | ``ABIAttributeArgumentsSyntax``)? +/// - `arguments`: (``LabeledExprListSyntax`` | ``AvailabilityArgumentListSyntax`` | ``SpecializeAttributeArgumentListSyntax`` | ``SpecializedAttributeArgumentSyntax`` | ``ObjCSelectorPieceListSyntax`` | ``ImplementsAttributeArgumentsSyntax`` | ``DifferentiableAttributeArgumentsSyntax`` | ``DerivativeAttributeArgumentsSyntax`` | ``BackDeployedAttributeArgumentsSyntax`` | ``OriginallyDefinedInAttributeArgumentsSyntax`` | ``DynamicReplacementAttributeArgumentsSyntax`` | ``EffectsAttributeArgumentListSyntax`` | ``DocumentationAttributeArgumentListSyntax`` | ``ABIAttributeArgumentsSyntax``)? /// - `rightParen`: `)`? /// /// ### Contained in @@ -3110,6 +3110,7 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr case argumentList(LabeledExprListSyntax) case availability(AvailabilityArgumentListSyntax) case specializeArguments(SpecializeAttributeArgumentListSyntax) + case specializedArguments(SpecializedAttributeArgumentSyntax) case objCName(ObjCSelectorPieceListSyntax) case implementsArguments(ImplementsAttributeArgumentsSyntax) case differentiableArguments(DifferentiableAttributeArgumentsSyntax) @@ -3129,6 +3130,8 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr return node._syntaxNode case .specializeArguments(let node): return node._syntaxNode + case .specializedArguments(let node): + return node._syntaxNode case .objCName(let node): return node._syntaxNode case .implementsArguments(let node): @@ -3164,6 +3167,10 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr self = .specializeArguments(node) } + public init(_ node: SpecializedAttributeArgumentSyntax) { + self = .specializedArguments(node) + } + public init(_ node: ObjCSelectorPieceListSyntax) { self = .objCName(node) } @@ -3211,6 +3218,8 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr self = .availability(node) } else if let node = node.as(SpecializeAttributeArgumentListSyntax.self) { self = .specializeArguments(node) + } else if let node = node.as(SpecializedAttributeArgumentSyntax.self) { + self = .specializedArguments(node) } else if let node = node.as(ObjCSelectorPieceListSyntax.self) { self = .objCName(node) } else if let node = node.as(ImplementsAttributeArgumentsSyntax.self) { @@ -3241,6 +3250,7 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr .node(LabeledExprListSyntax.self), .node(AvailabilityArgumentListSyntax.self), .node(SpecializeAttributeArgumentListSyntax.self), + .node(SpecializedAttributeArgumentSyntax.self), .node(ObjCSelectorPieceListSyntax.self), .node(ImplementsAttributeArgumentsSyntax.self), .node(DifferentiableAttributeArgumentsSyntax.self), @@ -3320,6 +3330,28 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr return self.as(SpecializeAttributeArgumentListSyntax.self)! } + /// Checks if the current syntax node can be cast to ``SpecializedAttributeArgumentSyntax``. + /// + /// - Returns: `true` if the node can be cast, `false` otherwise. + public func `is`(_ syntaxType: SpecializedAttributeArgumentSyntax.Type) -> Bool { + return self.as(syntaxType) != nil + } + + /// Attempts to cast the current syntax node to ``SpecializedAttributeArgumentSyntax``. + /// + /// - Returns: An instance of ``SpecializedAttributeArgumentSyntax``, or `nil` if the cast fails. + public func `as`(_ syntaxType: SpecializedAttributeArgumentSyntax.Type) -> SpecializedAttributeArgumentSyntax? { + return SpecializedAttributeArgumentSyntax.init(self) + } + + /// Force-casts the current syntax node to ``SpecializedAttributeArgumentSyntax``. + /// + /// - Returns: An instance of ``SpecializedAttributeArgumentSyntax``. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + public func cast(_ syntaxType: SpecializedAttributeArgumentSyntax.Type) -> SpecializedAttributeArgumentSyntax { + return self.as(SpecializedAttributeArgumentSyntax.self)! + } + /// Checks if the current syntax node can be cast to ``ObjCSelectorPieceListSyntax``. /// /// - Returns: `true` if the node can be cast, `false` otherwise. diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index 6fd799b9e7f..b61d7b799ca 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -1261,6 +1261,7 @@ public struct GenericSpecializationExprSyntax: ExprSyntaxProtocol, SyntaxHashabl /// - ``MacroDeclSyntax``.``MacroDeclSyntax/genericWhereClause`` /// - ``ProtocolDeclSyntax``.``ProtocolDeclSyntax/genericWhereClause`` /// - ``SpecializeAttributeArgumentListSyntax`` +/// - ``SpecializedAttributeArgumentSyntax``.``SpecializedAttributeArgumentSyntax/genericWhereClause`` /// - ``StructDeclSyntax``.``StructDeclSyntax/genericWhereClause`` /// - ``SubscriptDeclSyntax``.``SubscriptDeclSyntax/genericWhereClause`` /// - ``TypeAliasDeclSyntax``.``TypeAliasDeclSyntax/genericWhereClause`` diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift index 1a705af1c4d..e8af78d650f 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift @@ -2062,6 +2062,87 @@ public struct SpecializeTargetFunctionArgumentSyntax: SyntaxProtocol, SyntaxHash ]) } +// MARK: - SpecializedAttributeArgumentSyntax + +/// The generic where clause for the `@specialized` attribute +/// +/// ### Children +/// +/// - `genericWhereClause`: ``GenericWhereClauseSyntax`` +/// +/// ### Contained in +/// +/// - ``AttributeSyntax``.``AttributeSyntax/arguments`` +public struct SpecializedAttributeArgumentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProtocol { + public let _syntaxNode: Syntax + + public init?(_ node: __shared some SyntaxProtocol) { + guard node.raw.kind == .specializedAttributeArgument else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + @_transparent + init(unsafeCasting node: Syntax) { + self._syntaxNode = node + } + + /// - 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, + _ unexpectedBeforeGenericWhereClause: UnexpectedNodesSyntax? = nil, + genericWhereClause: GenericWhereClauseSyntax, + _ unexpectedAfterGenericWhereClause: 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((RawSyntaxArena(), (unexpectedBeforeGenericWhereClause, genericWhereClause, unexpectedAfterGenericWhereClause))) { (arena, _) in + let layout: [RawSyntax?] = [unexpectedBeforeGenericWhereClause?.raw, genericWhereClause.raw, unexpectedAfterGenericWhereClause?.raw] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.specializedAttributeArgument, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + ) + return Syntax.forRoot(raw, rawNodeArena: arena).cast(Self.self) + } + } + + public var unexpectedBeforeGenericWhereClause: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 0, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(SpecializedAttributeArgumentSyntax.self) + } + } + + public var genericWhereClause: GenericWhereClauseSyntax { + get { + return Syntax(self).child(at: 1)!.cast(GenericWhereClauseSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(SpecializedAttributeArgumentSyntax.self) + } + } + + public var unexpectedAfterGenericWhereClause: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(SpecializedAttributeArgumentSyntax.self) + } + } + + public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforeGenericWhereClause, \Self.genericWhereClause, \Self.unexpectedAfterGenericWhereClause]) +} + // MARK: - StringLiteralExprSyntax /// A string literal. diff --git a/Tests/SwiftParserTest/AttributeTests.swift b/Tests/SwiftParserTest/AttributeTests.swift index 5d82301c61e..695df2b4735 100644 --- a/Tests/SwiftParserTest/AttributeTests.swift +++ b/Tests/SwiftParserTest/AttributeTests.swift @@ -39,6 +39,30 @@ final class AttributeTests: ParserTestCase { } """ ) + + assertParse( + """ + @specializedℹ️(1️⃣ + func 2️⃣foo() { + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected argument for '@specialized' attribute", + fixIts: ["insert attribute argument"] + ), + DiagnosticSpec( + message: "expected ')' to end attribute", + notes: [NoteSpec(message: "to match this opening '('")], + fixIts: ["insert ')'"] + ), + ], + fixedSource: """ + @specialized(where <#type#> == <#type#>) + func foo() { + } + """ + ) } func testMissingGenericTypeToAttribute() { @@ -87,6 +111,12 @@ final class AttributeTests: ParserTestCase { func foo(_ t: T) {} """ ) + assertParse( + """ + @specialized(where T : Int) + func foo(_ t: T) {} + """ + ) } func testMissingClosingParenToAttribute() { diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index 7ec097ec5bd..77d621a8f64 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -770,6 +770,15 @@ final class DeclarationTests: ParserTestCase { } """ ) + assertParse( + """ + @specialized(where Array == Int) + @specialized(where T.Element == Int) + public func funcWithComplexSpecializeRequirements(t: T) -> Int { + return 55555 + } + """ + ) } func testParseRetroactiveExtension() {