Skip to content

Commit b6bfbb2

Browse files
committed
Fix a crash when string interpolation creates a MissingStmtSyntax
We were crashing here because string interpolation created a `MissingStmtSyntax`, which doesn’t have any children. It then tried to assign the remaining tokens as unexpected tokens to the last child of the `MissingStmtSyntax`, which failed (because there are no children). The fix here is to just add an `unexpected` child to the missing nodes. I’ve got a gut feeling that that might be useful anyway.
1 parent 64cabae commit b6bfbb2

File tree

10 files changed

+270
-25
lines changed

10 files changed

+270
-25
lines changed

Sources/SwiftSyntax/Raw/gyb_generated/RawSyntaxNodes.swift

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,20 @@ public struct RawMissingSyntax: RawSyntaxNodeProtocol {
203203
}
204204

205205
public init(
206+
_ unexpected: RawUnexpectedNodesSyntax? = nil,
206207
arena: __shared SyntaxArena
207208
) {
208-
let raw = RawSyntax.makeEmptyLayout(kind: .missing, arena: arena)
209+
let raw = RawSyntax.makeLayout(
210+
kind: .missing, uninitializedCount: 1, arena: arena) { layout in
211+
layout.initialize(repeating: nil)
212+
layout[0] = unexpected?.raw
213+
}
209214
self.init(raw: raw)
210215
}
211216

217+
public var unexpected: RawUnexpectedNodesSyntax? {
218+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
219+
}
212220
}
213221

214222
@_spi(RawSyntax)
@@ -295,12 +303,20 @@ public struct RawMissingExprSyntax: RawExprSyntaxNodeProtocol {
295303
}
296304

297305
public init(
306+
_ unexpected: RawUnexpectedNodesSyntax? = nil,
298307
arena: __shared SyntaxArena
299308
) {
300-
let raw = RawSyntax.makeEmptyLayout(kind: .missingExpr, arena: arena)
309+
let raw = RawSyntax.makeLayout(
310+
kind: .missingExpr, uninitializedCount: 1, arena: arena) { layout in
311+
layout.initialize(repeating: nil)
312+
layout[0] = unexpected?.raw
313+
}
301314
self.init(raw: raw)
302315
}
303316

317+
public var unexpected: RawUnexpectedNodesSyntax? {
318+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
319+
}
304320
}
305321

306322
@_spi(RawSyntax)
@@ -327,12 +343,20 @@ public struct RawMissingStmtSyntax: RawStmtSyntaxNodeProtocol {
327343
}
328344

329345
public init(
346+
_ unexpected: RawUnexpectedNodesSyntax? = nil,
330347
arena: __shared SyntaxArena
331348
) {
332-
let raw = RawSyntax.makeEmptyLayout(kind: .missingStmt, arena: arena)
349+
let raw = RawSyntax.makeLayout(
350+
kind: .missingStmt, uninitializedCount: 1, arena: arena) { layout in
351+
layout.initialize(repeating: nil)
352+
layout[0] = unexpected?.raw
353+
}
333354
self.init(raw: raw)
334355
}
335356

357+
public var unexpected: RawUnexpectedNodesSyntax? {
358+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
359+
}
336360
}
337361

338362
@_spi(RawSyntax)
@@ -359,12 +383,20 @@ public struct RawMissingTypeSyntax: RawTypeSyntaxNodeProtocol {
359383
}
360384

361385
public init(
386+
_ unexpected: RawUnexpectedNodesSyntax? = nil,
362387
arena: __shared SyntaxArena
363388
) {
364-
let raw = RawSyntax.makeEmptyLayout(kind: .missingType, arena: arena)
389+
let raw = RawSyntax.makeLayout(
390+
kind: .missingType, uninitializedCount: 1, arena: arena) { layout in
391+
layout.initialize(repeating: nil)
392+
layout[0] = unexpected?.raw
393+
}
365394
self.init(raw: raw)
366395
}
367396

