Skip to content

Commit 02f166b

Browse files
committed
Create test case testFreestandingMacroExpansion
1 parent 1d5f66e commit 02f166b

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

Tests/SourceKitLSPTests/ExecuteCommandTests.swift

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,95 @@ final class ExecuteCommandTests: XCTestCase {
136136
)
137137
}
138138

139+
func testFreestandingMacroExpansion() async throws {
140+
try await SkipUnless.canBuildMacroUsingSwiftSyntaxFromSourceKitLSPBuild()
141+
142+
let project = try await SwiftPMTestProject(
143+
files: [
144+
"MyMacros/MyMacros.swift": #"""
145+
import SwiftCompilerPlugin
146+
import SwiftSyntax
147+
import SwiftSyntaxBuilder
148+
import SwiftSyntaxMacros
149+
150+
public struct StringifyMacro: ExpressionMacro {
151+
public static func expansion(
152+
of node: some FreestandingMacroExpansionSyntax,
153+
in context: some MacroExpansionContext
154+
) -> ExprSyntax {
155+
guard let argument = node.argumentList.first?.expression else {
156+
fatalError("compiler bug: the macro does not have any arguments")
157+
}
158+
159+
return "(\(argument), \(literal: argument.description))"
160+
}
161+
}
162+
163+
@main
164+
struct MyMacroPlugin: CompilerPlugin {
165+
let providingMacros: [Macro.Type] = [
166+
StringifyMacro.self,
167+
]
168+
}
169+
"""#,
170+
"MyMacroClient/MyMacroClient.swift": """
171+
@freestanding(expression)
172+
public macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MyMacros", type: "StringifyMacro")
173+
174+
func test() {
175+
1️⃣#stringify2️⃣(1 + 2)
176+
}
177+
""",
178+
],
179+
manifest: SwiftPMTestProject.macroPackageManifest
180+
)
181+
try await SwiftPMTestProject.build(at: project.scratchDirectory)
182+
183+
let (uri, positions) = try project.openDocument("MyMacroClient.swift")
184+
185+
let args = ExpandMacroCommand(
186+
positionRange: positions["1️⃣"]..<positions["2️⃣"],
187+
textDocument: TextDocumentIdentifier(uri)
188+
)
189+
190+
let metadata = SourceKitLSPCommandMetadata(textDocument: TextDocumentIdentifier(uri))
191+
192+
var command = try args.asCommand()
193+
command.arguments?.append(metadata.encodeToLSPAny())
194+
195+
let request = ExecuteCommandRequest(command: command.command, arguments: command.arguments)
196+
197+
project.testClient.handleSingleRequest { (req: ShowDocumentRequest) -> ShowDocumentResponse in
198+
return ShowDocumentResponse(success: true)
199+
}
200+
201+
let result = try await project.testClient.send(request)
202+
203+
guard let resultArray: [MacroExpansionEdit] = Array(fromLSPArray: result ?? .null) else {
204+
XCTFail("Result is not an array.")
205+
return
206+
}
207+
208+
XCTAssertEqual(resultArray.count, 1)
209+
XCTAssertEqual(resultArray[0].newText, "(1 + 2, \"1 + 2\")")
210+
211+
let generatedMacroExpansionsPath = SourceKitLSPServer.Options.testDefault.generatedMacroExpansionsPath
212+
213+
XCTAssert(
214+
(try? generatedMacroExpansionsPath.appending(component: resultArray[0].bufferName).asURL
215+
.checkResourceIsReachable()) ?? false
216+
)
217+
218+
let fileContents = try XCTUnwrap(
219+
try? String(
220+
contentsOf: generatedMacroExpansionsPath.appending(component: resultArray[0].bufferName).asURL,
221+
encoding: .utf8
222+
)
223+
)
224+
225+
XCTAssertTrue(fileContents.contains("(1 + 2, \"1 + 2\")"))
226+
}
227+
139228
func testLSPCommandMetadataRetrieval() {
140229
var req = ExecuteCommandRequest(command: "", arguments: nil)
141230
XCTAssertNil(req.metadata)

0 commit comments

Comments
 (0)