Skip to content
← Back

src/syntax/process/scopevisitorbase.ghul

1
namespace Syntax is
2
use IO.Std;
3
4
5
use Logging;
6
use Source;
7
use Trees;
8
9
class ScopeVisitorBase: Visitor abstract is
10
_symbol_table: Semantic.SYMBOL_TABLE;
11
_namespaces: Semantic.NAMESPACES;
12
13
current_scope: Semantic.Scope => _symbol_table.current_scope;
14
current_namespace_context: Semantic.NamespaceContext => _symbol_table.current_namespace_context;
15
current_capture_context: Semantic.Symbols.Symbol? => _symbol_table.current_capture_context;
16
current_closure_context: Semantic.ClosureContext => _symbol_table.current_closure_context;
17
current_closure: Semantic.Symbols.Closure? => _symbol_table.current_closure;
18
current_union_context: Semantic.Symbols.UNION? => _symbol_table.current_union_context;
19
current_instance_context: Semantic.Symbols.Classy? => _symbol_table.current_instance_context;
20
current_function: Semantic.Symbols.Function? => _symbol_table.current_function;
21
current_declaration_context: Semantic.DeclarationContext => _symbol_table.current_declaration_context;
22
23
init(
24
symbol_table: Semantic.SYMBOL_TABLE,
25
namespaces: Semantic.NAMESPACES
26
)
27
is
28
super.init();
29
_symbol_table = symbol_table;
30
_namespaces = namespaces;
31
si
32
33
scope_for(node: Node) -> Semantic.Scope? => _symbol_table.scope_for(node);
34
35
// The _symbol_ helpers look through stand-in scopes (an impl or
36
// partial block's scope stands in for its target type), so a
37
// definition node associated with a stand-in still reports the
38
// symbol it declares into.
39
symbol_for(node: Node) -> Semantic.Symbols.Symbol? =>
40
let scope = _symbol_table.scope_for(node) in
41
if scope? then cast Semantic.Symbols.Symbol?(scope.underlying_scope) else null fi;
42
43
class_or_trait_for(node: Node) -> Semantic.Symbols.Classy? =>
44
let scope = _symbol_table.scope_for(node) in
45
if scope? then cast Semantic.Symbols.Classy?(scope.underlying_scope) else null fi;
46
47
function_for(node: Node) -> Semantic.Symbols.Function? =>
48
let scope = _symbol_table.scope_for(node) in
49
if scope? then cast Semantic.Symbols.Function?(scope.underlying_scope) else null fi;
50
51
find_member(identifier: Identifiers.Identifier) -> Semantic.Symbols.Symbol? =>
52
let qualifier = identifier.qualifier in
53
if qualifier? then
54
let qualifier_symbol = find_member(qualifier) in
55
if qualifier_symbol? then qualifier_symbol.find_member(identifier.name) else null fi
56
else
57
current_scope.find_member(identifier.name)
58
fi;
59
60
find_enclosing(identifier: Identifiers.Identifier) -> Semantic.Symbols.Symbol? =>
61
let qualifier = identifier.qualifier in
62
if qualifier? then
63
let qualifier_symbol = find_enclosing(qualifier) in
64
if qualifier_symbol? then qualifier_symbol.find_enclosing(identifier.name) else null fi
65
else
66
current_scope.find_enclosing(identifier.name)
67
fi;
68
69
create_and_enter_block_scope(node: ScopeCarrier) is
70
let scope = Semantic.BLOCK_SCOPE(current_scope);
71
associate_and_enter_scope(node, scope);
72
si
73
74
associate_and_enter_scope(node: ScopeCarrier, scope: Semantic.Scope) is
75
associate_node_with_scope(node, scope);
76
enter_scope(scope);
77
si
78
79
associate_node_with_scope(node: ScopeCarrier, scope: Semantic.Scope) is
80
_symbol_table.associate_node_with_scope(node, scope);
81
si
82
83
mark_scope_stack() -> int => _symbol_table.mark_scope_stack();
84
release_scope_stack(mark: int) is
85
_symbol_table.release_scope_stack(mark);
86
si
87
88
enter_scope(node: ScopeCarrier) is
89
_symbol_table.enter_scope(node);
90
si
91
92
enter_scope(scope: Semantic.Scope) is
93
_symbol_table.enter_scope(scope);
94
si
95
96
leave_scope(node: ScopeCarrier) is
97
_symbol_table.leave_scope(node);
98
si
99
100
leave_scope(scope: Semantic.Scope) is
101
_symbol_table.leave_scope(scope);
102
si
103
104
declare_and_enter_namespace(
105
`namespace: Definitions.NAMESPACE,
106
symbol_definition_listener: Semantic.SymbolDefinitionListener,
107
is_compiler_generated: bool
108
) -> Semantic.NAMESPACE_SCOPE
109
is
110
let identifier = `namespace.name;
111
112
let namespace_symbol = _namespaces.declare_and_enter_namespace(identifier.location, identifier.name, symbol_definition_listener, is_compiler_generated);
113
114
let namespace_scope = Semantic.NAMESPACE_SCOPE(namespace_symbol);
115
116
associate_and_enter_scope(`namespace, namespace_scope);
117
118
return namespace_scope;
119
si
120
121
enter_namespace(`namespace: Definitions.NAMESPACE) -> Semantic.NAMESPACE_SCOPE is
122
_namespaces.enter_namespace(`namespace.name.location, `namespace.name.name);
123
124
let namespace_scope = cast Semantic.NAMESPACE_SCOPE?(`namespace.scope)!;
125
126
enter_scope(namespace_scope);
127
128
return namespace_scope;
129
si
130
131
leave_namespace(`namespace: Definitions.NAMESPACE) is
132
let namespace_scope = cast Semantic.NAMESPACE_SCOPE?(`namespace.scope)!;
133
134
leave_scope(namespace_scope);
135
136
_namespaces.leave_namespace(`namespace.name.location, `namespace.name.name);
137
si
138
139
enter_uses(`namespace: Definitions.NAMESPACE) is
140
// FIXME: remove me
141
si
142
143
leave_uses(`namespace: Definitions.NAMESPACE) is
144
// FIXME: remove me
145
si
146
si
147
si