Skip to content

Commit b05cd4e

Browse files
committed
InitAccessors: Parse initializer exprs associated with computed properties that have init accessor
Initialization expressions are not allowed on computed properties but if a property has `init` accessor it should be allowed because it could be used by a memberwise initializer.
1 parent ee21d9c commit b05cd4e

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

Sources/SwiftParser/Lookahead.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ extension Parser.Lookahead {
254254
// If we have a 'didSet' or a 'willSet' label, disambiguate immediately as
255255
// an accessor block.
256256
let nextToken = self.peek()
257-
if TokenSpec(.didSet) ~= nextToken || TokenSpec(.willSet) ~= nextToken {
257+
if TokenSpec(.didSet) ~= nextToken || TokenSpec(.willSet) ~= nextToken || TokenSpec(.`init`) ~= nextToken {
258258
return true
259259
}
260260

@@ -278,8 +278,8 @@ extension Parser.Lookahead {
278278
}
279279
}
280280

281-
// Check if we have 'didSet'/'willSet' after attributes.
282-
return lookahead.at(.keyword(.didSet), .keyword(.willSet))
281+
// Check if we have 'didSet'/'willSet' or 'init' after attributes.
282+
return lookahead.at(.keyword(.didSet), .keyword(.willSet), .keyword(.`init`))
283283
}
284284
}
285285

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,4 +2540,82 @@ final class DeclarationTests: XCTestCase {
25402540
fixedSource: "let foo: [Int] = []"
25412541
)
25422542
}
2543+
2544+
func testInitAccessorsWithDefaultValues() {
2545+
assertParse(
2546+
"""
2547+
struct Test {
2548+
var pair: (Int, Int) = (42, 0) {
2549+
init(initialValue) {}
2550+
2551+
get { (0, 42) }
2552+
set { }
2553+
}
2554+
}
2555+
"""
2556+
)
2557+
2558+
assertParse(
2559+
"""
2560+
struct Test {
2561+
var pair: (Int, Int) = (42, 0) {
2562+
init initializes(a) {}
2563+
2564+
get { (0, 42) }
2565+
set { }
2566+
}
2567+
}
2568+
"""
2569+
)
2570+
2571+
assertParse(
2572+
"""
2573+
struct Test {
2574+
var pair: (Int, Int) = (42, 0) {
2575+
get { (0, 42) }
2576+
set { }
2577+
2578+
init(initialValue1️⃣) {}
2579+
}
2580+
}
2581+
""",
2582+
substructure: Syntax(
2583+
InitializerDeclSyntax(
2584+
initKeyword: .keyword(.`init`),
2585+
signature: FunctionSignatureSyntax(
2586+
input: ParameterClauseSyntax(
2587+
leftParen: .leftParenToken(),
2588+
parameterList: FunctionParameterListSyntax([
2589+
FunctionParameterSyntax(
2590+
firstName: .identifier("initialValue"),
2591+
colon: .colonToken(presence: .missing),
2592+
type: TypeSyntax(MissingTypeSyntax(placeholder: .identifier("<#type#>", presence: .missing)))
2593+
)
2594+
]),
2595+
rightParen: .rightParenToken(trailingTrivia: .space)
2596+
)
2597+
),
2598+
body: CodeBlockSyntax(
2599+
leftBrace: .leftBraceToken(),
2600+
statements: CodeBlockItemListSyntax([]),
2601+
rightBrace: .rightBraceToken()
2602+
)
2603+
)
2604+
),
2605+
diagnostics: [
2606+
DiagnosticSpec(message: "expected ':' and type in parameter", fixIts: ["insert ':' and type"])
2607+
],
2608+
fixedSource:
2609+
"""
2610+
struct Test {
2611+
var pair: (Int, Int) = (42, 0) {
2612+
get { (0, 42) }
2613+
set { }
2614+
2615+
init(initialValue: <#type#>) {}
2616+
}
2617+
}
2618+
"""
2619+
)
2620+
}
25432621
}

0 commit comments

Comments
 (0)