Skip to content

Commit 1e9a9c5

Browse files
authored
Merge pull request #751 from CodaFi/parse-for-the-course
.swiftinterface-Related Fixes
2 parents ada5bb3 + 8562e7b commit 1e9a9c5

29 files changed

+604
-20
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,22 @@ extension Parser {
776776
}
777777
}
778778

779+
extension Parser {
780+
mutating func parseOpaqueReturnTypeOfAttributeArguments() -> RawOpaqueReturnTypeOfAttributeArgumentsSyntax {
781+
let (unexpectedBeforeString, mangledName) = self.expect(.stringLiteral)
782+
let (unexpectedBeforeComma, comma) = self.expect(.comma)
783+
let (unexpectedBeforeOrdinal, ordinal) = self.expect(.integerLiteral)
784+
return RawOpaqueReturnTypeOfAttributeArgumentsSyntax(
785+
unexpectedBeforeString,
786+
mangledName: mangledName,
787+
unexpectedBeforeComma,
788+
comma: comma,
789+
unexpectedBeforeOrdinal,
790+
ordinal: ordinal,
791+
arena: self.arena)
792+
}
793+
}
794+
779795
// MARK: Lookahead
780796

781797
extension Parser.Lookahead {

Sources/SwiftParser/Declarations.swift

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension TokenConsumer {
2424
var attributeProgress = LoopProgressCondition()
2525
while attributeProgress.evaluate(subparser.currentToken) && subparser.at(.atSign) {
2626
hasAttribute = true
27-
_ = subparser.eatParseAttributeList()
27+
_ = subparser.consumeAttributeList()
2828
}
2929

3030
var modifierProgress = LoopProgressCondition()
@@ -130,7 +130,7 @@ extension Parser {
130130
case (.enumKeyword, _)?:
131131
return RawDeclSyntax(self.parseEnumDeclaration(attrs))
132132
case (.caseKeyword, _)?:
133-
return RawDeclSyntax(self.parseDeclEnumCase(attrs))
133+
return RawDeclSyntax(self.parseEnumCaseDeclaration(attrs))
134134
case (.structKeyword, _)?:
135135
return RawDeclSyntax(self.parseStructDeclaration(attrs))
136136
case (.protocolKeyword, _)?:
@@ -719,7 +719,7 @@ extension Parser {
719719
/// raw-value-assignment → = raw-value-literal
720720
/// raw-value-literal → numeric-literal | static-string-literal | boolean-literal
721721
@_spi(RawSyntax)
722-
public mutating func parseDeclEnumCase(_ attrs: DeclAttributes) -> RawEnumCaseDeclSyntax {
722+
public mutating func parseEnumCaseDeclaration(_ attrs: DeclAttributes) -> RawEnumCaseDeclSyntax {
723723
let (unexpectedBeforeCaseKeyword, caseKeyword) = self.expect(.caseKeyword)
724724
var elements = [RawEnumCaseElementSyntax]()
725725
do {
@@ -730,7 +730,7 @@ extension Parser {
730730

731731
let associatedValue: RawParameterClauseSyntax?
732732
if self.at(.leftParen, where: { !$0.isAtStartOfLine }) {
733-
associatedValue = self.parseParameterClause()
733+
associatedValue = self.parseParameterClause(for: .enumCase)
734734
} else {
735735
associatedValue = nil
736736
}
@@ -1149,27 +1149,52 @@ extension Parser {
11491149

11501150
extension Parser {
11511151
@_spi(RawSyntax)
1152-
public mutating func parseParameterClause(isClosure: Bool = false) -> RawParameterClauseSyntax {
1152+
public enum ParameterSubject {
1153+
case closure
1154+
case enumCase
1155+
case functionParameters
1156+
case indices
1157+
1158+
var isClosure: Bool {
1159+
switch self {
1160+
case .closure: return true
1161+
case .enumCase: return false
1162+
case .functionParameters: return false
1163+
case .indices: return false
1164+
}
1165+
}
1166+
}
1167+
1168+
@_spi(RawSyntax)
1169+
public mutating func parseParameterClause(for subject: ParameterSubject) -> RawParameterClauseSyntax {
11531170
let (unexpectedBeforeLParen, lparen) = self.expect(.leftParen)
11541171
var elements = [RawFunctionParameterSyntax]()
1155-
// If we are missing the left parenthesis and the next token doesn't appear to be an argument label, don't parse any parameters.
1172+
// If we are missing the left parenthesis and the next token doesn't appear
1173+
// to be an argument label, don't parse any parameters.
11561174
let shouldSkipParameterParsing = lparen.isMissing && (!currentToken.canBeArgumentLabel || currentToken.isKeyword)
11571175
if !shouldSkipParameterParsing {
11581176
var keepGoing = true
11591177
var loopProgress = LoopProgressCondition()
11601178
while !self.at(any: [.eof, .rightParen])
11611179
&& keepGoing
11621180
&& loopProgress.evaluate(currentToken) {
1163-
// Attributes.
1164-
let attrs = self.parseAttributeList()
1181+
// Parse any declaration attributes. The exception here is enum cases
1182+
// which only allow types, so we do not consume attributes to allow the
1183+
// type attribute grammar a chance to examine them.
1184+
let attrs: RawAttributeListSyntax?
1185+
if case .enumCase = subject {
1186+
attrs = nil
1187+
} else {
1188+
attrs = self.parseAttributeList()
1189+
}
11651190

11661191
let firstName: RawTokenSyntax?
11671192
let secondName: RawTokenSyntax?
11681193
let unexpectedBeforeColon: RawUnexpectedNodesSyntax?
11691194
let colon: RawTokenSyntax?
11701195
let shouldParseType: Bool
11711196

1172-
if self.lookahead().startsParameterName(isClosure) {
1197+
if self.lookahead().startsParameterName(subject.isClosure) {
11731198
if self.currentToken.canBeArgumentLabel {
11741199
firstName = self.parseArgumentLabel()
11751200
} else {
@@ -1181,7 +1206,7 @@ extension Parser {
11811206
} else {
11821207
secondName = nil
11831208
}
1184-
if isClosure {
1209+
if subject.isClosure {
11851210
unexpectedBeforeColon = nil
11861211
colon = self.consume(if: .colon)
11871212
shouldParseType = (colon != nil)
@@ -1324,7 +1349,7 @@ extension Parser {
13241349

13251350
@_spi(RawSyntax)
13261351
public mutating func parseFunctionSignature() -> RawFunctionSignatureSyntax {
1327-
let input = self.parseParameterClause()
1352+
let input = self.parseParameterClause(for: .functionParameters)
13281353

13291354
let async = self.consumeIfContextualKeyword("async")
13301355

@@ -1371,7 +1396,7 @@ extension Parser {
13711396
genericParameterClause = nil
13721397
}
13731398

1374-
let indices = self.parseParameterClause()
1399+
let indices = self.parseParameterClause(for: .indices)
13751400

13761401
let result: RawReturnClauseSyntax
13771402
if self.at(.arrow) {

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,7 @@ extension Parser {
18311831
if !self.at(.inKeyword) {
18321832
if self.at(.leftParen) {
18331833
// Parse the closure arguments.
1834-
input = RawSyntax(self.parseParameterClause(isClosure: true))
1834+
input = RawSyntax(self.parseParameterClause(for: .closure))
18351835
} else {
18361836
var params = [RawClosureParamSyntax]()
18371837
var loopProgress = LoopProgressCondition()

Sources/SwiftParser/Lookahead.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,23 @@ extension Parser.Lookahead {
171171
public mutating func eat(_ kind: RawTokenKind) -> Token {
172172
return self.consume(if: kind)!
173173
}
174+
}
174175

175-
mutating func eatParseAttributeList() -> Bool {
176+
extension Parser.Lookahead {
177+
mutating func consumeAttributeList() -> Bool {
176178
guard self.at(.atSign) else {
177179
return false
178180
}
179181

180182
while let _ = self.consume(if: .atSign) {
181-
self.expectIdentifierOrRethrowsWithoutRecovery()
183+
// Consume qualified names that may or may not involve generic arguments.
184+
repeat {
185+
self.expectIdentifierOrRethrowsWithoutRecovery()
186+
// We don't care whether this succeeds or fails to eat generic
187+
// parameters.
188+
_ = self.consumeGenericArguments()
189+
} while self.consume(if: .period) != nil
190+
182191
if self.consume(if: .leftParen) != nil {
183192
while !self.at(any: [.eof, .rightParen, .poundEndifKeyword]) {
184193
self.skipSingle()

Sources/SwiftParser/Types.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ extension Parser.Lookahead {
711711
self.consumeAnyToken()
712712

713713
// Parse an optional generic argument list.
714-
if self.currentToken.starts(with: "<") && !self.canParseGenericArguments() {
714+
if self.currentToken.starts(with: "<") && !self.consumeGenericArguments() {
715715
return false
716716
}
717717

@@ -724,13 +724,13 @@ extension Parser.Lookahead {
724724
}
725725

726726
var lookahead = self.lookahead()
727-
guard lookahead.canParseGenericArguments() else {
727+
guard lookahead.consumeGenericArguments() else {
728728
return false
729729
}
730730
return lookahead.currentToken.isGenericTypeDisambiguatingToken
731731
}
732732

733-
mutating func canParseGenericArguments() -> Bool {
733+
mutating func consumeGenericArguments() -> Bool {
734734
// Parse the opening '<'.
735735
guard self.currentToken.starts(with: "<") else {
736736
return false
@@ -821,6 +821,26 @@ extension Parser {
821821
arena: self.arena
822822
)
823823
)
824+
case ._opaqueReturnTypeOf:
825+
let (unexpectedBeforeAt, at) = self.expect(.atSign)
826+
let ident = self.expectIdentifierWithoutRecovery()
827+
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
828+
let argument = self.parseOpaqueReturnTypeOfAttributeArguments()
829+
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
830+
return RawSyntax(
831+
RawAttributeSyntax(
832+
unexpectedBeforeAt,
833+
atSignToken: at,
834+
attributeName: ident,
835+
unexpectedBeforeLeftParen,
836+
leftParen: leftParen,
837+
argument: RawSyntax(argument),
838+
unexpectedBeforeRightParen,
839+
rightParen: rightParen,
840+
tokenList: nil,
841+
arena: self.arena
842+
)
843+
)
824844

825845
default:
826846
let (unexpectedBeforeAt, at) = self.expect(.atSign)

Sources/SwiftSyntax/Documentation.docc/gyb_generated/SwiftSyntax.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code.
361361
- <doc:SwiftSyntax/BackDeployAttributeSpecListSyntax>
362362
- <doc:SwiftSyntax/BackDeployVersionListSyntax>
363363
- <doc:SwiftSyntax/BackDeployVersionArgumentSyntax>
364+
- <doc:SwiftSyntax/OpaqueReturnTypeOfAttributeArgumentsSyntax>
364365
- <doc:SwiftSyntax/SwitchCaseListSyntax>
365366
- <doc:SwiftSyntax/WhereClauseSyntax>
366367
- <doc:SwiftSyntax/CatchClauseListSyntax>

Sources/SwiftSyntax/Raw/gyb_generated/RawSyntaxNodes.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10577,6 +10577,69 @@ public struct RawBackDeployVersionArgumentSyntax: RawSyntaxNodeProtocol {
1057710577
}
1057810578
}
1057910579

10580+
@_spi(RawSyntax)
10581+
public struct RawOpaqueReturnTypeOfAttributeArgumentsSyntax: RawSyntaxNodeProtocol {
10582+
var layoutView: RawSyntaxLayoutView {
10583+
return raw.layoutView!
10584+
}
10585+
10586+
public static func isKindOf(_ raw: RawSyntax) -> Bool {
10587+
return raw.kind == .opaqueReturnTypeOfAttributeArguments
10588+
}
10589+
10590+
public var raw: RawSyntax
10591+
init(raw: RawSyntax) {
10592+
assert(Self.isKindOf(raw))
10593+
self.raw = raw
10594+
}
10595+
10596+
public init?<Node: RawSyntaxNodeProtocol>(_ other: Node) {
10597+
guard Self.isKindOf(other.raw) else { return nil }
10598+
self.init(raw: other.raw)
10599+
}
10600+
10601+
public init(
10602+
_ unexpectedBeforeMangledName: RawUnexpectedNodesSyntax? = nil,
10603+
mangledName: RawTokenSyntax,
10604+
_ unexpectedBetweenMangledNameAndComma: RawUnexpectedNodesSyntax? = nil,
10605+
comma: RawTokenSyntax,
10606+
_ unexpectedBetweenCommaAndOrdinal: RawUnexpectedNodesSyntax? = nil,
10607+
ordinal: RawTokenSyntax,
10608+
arena: __shared SyntaxArena
10609+
) {
10610+
let raw = RawSyntax.makeLayout(
10611+
kind: .opaqueReturnTypeOfAttributeArguments, uninitializedCount: 6, arena: arena) { layout in
10612+
layout.initialize(repeating: nil)
10613+
layout[0] = unexpectedBeforeMangledName?.raw
10614+
layout[1] = mangledName.raw
10615+
layout[2] = unexpectedBetweenMangledNameAndComma?.raw
10616+
layout[3] = comma.raw
10617+
layout[4] = unexpectedBetweenCommaAndOrdinal?.raw
10618+
layout[5] = ordinal.raw
10619+
}
10620+
self.init(raw: raw)
10621+
}
10622+
10623+
public var unexpectedBeforeMangledName: RawUnexpectedNodesSyntax? {
10624+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
10625+
}
10626+
public var mangledName: RawTokenSyntax {
10627+
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
10628+
}
10629+
public var unexpectedBetweenMangledNameAndComma: RawUnexpectedNodesSyntax? {
10630+
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
10631+
}
10632+
public var comma: RawTokenSyntax {
10633+
layoutView.children[3].map(RawTokenSyntax.init(raw:))!
10634+
}
10635+
public var unexpectedBetweenCommaAndOrdinal: RawUnexpectedNodesSyntax? {
10636+
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
10637+
}
10638+
public var ordinal: RawTokenSyntax {
10639+
layoutView.children[5].map(RawTokenSyntax.init(raw:))!
10640+
}
10641+
}
10642+
1058010643
@_spi(RawSyntax)
1058110644
public struct RawLabeledStmtSyntax: RawStmtSyntaxNodeProtocol {
1058210645
var layoutView: RawSyntaxLayoutView {

Sources/SwiftSyntax/Raw/gyb_generated/RawSyntaxValidation.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,15 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
15181518
_verify(layout[2], as: RawUnexpectedNodesSyntax?.self)
15191519
_verify(layout[3], as: RawTokenSyntax?.self)
15201520
break
1521+
case .opaqueReturnTypeOfAttributeArguments:
1522+
assert(layout.count == 6)
1523+
_verify(layout[0], as: RawUnexpectedNodesSyntax?.self)
1524+
_verify(layout[1], as: RawTokenSyntax.self)
1525+
_verify(layout[2], as: RawUnexpectedNodesSyntax?.self)
1526+
_verify(layout[3], as: RawTokenSyntax.self)
1527+
_verify(layout[4], as: RawUnexpectedNodesSyntax?.self)
1528+
_verify(layout[5], as: RawTokenSyntax.self)
1529+
break
15211530
case .labeledStmt:
15221531
assert(layout.count == 6)
15231532
_verify(layout[0], as: RawUnexpectedNodesSyntax?.self)

Sources/SwiftSyntax/gyb_generated/Misc.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ extension Syntax {
381381
return node
382382
case .backDeployVersionArgument(let node):
383383
return node
384+
case .opaqueReturnTypeOfAttributeArguments(let node):
385+
return node
384386
case .labeledStmt(let node):
385387
return node
386388
case .continueStmt(let node):
@@ -742,6 +744,7 @@ extension SyntaxKind {
742744
case .backDeployAttributeSpecList: return BackDeployAttributeSpecListSyntax.self
743745
case .backDeployVersionList: return BackDeployVersionListSyntax.self
744746
case .backDeployVersionArgument: return BackDeployVersionArgumentSyntax.self
747+
case .opaqueReturnTypeOfAttributeArguments: return OpaqueReturnTypeOfAttributeArgumentsSyntax.self
745748
case .labeledStmt: return LabeledStmtSyntax.self
746749
case .continueStmt: return ContinueStmtSyntax.self
747750
case .whileStmt: return WhileStmtSyntax.self

Sources/SwiftSyntax/gyb_generated/SyntaxAnyVisitor.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,13 @@ open class SyntaxAnyVisitor: SyntaxVisitor {
12931293
override open func visitPost(_ node: BackDeployVersionArgumentSyntax) {
12941294
visitAnyPost(node._syntaxNode)
12951295
}
1296+
override open func visit(_ node: OpaqueReturnTypeOfAttributeArgumentsSyntax) -> SyntaxVisitorContinueKind {
1297+
return visitAny(node._syntaxNode)
1298+
}
1299+
1300+
override open func visitPost(_ node: OpaqueReturnTypeOfAttributeArgumentsSyntax) {
1301+
visitAnyPost(node._syntaxNode)
1302+
}
12961303
override open func visit(_ node: LabeledStmtSyntax) -> SyntaxVisitorContinueKind {
12971304
return visitAny(node._syntaxNode)
12981305
}

Sources/SwiftSyntax/gyb_generated/SyntaxEnum.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ public enum SyntaxEnum {
192192
case backDeployAttributeSpecList(BackDeployAttributeSpecListSyntax)
193193
case backDeployVersionList(BackDeployVersionListSyntax)
194194
case backDeployVersionArgument(BackDeployVersionArgumentSyntax)
195+
case opaqueReturnTypeOfAttributeArguments(OpaqueReturnTypeOfAttributeArgumentsSyntax)
195196
case labeledStmt(LabeledStmtSyntax)
196197
case continueStmt(ContinueStmtSyntax)
197198
case whileStmt(WhileStmtSyntax)
@@ -639,6 +640,8 @@ public enum SyntaxEnum {
639640
return "version list"
640641
case .backDeployVersionArgument:
641642
return "version"
643+
case .opaqueReturnTypeOfAttributeArguments:
644+
return "opaque return type arguments"
642645
case .labeledStmt:
643646
return "labeled statement"
644647
case .continueStmt:
@@ -1179,6 +1182,8 @@ public extension Syntax {
11791182
return .backDeployVersionList(BackDeployVersionListSyntax(self)!)
11801183
case .backDeployVersionArgument:
11811184
return .backDeployVersionArgument(BackDeployVersionArgumentSyntax(self)!)
1185+
case .opaqueReturnTypeOfAttributeArguments:
1186+
return .opaqueReturnTypeOfAttributeArguments(OpaqueReturnTypeOfAttributeArgumentsSyntax(self)!)
11821187
case .labeledStmt:
11831188
return .labeledStmt(LabeledStmtSyntax(self)!)
11841189
case .continueStmt:

0 commit comments

Comments
 (0)