Skip to content

Commit 0df94f1

Browse files
committed
[ASTGen] Fix end location of TopLevelCodeDecl
TopLevelCodeDecl::getEndLoc() should return the token location of the last token. If the last token is a string literal or a regex literal, it should be the location of the literal token.
1 parent 23b721f commit 0df94f1

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

lib/ASTGen/Sources/ASTGen/ASTGen.swift

+17-2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,21 @@ struct ASTGenVisitor {
110110
split: Self.splitCodeBlockItemIfConfig
111111
) { element in
112112
let loc = self.generateSourceLoc(element)
113+
114+
func endLoc() -> BridgedSourceLoc {
115+
if let endTok = element.lastToken(viewMode: .sourceAccurate) {
116+
switch endTok.parent?.kind {
117+
case .stringLiteralExpr, .regexLiteralExpr:
118+
// string/regex literal are single token in AST.
119+
return self.generateSourceLoc(endTok.parent)
120+
default:
121+
return self.generateSourceLoc(endTok)
122+
}
123+
} else {
124+
return loc
125+
}
126+
}
127+
113128
let swiftASTNodes = generate(codeBlockItem: element)
114129
switch swiftASTNodes {
115130
case .decl(let d):
@@ -120,7 +135,7 @@ struct ASTGenVisitor {
120135
declContext: self.declContext,
121136
startLoc: loc,
122137
stmt: s,
123-
endLoc: loc
138+
endLoc: endLoc()
124139
)
125140
out.append(topLevelDecl.asDecl)
126141
case .expr(let e):
@@ -129,7 +144,7 @@ struct ASTGenVisitor {
129144
declContext: self.declContext,
130145
startLoc: loc,
131146
expr: e,
132-
endLoc: loc
147+
endLoc: endLoc()
133148
)
134149
out.append(topLevelDecl.asDecl)
135150
}

test/ASTGen/top_level.swift

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-experimental-move-only -enable-experimental-feature ParserASTGen > %t/astgen.ast.raw
3+
// RUN: %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-experimental-move-only > %t/cpp-parser.ast.raw
4+
5+
// Filter out any addresses in the dump, since they can differ.
6+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/cpp-parser.ast.raw > %t/cpp-parser.ast
7+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/astgen.ast.raw > %t/astgen.ast
8+
9+
// RUN: %diff -u %t/astgen.ast %t/cpp-parser.ast
10+
11+
// -enable-experimental-feature requires an asserts build
12+
// REQUIRES: asserts
13+
// rdar://116686158
14+
// UNSUPPORTED: asan
15+
16+
_ = ##"foo bar"##
17+
_ = ##/foo bar/##
18+
19+
if let first = [1,2,3].first {
20+
foo(x: first)
21+
}
22+
23+
func foo(x: Int) {}
24+
25+
// FIXME: Top-level pattern binding decl must be enclosed with TopLevelCodeDecl
26+
// let a = 42

0 commit comments

Comments
 (0)