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 | // Drops every remembered lookup. A name resolved through this | |
| 87 | // scope is remembered against the symbol it found, so a symbol | |
| 88 | // removed from the namespace, or declared into it after a name | |
| 89 | // was first looked up, is otherwise not seen from here. | |
| 90 | forget_lookups() is | |
| 91 | _symbols.clear() | |
| 92 | si | |
| 93 | ||
| 94 | find_member(name: string) -> Symbol? => | |
| 95 | find_enclosing(name) | |
| 96 | ||
| 97 | find_enclosing(name: string) -> Symbol? is | |
| 98 | let ns_location = _namespace.location | |
| 99 | ||
| 100 | if _symbols.contains_key(name) then | |
| 101 | return _symbols[name] | |
| 102 | fi | |
| 103 | ||
| 104 | let search = NAMESPACE_SEARCH(_namespace, name) | |
| 105 | ||
| 106 | let symbol mut = find_direct(name) | |
| 107 | ||
| 108 | if search.add(ns_location, symbol, false) then | |
| 109 | return cache_result(search) | |
| 110 | fi | |
| 111 | ||
| 112 | if _used_symbols.contains_key(name) then | |
| 113 | symbol = _used_symbols[name] | |
| 114 | ||
| 115 | if search.add(ns_location, symbol, true) then | |
| 116 | return cache_result(search) | |
| 117 | fi | |
| 118 | fi | |
| 119 | ||
| 120 | for ns in _used_namespaces do | |
| 121 | symbol = ns.find_direct(name) | |
| 122 | ||
| 123 | if search.add(ns_location, symbol, false) then | |
| 124 | return cache_result(search) | |
| 125 | fi | |
| 126 | od | |
| 127 | ||
| 128 | symbol = _namespace.enclosing_scope?.find_enclosing(name) | |
| 129 | ||
| 130 | if search.add(ns_location, symbol, false) then | |
| 131 | return cache_result(search) | |
| 132 | fi | |
| 133 | ||
| 134 | return cache_result(search) | |
| 135 | si | |
| 136 | ||
| 137 | find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 138 | _namespace.find_enclosing_matches(prefix, matches) | |
| 139 | ||
| 140 | for n in _used_namespaces do | |
| 141 | n.find_member_matches(prefix, matches) | |
| 142 | od | |
| 143 | ||
| 144 | for s in _used_symbols do | |
| 145 | Semantic.SYMBOL_STORE.add_match(s.key, s.value, matches) | |
| 146 | od | |
| 147 | si | |
| 148 | ||
| 149 | declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 150 | _namespace.declare_class(location, span, name, arguments, enclosing, symbol_definition_listener) | |
| 151 | ||
| 152 | declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 153 | _namespace.declare_trait(location, span, name, arguments, enclosing, symbol_definition_listener) | |
| 154 | ||
| 155 | declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 156 | _namespace.declare_struct(location, span, name, arguments, enclosing, symbol_definition_listener) | |
| 157 | ||
| 158 | declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 159 | _namespace.declare_union(location, span, name, arguments, enclosing, symbol_definition_listener) | |
| 160 | ||
| 161 | declare_variant(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 162 | _namespace.declare_variant(location, span, name, enclosing, symbol_definition_listener) | |
| 163 | ||
| 164 | declare_type(location: LOCATION, name: string, index: int, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 165 | _namespace.declare_type(location, name, index, symbol_definition_listener) | |
| 166 | ||
| 167 | declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 168 | _namespace.declare_enum(location, span, name, enclosing, symbol_definition_listener) | |
| 169 | ||
| 170 | declare_enum_member(location: LOCATION, name: string, value: string?, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 171 | _namespace.declare_enum_member(location, name, value, symbol_definition_listener) | |
| 172 | si | |
| 173 | ||
| 174 | declare_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 175 | _namespace.declare_closure(location, name, owner, enclosing, is_recursive, symbol_definition_listener) | |
| 176 | ||
| 177 | declare_async_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 178 | _namespace.declare_async_closure(location, name, owner, enclosing, is_recursive, symbol_definition_listener) | |
| 179 | ||
| 180 | declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 181 | _namespace.declare_innate(location, name, innate_name, enclosing, symbol_definition_listener) | |
| 182 | ||
| 183 | 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 => | |
| 184 | _namespace.declare_function(location, span, name, is_static, is_private, has_body, is_property_accessor, enclosing, symbol_definition_listener) | |
| 185 | ||
| 186 | 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 => | |
| 187 | _namespace.declare_generator_function(location, span, name, is_static, is_private, has_body, enclosing, symbol_definition_listener) | |
| 188 | ||
| 189 | 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 => | |
| 190 | _namespace.declare_async_function(location, span, name, is_static, is_private, has_body, enclosing, symbol_definition_listener) | |
| 191 | ||
| 192 | declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 193 | _namespace.declare_variable(location, name, is_static, symbol_definition_listener) | |
| 194 | ||
| 195 | declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol => | |
| 196 | _namespace.declare_property(location, span, name, is_static, is_private, is_assignable, symbol_definition_listener) | |
| 197 | ||
| 198 | declare_label(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 199 | _namespace.declare_label(location, name, symbol_definition_listener) | |
| 200 | si | |
| 201 | ||
| 202 | declare_namespace(location: LOCATION, name: string, `namespace: Symbols.NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is | |
| 203 | _namespace.declare_namespace(location, name, `namespace, symbol_definition_listener) | |
| 204 | si | |
| 205 | ||
| 206 | add(`namespace: Symbols.NAMESPACE) is | |
| 207 | _used_namespaces.add(`namespace) | |
| 208 | si | |
| 209 | ||
| 210 | add(name: string, symbol: Symbol) is | |
| 211 | _used_symbols[name] = symbol | |
| 212 | si | |
| 213 | ||
| 214 | contains_used_symbol(name: string) -> bool => _used_symbols.contains_key(name) | |
| 215 | ||
| 216 | get_used_symbol(name: string) -> Symbol? is | |
| 217 | let result: Symbol mut | |
| 218 | ||
| 219 | _used_symbols.try_get_value(name, result ref) | |
| 220 | ||
| 221 | return result | |
| 222 | si | |
| 223 | ||
| 224 | to_string() -> string => "namespace scope for: {_namespace.name}" | |
| 225 | si | |
| 226 | si |