-
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathVariable.swift
More file actions
79 lines (70 loc) · 2.59 KB
/
Variable.swift
File metadata and controls
79 lines (70 loc) · 2.59 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
70
71
72
73
74
75
76
77
78
79
import SwiftSyntax
/// Wraps a variable declaration (e.g. `var myVariable: Int = 5`)
public struct Variable {
/// The underlying syntax node.
public var _syntax: VariableDeclSyntax
/// Wraps a syntax node.
public init(_ syntax: VariableDeclSyntax) {
_syntax = syntax
}
/// Attempts to get an arbitrary declaration as a variable declaration.
public init?(_ syntax: any DeclSyntaxProtocol) {
guard let syntax = syntax.as(VariableDeclSyntax.self) else {
return nil
}
_syntax = syntax
}
/// The bindings within the variable declaration. A single variable declaration can
/// define multiple bindings (e.g. `var a: Int, b: Int`).
public var bindings: [VariableBinding] {
_syntax.bindings.map(VariableBinding.init)
}
/// All identifiers declared in the variable declaration (can be multiple in cases such
/// as `var a: Int, b: Int`).
public var identifiers: [String] {
bindings.compactMap(\.identifier)
}
/// The attributes attached to the variable declaration.
public var attributes: [AttributeListElement] {
_syntax.attributes.map { attribute in
switch attribute {
case .attribute(let attributeSyntax):
return .attribute(Attribute(attributeSyntax))
case .ifConfigDecl(let ifConfigDeclSyntax):
return .conditionalCompilationBlock(
ConditionalCompilationBlock(ifConfigDeclSyntax)
)
}
}
}
/// Returns the attribute with the given name if the declaration has such an attribute.
public func attribute(named name: String) -> Attribute? {
for element in attributes {
guard case let .attribute(attribute) = element else {
continue
}
if attribute.name.name == name {
return attribute
}
}
return nil
}
/// Determines whether the variable has the syntax of a stored property.
///
/// This syntactic check cannot account for semantic adjustments due to,
/// e.g., accessor macros or property wrappers.
public var isStoredProperty: Bool {
guard let binding = destructureSingle(bindings) else {
return false
}
for accessor in binding.accessors {
switch accessor.accessorSpecifier.tokenKind {
case .keyword(.willSet), .keyword(.didSet):
break
default:
return false
}
}
return true
}
}