From d141df51a8a5dde0793ae2433b5082ac3ebc7494 Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Tue, 25 Apr 2023 13:44:55 -0700 Subject: [PATCH] redo parsing of without operator to match C++ parser This basically moves the logic out from only when encountering an inheritance entry and instead when generally parsing a type, since that was a better way to go on the C++ side. --- .../Sources/SyntaxSupport/DeclNodes.swift | 8 -- .../Sources/SyntaxSupport/TypeNodes.swift | 17 +++ Sources/SwiftParser/Declarations.swift | 2 +- Sources/SwiftParser/Nominals.swift | 3 - Sources/SwiftParser/Types.swift | 12 ++ .../SyntaxKindNameForDiagnostics.swift | 2 + .../generated/SwiftSyntax.md | 1 + .../generated/ChildNameForKeyPath.swift | 18 ++- .../generated/SyntaxAnyVisitor.swift | 8 ++ .../generated/SyntaxBaseNodes.swift | 6 +- .../SwiftSyntax/generated/SyntaxEnum.swift | 3 + .../SwiftSyntax/generated/SyntaxKind.swift | 3 + .../generated/SyntaxRewriter.swift | 25 ++++ .../generated/SyntaxTransform.swift | 14 +++ .../SwiftSyntax/generated/SyntaxVisitor.swift | 25 ++++ .../generated/raw/RawSyntaxNodes.swift | 108 ++++++++++++---- .../generated/raw/RawSyntaxValidation.swift | 15 ++- .../generated/syntaxNodes/SyntaxNodes.swift | 52 ++------ .../syntaxNodes/SyntaxTypeNodes.swift | 116 ++++++++++++++++++ Tests/SwiftParserTest/DeclarationTests.swift | 46 ++++++- 20 files changed, 391 insertions(+), 93 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift index bbdd92c9951..31b8c5b2a36 100644 --- a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift @@ -1028,14 +1028,6 @@ public let DECL_NODES: [Node] = [ "WithTrailingComma" ], children: [ - /// Indicates whether the 'without' operator was applied to the type to - /// indicate the suppression of implicit conformance to this type. - /// This child stores the token representing the 'without' operator. - Child( - name: "WithoutTilde", - kind: .token(choices: [.token(tokenKind: "PrefixOperatorToken")]), - isOptional: true - ), Child( name: "TypeName", kind: .node(kind: "Type") diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index ad6659aaa33..b766b6f0744 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -349,6 +349,23 @@ public let TYPE_NODES: [Node] = [ ] ), + // suppressed-type -> '~' type + Node( + name: "SuppressedType", + nameForDiagnostics: "suppressed type conformance", + kind: "Type", + children: [ + Child( + name: "WithoutTilde", + kind: .token(choices: [.token(tokenKind: "PrefixOperatorToken")]) + ), + Child( + name: "PatternType", + kind: .node(kind: "Type") + ), + ] + ), + // pack-expansion-type -> type '...' Node( name: "PackExpansionType", diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 07d3fcdf6fa..c96a237983d 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -497,7 +497,7 @@ extension Parser { let unexpectedBeforeInherited: RawUnexpectedNodesSyntax? let inherited: RawTypeSyntax? if colon != nil { - if self.at(.identifier, .keyword(.protocol), .keyword(.Any)) { + if self.at(.identifier, .keyword(.protocol), .keyword(.Any)) || self.atContextualPunctuator("~") { unexpectedBeforeInherited = nil inherited = self.parseType() } else if let classKeyword = self.consume(if: .keyword(.class)) { diff --git a/Sources/SwiftParser/Nominals.swift b/Sources/SwiftParser/Nominals.swift index 8a0a36129ec..7429c868903 100644 --- a/Sources/SwiftParser/Nominals.swift +++ b/Sources/SwiftParser/Nominals.swift @@ -292,7 +292,6 @@ extension Parser { var keepGoing: RawTokenSyntax? = nil var loopProgress = LoopProgressCondition() repeat { - var withoutToken: RawTokenSyntax? = nil let type: RawTypeSyntax if let classKeyword = self.consume(if: .keyword(.class)) { type = RawTypeSyntax( @@ -302,14 +301,12 @@ extension Parser { ) ) } else { - withoutToken = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator) type = self.parseType() } keepGoing = self.consume(if: .comma) elements.append( RawInheritedTypeSyntax( - withoutTilde: withoutToken, typeName: type, trailingComma: keepGoing, arena: self.arena diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index f6b7e05bea8..94827578652 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -37,6 +37,18 @@ extension Parser { ) } + // Parse without operator preceding a type '~ T'. + if let withoutTilde = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator) { + let type = self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers) + return RawTypeSyntax( + RawSuppressedTypeSyntax( + withoutTilde: withoutTilde, + patternType: type, + arena: self.arena + ) + ) + } + return self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers) } diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index b35327cad6d..d0cee23cd41 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -341,6 +341,8 @@ extension SyntaxKind { return "subscript" case .subscriptExpr: return "subscript" + case .suppressedType: + return "suppressed type conformance" case .switchCase: return "switch case" case .switchExpr: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index c3924e1afc6..5a9987700bf 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -186,6 +186,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- - ### Collections diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 25c595d3ea7..55ac767a29d 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -1712,12 +1712,8 @@ internal func childName(_ keyPath: AnyKeyPath) -> String? { return "rightOperand" case \InfixOperatorExprSyntax.unexpectedAfterRightOperand: return "unexpectedAfterRightOperand" - case \InheritedTypeSyntax.unexpectedBeforeWithoutTilde: - return "unexpectedBeforeWithoutTilde" - case \InheritedTypeSyntax.withoutTilde: - return "withoutTilde" - case \InheritedTypeSyntax.unexpectedBetweenWithoutTildeAndTypeName: - return "unexpectedBetweenWithoutTildeAndTypeName" + case \InheritedTypeSyntax.unexpectedBeforeTypeName: + return "unexpectedBeforeTypeName" case \InheritedTypeSyntax.typeName: return "typeName" case \InheritedTypeSyntax.unexpectedBetweenTypeNameAndTrailingComma: @@ -2872,6 +2868,16 @@ internal func childName(_ keyPath: AnyKeyPath) -> String? { return "superKeyword" case \SuperRefExprSyntax.unexpectedAfterSuperKeyword: return "unexpectedAfterSuperKeyword" + case \SuppressedTypeSyntax.unexpectedBeforeWithoutTilde: + return "unexpectedBeforeWithoutTilde" + case \SuppressedTypeSyntax.withoutTilde: + return "withoutTilde" + case \SuppressedTypeSyntax.unexpectedBetweenWithoutTildeAndPatternType: + return "unexpectedBetweenWithoutTildeAndPatternType" + case \SuppressedTypeSyntax.patternType: + return "patternType" + case \SuppressedTypeSyntax.unexpectedAfterPatternType: + return "unexpectedAfterPatternType" case \SwitchCaseLabelSyntax.unexpectedBeforeCaseKeyword: return "unexpectedBeforeCaseKeyword" case \SwitchCaseLabelSyntax.caseKeyword: diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index 08f7d2307a1..783e957d60a 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -1869,6 +1869,14 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: SuppressedTypeSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: SuppressedTypeSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: SwitchCaseLabelSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index a91643e1fe9..d1b37a196fa 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -610,7 +610,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { public init?(_ node: S) { switch node.raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .suppressedType, .tupleType: self._syntaxNode = node._syntaxNode default: return nil @@ -622,7 +622,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { /// is undefined. internal init(_ data: SyntaxData) { switch data.raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .suppressedType, .tupleType: break default: preconditionFailure("Unable to create TypeSyntax from \(data.raw.kind)") @@ -674,6 +674,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { .node(PackExpansionTypeSyntax.self), .node(PackReferenceTypeSyntax.self), .node(SimpleTypeIdentifierSyntax.self), + .node(SuppressedTypeSyntax.self), .node(TupleTypeSyntax.self) ]) } @@ -910,6 +911,7 @@ extension Syntax { .node(SubscriptDeclSyntax.self), .node(SubscriptExprSyntax.self), .node(SuperRefExprSyntax.self), + .node(SuppressedTypeSyntax.self), .node(SwitchCaseLabelSyntax.self), .node(SwitchCaseListSyntax.self), .node(SwitchCaseSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index 8e9144700ab..390943e141c 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -243,6 +243,7 @@ public enum SyntaxEnum { case subscriptDecl(SubscriptDeclSyntax) case subscriptExpr(SubscriptExprSyntax) case superRefExpr(SuperRefExprSyntax) + case suppressedType(SuppressedTypeSyntax) case switchCaseLabel(SwitchCaseLabelSyntax) case switchCaseList(SwitchCaseListSyntax) case switchCase(SwitchCaseSyntax) @@ -746,6 +747,8 @@ public extension Syntax { return .subscriptExpr(SubscriptExprSyntax(self)!) case .superRefExpr: return .superRefExpr(SuperRefExprSyntax(self)!) + case .suppressedType: + return .suppressedType(SuppressedTypeSyntax(self)!) case .switchCaseLabel: return .switchCaseLabel(SwitchCaseLabelSyntax(self)!) case .switchCaseList: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index 518f1f43a0f..aa199255f7b 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -243,6 +243,7 @@ public enum SyntaxKind { case subscriptDecl case subscriptExpr case superRefExpr + case suppressedType case switchCaseLabel case switchCaseList case switchCase @@ -861,6 +862,8 @@ public enum SyntaxKind { return SubscriptExprSyntax.self case .superRefExpr: return SuperRefExprSyntax.self + case .suppressedType: + return SuppressedTypeSyntax.self case .switchCaseLabel: return SwitchCaseLabelSyntax.self case .switchCaseList: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index 3fdb902fd64..909cee80a34 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -1614,6 +1614,13 @@ open class SyntaxRewriter { return ExprSyntax(visitChildren(node)) } + /// Visit a `SuppressedTypeSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: SuppressedTypeSyntax) -> TypeSyntax { + return TypeSyntax(visitChildren(node)) + } + /// Visit a `SwitchCaseLabelSyntax`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -5153,6 +5160,20 @@ open class SyntaxRewriter { return Syntax(visit(node)) } + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplSuppressedTypeSyntax(_ data: SyntaxData) -> Syntax { + let node = SuppressedTypeSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + /// Implementation detail of visit(_:). Do not call directly. private func visitImplSwitchCaseLabelSyntax(_ data: SyntaxData) -> Syntax { let node = SwitchCaseLabelSyntax(data) @@ -6223,6 +6244,8 @@ open class SyntaxRewriter { return visitImplSubscriptExprSyntax case .superRefExpr: return visitImplSuperRefExprSyntax + case .suppressedType: + return visitImplSuppressedTypeSyntax case .switchCaseLabel: return visitImplSwitchCaseLabelSyntax case .switchCaseList: @@ -6769,6 +6792,8 @@ open class SyntaxRewriter { return visitImplSubscriptExprSyntax(data) case .superRefExpr: return visitImplSuperRefExprSyntax(data) + case .suppressedType: + return visitImplSuppressedTypeSyntax(data) case .switchCaseLabel: return visitImplSwitchCaseLabelSyntax(data) case .switchCaseList: diff --git a/Sources/SwiftSyntax/generated/SyntaxTransform.swift b/Sources/SwiftSyntax/generated/SyntaxTransform.swift index 4d84a26cc30..cbbeb096f34 100644 --- a/Sources/SwiftSyntax/generated/SyntaxTransform.swift +++ b/Sources/SwiftSyntax/generated/SyntaxTransform.swift @@ -1154,6 +1154,11 @@ public protocol SyntaxTransformVisitor { /// - Returns: the sum of whatever the child visitors return. func visit(_ node: SuperRefExprSyntax) -> ResultType + /// Visiting `SuppressedTypeSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: SuppressedTypeSyntax) -> ResultType + /// Visiting `SwitchCaseLabelSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: the sum of whatever the child visitors return. @@ -2954,6 +2959,13 @@ extension SyntaxTransformVisitor { visitAny(Syntax(node)) } + /// Visiting `SuppressedTypeSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: SuppressedTypeSyntax) -> ResultType { + visitAny(Syntax(node)) + } + /// Visiting `SwitchCaseLabelSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: nil by default. @@ -3699,6 +3711,8 @@ extension SyntaxTransformVisitor { return visit(derived) case .superRefExpr(let derived): return visit(derived) + case .suppressedType(let derived): + return visit(derived) case .switchCaseLabel(let derived): return visit(derived) case .switchCaseList(let derived): diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index 0e9e589d93c..b7124bbd68e 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -2758,6 +2758,18 @@ open class SyntaxVisitor { open func visitPost(_ node: SuperRefExprSyntax) { } + /// Visiting `SuppressedTypeSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: SuppressedTypeSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `SuppressedTypeSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: SuppressedTypeSyntax) { + } + /// Visiting `SwitchCaseLabelSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -5759,6 +5771,17 @@ open class SyntaxVisitor { visitPost(node) } + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplSuppressedTypeSyntax(_ data: SyntaxData) { + let node = SuppressedTypeSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + /// Implementation detail of doVisit(_:_:). Do not call directly. private func visitImplSwitchCaseLabelSyntax(_ data: SyntaxData) { let node = SwitchCaseLabelSyntax(data) @@ -6671,6 +6694,8 @@ open class SyntaxVisitor { visitImplSubscriptExprSyntax(data) case .superRefExpr: visitImplSuperRefExprSyntax(data) + case .suppressedType: + visitImplSuppressedTypeSyntax(data) case .switchCaseLabel: visitImplSwitchCaseLabelSyntax(data) case .switchCaseList: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift index 9119faec524..ac0210ca88c 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift @@ -11708,9 +11708,7 @@ public struct RawInheritedTypeSyntax: RawSyntaxNodeProtocol { } public init( - _ unexpectedBeforeWithoutTilde: RawUnexpectedNodesSyntax? = nil, - withoutTilde: RawTokenSyntax?, - _ unexpectedBetweenWithoutTildeAndTypeName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeTypeName: RawUnexpectedNodesSyntax? = nil, typeName: RawTypeSyntax, _ unexpectedBetweenTypeNameAndTrailingComma: RawUnexpectedNodesSyntax? = nil, trailingComma: RawTokenSyntax?, @@ -11718,45 +11716,35 @@ public struct RawInheritedTypeSyntax: RawSyntaxNodeProtocol { arena: __shared SyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .inheritedType, uninitializedCount: 7, arena: arena) { layout in + kind: .inheritedType, uninitializedCount: 5, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeWithoutTilde?.raw - layout[1] = withoutTilde?.raw - layout[2] = unexpectedBetweenWithoutTildeAndTypeName?.raw - layout[3] = typeName.raw - layout[4] = unexpectedBetweenTypeNameAndTrailingComma?.raw - layout[5] = trailingComma?.raw - layout[6] = unexpectedAfterTrailingComma?.raw + layout[0] = unexpectedBeforeTypeName?.raw + layout[1] = typeName.raw + layout[2] = unexpectedBetweenTypeNameAndTrailingComma?.raw + layout[3] = trailingComma?.raw + layout[4] = unexpectedAfterTrailingComma?.raw } self.init(unchecked: raw) } - public var unexpectedBeforeWithoutTilde: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeTypeName: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var withoutTilde: RawTokenSyntax? { - layoutView.children[1].map(RawTokenSyntax.init(raw:)) - } - - public var unexpectedBetweenWithoutTildeAndTypeName: RawUnexpectedNodesSyntax? { - layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) - } - public var typeName: RawTypeSyntax { - layoutView.children[3].map(RawTypeSyntax.init(raw:))! + layoutView.children[1].map(RawTypeSyntax.init(raw:))! } public var unexpectedBetweenTypeNameAndTrailingComma: RawUnexpectedNodesSyntax? { - layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } public var trailingComma: RawTokenSyntax? { - layoutView.children[5].map(RawTokenSyntax.init(raw:)) + layoutView.children[3].map(RawTokenSyntax.init(raw:)) } public var unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? { - layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } } @@ -19040,6 +19028,76 @@ public struct RawSuperRefExprSyntax: RawExprSyntaxNodeProtocol { } } +@_spi(RawSyntax) +public struct RawSuppressedTypeSyntax: RawTypeSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .suppressedType + } + + 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: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeWithoutTilde: RawUnexpectedNodesSyntax? = nil, + withoutTilde: RawTokenSyntax, + _ unexpectedBetweenWithoutTildeAndPatternType: RawUnexpectedNodesSyntax? = nil, + patternType: RawTypeSyntax, + _ unexpectedAfterPatternType: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .suppressedType, uninitializedCount: 5, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeWithoutTilde?.raw + layout[1] = withoutTilde.raw + layout[2] = unexpectedBetweenWithoutTildeAndPatternType?.raw + layout[3] = patternType.raw + layout[4] = unexpectedAfterPatternType?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeWithoutTilde: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var withoutTilde: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenWithoutTildeAndPatternType: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var patternType: RawTypeSyntax { + layoutView.children[3].map(RawTypeSyntax.init(raw:))! + } + + public var unexpectedAfterPatternType: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + @_spi(RawSyntax) public struct RawSwitchCaseLabelSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) @@ -20917,7 +20975,7 @@ public struct RawTypeSyntax: RawTypeSyntaxNodeProtocol { public static func isKindOf(_ raw: RawSyntax) -> Bool { switch raw.kind { - case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .tupleType: + case .arrayType, .attributedType, .classRestrictionType, .compositionType, .constrainedSugarType, .dictionaryType, .functionType, .implicitlyUnwrappedOptionalType, .memberTypeIdentifier, .metatypeType, .missingType, .namedOpaqueReturnType, .optionalType, .packExpansionType, .packReferenceType, .simpleTypeIdentifier, .suppressedType, .tupleType: return true default: return false diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 26af69ca687..15a509572e8 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -1505,14 +1505,12 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, index, verify(element, as: RawInheritedTypeSyntax.self)) } case .inheritedType: - assert(layout.count == 7) + assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.prefixOperator)])) + assertNoError(kind, 1, verify(layout[1], as: RawTypeSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTypeSyntax.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) - assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) case .initializerClause: assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) @@ -2322,6 +2320,13 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("super")])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + case .suppressedType: + assert(layout.count == 5) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.prefixOperator)])) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTypeSyntax.self)) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) case .switchCaseLabel: assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift index ff4acd30865..686a7d1e6ff 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift @@ -10564,9 +10564,7 @@ public struct InheritedTypeSyntax: SyntaxProtocol, SyntaxHashable { public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeWithoutTilde: UnexpectedNodesSyntax? = nil, - withoutTilde: TokenSyntax? = nil, - _ unexpectedBetweenWithoutTildeAndTypeName: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeTypeName: UnexpectedNodesSyntax? = nil, typeName: T, _ unexpectedBetweenTypeNameAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax? = nil, @@ -10577,18 +10575,14 @@ public struct InheritedTypeSyntax: SyntaxProtocol, SyntaxHashable { // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( - unexpectedBeforeWithoutTilde, - withoutTilde, - unexpectedBetweenWithoutTildeAndTypeName, + unexpectedBeforeTypeName, typeName, unexpectedBetweenTypeNameAndTrailingComma, trailingComma, unexpectedAfterTrailingComma ))) {(arena, _) in let layout: [RawSyntax?] = [ - unexpectedBeforeWithoutTilde?.raw, - withoutTilde?.raw, - unexpectedBetweenWithoutTildeAndTypeName?.raw, + unexpectedBeforeTypeName?.raw, typeName.raw, unexpectedBetweenTypeNameAndTrailingComma?.raw, trailingComma?.raw, @@ -10607,7 +10601,7 @@ public struct InheritedTypeSyntax: SyntaxProtocol, SyntaxHashable { self.init(data) } - public var unexpectedBeforeWithoutTilde: UnexpectedNodesSyntax? { + public var unexpectedBeforeTypeName: UnexpectedNodesSyntax? { get { return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } @@ -10616,65 +10610,45 @@ public struct InheritedTypeSyntax: SyntaxProtocol, SyntaxHashable { } } - public var withoutTilde: TokenSyntax? { - get { - return data.child(at: 1, parent: Syntax(self)).map(TokenSyntax.init) - } - set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 1, with: value?.raw, arena: SyntaxArena())) - } - } - - public var unexpectedBetweenWithoutTildeAndTypeName: UnexpectedNodesSyntax? { - get { - return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) - } - set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) - } - } - public var typeName: TypeSyntax { get { - return TypeSyntax(data.child(at: 3, parent: Syntax(self))!) + return TypeSyntax(data.child(at: 1, parent: Syntax(self))!) } set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) + self = InheritedTypeSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) } } public var unexpectedBetweenTypeNameAndTrailingComma: UnexpectedNodesSyntax? { get { - return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + self = InheritedTypeSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) } } public var trailingComma: TokenSyntax? { get { - return data.child(at: 5, parent: Syntax(self)).map(TokenSyntax.init) + return data.child(at: 3, parent: Syntax(self)).map(TokenSyntax.init) } set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 5, with: value?.raw, arena: SyntaxArena())) + self = InheritedTypeSyntax(data.replacingChild(at: 3, with: value?.raw, arena: SyntaxArena())) } } public var unexpectedAfterTrailingComma: UnexpectedNodesSyntax? { get { - return data.child(at: 6, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) } set(value) { - self = InheritedTypeSyntax(data.replacingChild(at: 6, with: value?.raw, arena: SyntaxArena())) + self = InheritedTypeSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) } } public static var structure: SyntaxNodeStructure { return .layout([ - \Self.unexpectedBeforeWithoutTilde, - \Self.withoutTilde, - \Self.unexpectedBetweenWithoutTildeAndTypeName, + \Self.unexpectedBeforeTypeName, \Self.typeName, \Self.unexpectedBetweenTypeNameAndTrailingComma, \Self.trailingComma, diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxTypeNodes.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxTypeNodes.swift index b3c42bda968..681a100811f 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxTypeNodes.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxTypeNodes.swift @@ -2098,6 +2098,122 @@ public struct SimpleTypeIdentifierSyntax: TypeSyntaxProtocol, SyntaxHashable { } } +// MARK: - SuppressedTypeSyntax + + +public struct SuppressedTypeSyntax: TypeSyntaxProtocol, SyntaxHashable { + public let _syntaxNode: Syntax + + public init?(_ node: S) { + guard node.raw.kind == .suppressedType else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// Creates a `SuppressedTypeSyntax` node from the given `SyntaxData`. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .suppressedType) + self._syntaxNode = Syntax(data) + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeWithoutTilde: UnexpectedNodesSyntax? = nil, + withoutTilde: TokenSyntax, + _ unexpectedBetweenWithoutTildeAndPatternType: UnexpectedNodesSyntax? = nil, + patternType: P, + _ unexpectedAfterPatternType: 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. + let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeWithoutTilde, + withoutTilde, + unexpectedBetweenWithoutTildeAndPatternType, + patternType, + unexpectedAfterPatternType + ))) {(arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeWithoutTilde?.raw, + withoutTilde.raw, + unexpectedBetweenWithoutTildeAndPatternType?.raw, + patternType.raw, + unexpectedAfterPatternType?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.suppressedType, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + + ) + return SyntaxData.forRoot(raw) + } + self.init(data) + } + + public var unexpectedBeforeWithoutTilde: UnexpectedNodesSyntax? { + get { + return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = SuppressedTypeSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) + } + } + + public var withoutTilde: TokenSyntax { + get { + return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) + } + set(value) { + self = SuppressedTypeSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenWithoutTildeAndPatternType: UnexpectedNodesSyntax? { + get { + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = SuppressedTypeSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) + } + } + + public var patternType: TypeSyntax { + get { + return TypeSyntax(data.child(at: 3, parent: Syntax(self))!) + } + set(value) { + self = SuppressedTypeSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedAfterPatternType: UnexpectedNodesSyntax? { + get { + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = SuppressedTypeSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + } + } + + public static var structure: SyntaxNodeStructure { + return .layout([ + \Self.unexpectedBeforeWithoutTilde, + \Self.withoutTilde, + \Self.unexpectedBetweenWithoutTildeAndPatternType, + \Self.patternType, + \Self.unexpectedAfterPatternType + ]) + } +} + // MARK: - TupleTypeSyntax diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index e8062c54128..9b6293b8a7f 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -1580,8 +1580,10 @@ final class DeclarationTests: XCTestCase { """, substructure: Syntax( InheritedTypeSyntax( - withoutTilde: .prefixOperator("~"), - typeName: TypeSyntax(stringLiteral: "Copyable") + typeName: SuppressedTypeSyntax( + withoutTilde: .prefixOperator("~"), + patternType: TypeSyntax(stringLiteral: "Copyable") + ) ) ) ) @@ -1600,8 +1602,10 @@ final class DeclarationTests: XCTestCase { trailingComma: .commaToken() ), InheritedTypeSyntax( - withoutTilde: .prefixOperator("~"), - typeName: TypeSyntax(stringLiteral: "Hashable"), + typeName: SuppressedTypeSyntax( + withoutTilde: .prefixOperator("~"), + patternType: TypeSyntax(stringLiteral: "Hashable") + ), trailingComma: .commaToken() ), InheritedTypeSyntax(typeName: TypeSyntax(stringLiteral: "Equatable")), @@ -1609,6 +1613,40 @@ final class DeclarationTests: XCTestCase { ) ) ) + + assertParse( + """ + typealias T = ~1️⃣Int 2️⃣-> Bool + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "expected '(' to start function type", + fixIts: ["insert '('"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected ')' in function type", + fixIts: ["insert ')'"] + ), + ], + fixedSource: """ + typealias T = ~(Int) -> Bool + """ + ) + + assertParse( + """ + typealias T = ~(Int) -> Bool + """, + substructure: + Syntax( + SuppressedTypeSyntax( + withoutTilde: .prefixOperator("~"), + patternType: FunctionTypeSyntax(arguments: [TupleTypeElementSyntax(type: TypeSyntax("Int"))], output: ReturnClauseSyntax(returnType: TypeSyntax("Bool"))) + ) + ) + ) } }