Appearance
| 1 | namespace Semantic is | |
| 2 | use IO.Std; | |
| 3 | ||
| 4 | use System.Text.StringBuilder; | |
| 5 | ||
| 6 | use Collections.Iterable; | |
| 7 | use Collections.Iterator; | |
| 8 | ||
| 9 | use Collections.MAP; | |
| 10 | use Collections.SET; | |
| 11 | ||
| 12 | use Symbols.Symbol; | |
| 13 | use Symbols.Function; | |
| 14 | ||
| 15 | class METHOD_OVERRIDE_MAP(name: string): Iterable[METHOD_OVERRIDE_SET] is | |
| 16 | _symbols: SET[SYMBOL_WRAPPER]; | |
| 17 | _symbols_list: Collections.LIST[Symbol]?; | |
| 18 | ||
| 19 | methods: MAP[METHOD_OVERRIDE_CLASS,METHOD_OVERRIDE_SET]; | |
| 20 | ||
| 21 | // Read several times per class during override resolution, so the | |
| 22 | // projected list is built once and reused; `add` resets it. | |
| 23 | symbols: Iterable[Symbol] is | |
| 24 | if _symbols_list? then | |
| 25 | return _symbols_list; | |
| 26 | fi | |
| 27 | ||
| 28 | let list = Collections.LIST[Symbol](); | |
| 29 | ||
| 30 | for w in _symbols do | |
| 31 | list.add(w.symbol); | |
| 32 | od | |
| 33 | ||
| 34 | _symbols_list = list; | |
| 35 | ||
| 36 | return list; | |
| 37 | si | |
| 38 | ||
| 39 | // Avoids building and piping `symbols` when only the first element | |
| 40 | // is wanted. | |
| 41 | first_symbol: Symbol? is | |
| 42 | for w in _symbols do | |
| 43 | return w.symbol; | |
| 44 | od | |
| 45 | ||
| 46 | return null; | |
| 47 | si | |
| 48 | ||
| 49 | iterator: Iterator[METHOD_OVERRIDE_SET] => methods.values.iterator; | |
| 50 | ||
| 51 | contains_any_methods: bool => methods.count > 0; | |
| 52 | contains_any_symbols: bool => _symbols.count > 0; | |
| 53 | ||
| 54 | _empty: METHOD_OVERRIDE_MAP? static; | |
| 55 | ||
| 56 | // Shared, read-only empty map for the common case where a class | |
| 57 | // declares no member of a given name. Only ever read, never added to. | |
| 58 | empty: METHOD_OVERRIDE_MAP static is | |
| 59 | if _empty? then | |
| 60 | return _empty; | |
| 61 | fi | |
| 62 | ||
| 63 | let empty = METHOD_OVERRIDE_MAP(""); | |
| 64 | ||
| 65 | _empty = empty; | |
| 66 | ||
| 67 | return empty; | |
| 68 | si | |
| 69 | ||
| 70 | [method_class: METHOD_OVERRIDE_CLASS]: METHOD_OVERRIDE_SET? is | |
| 71 | let result: METHOD_OVERRIDE_SET mut; | |
| 72 | ||
| 73 | if methods.try_get_value(method_class, result ref) then | |
| 74 | return result; | |
| 75 | fi | |
| 76 | ||
| 77 | return null; | |
| 78 | si | |
| 79 | ||
| 80 | init(..) is | |
| 81 | methods = MAP(); | |
| 82 | _symbols = SET(); | |
| 83 | si | |
| 84 | ||
| 85 | contains(override_class: METHOD_OVERRIDE_CLASS) -> bool => methods.contains_key(override_class); | |
| 86 | ||
| 87 | add(symbol: Symbol) is | |
| 88 | if isa Function(symbol) then | |
| 89 | add(symbol); | |
| 90 | ||
| 91 | return; | |
| 92 | fi | |
| 93 | ||
| 94 | let wrapper = SYMBOL_WRAPPER(symbol); | |
| 95 | ||
| 96 | if !_symbols.contains(wrapper) then | |
| 97 | _symbols.add(wrapper); | |
| 98 | _symbols_list = null; | |
| 99 | fi | |
| 100 | si | |
| 101 | ||
| 102 | add(group: Symbols.FUNCTION_GROUP) is | |
| 103 | for f in group.functions do | |
| 104 | add(f); | |
| 105 | od | |
| 106 | si | |
| 107 | ||
| 108 | add(functions: Iterable[Function]) is | |
| 109 | for f in functions do | |
| 110 | add(f); | |
| 111 | od | |
| 112 | si | |
| 113 | ||
| 114 | add(method: Function) is | |
| 115 | let c = method.override_class; | |
| 116 | ||
| 117 | let method_set: METHOD_OVERRIDE_SET mut; | |
| 118 | ||
| 119 | if !methods.try_get_value(c, method_set ref) then | |
| 120 | method_set = METHOD_OVERRIDE_SET(c); | |
| 121 | methods[c] = method_set; | |
| 122 | fi | |
| 123 | ||
| 124 | assert method_set? else "no method set for {method.qualified_name}"; | |
| 125 | ||
| 126 | method_set.add(method); | |
| 127 | si | |
| 128 | ||
| 129 | to_string() -> string is | |
| 130 | let result = StringBuilder(); | |
| 131 | ||
| 132 | for s in methods do | |
| 133 | result.append("{name}: [{s.key}: {s.value}]"); | |
| 134 | od | |
| 135 | ||
| 136 | result.append(" others: ").append(symbols|); | |
| 137 | ||
| 138 | return result.to_string(); | |
| 139 | si | |
| 140 | si | |
| 141 | si |