Skip to content

Commit e7e16ff

Browse files
authored
Merge pull request #16927 from nkcsgexi/parse-buffer
SwiftSourceKit: add API to generate a syntax tree from a given source buffer.
2 parents b7acd02 + d4b7406 commit e7e16ff

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

test/SwiftSyntax/ParseFile.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,13 @@ ParseFile.test("ParseSingleFile") {
3737
})
3838
}
3939

40+
ParseFile.test("ParseBuffer") {
41+
expectDoesNotThrow({
42+
let content = "func foo() {}"
43+
let parsed = try SourceFileSyntax.decodeSourceFileSyntax(try
44+
SwiftLang.parse(content))
45+
expectEqual("\(parsed)", content)
46+
})
47+
}
48+
4049
runAllTests()

tools/SourceKit/tools/swift-lang/SwiftLang.swift

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,64 @@
1414

1515
import Foundation
1616

17+
enum SourceKitdError: Error, CustomStringConvertible {
18+
case EditorOpenError(message: String)
19+
case EditorCloseError(message: String)
20+
21+
var description: String {
22+
switch self {
23+
case .EditorOpenError(let message):
24+
return "cannot open document: \(message)"
25+
case .EditorCloseError(let message):
26+
return "cannot close document: \(message)"
27+
}
28+
}
29+
}
30+
1731
public class SwiftLang {
1832

19-
/// Parses the Swift file at the provided URL into a `Syntax` tree in Json
20-
/// serialization format by querying SourceKitd service.
21-
/// - Parameter url: The URL you wish to parse.
22-
/// - Returns: The syntax tree in Json format string.
23-
public static func parse(_ url: URL) throws -> String {
33+
fileprivate static func parse(content: String, name: String, isURL: Bool) throws -> String {
2434
let Service = SourceKitdService()
2535
let Request = SourceKitdRequest(uid: .request_EditorOpen)
26-
let Path = url.path
27-
Request.addParameter(.key_SourceFile, value: Path)
28-
Request.addParameter(.key_Name, value: Path)
36+
if isURL {
37+
Request.addParameter(.key_SourceFile, value: content)
38+
} else {
39+
Request.addParameter(.key_SourceText, value: content)
40+
}
41+
Request.addParameter(.key_Name, value: name)
2942
Request.addParameter(.key_EnableSyntaxTree, value: 1)
43+
Request.addParameter(.key_SyntacticOnly, value: 1)
3044

3145
// FIXME: SourceKitd error handling.
3246
let Resp = Service.sendSyn(request: Request)
47+
if Resp.isError {
48+
throw SourceKitdError.EditorOpenError(message: Resp.description)
49+
}
50+
51+
let CloseReq = SourceKitdRequest(uid: .request_EditorClose)
52+
CloseReq.addParameter(.key_Name, value: name)
53+
let CloseResp = Service.sendSyn(request: CloseReq)
54+
if CloseResp.isError {
55+
throw SourceKitdError.EditorCloseError(message: CloseResp.description)
56+
}
3357
return Resp.value.getString(.key_SerializedSyntaxTree)
3458
}
35-
}
59+
60+
/// Parses the Swift file at the provided URL into a `Syntax` tree in Json
61+
/// serialization format by querying SourceKitd service. This function isn't
62+
/// thread safe.
63+
/// - Parameter url: The URL you wish to parse.
64+
/// - Returns: The syntax tree in Json format string.
65+
public static func parse(_ url: URL) throws -> String {
66+
let Path = url.path
67+
return try parse(content: Path, name: Path, isURL: true)
68+
}
69+
70+
/// Parses a given source buffer into a `Syntax` tree in Json serialization
71+
/// format by querying SourceKitd service. This function isn't thread safe.
72+
/// - Parameter source: The source buffer you wish to parse.
73+
/// - Returns: The syntax tree in Json format string.
74+
public static func parse(_ source: String) throws -> String {
75+
return try parse(content: source, name: "foo", isURL: false)
76+
}
77+
}

0 commit comments

Comments
 (0)