Skip to content

[Macros] Use 'LibraryPluginProvider' in swift-plugin-server #69236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/Macros/macro_plugin_server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func testStringify(a: Int, b: Int) {
let s3: String = #stringify(b + a).1
print(s3)

// expected-error @+1 {{macro implementation type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '}}
// expected-error @+1 {{type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '}}
_ = #missing()

// expected-error @+1 {{type 'MacroDefinition.NotMacroStruct' is not a valid macro implementation type in library plugin '}}
Expand Down
21 changes: 1 addition & 20 deletions tools/swift-plugin-server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
if (SWIFT_BUILD_SWIFT_SYNTAX)
# _swiftCSwiftPluginServer is just a C support library for swift-plugin-server
# Don't bother to create '.a' for that.
add_swift_host_library(_swiftCSwiftPluginServer STATIC
Sources/CSwiftPluginServer/PluginServer.cpp
LLVM_LINK_COMPONENTS support
)
target_link_libraries(_swiftCSwiftPluginServer PRIVATE
swiftDemangling
)
target_include_directories(_swiftCSwiftPluginServer PUBLIC
Sources/CSwiftPluginServer/include
)

add_pure_swift_host_tool(swift-plugin-server
Sources/swift-plugin-server/swift-plugin-server.swift
DEPENDENCIES
_swiftCSwiftPluginServer
SWIFT_COMPONENT
compiler
SWIFT_DEPENDENCIES
SwiftSyntaxMacros
SwiftSyntaxMacroExpansion
SwiftCompilerPluginMessageHandling
)
target_include_directories(swift-plugin-server PRIVATE
Sources/CSwiftPluginServer/include
SwiftLibraryPluginProvider
)
endif()
15 changes: 0 additions & 15 deletions tools/swift-plugin-server/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,10 @@ let package = Package(
.package(path: "../../../swift-syntax"),
],
targets: [
.target(
name: "CSwiftPluginServer",
cxxSettings: [
.unsafeFlags([
"-I", "../../include",
"-I", "../../../llvm-project/llvm/include",
])
]
),
.executableTarget(
name: "swift-plugin-server",
dependencies: [
.product(name: "SwiftCompilerPluginMessageHandling", package: "swift-syntax"),
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
"CSwiftPluginServer"
]
),
],
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,96 +11,16 @@
//===----------------------------------------------------------------------===//

@_spi(PluginMessage) import SwiftCompilerPluginMessageHandling
import SwiftSyntaxMacros
import CSwiftPluginServer
@_spi(PluginMessage) import SwiftLibraryPluginProvider

@main
final class SwiftPluginServer {
struct MacroRef: Hashable {
var moduleName: String
var typeName: String
init(_ moduleName: String, _ typeName: String) {
self.moduleName = moduleName
self.typeName = typeName
}
}

struct LoadedLibraryPlugin {
var libraryPath: String
var handle: UnsafeMutableRawPointer
}

/// Loaded dylib handles associated with the module name.
var loadedLibraryPlugins: [String: LoadedLibraryPlugin] = [:]

/// Resolved cached macros.
var resolvedMacros: [MacroRef: Macro.Type] = [:]

/// @main entry point.
static func main() throws {
let connection = try StandardIOMessageConnection()
let listener = CompilerPluginMessageListener(
connection: connection,
provider: self.init()
provider: LibraryPluginProvider.shared
)
try listener.main()
}
}

extension SwiftPluginServer: PluginProvider {
/// Load a macro implementation from the dynamic link library.
func loadPluginLibrary(libraryPath: String, moduleName: String) throws {
var errorMessage: UnsafePointer<CChar>?
guard let dlHandle = PluginServer_load(libraryPath, &errorMessage) else {
throw PluginServerError(message: "loader error: " + String(cString: errorMessage!))
}
loadedLibraryPlugins[moduleName] = LoadedLibraryPlugin(
libraryPath: libraryPath,
handle: dlHandle
)
}

/// Lookup a loaded macro by a pair of module name and type name.
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
if let resolved = resolvedMacros[.init(moduleName, typeName)] {
return resolved
}

// Find 'dlopen'ed library for the module name.
guard let plugin = loadedLibraryPlugins[moduleName] else {
// NOTE: This should be unreachable. Compiler should not use this server
// unless the plugin loading succeeded.
throw PluginServerError(message: "(plugin-server) plugin not loaded for module '\(moduleName)'")
}

// Lookup the type metadata.
var errorMessage: UnsafePointer<CChar>?
guard let macroTypePtr = PluginServer_lookupMacroTypeMetadataByExternalName(
moduleName, typeName, plugin.handle, &errorMessage
) else {
throw PluginServerError(message: "macro implementation type '\(moduleName).\(typeName)' could not be found in library plugin '\(plugin.libraryPath)'")
}

// THe type must be a 'Macro' type.
let macroType = unsafeBitCast(macroTypePtr, to: Any.Type.self)
guard let macro = macroType as? Macro.Type else {
throw PluginServerError(message: "type '\(moduleName).\(typeName)' is not a valid macro implementation type in library plugin '\(plugin.libraryPath)'")
}

// Cache the resolved type.
resolvedMacros[.init(moduleName, typeName)] = macro
return macro
}

/// This 'PluginProvider' implements 'loadLibraryMacro()'.
var features: [SwiftCompilerPluginMessageHandling.PluginFeature] {
[.loadPluginLibrary]
}
}

struct PluginServerError: Error, CustomStringConvertible {
var description: String
init(message: String) {
self.description = message
listener.main()
}
}