Skip to content
← Back

src/syntax/trees/identifiers/identifier.ghul

1
namespace Syntax.Trees.Identifiers is
2
use IO.Std
3
4
use Source
5
6
// Constructed, so UPPER_SNAKE_CASE by convention, but the
7
// UPPER_SNAKE_CASE name IDENTIFIER is already taken by
8
// Trees.Expressions.IDENTIFIER, which many files reference
9
// unqualified alongside this namespace.
10
@suppress("non-upper-snake-case-name")
11
class Identifier(location: LOCATION, name: string mut): Trees.Node, Collections.Iterable[string] is
12
name: string public
13
14
qualifier: Identifier? => null
15
16
qualifier_names: Collections.LIST[string] => Collections.LIST[string](0)
17
18
names: Collections.LIST[string] => Collections.LIST[string]([name]) // : string;
19
20
is_qualified: bool => false
21
22
right_location: LOCATION => location
23
24
iterator: Collections.Iterator[string] => names.iterator
25
26
super(location)
27
28
init(..) is
29
// A completion target - the user has typed a `.` and no name
30
// yet - is built with no name. Poison it so it never resolves
31
// and no diagnostic reports a member with an empty name.
32
if name.length == 0 then
33
poison()
34
self.name = "$poisoned"
35
fi
36
si
37
38
copy() -> Identifier =>
39
Identifier(location, name)
40
41
copy_as_expression() -> Expressions.Expression is
42
if let self.qualifier? then
43
return Expressions.MEMBER(location, qualifier.copy_as_expression(), Identifier(right_location, name), right_location)
44
else
45
return Expressions.IDENTIFIER(location, self.copy())
46
fi
47
si
48
49
accept(visitor: Visitor) is
50
visitor.visit(self)
51
si
52
si
53
54
class QUALIFIED(
55
location: LOCATION,
56
_qualifier: Identifier,
57
name: string,
58
completion_target: LOCATION,
59
// Assignable for the same reason `location` is: an incremental edit
60
// moves the name, and a use of the symbol it resolves to is recorded
61
// here rather than at the node's own span. Left read-only it keeps
62
// its original parse position, and the reconciliation that translates
63
// those uses is keyed on a position the text no longer has.
64
right_location: LOCATION public
65
): Identifier is
66
is_qualified: bool => true
67
68
qualifier: Identifier => _qualifier
69
70
qualifier_names: Collections.LIST[string] is
71
let result = Collections.LIST[string]()
72
let p: Identifier? mut = qualifier
73
74
while p? do
75
result.add(p.name)
76
p = p.qualifier
77
od
78
79
return result
80
si
81
82
names: Collections.LIST[string] is
83
let result = Collections.LIST[string]()
84
85
result.add(name)
86
87
let p: Identifier? mut = qualifier
88
89
while p? do
90
result.add(p.name)
91
p = p.qualifier
92
od
93
94
return result
95
si
96
97
iterator: Collections.Iterator[string] is
98
let result = Collections.LIST[string]()
99
100
result.add(name)
101
102
let p: Identifier? mut = qualifier
103
104
while p? do
105
result.add(p.name)
106
p = p.qualifier
107
od
108
109
return result.iterator
110
si
111
112
super(location, name)
113
114
init(..) is
115
poison(qualifier.is_poisoned)
116
si
117
118
copy() -> Identifier is
119
let np = qualifier.copy()
120
121
return QUALIFIED(
122
location,
123
np,
124
name,
125
completion_target,
126
right_location
127
)
128
si
129
130
accept(visitor: Visitor) is
131
visitor.visit(self)
132
si
133
134
walk(visitor: Visitor) is
135
if !visitor.pre(self) then
136
qualifier.walk(visitor)
137
fi
138
139
accept(visitor)
140
si
141
si
142
si