-
-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathIgnoreEncoding.swift
More file actions
69 lines (64 loc) · 2.53 KB
/
Copy pathIgnoreEncoding.swift
File metadata and controls
69 lines (64 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import SwiftDiagnostics
import SwiftSyntax
import SwiftSyntaxMacros
/// Attribute type for `IgnoreEncoding` macro-attribute.
///
/// This type can validate`IgnoreEncoding` macro-attribute
/// usage and extract data for `Codable` macro to
/// generate implementation.
package struct IgnoreEncoding: PropertyAttribute {
/// The node syntax provided
/// during initialization.
let node: AttributeSyntax
/// Optional encoding condition closure expression with label specified.
///
/// This closure may take one or multiple arguments depending on
/// whether attached to property or enum case, and includes information
/// about whether it's an 'if' or 'basedOn' condition.
var conditionExpr: LabeledExprSyntax? {
guard let args = node.arguments?.as(LabeledExprListSyntax.self) else {
return nil
}
return args.first { expr in
expr.label?.tokenKind == .identifier("if") ||
expr.label?.tokenKind == .identifier("basedOn")
}
}
/// Creates a new instance with the provided node.
///
/// The initializer fails to create new instance if the name
/// of the provided node is different than this attribute.
///
/// - Parameter node: The attribute syntax to create with.
/// - Returns: Newly created attribute instance.
init?(from node: AttributeSyntax) {
guard
node.attributeName.as(IdentifierTypeSyntax.self)!
.name.text == Self.name
else { return nil }
self.node = node
}
/// Builds diagnoser that can validate this macro attached declaration.
///
/// The following conditions are checked by the built diagnoser:
/// * Attached declaration is a variable/type/enum-case declaration.
/// * Additionally, warning generated if macro usage is duplicated
/// for the same declaration.
/// * Additionally, warning also generated if this attribute is used
/// combined with `IgnoreCoding` attribute.
/// * Attached type declaration must not have`Codable` attribute
/// attached.
///
/// - Returns: The built diagnoser instance.
func diagnoser() -> DiagnosticProducer {
return AggregatedDiagnosticProducer {
cantDuplicate()
shouldNotBeCombined(with: IgnoreCoding.self)
`if`(
isStruct || isClass || isActor || isEnum || isProtocol,
mustBeCombined(with: Codable.self),
else: expect(syntaxes: IgnoreCoding.ignorableDeclarations)
)
}
}
}