397+
public var unexpected: RawUnexpectedNodesSyntax? {
398+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
399+
}
368400
}
369401

370402
@_spi(RawSyntax)
@@ -391,12 +423,20 @@ public struct RawMissingPatternSyntax: RawPatternSyntaxNodeProtocol {
391423
}
392424

393425
public init(
426+
_ unexpected: RawUnexpectedNodesSyntax? = nil,
394427
arena: __shared SyntaxArena
395428
) {
396-
let raw = RawSyntax.makeEmptyLayout(kind: .missingPattern, arena: arena)
429+
let raw = RawSyntax.makeLayout(
430+
kind: .missingPattern, uninitializedCount: 1, arena: arena) { layout in
431+
layout.initialize(repeating: nil)
432+
layout[0] = unexpected?.raw
433+
}
397434
self.init(raw: raw)
398435
}
399436

437+
public var unexpected: RawUnexpectedNodesSyntax? {
438+
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
439+
}
400440
}
401441

402442
@_spi(RawSyntax)

Sources/SwiftSyntax/Raw/gyb_generated/RawSyntaxValidation.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
8888
case .token:
8989
assertionFailure("validateLayout for .token kind is not supported")
9090
case .missing:
91-
assert(layout.count == 0)
91+
assert(layout.count == 1)
92+
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
9293
break
9394
case .missingDecl:
9495
assert(layout.count == 5)
@@ -99,16 +100,20 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
99100
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
100101
break
101102
case .missingExpr:
102-
assert(layout.count == 0)
103+
assert(layout.count == 1)
104+
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
103105
break
104106
case .missingStmt:
105-
assert(layout.count == 0)
107+
assert(layout.count == 1)
108+
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
106109
break
107110
case .missingType:
108-
assert(layout.count == 0)
111+
assert(layout.count == 1)
112+
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
109113
break
110114
case .missingPattern:
111-
assert(layout.count == 0)
115+
assert(layout.count == 1)
116+
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
112117
break
113118
case .codeBlockItem:
114119
assert(layout.count == 5)

Sources/SwiftSyntax/gyb_generated/SyntaxFactory.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,25 @@ public enum SyntaxFactory {
4141

4242

4343

44+
@available(*, deprecated, message: "Use initializer on MissingSyntax")
45+
public static func makeMissing(_ unexpected: UnexpectedNodesSyntax? = nil) -> MissingSyntax {
46+
let layout: [RawSyntax?] = [
47+
unexpected?.raw,
48+
]
49+
return withExtendedLifetime(SyntaxArena()) { arena in
50+
let raw = RawSyntax.makeLayout(kind: SyntaxKind.missing,
51+
from: layout, arena: arena)
52+
let data = SyntaxData.forRoot(raw)
53+
return MissingSyntax(data)
54+
}
55+
}
4456

4557
@available(*, deprecated, message: "Use initializer on MissingSyntax")
4658
public static func makeBlankMissing(presence: SourcePresence = .missing) -> MissingSyntax {
4759
return withExtendedLifetime(SyntaxArena()) { arena in
4860
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .missing,
4961
from: [
62+
nil,
5063
], arena: arena))
5164
return MissingSyntax(data)
5265
}
@@ -82,42 +95,94 @@ public enum SyntaxFactory {
8295
return MissingDeclSyntax(data)
8396
}
8497
}
98+
@available(*, deprecated, message: "Use initializer on MissingExprSyntax")
99+
public static func makeMissingExpr(_ unexpected: UnexpectedNodesSyntax? = nil) -> MissingExprSyntax {
100+
let layout: [RawSyntax?] = [
101+
unexpected?.raw,
102+
]
103+
return withExtendedLifetime(SyntaxArena()) { arena in
104+
let raw = RawSyntax.makeLayout(kind: SyntaxKind.missingExpr,
105+
from: layout, arena: arena)
106+
let data = SyntaxData.forRoot(raw)
107+
return MissingExprSyntax(data)
108+
}
109+
}
85110

