Appearance
| 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 |