Appearance
| 1 | namespace Semantic is | |
| 2 | use IO.Std; | |
| 3 | ||
| 4 | use IoC; | |
| 5 | use Logging; | |
| 6 | use Source; | |
| 7 | ||
| 8 | use Semantic.Symbols.NAMESPACE; | |
| 9 | ||
| 10 | use Types.Type; | |
| 11 | use Symbols.Symbol; | |
| 12 | ||
| 13 | /* | |
| 14 | a namespace block with associated uses of other namespaces + symbols | |
| 15 | declaration of symbols is forwarded to the aggregate namespace symbol | |
| 16 | symbol search needs to be done in a specific order: | |
| 17 | 1) symbols declared directly within the namespace | |
| 18 | 2) symbols imported into this namespace block by uses | |
| 19 | 3) symbols declared directly in namespaces imported into this namespace block by uses | |
| 20 | 4) symbols declared in aggregate namespaces that enclose this one | |
| 21 | */ | |
| 22 | ||
| 23 | class NAMESPACE_SCOPE: Scope, NamespaceContext, DeclarationContext, ClosureContext is | |
| 24 | _namespace: Symbols.NAMESPACE; | |
| 25 | ||
| 26 | _symbols: Collections.MAP[string,Symbol]; | |
| 27 | _used_symbols: Collections.MAP[string,Symbol]; | |
| 28 | _used_namespaces: Collections.LIST[Symbols.NAMESPACE]; | |
| 29 | _closures: Collections.SET[Symbols.Closure]?; | |
| 30 | ||
| 31 | type: Type => Types.NONE.instance; | |
| 32 | ||
| 33 | unspecialized_symbol: Symbol? => null; | |
| 34 | ||
| 35 | name: string => _namespace.name; | |
| 36 | qualified_name: string => _namespace.qualified_name; | |
| 37 | symbols: Collections.Iterable[Symbol] => _namespace.symbols; | |
| 38 | ||
| 39 | containing_namespace: Symbols.NAMESPACE => _namespace; | |
| 40 | ||
| 41 | is_capture_context: bool => true; | |
| 42 | is_namespace: bool => true; | |
| 43 | ||
| 44 | init(`namespace: Symbols.NAMESPACE) is | |
| 45 | _namespace = `namespace; | |
| 46 | _symbols = Collections.MAP[string,Symbol](); | |
| 47 | _used_symbols = Collections.MAP[string,Symbol](); | |
| 48 | _used_namespaces = Collections.LIST[Symbols.NAMESPACE](); | |
| 49 | si | |
| 50 | ||
| 51 | add_closure(closure: Symbols.Closure) is | |
| 52 | if !_closures? then | |
| 53 | _closures = Collections.SET[Symbols.Closure](); | |
| 54 | fi | |
| 55 | ||
| 56 | if !_closures.contains(closure) then | |
| 57 | _closures.add(closure); | |
| 58 | fi | |
| 59 | si | |
| 60 | ||
| 61 | get_closures() -> Collections.Iterable[Symbols.Closure] => | |
| 62 | if _closures? then _closures else Collections.LIST[Symbols.Closure](0) fi; | |
| 63 | ||
| 64 | qualify(name: string) -> string => _namespace.qualify(name); | |
| 65 | ||
| 66 | find_direct(name: string) -> Symbol? => _namespace.find_direct(name); | |
| 67 | ||
| 68 | find_direct_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 69 | _namespace.find_direct_matches(prefix, matches); | |
| 70 | si | |
| 71 | ||
| 72 | find_member_matches(prefix: string, results: Collections.MutableMap[string,Symbol]) is | |
| 73 | _namespace.find_member_matches(prefix, results); | |
| 74 | si | |
| 75 | ||
| 76 | cache_result(search: NAMESPACE_SEARCH) -> Symbol? is | |
| 77 | let result = search.get_result(); | |
| 78 | ||
| 79 | if result? then | |
| 80 | _symbols[search.name] = result; | |
| 81 | fi | |
| 82 | ||
| 83 | return result; | |
| 84 | si | |
| 85 | ||
| 86 | find_member(name: string) -> Symbol? => | |
| 87 | find_enclosing(name); | |
| 88 | ||
| 89 | find_enclosing(name: string) -> Symbol? is | |
| 90 | let ns_location = _namespace.location; | |
| 91 | ||
| 92 | if _symbols.contains_key(name) then | |
| 93 | return _symbols[name]; | |
| 94 | fi | |
| 95 | ||
| 96 | let search = NAMESPACE_SEARCH(_namespace, name); | |
| 97 | ||
| 98 | let symbol mut = find_direct(name); | |
| 99 | ||
| 100 | if search.add(ns_location, symbol, false) then | |
| 101 | return cache_result(search); | |
| 102 | fi | |
| 103 | ||
| 104 | if _used_symbols.contains_key(name) then | |
| 105 | symbol = _used_symbols[name]; | |
| 106 | ||
| 107 | if search.add(ns_location, symbol, true) then | |
| 108 | return cache_result(search); | |
| 109 | fi | |
| 110 | fi | |
| 111 | ||
| 112 | for ns in _used_namespaces do | |
| 113 | symbol = ns.find_direct(name); | |
| 114 | ||
| 115 | if search.add(ns_location, symbol, false) then | |
| 116 | return cache_result(search); | |
| 117 | fi | |
| 118 | od | |
| 119 | ||
| 120 | symbol = _namespace.enclosing_scope?.find_enclosing(name); | |
| 121 | ||
| 122 | if search.add(ns_location, symbol, false) then | |
| 123 | return cache_result(search); | |
| 124 | fi | |
| 125 | ||
| 126 | return cache_result(search); | |
| 127 | si | |
| 128 | ||
| 129 | find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 130 | _namespace.find_enclosing_matches(prefix, matches); | |
| 131 | ||
| 132 | for n in _used_namespaces do | |
| 133 | n.find_member_matches(prefix, matches); | |
| 134 | od | |
| 135 | ||
| 136 | for s in _used_symbols do | |
| 137 | Semantic.SYMBOL_STORE.add_match(s.key, s.value, matches); | |
| 138 | od | |
| 139 | si | |
| 140 | ||
| 141 | declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 142 | _namespace.declare_class(location, span, name, arguments, enclosing, symbol_definition_listener); | |
| 143 | ||
| 144 | declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 145 | _namespace.declare_trait(location, span, name, arguments, enclosing, symbol_definition_listener); | |
| 146 | ||
| 147 | declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 148 | _namespace.declare_struct(location, span, name, arguments, enclosing, symbol_definition_listener); | |
| 149 | ||
| 150 | declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 151 | _namespace.declare_union(location, span, name, arguments, enclosing, symbol_definition_listener); | |
| 152 | ||
| 153 | declare_variant(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 154 | _namespace.declare_variant(location, span, name, enclosing, symbol_definition_listener); | |
| 155 | ||
| 156 | declare_type(location: LOCATION, name: string, index: int, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 157 | _namespace.declare_type(location, name, index, symbol_definition_listener); | |
| 158 | ||
| 159 | declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 160 | _namespace.declare_enum(location, span, name, enclosing, symbol_definition_listener); | |
| 161 | ||
| 162 | declare_enum_member(location: LOCATION, name: string, value: string?, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 163 | _namespace.declare_enum_member(location, name, value, symbol_definition_listener); | |
| 164 | si | |
| 165 | ||
| 166 | declare_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 167 | _namespace.declare_closure(location, name, owner, enclosing, is_recursive, symbol_definition_listener); | |
| 168 | ||
| 169 | declare_async_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 170 | _namespace.declare_async_closure(location, name, owner, enclosing, is_recursive, symbol_definition_listener); | |
| 171 | ||
| 172 | declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 173 | _namespace.declare_innate(location, name, innate_name, enclosing, symbol_definition_listener); | |
| 174 | ||
| 175 | declare_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 176 | _namespace.declare_function(location, span, name, is_static, is_private, has_body, enclosing, symbol_definition_listener); | |
| 177 | ||
| 178 | 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 => | |
| 179 | _namespace.declare_generator_function(location, span, name, is_static, is_private, has_body, enclosing, symbol_definition_listener); | |
| 180 | ||
| 181 | 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 => | |
| 182 | _namespace.declare_async_function(location, span, name, is_static, is_private, has_body, enclosing, symbol_definition_listener); | |
| 183 | ||
| 184 | declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 185 | _namespace.declare_variable(location, name, is_static, symbol_definition_listener); | |
| 186 | ||
| 187 | declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 188 | _namespace.declare_property(location, span, name, is_static, is_private, is_assignable, symbol_definition_listener); | |
| 189 | ||
| 190 | declare_label(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 191 | _namespace.declare_label(location, name, symbol_definition_listener); | |
| 192 | si | |
| 193 | ||
| 194 | declare_namespace(location: LOCATION, name: string, `namespace: Symbols.NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 195 | _namespace.declare_namespace(location, name, `namespace, symbol_definition_listener); | |
| 196 | si | |
| 197 | ||
| 198 | add(`namespace: Symbols.NAMESPACE) is | |
| 199 | _used_namespaces.add(`namespace); | |
| 200 | si | |
| 201 | ||
| 202 | add(name: string, symbol: Symbol) is | |
| 203 | _used_symbols[name] = symbol; | |
| 204 | si | |
| 205 | ||
| 206 | contains_used_symbol(name: string) -> bool => _used_symbols.contains_key(name); | |
| 207 | ||
| 208 | get_used_symbol(name: string) -> Symbol? is | |
| 209 | let result: Symbol mut; | |
| 210 | ||
| 211 | _used_symbols.try_get_value(name, result ref); | |
| 212 | ||
| 213 | return result; | |
| 214 | si | |
| 215 | ||
| 216 | gen_dot(buffer: System.Text.StringBuilder) is | |
| 217 | buffer.append("."); | |
| 218 | si | |
| 219 | ||
| 220 | gen_dotted_name(buffer: System.Text.StringBuilder, qualifying: Scope) is | |
| 221 | _namespace.gen_dotted_name(buffer, qualifying); | |
| 222 | si | |
| 223 | ||
| 224 | gen_type_spec(buffer: System.Text.StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}"); | |
| 225 | gen_class_name(buffer: System.Text.StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}"); | |
| 226 | gen_reference(buffer: System.Text.StringBuilder) is | |
| 227 | _namespace.gen_reference(buffer); | |
| 228 | si | |
| 229 | ||
| 230 | gen_type(buffer: System.Text.StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}"); | |
| 231 | to_string() -> string => "namespace scope for: {_namespace.name}"; | |
| 232 | si | |
| 233 | si |