86111
@available(*, deprecated, message: "Use initializer on MissingExprSyntax")
87112
public static func makeBlankMissingExpr(presence: SourcePresence = .missing) -> MissingExprSyntax {
88113
return withExtendedLifetime(SyntaxArena()) { arena in
89114
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .missingExpr,
90115
from: [
116+
nil,
91117
], arena: arena))
92118
return MissingExprSyntax(data)
93119
}
94120
}
121+
@available(*, deprecated, message: "Use initializer on MissingStmtSyntax")
122+
public static func makeMissingStmt(_ unexpected: UnexpectedNodesSyntax? = nil) -> MissingStmtSyntax {
123+
let layout: [RawSyntax?] = [
124+
unexpected?.raw,
125+
]
126+
return withExtendedLifetime(SyntaxArena()) { arena in
127+
let raw = RawSyntax.makeLayout(kind: SyntaxKind.missingStmt,
128+
from: layout, arena: arena)
129+
let data = SyntaxData.forRoot(raw)
130+
return MissingStmtSyntax(data)
131+
}
132+
}
95133

96134
@available(*, deprecated, message: "Use initializer on MissingStmtSyntax")
97135
public static func makeBlankMissingStmt(presence: SourcePresence = .missing) -> MissingStmtSyntax {
98136
return withExtendedLifetime(SyntaxArena()) { arena in
99137
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .missingStmt,
100138
from: [
139+
nil,
101140
], arena: arena))
102141
return MissingStmtSyntax(data)
103142
}
104143
}
144+
@available(*, deprecated, message: "Use initializer on MissingTypeSyntax")
145+
public static func makeMissingType(_ unexpected: UnexpectedNodesSyntax? = nil) -> MissingTypeSyntax {
146+
let layout: [RawSyntax?] = [
147+
unexpected?.raw,
148+
]
149+
return withExtendedLifetime(SyntaxArena()) { arena in
150+
let raw = RawSyntax.makeLayout(kind: SyntaxKind.missingType,
151+
from: layout, arena: arena)
152+
let data = SyntaxData.forRoot(raw)
153+
return MissingTypeSyntax(data)
154+
}
155+
}
105156

106157
@available(*, deprecated, message: "Use initializer on MissingTypeSyntax")
107158
public static func makeBlankMissingType(presence: SourcePresence = .missing) -> MissingTypeSyntax {
108159
return withExtendedLifetime(SyntaxArena()) { arena in
109160
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .missingType,
110161
from: [
162+
nil,
111163
], arena: arena))
112164
return MissingTypeSyntax(data)
113165
}
114166
}
167+
@available(*, deprecated, message: "Use initializer on MissingPatternSyntax")
168+
public static func makeMissingPattern(_ unexpected: UnexpectedNodesSyntax? = nil) -> MissingPatternSyntax {
169+
let layout: [RawSyntax?] = [
170+
unexpected?.raw,
171+
]
172+
return withExtendedLifetime(SyntaxArena()) { arena in
173+
let raw = RawSyntax.makeLayout(kind: SyntaxKind.missingPattern,
174+
from: layout, arena: arena)
175+
let data = SyntaxData.forRoot(raw)
176+
return MissingPatternSyntax(data)
177+
}
178+
}
115179

116180
@available(*, deprecated, message: "Use initializer on MissingPatternSyntax")
117181
public static func makeBlankMissingPattern(presence: SourcePresence = .missing) -> MissingPatternSyntax {
118182
return withExtendedLifetime(SyntaxArena()) { arena in
119183
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .missingPattern,
120184
from: [
185+
nil,
121186
], arena: arena))
122187
return MissingPatternSyntax(data)
123188
}

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxExprNodes.swift

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,44 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
3131
self._syntaxNode = Syntax(data)
3232
}
3333

