Skip to content

Commit e106077

Browse files
committed
Parse @differentiable on types
1 parent 323cb3c commit e106077

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

Sources/SwiftParser/Types.swift

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -807,41 +807,57 @@ extension Parser {
807807

808808
var attributeProgress = LoopProgressCondition()
809809
while self.at(.atSign) && attributeProgress.evaluate(currentToken) {
810-
elements.append(RawSyntax(self.parseTypeAttribute()))
810+
elements.append(self.parseTypeAttribute())
811811
}
812812
return RawAttributeListSyntax(elements: elements, arena: self.arena)
813813
}
814814

815815
@_spi(RawSyntax)
816-
public mutating func parseTypeAttribute() -> RawAttributeSyntax {
817-
let at = self.eat(.atSign)
818-
let ident = self.consumeIdentifier()
819-
if let attr = Parser.TypeAttribute(rawValue: ident.tokenText) {
820-
// Ok, it is a valid attribute, eat it, and then process it.
821-
if case .convention = attr {
822-
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
823-
let convention = self.consumeIdentifier()
824-
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
825-
return RawAttributeSyntax(
816+
public mutating func parseTypeAttribute() -> RawSyntax {
817+
guard let typeAttr = Parser.TypeAttribute(rawValue: self.peek().tokenText) else {
818+
return RawSyntax(self.parseCustomAttribute())
819+
}
820+
821+
switch typeAttr {
822+
case .differentiable:
823+
return RawSyntax(self.parseDifferentiableAttribute())
824+
825+
case .convention:
826+
let at = self.eat(.atSign)
827+
let ident = self.consumeIdentifier()
828+
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
829+
let argument = self.consumeIdentifier()
830+
831+
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
832+
return RawSyntax(
833+
RawAttributeSyntax(
826834
atSignToken: at,
827835
attributeName: ident,
828836
unexpectedBeforeLeftParen,
829837
leftParen: leftParen,
830-
argument: RawSyntax(convention),
838+
argument: RawSyntax(argument),
831839
unexpectedBeforeRightParen,
832840
rightParen: rightParen,
833841
tokenList: nil,
834-
arena: self.arena)
835-
}
842+
arena: self.arena
843+
)
844+
)
845+
846+
default:
847+
let at = self.eat(.atSign)
848+
let ident = self.consumeIdentifier()
849+
return RawSyntax(
850+
RawAttributeSyntax(
851+
atSignToken: at,
852+
attributeName: ident,
853+
leftParen: nil,
854+
argument: nil,
855+
rightParen: nil,
856+
tokenList: nil,
857+
arena: self.arena
858+
)
859+
)
836860
}
837-
return RawAttributeSyntax(
838-
atSignToken: at,
839-
attributeName: ident,
840-
leftParen: nil,
841-
argument: nil,
842-
rightParen: nil,
843-
tokenList: nil,
844-
arena: self.arena)
845861
}
846862
}
847863

Tests/SwiftParserTest/Attributes.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,22 @@ final class AttributeTests: XCTestCase {
7575
"""
7676
)
7777
}
78+
79+
func testAutoclosureAttribute() {
80+
AssertParse(
81+
"""
82+
func f(in: @autoclosure () -> Int) { }
83+
func g(in: @autoclosure @escaping () -> Int) { }
84+
"""
85+
)
86+
}
87+
88+
func testDifferentiableAttribute() {
89+
AssertParse(
90+
"""
91+
func f(in: @differentiable(reverse) (Int) -> Int) { }
92+
func f(in: @differentiable(reverse, wrt: a) (Int) -> Int) { }
93+
"""
94+
)
95+
}
7896
}

0 commit comments

Comments
 (0)