Skip to content

Commit 123ccc7

Browse files
authored
SwiftSyntax: add an API to check whether a syntax node has underlying source. (#15389)
1 parent c133e09 commit 123ccc7

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

test/SwiftSyntax/AbsolutePosition.swift

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,34 +101,45 @@ PositionTests.test("Recursion") {
101101
})
102102
}
103103

104-
PositionTests.test("Trivias") {
105-
expectDoesNotThrow({
106-
let leading = Trivia(pieces: [
104+
func createSourceFile(_ count: Int) -> SourceFileSyntax {
105+
let leading = Trivia(pieces: [
107106
.newlines(1),
108107
.backticks(1),
109108
.docLineComment("/// some comment")
110109
])
111-
let trailing = Trivia.docLineComment("/// This is comment\n")
112-
let idx = 5
113-
let items : [CodeBlockItemSyntax] =
114-
[CodeBlockItemSyntax](repeating: CodeBlockItemSyntax {
115-
$0.useItem(ReturnStmtSyntax {
116-
$0.useReturnKeyword(
117-
SyntaxFactory.makeReturnKeyword(
118-
leadingTrivia: leading,
119-
trailingTrivia: trailing))
120-
})}, count: idx + 1)
121-
let root = SyntaxFactory.makeSourceFile(
122-
statements: SyntaxFactory.makeCodeBlockItemList(items),
123-
eofToken: SyntaxFactory.makeToken(.eof, presence: .present))
110+
let trailing = Trivia.docLineComment("/// This is comment\n")
111+
let items : [CodeBlockItemSyntax] =
112+
[CodeBlockItemSyntax](repeating: CodeBlockItemSyntax {
113+
$0.useItem(ReturnStmtSyntax {
114+
$0.useReturnKeyword(
115+
SyntaxFactory.makeReturnKeyword(
116+
leadingTrivia: leading,
117+
trailingTrivia: trailing))
118+
})}, count: count)
119+
return SyntaxFactory.makeSourceFile(
120+
statements: SyntaxFactory.makeCodeBlockItemList(items),
121+
eofToken: SyntaxFactory.makeToken(.eof, presence: .present))
122+
}
124123

124+
PositionTests.test("Trivias") {
125+
expectDoesNotThrow({
126+
let idx = 5
127+
let root = createSourceFile(idx + 1)
125128
expectEqual(root.leadingTrivia!.count, 3)
126129
expectEqual(root.trailingTrivia!.count, 0)
127130
let state = root.statements[idx]
128131
expectEqual(state.leadingTrivia!.count, 3)
129132
expectEqual(state.trailingTrivia!.count, 1)
130133
expectEqual(state.leadingTrivia!.byteSize + state.trailingTrivia!.byteSize
131134
+ state.byteSizeAfterTrimmingTrivia, state.byteSize)
135+
expectFalse(root.statements.isImplicit)
136+
})
137+
}
138+
139+
PositionTests.test("Implicit") {
140+
expectDoesNotThrow({
141+
let root = createSourceFile(0)
142+
expectTrue(root.statements.isImplicit)
132143
})
133144
}
134145

tools/SwiftSyntax/Syntax.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ extension Syntax {
152152
return raw.trailingTrivia
153153
}
154154

155+
/// When isImplicit is true, the syntax node doesn't include any
156+
/// underlying tokens, e.g. an empty CodeBlockItemList.
157+
public var isImplicit: Bool {
158+
return leadingTrivia == nil
159+
}
160+
155161
/// The textual byte length of this node exluding leading and trailing trivia.
156162
public var byteSizeAfterTrimmingTrivia: Int {
157163
return data.byteSize - (leadingTrivia?.byteSize ?? 0) -

0 commit comments

Comments
 (0)