11
11
//===----------------------------------------------------------------------===//
12
12
13
13
import SwiftSyntax
14
+ import SwiftParser
15
+ #if canImport(_CompilerPluginSupport)
16
+ import _CompilerPluginSupport
17
+ #endif
14
18
15
19
/// Describes a macro that is explicitly expanded as an expression.
16
20
public protocol ExpressionMacro : Macro {
@@ -20,3 +24,56 @@ public protocol ExpressionMacro: Macro {
20
24
_ macro: MacroExpansionExprSyntax , in context: MacroEvaluationContext
21
25
) -> MacroResult < ExprSyntax >
22
26
}
27
+
28
+ #if canImport(_CompilerPluginSupport)
29
+ extension ExpressionMacro {
30
+ public static func _kind( ) -> _CompilerPluginKind {
31
+ . expressionMacro
32
+ }
33
+
34
+ public static func _rewrite(
35
+ targetModuleName: UnsafePointer < UInt8 > ,
36
+ targetModuleNameCount: Int ,
37
+ filePath: UnsafePointer < UInt8 > ,
38
+ filePathCount: Int ,
39
+ sourceFileText: UnsafePointer < UInt8 > ,
40
+ sourceFileTextCount: Int ,
41
+ localSourceText: UnsafePointer < UInt8 > ,
42
+ localSourceTextCount: Int
43
+ ) -> ( UnsafePointer < UInt8 > ? , count: Int ) {
44
+ let targetModuleNameBuffer = UnsafeBufferPointer (
45
+ start: filePath, count: targetModuleNameCount)
46
+ let targetModuleName = String (
47
+ decoding: targetModuleNameBuffer, as: UTF8 . self)
48
+ let filePathBuffer = UnsafeBufferPointer (
49
+ start: filePath, count: filePathCount)
50
+ let filePath = String ( decoding: filePathBuffer, as: UTF8 . self)
51
+ let sourceFileTextBuffer = UnsafeBufferPointer (
52
+ start: sourceFileText, count: sourceFileTextCount)
53
+ let sourceFileString = String ( decoding: sourceFileTextBuffer, as: UTF8 . self)
54
+ let sourceFileSyntax = Parser . parse ( source: sourceFileString)
55
+ let converter = SourceLocationConverter (
56
+ file: filePath, tree: sourceFileSyntax)
57
+ let context = MacroEvaluationContext (
58
+ moduleName: targetModuleName, sourceLocationConverter: converter)
59
+ let meePosition = AbsolutePosition (
60
+ utf8Offset: localSourceText. distance ( to: localSourceText) )
61
+ guard let meeStartToken = sourceFileSyntax. token ( at: meePosition) ,
62
+ let mee = meeStartToken. parent? . as ( MacroExpansionExprSyntax . self)
63
+ else {
64
+ fatalError ( " Unable to locate 'MacroExpansionExprSyntax' " )
65
+ }
66
+
67
+ // Evaluate the macro.
68
+ let evalResult = apply ( mee, in: context)
69
+
70
+ var resultString = " \( evalResult. rewritten) "
71
+ return resultString. withUTF8 { buffer in
72
+ let result = UnsafeMutableBufferPointer< UInt8> . allocate(
73
+ capacity: buffer. count)
74
+ _ = result. initialize ( from: buffer)
75
+ return ( UnsafePointer ( result. baseAddress) , result. count)
76
+ }
77
+ }
78
+ }
79
+ #endif
0 commit comments