Appearance
| 1 | namespace Syntax.Process is | |
| 2 | use Ghul.Pipes | |
| 3 | ||
| 4 | // Whether a member is one an operator expression can never call. | |
| 5 | // | |
| 6 | // The flag is set on the reflected interface member of a type whose | |
| 7 | // operator is innate - the scalars, whose `<>` is a comparison | |
| 8 | // opcode, and `string`, whose `=~` is the null-safe intrinsic. Every | |
| 9 | // operator on those resolves to the innate instead, `<>` written | |
| 10 | // directly included. | |
| 11 | // | |
| 12 | // Both the operator compiler and the store-free analysis have to | |
| 13 | // agree on this. The first discards these members when it gathers | |
| 14 | // candidates; the second must then not follow their call edges, or | |
| 15 | // it would bound the enclosing function by a method the operator | |
| 16 | // cannot invoke. Sharing one predicate is what keeps the two from | |
| 17 | // drifting apart. | |
| 18 | class HIDDEN_OPERATOR_MEMBERS is | |
| 19 | is_hidden(symbol: Semantic.Symbols.Symbol?) -> bool static is | |
| 20 | if !symbol? then | |
| 21 | return false | |
| 22 | fi | |
| 23 | ||
| 24 | if isa Semantic.Symbols.FUNCTION_GROUP(symbol) then | |
| 25 | let group = cast Semantic.Symbols.FUNCTION_GROUP(symbol) | |
| 26 | ||
| 27 | // An empty group has nothing to hide, and `all` over | |
| 28 | // nothing would answer true. | |
| 29 | if group.functions.count == 0 then | |
| 30 | return false | |
| 31 | fi | |
| 32 | ||
| 33 | return group.functions |> all(f => f.is_hidden_from_operator_resolution) | |
| 34 | fi | |
| 35 | ||
| 36 | if isa Semantic.Symbols.Function(symbol) then | |
| 37 | return (cast Semantic.Symbols.Function(symbol)).is_hidden_from_operator_resolution | |
| 38 | fi | |
| 39 | ||
| 40 | return false | |
| 41 | si | |
| 42 | si | |
| 43 | si |