Appearance
| 1 | namespace Semantic is | |
| 2 | use System.Text.StringBuilder | |
| 3 | ||
| 4 | use Types.Type | |
| 5 | use Symbols.Symbol | |
| 6 | ||
| 7 | // Scope for the body of an `impl` or `partial` block, which declares | |
| 8 | // members into a target type that can be declared somewhere else | |
| 9 | // entirely. The target's own members and type parameters are found | |
| 10 | // first, exactly as inside the target's declaration body; any other | |
| 11 | // name resolves from the block's write site - its enclosing namespace | |
| 12 | // and `use` imports - rather than from the target's declaring scope. | |
| 13 | class INJECTION_SCOPE: Scope, ClosureContext is | |
| 14 | _target: Symbols.Classy | |
| 15 | _lexical: Scope | |
| 16 | _closures: Collections.SET[Symbols.Closure]? | |
| 17 | ||
| 18 | target: Symbols.Classy => _target | |
| 19 | ||
| 20 | underlying_scope: Scope => _target | |
| 21 | ||
| 22 | name: string => _target.name | |
| 23 | qualified_name: string => _target.qualified_name | |
| 24 | ||
| 25 | symbols: Collections.Iterable[Symbol] => _target.symbols | |
| 26 | ||
| 27 | type: Type? => _target.type | |
| 28 | ||
| 29 | unspecialized_symbol: Symbol? => _target.unspecialized_symbol | |
| 30 | ||
| 31 | is_trait: bool => _target.is_trait | |
| 32 | is_classy: bool => _target.is_classy | |
| 33 | is_union: bool => _target.is_union | |
| 34 | is_variant: bool => _target.is_variant | |
| 35 | is_closed_root: bool => _target.is_closed_root | |
| 36 | is_unit_variant: bool => _target.is_unit_variant | |
| 37 | is_instance_context: bool => _target.is_instance_context | |
| 38 | ||
| 39 | // Closures declared inside an injected member are tracked on this | |
| 40 | // scope rather than the target so the block emits them itself, once | |
| 41 | // their bodies have been walked. Emitting them from the target's | |
| 42 | // primary definition would run before the block's bodies are | |
| 43 | // generated, leaving the closure methods bodyless. Without this | |
| 44 | // ClosureContext the closure-context search skips the injection | |
| 45 | // scope and registers the closure on the enclosing namespace. | |
| 46 | add_closure(closure: Symbols.Closure) is | |
| 47 | if !_closures? then | |
| 48 | _closures = Collections.SET[Symbols.Closure]() | |
| 49 | fi | |
| 50 | ||
| 51 | if !_closures.contains(closure) then | |
| 52 | _closures.add(closure) | |
| 53 | fi | |
| 54 | si | |
| 55 | ||
| 56 | get_closures() -> Collections.Iterable[Symbols.Closure] => | |
| 57 | if _closures? then _closures else Collections.LIST[Symbols.Closure](0) fi | |
| 58 | ||
| 59 | init(target: Symbols.Classy, lexical: Scope) is | |
| 60 | _target = target | |
| 61 | _lexical = lexical | |
| 62 | si | |
| 63 | ||
| 64 | qualify(name: string) -> string => _target.qualify(name) | |
| 65 | ||
| 66 | find_direct(name: string) -> Symbol? => _target.find_direct(name) | |
| 67 | ||
| 68 | find_member(name: string) -> Symbol? => _target.find_member(name) | |
| 69 | ||
| 70 | find_enclosing(name: string) -> Symbol? is | |
| 71 | let result = _target.find_direct(name) | |
| 72 | ||
| 73 | if result? then | |
| 74 | if !isa Symbols.FUNCTION_GROUP(result) then | |
| 75 | return result | |
| 76 | fi | |
| 77 | ||
| 78 | let outer = _lexical.find_enclosing(name) | |
| 79 | ||
| 80 | if !outer? \/ !isa Symbols.FUNCTION_GROUP(outer) then | |
| 81 | return result | |
| 82 | fi | |
| 83 | ||
| 84 | return result.merged_over(outer) | |
| 85 | fi | |
| 86 | ||
| 87 | return _lexical.find_enclosing(name) | |
| 88 | si | |
| 89 | ||
| 90 | find_direct_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 91 | _target.find_direct_matches(prefix, matches) | |
| 92 | si | |
| 93 | ||
| 94 | find_member_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 95 | _target.find_member_matches(prefix, matches) | |
| 96 | si | |
| 97 | ||
| 98 | find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string,Symbol]) is | |
| 99 | _target.find_direct_matches(prefix, matches) | |
| 100 | _lexical.find_enclosing_matches(prefix, matches) | |
| 101 | si | |
| 102 | ||
| 103 | to_string() -> string => "injection scope for: {_target.qualified_name}" | |
| 104 | si | |
| 105 | si |