1111//
1212//===----------------------------------------------------------------------===//
1313
14+ import SwiftDiagnostics
1415import SwiftSyntax
1516import SwiftSyntaxBuilder
1617import SwiftSyntaxMacros
@@ -33,15 +34,15 @@ public struct FlagMacro {
3334 /// Create a FlagMacro from the given attribute/declaration
3435 init ( node: AttributeSyntax , declaration: some DeclSyntaxProtocol , context: some MacroExpansionContext ) throws {
3536 guard node. attributeName. as ( IdentifierTypeSyntax . self) ? . name. text == " Flag " else {
36- throw Diagnostic . notFlagMacro
37+ throw DiagnosticsError ( diagnostics : [ . init ( node : node , message : Diagnostic . notFlagMacro) ] )
3738 }
3839 guard let arguments = node. arguments else {
39- throw Diagnostic . missingArguments
40+ throw DiagnosticsError ( diagnostics : [ . init ( node : node , message : Diagnostic . missingArguments) ] )
4041 }
4142
4243 // Description can have an explicit or omitted label
4344 guard let description = arguments. descriptionArgument else {
44- throw Diagnostic . missingDescription
45+ throw DiagnosticsError ( diagnostics : [ . init ( node : node , message : Diagnostic . missingDescription) ] )
4546 }
4647
4748 guard
@@ -51,11 +52,16 @@ public struct FlagMacro {
5152 let type = binding. typeAnnotation? . type ?? binding. inferredType,
5253 binding. accessorBlock == nil
5354 else {
54- throw Diagnostic . onlySimpleVariableSupported
55+ throw DiagnosticsError ( diagnostics : [ . init ( node : node , message : Diagnostic . onlySimpleVariableSupported) ] )
5556 }
5657
57- guard let defaultExprSyntax = arguments [ label: " default " ] ? . expression ?? binding. initializer? . value else {
58- throw Diagnostic . missingDefaultValue
58+ var defaultExprSyntax : ExprSyntax
59+ if let defaultExpr = arguments [ label: " default " ] ? . expression ?? binding. initializer? . value {
60+ defaultExprSyntax = defaultExpr
61+ } else if binding. typeAnnotation? . type. is ( OptionalTypeSyntax . self) == true {
62+ defaultExprSyntax = ExprSyntax ( NilLiteralExprSyntax ( ) )
63+ } else {
64+ throw DiagnosticsError ( diagnostics: [ . init( node: node, message: Diagnostic . missingDefaultValue) ] )
5965 }
6066
6167 let strategy = KeyStrategy ( exprSyntax: arguments [ label: " keyStrategy " ] ? . expression) ?? . default
@@ -123,18 +129,14 @@ extension FlagMacro: AccessorMacro {
123129 providingAccessorsOf declaration: some DeclSyntaxProtocol ,
124130 in context: some MacroExpansionContext
125131 ) throws -> [ AccessorDeclSyntax ] {
126- do {
127- let macro = try FlagMacro ( node: node, declaration: declaration, context: context)
128- return [
129- """
130- get {
131- \( macro. makeLookupExpression ( ) )
132- }
133- """ ,
134- ]
135- } catch {
136- return [ ]
137- }
132+ let macro = try FlagMacro ( node: node, declaration: declaration, context: context)
133+ return [
134+ """
135+ get {
136+ \( macro. makeLookupExpression ( ) )
137+ }
138+ """ ,
139+ ]
138140 }
139141
140142}
@@ -177,12 +179,36 @@ extension FlagMacro: PeerMacro {
177179
178180extension FlagMacro {
179181
180- enum Diagnostic : Error {
182+ enum Diagnostic : DiagnosticMessage {
181183 case notFlagMacro
182184 case missingArguments
183185 case missingDefaultValue
184186 case missingDescription
185187 case onlySimpleVariableSupported
188+
189+ var message : String {
190+ switch self {
191+ case . notFlagMacro: " This is not a @Flag macro..? "
192+ case . missingArguments: " Required arguments have not been provided. "
193+ case . missingDefaultValue: " Could not infer the default value. Initialise the property or set the default: parameter. "
194+ case . missingDescription: " Description parameter missing. "
195+ case . onlySimpleVariableSupported: " Only simple single-binding properties supported. "
196+ }
197+ }
198+
199+ var diagnosticID : MessageID {
200+ switch self {
201+ case . notFlagMacro: MessageID ( domain: " com.unsignedapps.vexil.flagMacro " , id: " notFlagMacro " )
202+ case . missingArguments: MessageID ( domain: " com.unsignedapps.vexil.flagMacro " , id: " missingArguments " )
203+ case . missingDefaultValue: MessageID ( domain: " com.unsignedapps.vexil.flagMacro " , id: " missingDefaultValue " )
204+ case . missingDescription: MessageID ( domain: " com.unsignedapps.vexil.flagMacro " , id: " missingDescription " )
205+ case . onlySimpleVariableSupported: MessageID ( domain: " com.unsignedapps.vexil.flagMacro " , id: " onlySimpleVariableSupported " )
206+ }
207+ }
208+
209+ var severity : DiagnosticSeverity {
210+ . error
211+ }
186212 }
187213
188214}
0 commit comments