Skip to content

Commit 7be636b

Browse files
authored
Merge pull request #1740 from bnbarham/cherry-code-item-parse
2 parents dd22ee8 + 862d810 commit 7be636b

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public let COMMON_NODES: [Node] = [
2626
nameForDiagnostics: nil,
2727
description: "A CodeBlockItem is any Syntax node that appears on its own line inside a CodeBlock.",
2828
kind: "Syntax",
29+
parserFunction: "parseNonOptionalCodeBlockItem",
2930
children: [
3031
Child(
3132
name: "Item",

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,22 @@ let parserEntryFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
100100
}
101101
"""
102102
)
103+
104+
DeclSyntax(
105+
"""
106+
mutating func parseNonOptionalCodeBlockItem() -> RawCodeBlockItemSyntax {
107+
guard let node = self.parseCodeBlockItem(isAtTopLevel: false, allowInitDecl: true) else {
108+
// The missing item is not neccessary to be a declaration,
109+
// which is just a placeholder here
110+
return RawCodeBlockItemSyntax(
111+
item: .decl(RawDeclSyntax(RawMissingDeclSyntax(attributes: nil, modifiers: nil, arena: self.arena))),
112+
semicolon: nil,
113+
arena: self.arena
114+
)
115+
}
116+
return node
117+
}
118+
"""
119+
)
103120
}
104121
}

Sources/SwiftParser/generated/Parser+Entry.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ extension ClosureParameterSyntax: SyntaxParseable {
7373
}
7474
}
7575

76+
extension CodeBlockItemSyntax: SyntaxParseable {
77+
public static func parse(from parser: inout Parser) -> Self {
78+
let node = parser.parseNonOptionalCodeBlockItem()
79+
let raw = RawSyntax(parser.parseRemainder(into: node))
80+
return Syntax(raw: raw).cast(Self.self)
81+
}
82+
}
83+
7684
extension DeclSyntax: SyntaxParseable {
7785
public static func parse(from parser: inout Parser) -> Self {
7886
let node = parser.parseDeclaration()
@@ -184,4 +192,17 @@ fileprivate extension Parser {
184192
let withUnexpected = layout.replacingChild(at: layout.children.count - 1, with: unexpected.raw, arena: self.arena)
185193
return R.init(withUnexpected)!
186194
}
195+
196+
mutating func parseNonOptionalCodeBlockItem() -> RawCodeBlockItemSyntax {
197+
guard let node = self.parseCodeBlockItem(isAtTopLevel: false, allowInitDecl: true) else {
198+
// The missing item is not neccessary to be a declaration,
199+
// which is just a placeholder here
200+
return RawCodeBlockItemSyntax(
201+
item: .decl(RawDeclSyntax(RawMissingDeclSyntax(attributes: nil, modifiers: nil, arena: self.arena))),
202+
semicolon: nil,
203+
arena: self.arena
204+
)
205+
}
206+
return node
207+
}
187208
}

Sources/SwiftSyntaxBuilder/generated/SyntaxExpressibleByStringInterpolationConformances.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ extension CatchClauseSyntax: SyntaxExpressibleByStringInterpolation {}
3434

3535
extension ClosureParameterSyntax: SyntaxExpressibleByStringInterpolation {}
3636

37+
extension CodeBlockItemSyntax: SyntaxExpressibleByStringInterpolation {}
38+
3739
extension DeclSyntax: SyntaxExpressibleByStringInterpolation {}
3840

3941
extension EnumCaseParameterSyntax: SyntaxExpressibleByStringInterpolation {}

Tests/SwiftSyntaxBuilderTest/CollectionNodeFlatteningTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,19 @@ final class CollectionNodeFlatteningTests: XCTestCase {
4444
"""
4545
)
4646
}
47+
48+
func test_FlattenCodeBlockItemListWithCodeBlockItemStrings() {
49+
let buildable = CodeBlockItemListSyntax {
50+
"let one = object.methodOne()"
51+
"let two = object.methodTwo()"
52+
}
53+
54+
assertBuildResult(
55+
buildable,
56+
"""
57+
let one = object.methodOne()
58+
let two = object.methodTwo()
59+
"""
60+
)
61+
}
4762
}

Tests/SwiftSyntaxBuilderTest/StringInterpolationTests.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,26 @@ final class StringInterpolationTests: XCTestCase {
408408
)
409409
}
410410

411+
func testCodeBlockItemInterpolation() {
412+
let codeBlockItem: CodeBlockItemSyntax =
413+
"""
414+
func foo() {
415+
return bar
416+
}
417+
"""
418+
419+
XCTAssertTrue(codeBlockItem.is(CodeBlockItemSyntax.self))
420+
assertStringsEqualWithDiff(
421+
codeBlockItem.description,
422+
"""
423+
func foo() {
424+
return bar
425+
}
426+
"""
427+
)
428+
429+
}
430+
411431
func testInvalidTrivia() {
412432
let invalid = Trivia("/*comment*/ invalid /*comm*/")
413433
XCTAssertEqual(invalid, [.blockComment("/*comment*/"), .spaces(1), .unexpectedText("invalid"), .spaces(1), .blockComment("/*comm*/")])
@@ -460,4 +480,21 @@ final class StringInterpolationTests: XCTestCase {
460480
)
461481
}
462482
}
483+
484+
func testInvalidSyntax3() {
485+
let invalid: CodeBlockItemSyntax = " "
486+
487+
XCTAssert(invalid.hasError)
488+
XCTAssertThrowsError(try CodeBlockItemSyntax(validating: " ")) { error in
489+
assertStringsEqualWithDiff(
490+
String(describing: error),
491+
"""
492+
493+
1 │
494+
│ ╰─ error: expected declaration
495+
496+
"""
497+
)
498+
}
499+
}
463500
}

0 commit comments

Comments
 (0)