Skip to content

Commit 975ac26

Browse files
authored
Merge pull request swiftlang#2268 from rintaro/macro-resolveerror-rdar115571427
[Macros] Granular diagnostics when macro type is not found in a plugin
2 parents 8decbe4 + e4e6a95 commit 975ac26

File tree

4 files changed

+25
-25
lines changed

4 files changed

+25
-25
lines changed

Sources/SwiftCompilerPlugin/CompilerPlugin.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public protocol CompilerPlugin {
6363
}
6464

6565
extension CompilerPlugin {
66-
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
66+
@_spi(Testing)
67+
public func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
6768
let qualifedName = "\(moduleName).\(typeName)"
6869

6970
for type in providingMacros {
@@ -74,12 +75,9 @@ extension CompilerPlugin {
7475
return type
7576
}
7677
}
77-
return nil
78-
}
7978

80-
// @testable
81-
public func _resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
82-
resolveMacro(moduleName: moduleName, typeName: typeName)
79+
let pluginPath = CommandLine.arguments.first ?? Bundle.main.executablePath ?? ProcessInfo.processInfo.processName
80+
throw CompilerPluginError(message: "macro implementation type '\(moduleName).\(typeName)' could not be found in executable plugin '\(pluginPath)'")
8381
}
8482
}
8583

@@ -88,8 +86,8 @@ struct MacroProviderAdapter<Plugin: CompilerPlugin>: PluginProvider {
8886
init(plugin: Plugin) {
8987
self.plugin = plugin
9088
}
91-
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
92-
plugin.resolveMacro(moduleName: moduleName, typeName: typeName)
89+
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
90+
try plugin.resolveMacro(moduleName: moduleName, typeName: typeName)
9391
}
9492
}
9593

@@ -242,3 +240,10 @@ private extension FileHandle {
242240
}
243241
}
244242
}
243+
244+
struct CompilerPluginError: Error, CustomStringConvertible {
245+
var description: String
246+
init(message: String) {
247+
self.description = message
248+
}
249+
}

Sources/SwiftCompilerPluginMessageHandling/CompilerPluginMessageHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public enum PluginFeature: String {
2020
/// A type that provides the actual plugin functions.
2121
public protocol PluginProvider {
2222
/// Resolve macro type by the module name and the type name.
23-
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type?
23+
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type
2424

2525
/// Load dynamic link library at `libraryPath`. Implementations can use
2626
/// `moduleName` to associate the loaded library with it.

Sources/SwiftCompilerPluginMessageHandling/Macros.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import SwiftSyntaxMacros
1919

2020
extension CompilerPluginMessageHandler {
2121
/// Get concrete macro type from a pair of module name and type name.
22-
private func resolveMacro(_ ref: PluginMessage.MacroReference) -> Macro.Type? {
23-
provider.resolveMacro(moduleName: ref.moduleName, typeName: ref.typeName)
22+
private func resolveMacro(_ ref: PluginMessage.MacroReference) throws -> Macro.Type {
23+
try provider.resolveMacro(moduleName: ref.moduleName, typeName: ref.typeName)
2424
}
2525

2626
/// Expand `@freestainding(XXX)` macros.
@@ -43,10 +43,7 @@ extension CompilerPluginMessageHandler {
4343
guard let macroSyntax = syntax.asProtocol(FreestandingMacroExpansionSyntax.self) else {
4444
throw MacroExpansionError.freestandingMacroSyntaxIsNotMacro
4545
}
46-
guard let macroDefinition = resolveMacro(macro) else {
47-
throw MacroExpansionError.macroTypeNotFound(macro)
48-
}
49-
46+
let macroDefinition = try resolveMacro(macro)
5047
let macroRole: MacroRole
5148
if let pluginMacroRole {
5249
macroRole = MacroRole(messageMacroRole: pluginMacroRole)
@@ -113,9 +110,7 @@ extension CompilerPluginMessageHandler {
113110
// TODO: Make this a 'String?' and remove non-'hasExpandMacroResult' branches.
114111
let expandedSources: [String]?
115112
do {
116-
guard let macroDefinition = resolveMacro(macro) else {
117-
throw MacroExpansionError.macroTypeNotFound(macro)
118-
}
113+
let macroDefinition = try resolveMacro(macro)
119114
let role = MacroRole(messageMacroRole: macroRole)
120115

121116
let expansions = SwiftSyntaxMacroExpansion.expandAttachedMacroWithoutCollapsing(

Tests/SwiftCompilerPluginTest/CompilerPluginTests.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SwiftCompilerPlugin
13+
@_spi(Testing) import SwiftCompilerPlugin
1414
import SwiftSyntax
1515
import SwiftSyntaxMacros
1616
import XCTest
@@ -51,20 +51,20 @@ public class CompilerPluginTests: XCTestCase {
5151
func testResolveMacro() {
5252
let plugin = MyPlugin()
5353

54-
let registeredMacro = plugin._resolveMacro(
54+
let registeredMacro = try? plugin.resolveMacro(
5555
moduleName: "SwiftCompilerPluginTest",
5656
typeName: "RegisteredMacro"
5757
)
5858
XCTAssertNotNil(registeredMacro)
5959
XCTAssertTrue(registeredMacro == RegisteredMacro.self)
6060

6161
/// Test the plugin doesn't provide unregistered macros.
62-
let dummyMacro = plugin._resolveMacro(
63-
moduleName: "SwiftCompilerPluginTest",
64-
typeName: "DummyMacro"
62+
XCTAssertThrowsError(
63+
try plugin.resolveMacro(
64+
moduleName: "SwiftCompilerPluginTest",
65+
typeName: "DummyMacro"
66+
)
6567
)
66-
XCTAssertNil(dummyMacro)
67-
XCTAssertFalse(dummyMacro == DummyMacro.self)
6868

6969
}
7070
}

0 commit comments

Comments
 (0)