Skip to content

Commit 1066b7f

Browse files
committed
[SwiftParser] Ignore '(' on newline after attribute name
Some builtin attributes mistakingly accepted '(' on newline, while custom attribute didn't. For consistency, ignore '(' on next line.
1 parent 7b1fcd6 commit 1066b7f

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ extension Parser {
167167
self.withLookahead { $0.atAttributeOrSpecifierArgument() }
168168
&& self.at(TokenSpec(.leftParen, allowAtStartOfLine: false))
169169
case .optional:
170-
shouldParseArgument = self.at(.leftParen)
170+
shouldParseArgument = self.at(TokenSpec(.leftParen, allowAtStartOfLine: false))
171171
case .noArgument:
172172
shouldParseArgument = false
173173
}
174174
if shouldParseArgument {
175-
var (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
175+
var (unexpectedBeforeLeftParen, leftParen) = self.expect(TokenSpec(.leftParen, allowAtStartOfLine: false))
176176
if unexpectedBeforeLeftParen == nil
177177
&& (attributeName.raw.trailingTriviaByteLength > 0 || leftParen.leadingTriviaByteLength > 0)
178178
{

Sources/SwiftParser/Directives.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ extension Parser {
213213
/// Parse a line control directive.
214214
mutating func parsePoundSourceLocationDirective() -> RawPoundSourceLocationSyntax {
215215
let line = self.consumeAnyToken()
216-
let (unexpectedBeforeLParen, lparen) = self.expect(.leftParen)
216+
let (unexpectedBeforeLParen, lparen) = self.expect(TokenSpec(.leftParen, allowAtStartOfLine: false))
217217
let arguments: RawPoundSourceLocationArgumentsSyntax?
218218
if !self.at(.rightParen) {
219219
let (unexpectedBeforeFile, file) = self.expect(.keyword(.file))

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,21 @@ final class AttributeTests: ParserTestCase {
201201
)
202202
}
203203

204+
func testObjCAttributeNewlineParen() {
205+
assertParse(
206+
"""
207+
@objc
208+
1️⃣(foo) func foo()
209+
""",
210+
diagnostics: [
211+
DiagnosticSpec(
212+
locationMarker: "1️⃣",
213+
message: "unexpected code '(foo)' in function"
214+
)
215+
]
216+
)
217+
}
218+
204219
func testRethrowsAttribute() {
205220
assertParse(
206221
"""

Tests/SwiftParserTest/AvailabilityTests.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,33 @@ final class AvailabilityTests: ParserTestCase {
204204
]
205205
)
206206
}
207+
208+
func testAvailableNewlineParen() {
209+
assertParse(
210+
"""
211+
@available1️⃣
212+
2️⃣(*, unavailable) func foo() {}
213+
""",
214+
diagnostics: [
215+
DiagnosticSpec(
216+
locationMarker: "1️⃣",
217+
message: "expected '()' in attribute",
218+
fixIts: ["insert '()'"]
219+
),
220+
DiagnosticSpec(
221+
locationMarker: "1️⃣",
222+
message: "expected argument for '@available' attribute",
223+
fixIts: ["insert attribute argument"]
224+
),
225+
DiagnosticSpec(
226+
locationMarker: "2️⃣",
227+
message: "unexpected code '(*, unavailable)' in function"
228+
),
229+
],
230+
fixedSource: """
231+
@available()
232+
(*, unavailable) func foo() {}
233+
"""
234+
)
235+
}
207236
}

0 commit comments

Comments
 (0)