Skip to content
← Back

src/semantic/scope/block_scope.ghul

1
namespace Semantic is
2
use System.NotImplementedException
3
4
use IoC
5
use Logging
6
use Source
7
8
use Types.Type
9
use Symbols.Symbol
10
11
class BLOCK_SCOPE: Scope, DeclarationContext is
12
_enclosing: Scope?
13
_symbols: Semantic.SYMBOL_STORE
14
15
name: string => "[block]"
16
qualified_name: string =>
17
if let self._enclosing? then
18
"{_enclosing.qualified_name}.[block]"
19
else
20
"[block]"
21
fi
22
23
symbols: Collections.Iterable[Symbols.Symbol] => _symbols.values
24
25
type: Type => Types.NONE.instance
26
27
unspecialized_symbol: Symbols.Symbol? => null
28
29
init() is
30
init(null)
31
si
32
33
init(enclosing: Scope?) is
34
_enclosing = enclosing
35
_symbols = Semantic.SYMBOL_STORE()
36
si
37
38
qualify(name: string) -> string =>
39
if let self._enclosing? then
40
_enclosing.qualify(name)
41
else
42
name
43
fi
44
45
find_direct(name: string) -> Symbols.Symbol? =>
46
_symbols[name]
47
48
find_direct_matches(prefix: string, matches: Collections.MutableMap[string,Semantic.Symbols.Symbol]) is
49
_symbols.find_matches(prefix, matches)
50
si
51
52
find_member(name: string) -> Symbols.Symbol? => throw NotImplementedException("cannot search for member {name} in block scope")
53
find_member_matches(prefix: string, matches: Collections.MutableMap[string,Semantic.Symbols.Symbol]) => throw NotImplementedException("cannot search for member matches {prefix} in block scope")
54
find_enclosing(name: string) -> Symbols.Symbol? is
55
let result = find_direct(name)
56
57
if result? then
58
return result
59
elif _enclosing? then
60
return _enclosing.find_enclosing(name)
61
else
62
return null
63
fi
64
si
65
66
find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string,Semantic.Symbols.Symbol]) is
67
find_direct_matches(prefix, matches)
68
69
if let self._enclosing? then
70
_enclosing.find_enclosing_matches(prefix, matches)
71
fi
72
si
73
74
declare_undefined(location: LOCATION, kind: string, name: string) -> Semantic.Symbols.Symbol is
75
CONTAINER.instance.logger.error(location, "cannot declare {kind} here")
76
77
return Symbols.UNDEFINED(location, self, name)
78
si
79
80
declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
81
declare_undefined(location, "class", name)
82
83
declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
84
declare_undefined(location, "trait", name)
85
86
declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
87
declare_undefined(location, "struct", name)
88
89
declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
90
declare_undefined(location, "union", name)
91
92
declare_variant(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
93
declare_undefined(location, "variant", name)
94
95
declare_type(location: LOCATION, name: string, index: int, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
96
declare_undefined(location, "type", name)
97
98
declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
99
declare_undefined(location, "enum", name)
100
101
declare_enum_member(location: LOCATION, name: string, value: string?, symbol_definition_listener: SymbolDefinitionListener?) is
102
declare_undefined(location, "enum member", name)
103
si
104
105
declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
106
declare_undefined(location, "innate", name)
107
108
declare_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, is_property_accessor: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
109
declare_undefined(location, "function", name)
110
111
declare_generator_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
112
declare_undefined(location, "generator function", name)
113
114
declare_async_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
115
declare_undefined(location, "async function", name)
116
117
declare_namespace(location: LOCATION, name: string, `namespace: Symbols.NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is
118
declare_undefined(location, "namespace", name)
119
si
120
121
declare_label(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) is
122
let label = Symbols.LABEL(location, self, name)
123
declare(location, label, symbol_definition_listener)
124
si
125
126
declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
127
// FIXME: IoC
128
//
129
// A block scope reached with no enclosing capture context -
130
// a rejected `partial`/`impl` block at namespace scope
131
// routes its members here so each is rejected once rather
132
// than cascading - has nothing real to own this variable.
133
// Owning it here keeps a rejected function's own parameters
134
// resolvable within its body; nothing downstream reads the
135
// owner of a variable declared into a dead-end scope.
136
let capture_context = IoC.CONTAINER.instance.symbol_table.current_capture_context
137
let owner = if capture_context? then cast Scope(capture_context) else self fi
138
139
let variable = Symbols.LOCAL_VARIABLE(location, owner, name)
140
declare(location, variable, symbol_definition_listener)
141
return variable
142
si
143
144
declare_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => declare_undefined(location, "anonymous function", name)
145
declare_async_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => declare_undefined(location, "anonymous async function", name)
146
declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
147
declare_undefined(location, "property", name)
148
149
declare(location: LOCATION, symbol: Symbols.Symbol, symbol_definition_listener: SymbolDefinitionListener?) is
150
let name = symbol.name
151
let existing = find_direct(name)
152
153
if existing? then
154
CONTAINER.instance.logger.error(location, "redefining symbol {symbol.name}", existing.location, "symbol declared here")
155
CONTAINER.instance.logger.error(existing.location, "symbol {symbol.name} is redefined", location, "redefined here")
156
fi
157
158
if symbol_definition_listener? then
159
symbol_definition_listener.add_symbol_definition(location, symbol)
160
fi
161
162
_symbols[name] = symbol
163
si
164
165
to_string() -> string =>
166
"{get_type()} {_symbols}"
167
si
168
si