Skip to content

Commit d493f0f

Browse files
authored
Merge pull request #734 from DougGregor/misc-parser-fixes
2 parents e2d04d6 + a1567bd commit d493f0f

File tree

9 files changed

+109
-26
lines changed

9 files changed

+109
-26
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ extension Parser {
183183

184184

185185
let atSign = self.eat(.atSign)
186-
let ident = self.consumeIdentifier()
186+
let ident = self.consumeIdentifierOrRethrows()
187187
let leftParen: RawTokenSyntax?
188188
let arg: RawSyntax?
189189
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
@@ -458,7 +458,7 @@ extension Parser {
458458
name: name,
459459
colon: nil,
460460
arena: self.arena))
461-
continue
461+
break
462462
}
463463

464464
let (unexpectedBeforeColon, colon) = self.expect(.colon)

Sources/SwiftParser/Expressions.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,9 @@ extension Parser {
721721
case .__file__Keyword:
722722
let tok = self.eat(.__file__Keyword)
723723
return RawExprSyntax(RawPoundFileExprSyntax(poundFile: tok, arena: self.arena))
724+
case .poundFileIDKeyword:
725+
let tok = self.eat(.poundFileIDKeyword)
726+
return RawExprSyntax(RawPoundFileIDExprSyntax(poundFileID: tok, arena: self.arena))
724727
case .poundFileKeyword:
725728
let tok = self.eat(.poundFileKeyword)
726729
return RawExprSyntax(RawPoundFileExprSyntax(poundFile: tok, arena: self.arena))

Sources/SwiftParser/Lexer.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ extension Lexer.Cursor {
14391439
return .integerLiteral
14401440
}
14411441

1442-
self.advance(while: { $0.isDigit || $0 == Unicode.Scalar("_") })
1442+
self.advance(while: { $0.isHexDigit || $0 == Unicode.Scalar("_") })
14431443

14441444
if !self.isAtEndOfFile, self.peek() != UInt8(ascii: "p") && self.peek() != UInt8(ascii: "P") {
14451445
if !Unicode.Scalar(PtrOnDot!.peek(at: 1)).isDigit {
@@ -2007,6 +2007,8 @@ extension Lexer.Cursor {
20072007
) -> RawTokenKind? {
20082008
var Tmp = TokStart
20092009
var poundCount = 0
2010+
var parenCount = 0
2011+
20102012
while Tmp.advance(matching: UInt8(ascii: "#")) != nil {
20112013
poundCount += 1
20122014
}
@@ -2072,6 +2074,15 @@ extension Lexer.Cursor {
20722074
// // delimiter.
20732075
// throw DelimiterLexError(.unprintableASCII, resumeAt: cursor.successor())
20742076

2077+
case UInt8(ascii: "("):
2078+
parenCount += 1
2079+
2080+
case UInt8(ascii: ")"):
2081+
if parenCount == 0 {
2082+
return nil
2083+
}
2084+
parenCount -= 1
2085+
20752086
default:
20762087
continue DELIMITLOOP
20772088
}

Sources/SwiftParser/Lookahead.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ extension Parser.Lookahead {
146146

147147
repeat {
148148
self.eat(.atSign)
149-
self.consumeIdentifier()
149+
self.consumeIdentifierOrRethrows()
150150
if self.consume(if: .leftParen) != nil {
151151
while !self.at(.eof), !self.at(.rightParen), !self.at(.poundEndifKeyword) {
152152
self.skipSingle()

Sources/SwiftParser/Names.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,19 @@ extension TokenConsumer {
330330
}
331331
}
332332

333+
mutating func consumeIdentifierOrRethrows() -> Token {
334+
switch self.currentToken.tokenKind {
335+
case .selfKeyword,
336+
.capitalSelfKeyword,
337+
.anyKeyword,
338+
.identifier,
339+
.rethrowsKeyword:
340+
return self.consumeAnyToken()
341+
default:
342+
return self.missingToken(.identifier)
343+
}
344+
}
345+
333346
mutating func consumeInteger() -> Token {
334347
switch self.currentToken.tokenKind {
335348
case .integerLiteral:

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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,36 @@ final class AttributeTests: XCTestCase {
6363
"""
6464
@objc(zeroArg)
6565
class A { }
66+
67+
@objc(:::::)
68+
func f(_: Int, _: Int, _: Int, _: Int, _: Int) { }
69+
"""
70+
)
71+
}
72+
73+
func testRethrowsAttribute() {
74+
AssertParse(
75+
"""
76+
@rethrows
77+
protocol P { }
78+
"""
79+
)
80+
}
81+
82+
func testAutoclosureAttribute() {
83+
AssertParse(
84+
"""
85+
func f(in: @autoclosure () -> Int) { }
86+
func g(in: @autoclosure @escaping () -> Int) { }
87+
"""
88+
)
89+
}
90+
91+
func testDifferentiableAttribute() {
92+
AssertParse(
93+
"""
94+
func f(in: @differentiable(reverse) (Int) -> Int) { }
95+
func f(in: @differentiable(reverse, wrt: a) (Int) -> Int) { }
6696
"""
6797
)
6898
}

Tests/SwiftParserTest/Expressions.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ final class ExpressionTests: XCTestCase {
8686
AssertParse(
8787
"""
8888
#file
89+
#fileID
8990
(#line)
9091
#column
9192
#function

Tests/SwiftParserTest/LexerTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ public class LexerTests: XCTestCase {
130130
0xff.0p2
131131
-0xff.0p2
132132
+0xff.0p2
133+
0x1.921fb4p1
133134
"""
134135
data.withUTF8 { buf in
135136
let lexemes = Lexer.lex(buf)
@@ -146,6 +147,7 @@ public class LexerTests: XCTestCase {
146147
lexeme(.floatingLiteral, "0xff.0p2"),
147148
lexeme(.prefixOperator, "\n+", leading: 1),
148149
lexeme(.floatingLiteral, "0xff.0p2"),
150+
lexeme(.floatingLiteral, "\n0x1.921fb4p1", leading: 1),
149151
lexeme(.eof, ""),
150152
])
151153
}
@@ -347,6 +349,13 @@ public class LexerTests: XCTestCase {
347349
lexeme(.pound, "#"),
348350
lexeme(.eof, ""),
349351
]),
352+
("/a)/", [
353+
lexeme(.prefixOperator, "/"),
354+
lexeme(.identifier, "a"),
355+
lexeme(.rightParen, ")"),
356+
lexeme(.postfixOperator, "/"),
357+
lexeme(.eof, ""),
358+
]),
350359
]
351360
for (fixture, expectation) in fixtures {
352361
var fixture = fixture

0 commit comments

Comments
 (0)