Skip to content

Commit

Permalink
[Macros] Granular diagnostics when macro type is not found in a plugin
Browse files Browse the repository at this point in the history
rdar://115571427
  • Loading branch information
rintaro committed Oct 13, 2023
1 parent 71afbc1 commit f413c51
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 15 deletions.
19 changes: 14 additions & 5 deletions Sources/SwiftCompilerPlugin/CompilerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public protocol CompilerPlugin {
}

extension CompilerPlugin {
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
let qualifedName = "\(moduleName).\(typeName)"

for type in providingMacros {
Expand All @@ -74,12 +74,14 @@ extension CompilerPlugin {
return type
}
}
return nil

let pluginPath = CommandLine.arguments.first ?? Bundle.main.executablePath ?? ProcessInfo.processInfo.processName
throw CompilerPluginError(message: "macro implementation type '\(moduleName).\(typeName)' could not be found in executable plugin '\(pluginPath)'")
}

// @testable
public func _resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
resolveMacro(moduleName: moduleName, typeName: typeName)
try? resolveMacro(moduleName: moduleName, typeName: typeName)
}
}

Expand All @@ -88,8 +90,8 @@ struct MacroProviderAdapter<Plugin: CompilerPlugin>: PluginProvider {
init(plugin: Plugin) {
self.plugin = plugin
}
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type? {
plugin.resolveMacro(moduleName: moduleName, typeName: typeName)
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type {
try plugin.resolveMacro(moduleName: moduleName, typeName: typeName)
}
}

Expand Down Expand Up @@ -242,3 +244,10 @@ private extension FileHandle {
}
}
}

struct CompilerPluginError: Error, CustomStringConvertible {
var description: String
init(message: String) {
self.description = message
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum PluginFeature: String {
/// A type that provides the actual plugin functions.
public protocol PluginProvider {
/// Resolve macro type by the module name and the type name.
func resolveMacro(moduleName: String, typeName: String) -> Macro.Type?
func resolveMacro(moduleName: String, typeName: String) throws -> Macro.Type

/// Load dynamic link library at `libraryPath`. Implementations can use
/// `moduleName` to associate the loaded library with it.
Expand Down
13 changes: 4 additions & 9 deletions Sources/SwiftCompilerPluginMessageHandling/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import SwiftSyntaxMacros

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

/// Expand `@freestainding(XXX)` macros.
Expand All @@ -43,10 +43,7 @@ extension CompilerPluginMessageHandler {
guard let macroSyntax = syntax.asProtocol(FreestandingMacroExpansionSyntax.self) else {
throw MacroExpansionError.freestandingMacroSyntaxIsNotMacro
}
guard let macroDefinition = resolveMacro(macro) else {
throw MacroExpansionError.macroTypeNotFound(macro)
}

let macroDefinition = try resolveMacro(macro)
let macroRole: MacroRole
if let pluginMacroRole {
macroRole = MacroRole(messageMacroRole: pluginMacroRole)
Expand Down Expand Up @@ -113,9 +110,7 @@ extension CompilerPluginMessageHandler {
// TODO: Make this a 'String?' and remove non-'hasExpandMacroResult' branches.
let expandedSources: [String]?
do {
guard let macroDefinition = resolveMacro(macro) else {
throw MacroExpansionError.macroTypeNotFound(macro)
}
let macroDefinition = try resolveMacro(macro)
let role = MacroRole(messageMacroRole: macroRole)

let expansions = SwiftSyntaxMacroExpansion.expandAttachedMacroWithoutCollapsing(
Expand Down

0 comments on commit f413c51

Please sign in to comment.