Appearance
| 1 | namespace Syntax.Process is | |
| 2 | ||
| 3 | use Logging | |
| 4 | use Trees | |
| 5 | use Source | |
| 6 | ||
| 7 | class RESOLVE_OVERRIDES: ScopedVisitor is | |
| 8 | _logger: Logger | |
| 9 | _symbol_table: Semantic.SYMBOL_TABLE | |
| 10 | ||
| 11 | _done_object: bool | |
| 12 | ||
| 13 | _duplicate_method_checker: Semantic.DUPLICATE_METHOD_CHECKER | |
| 14 | ||
| 15 | init( | |
| 16 | logger: Logger, | |
| 17 | symbol_table: Semantic.SYMBOL_TABLE, | |
| 18 | namespaces: Semantic.NAMESPACES | |
| 19 | ) | |
| 20 | is | |
| 21 | super.init(logger, symbol_table, namespaces) | |
| 22 | ||
| 23 | _logger = logger | |
| 24 | _symbol_table = symbol_table | |
| 25 | ||
| 26 | _duplicate_method_checker = Semantic.DUPLICATE_METHOD_CHECKER(logger) | |
| 27 | si | |
| 28 | ||
| 29 | apply(root: Trees.Node) is | |
| 30 | // FIXME: this isn't needed | |
| 31 | if !_done_object then | |
| 32 | let lookup = IoC.CONTAINER.instance.innate_symbol_lookup | |
| 33 | ||
| 34 | lookup.get_object_type().symbol.pull_down_super_symbols() | |
| 35 | lookup.get_value_type().symbol.pull_down_super_symbols() | |
| 36 | ||
| 37 | _done_object = true | |
| 38 | fi | |
| 39 | ||
| 40 | root.walk(self) | |
| 41 | si | |
| 42 | ||
| 43 | check_duplicate_global_functions() is | |
| 44 | for ns in _namespaces do | |
| 45 | try | |
| 46 | _duplicate_method_checker.check(ns, "duplicate function") | |
| 47 | catch e: System.Exception | |
| 48 | _logger.exception(ns.location, e, "exception checking for duplicate global functions") | |
| 49 | yrt | |
| 50 | od | |
| 51 | si | |
| 52 | ||
| 53 | pre(`class: Trees.Definitions.CLASS) -> bool => true | |
| 54 | ||
| 55 | visit(`class: Definitions.CLASS) is | |
| 56 | let symbol = symbol_for(`class) | |
| 57 | ||
| 58 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 59 | _duplicate_method_checker.check(symbol, "duplicate method") | |
| 60 | ||
| 61 | symbol.pull_down_super_symbols() | |
| 62 | ||
| 63 | Semantic.Symbols.STATIC_INTERFACE_IMPLEMENTATION_CHECKER(_logger).check(symbol) | |
| 64 | fi | |
| 65 | si | |
| 66 | ||
| 67 | pre(`trait: Trees.Definitions.TRAIT) -> bool => true | |
| 68 | ||
| 69 | visit(`trait: Definitions.TRAIT) is | |
| 70 | let symbol = symbol_for(`trait) | |
| 71 | ||
| 72 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 73 | _duplicate_method_checker.check(symbol, "duplicate method") | |
| 74 | ||
| 75 | symbol.pull_down_super_symbols() | |
| 76 | ||
| 77 | Semantic.Symbols.VARIANCE_POSITION_CHECKER(symbol, _logger).check() | |
| 78 | fi | |
| 79 | si | |
| 80 | ||
| 81 | pre(`struct: Trees.Definitions.STRUCT) -> bool => true | |
| 82 | ||
| 83 | visit(`struct: Definitions.STRUCT) is | |
| 84 | let symbol = symbol_for(`struct) | |
| 85 | ||
| 86 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 87 | symbol.pull_down_super_symbols() | |
| 88 | ||
| 89 | Semantic.Symbols.STATIC_INTERFACE_IMPLEMENTATION_CHECKER(_logger).check(symbol) | |
| 90 | fi | |
| 91 | si | |
| 92 | ||
| 93 | // Walk into the union body so variants get visited (their | |
| 94 | // `pull_down_super_symbols()` runs in `visit(variant)` below). | |
| 95 | // Without this, variants never have inherited members like | |
| 96 | // `to_string` pulled into their scope, so member lookup on a | |
| 97 | // variant type misses anything inherited via the union from | |
| 98 | // `object`. | |
| 99 | pre(`union: Trees.Definitions.UNION) -> bool => false | |
| 100 | ||
| 101 | visit(`union: Definitions.UNION) is | |
| 102 | let symbol = symbol_for(`union) | |
| 103 | ||
| 104 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 105 | symbol.pull_down_super_symbols() | |
| 106 | fi | |
| 107 | si | |
| 108 | ||
| 109 | pre(variant: Trees.Definitions.VARIANT) -> bool => true | |
| 110 | ||
| 111 | visit(variant: Definitions.VARIANT) is | |
| 112 | let symbol = symbol_for(variant) | |
| 113 | ||
| 114 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 115 | symbol.pull_down_super_symbols() | |
| 116 | fi | |
| 117 | si | |
| 118 | ||
| 119 | pre(`enum: Trees.Definitions.ENUM) -> bool => true | |
| 120 | ||
| 121 | visit(`enum: Definitions.ENUM) is | |
| 122 | let symbol = symbol_for(`enum) | |
| 123 | ||
| 124 | if symbol? /\ isa Semantic.Symbols.Classy(symbol) then | |
| 125 | symbol.pull_down_super_symbols() | |
| 126 | fi | |
| 127 | si | |
| 128 | si | |
| 129 | si |