Skip to content

Commit 4a8b665

Browse files
committed
[Macros] Improve error messages
1 parent fe05c66 commit 4a8b665

File tree

3 files changed

+71
-23
lines changed

3 files changed

+71
-23
lines changed

Sources/SwiftCompilerPluginMessageHandling/Diagnostics.swift

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,32 @@ import SwiftDiagnostics
1414
import SwiftSyntax
1515

1616
/// Errors in macro handing.
17-
enum MacroExpansionError: String {
18-
case macroTypeNotFound = "macro expanding type not found"
19-
case unmathedMacroRole = "macro doesn't conform to required macro role"
20-
case freestandingMacroSyntaxIsNotMacro = "macro syntax couldn't be parsed"
21-
case invalidExpansionMessage = "internal message error; please file a bug report"
22-
case invalidMacroRole = "invalid macro role for expansion"
17+
enum MacroExpansionError {
18+
case macroTypeNotFound(PluginMessage.MacroReference)
19+
case unmatchedMacroRole
20+
case freestandingMacroSyntaxIsNotMacro
21+
case invalidExpansionMessage
22+
case invalidMacroRole(PluginMessage.MacroRole)
2323
}
2424

2525
extension MacroExpansionError: DiagnosticMessage {
2626
var message: String {
27-
self.rawValue
27+
switch self {
28+
case .macroTypeNotFound(let ref):
29+
return "macro type '\(ref.moduleName).\(ref.typeName)' not found when expanding macro '\(ref.name)'"
30+
31+
case .unmatchedMacroRole:
32+
return "macro doesn't conform to required macro role"
33+
34+
case .freestandingMacroSyntaxIsNotMacro:
35+
return "macro syntax couldn't be parsed"
36+
37+
case .invalidExpansionMessage:
38+
return "internal message error; please file a bug report"
39+
40+
case .invalidMacroRole(let role):
41+
return "invalid macro role '\(role)' for expansion"
42+
}
2843
}
2944
var diagnosticID: SwiftDiagnostics.MessageID {
3045
.init(domain: "SwiftCompilerPlugin", id: "\(type(of: self)).\(self)")

Sources/SwiftCompilerPluginMessageHandling/Macros.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ extension CompilerPluginMessageHandler {
4444
throw MacroExpansionError.freestandingMacroSyntaxIsNotMacro
4545
}
4646
guard let macroDefinition = resolveMacro(macro) else {
47-
throw MacroExpansionError.macroTypeNotFound
47+
throw MacroExpansionError.macroTypeNotFound(macro)
4848
}
4949

5050
let macroRole: MacroRole
@@ -55,7 +55,7 @@ extension CompilerPluginMessageHandler {
5555
case .codeItem: macroRole = .codeItem
5656

5757
case .accessor, .conformance, .member, .memberAttribute, .peer:
58-
throw MacroExpansionError.invalidMacroRole
58+
throw MacroExpansionError.invalidMacroRole(pluginMacroRole)
5959
}
6060
} else {
6161
macroRole = try inferFreestandingMacroRole(definition: macroDefinition)
@@ -105,7 +105,7 @@ extension CompilerPluginMessageHandler {
105105
let expandedSources: [String]?
106106
do {
107107
guard let macroDefinition = resolveMacro(macro) else {
108-
throw MacroExpansionError.macroTypeNotFound
108+
throw MacroExpansionError.macroTypeNotFound(macro)
109109
}
110110

111111
expandedSources = SwiftSyntaxMacroExpansion.expandAttachedMacro(

Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,48 @@ public enum MacroRole {
1212
case codeItem
1313
}
1414

15+
extension MacroRole {
16+
var protocolName: String {
17+
switch self {
18+
case .expression: return "ExpressionMacro"
19+
case .declaration: return "DeclarationMacro"
20+
case .accessor: return "AccessorMacro"
21+
case .memberAttribute: return "MemberAttributeMacro"
22+
case .member: return "MemberMacro"
23+
case .peer: return "PeerMacro"
24+
case .conformance: return "ConformanceMacro"
25+
case .codeItem: return "CodeItemMacro"
26+
}
27+
}
28+
}
29+
1530
/// Simple diagnostic message
16-
private enum MacroExpansionError: String, Error, CustomStringConvertible {
17-
case unmathedMacroRole = "macro doesn't conform to required macro role"
18-
case parentDeclGroupNil = "parent decl group is nil"
19-
case declarationNotDeclGroup = "declaration is not a decl group syntax"
20-
case declarationNotIdentified = "declaration is not a 'Identified' syntax"
21-
var description: String { self.rawValue }
31+
private enum MacroExpansionError: Error, CustomStringConvertible {
32+
case unmatchedMacroRole(Macro.Type, MacroRole)
33+
case parentDeclGroupNil
34+
case declarationNotDeclGroup
35+
case declarationNotIdentified
36+
case noFreestandingMacroRoles(Macro.Type)
37+
38+
var description: String {
39+
switch self {
40+
case .unmatchedMacroRole(let type, let role):
41+
return "macro implementation type '\(type)' doesn't conform to required protocol '\(role.protocolName)'"
42+
43+
case .parentDeclGroupNil:
44+
return "parent decl group is nil"
45+
46+
case .declarationNotDeclGroup:
47+
return "declaration is not a decl group syntax"
48+
49+
case .declarationNotIdentified:
50+
return "declaration is not a 'Identified' syntax"
51+
52+
case .noFreestandingMacroRoles(let type):
53+
return "macro implementation type '\(type)' does not conform to any freestanding macro protocol"
54+
55+
}
56+
}
2257
}
2358

2459
/// Expand `@freestanding(XXX)` macros.
@@ -66,11 +101,9 @@ public func expandFreestandingMacro(
66101
let rewritten = try codeItemMacroDef.expansion(of: node, in: context)
67102
expandedSyntax = Syntax(CodeBlockItemListSyntax(rewritten))
68103

69-
case (.expression, _), (.declaration, _), (.codeItem, _):
70-
throw MacroExpansionError.unmathedMacroRole
71-
72-
case (.accessor, _), (.memberAttribute, _), (.member, _), (.peer, _), (.conformance, _), (.codeItem, _):
73-
fatalError("macro role \(macroRole) is not a freestanding macro")
104+
case (.accessor, _), (.memberAttribute, _), (.member, _), (.peer, _), (.conformance, _), (.expression, _), (.declaration, _),
105+
(.codeItem, _):
106+
throw MacroExpansionError.unmatchedMacroRole(definition, macroRole)
74107
}
75108
return expandedSyntax.formattedExpansion(definition.formatMode)
76109
}
@@ -91,7 +124,7 @@ public func inferFreestandingMacroRole(definition: Macro.Type) throws -> MacroRo
91124
case is CodeItemMacro.Type: return .codeItem
92125

93126
default:
94-
throw MacroExpansionError.unmathedMacroRole
127+
throw MacroExpansionError.noFreestandingMacroRoles(definition)
95128
}
96129
}
97130

@@ -251,7 +284,7 @@ public func expandAttachedMacro<Context: MacroExpansionContext>(
251284
}
252285

253286
default:
254-
throw MacroExpansionError.unmathedMacroRole
287+
throw MacroExpansionError.unmatchedMacroRole(definition, macroRole)
255288
}
256289
} catch {
257290
context.addDiagnostics(from: error, node: attributeNode)

0 commit comments

Comments
 (0)