34-
public init() {
34+
public init(
35+
leadingTrivia: Trivia? = nil,
36+
_ unexpected: UnexpectedNodesSyntax? = nil,
37+
trailingTrivia: Trivia? = nil
38+
) {
3539
// Extend the lifetime of all parameters so their arenas don't get destroyed
3640
// before they can be added as children of the new arena.
37-
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ())) { (arena, _) in
38-
let raw = RawSyntax.makeEmptyLayout(kind: SyntaxKind.missingExpr, arena: arena)
41+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpected))) { (arena, _) in
42+
let layout: [RawSyntax?] = [
43+
unexpected?.raw,
44+
]
45+
let raw = RawSyntax.makeLayout(
46+
kind: SyntaxKind.missingExpr, from: layout, arena: arena,
47+
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
3948
return SyntaxData.forRoot(raw)
4049
}
4150
self.init(data)
4251
}
4352

53+
public var unexpected: UnexpectedNodesSyntax? {
54+
get {
55+
return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
56+
}
57+
set(value) {
58+
self = MissingExprSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena()))
59+
}
60+
}
61+
4462
public static var structure: SyntaxNodeStructure {
4563
return .layout([
64+
\Self.unexpected,
4665
])
4766
}
4867

4968
public func childNameForDiagnostics(_ index: SyntaxChildrenIndex) -> String? {
5069
switch index.data?.indexInParent {
70+
case 0:
71+
return nil
5172
default:
5273
fatalError("Invalid index")
5374
}
@@ -57,6 +78,7 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
5778
extension MissingExprSyntax: CustomReflectable {
5879
public var customMirror: Mirror {
5980
return Mirror(self, children: [
81+
"unexpected": unexpected.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
6082
])
6183
}
6284
}

Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxNodes.swift

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,44 @@ public struct MissingSyntax: SyntaxProtocol, SyntaxHashable {
3131
self._syntaxNode = Syntax(data)
3232
}
3333

34-
public init() {
34+
public init(
35+
leadingTrivia: Trivia? = nil,
36+
_ unexpected: UnexpectedNodesSyntax? = nil,
37+
trailingTrivia: Trivia? = nil
38+
) {
3539
// Extend the lifetime of all parameters so their arenas don't get destroyed
3640
// before they can be added as children of the new arena.
37-
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ())) { (arena, _) in
38-
let raw = RawSyntax.makeEmptyLayout(kind: SyntaxKind.missing, arena: arena)
41+
let data: SyntaxData = withExtendedLifetime((SyntaxArena(), (unexpected))) { (arena, _) in
42+
let layout: [RawSyntax?] = [
43+
unexpected?.raw,
44+
]
45+
let raw = RawSyntax.makeLayout(
46+
kind: SyntaxKind.missing, from: layout, arena: arena,
47+
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia)
3948
return SyntaxData.forRoot(raw)
4049
}
4150
self.init(data)
4251
}
4352

53+
public var unexpected: UnexpectedNodesSyntax? {
54+
get {
55+
return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init)
56+
}
57+
set(value) {
58+
self = MissingSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena()))
59+
}
60+
}
61+
4462
public static var structure: SyntaxNodeStructure {
4563
return .layout([
64+
\Self.unexpected,
4665
])
4766
}
4867

4968
public func childNameForDiagnostics(_ index: SyntaxChildrenIndex) -> String? {
5069
switch index.data?.indexInParent {
70+
case 0:
71+
return nil
5172
default:
5273
fatalError("Invalid index")
5374
}
@@ -57,6 +78,7 @@ public struct MissingSyntax: SyntaxProtocol, SyntaxHashable {
5778
extension MissingSyntax: CustomReflectable {
5879
public var customMirror: Mirror {
5980
return Mirror(self, children: [
81+
"unexpected": unexpected.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
6082
])
6183
}
6284
}

0 commit comments

Comments
 (0)