Appearance
| 1 | namespace Semantic.DotNet is | |
| 2 | use IO.Std; | |
| 3 | ||
| 4 | use Collections.Iterable; | |
| 5 | use Collections.Iterator; | |
| 6 | ||
| 7 | use Collections.SET; | |
| 8 | use Collections.LIST; | |
| 9 | use Collections.MAP; | |
| 10 | ||
| 11 | use Pair = Collections.KeyValuePair; | |
| 12 | ||
| 13 | use System.Reflection.MethodInfo; | |
| 14 | use System.Reflection.TypeInfo; | |
| 15 | ||
| 16 | use Ghul.Pipes; | |
| 17 | ||
| 18 | use Symbols.Symbol; | |
| 19 | use Symbols.Scope; | |
| 20 | use Symbols.Function; | |
| 21 | use Symbols.FUNCTION_GROUP; | |
| 22 | ||
| 23 | use Types.Type; | |
| 24 | ||
| 25 | class AMBIGUOUS_METHOD_CHECKER(_logger: Logging.Logger) is | |
| 26 | ||
| 27 | check( | |
| 28 | owner: Symbol, | |
| 29 | functions: Iterable[(function: Function, method_info: MethodInfo)] | |
| 30 | ) is | |
| 31 | let map = MAP[(name: string, number_of_arguments: int), LIST[(function: Function, method_info: MethodInfo)]](); | |
| 32 | ||
| 33 | for f_mi in functions do | |
| 34 | let list: LIST[(function: Function, method_info: MethodInfo)] mut; | |
| 35 | ||
| 36 | let name = f_mi.function.name; | |
| 37 | let number_of_arguments = f_mi.function.argument_names.count; | |
| 38 | ||
| 39 | if !map.try_get_value((name, number_of_arguments), list ref) then | |
| 40 | list = LIST[(Function, MethodInfo)](); | |
| 41 | map[(name, number_of_arguments)] = list; | |
| 42 | fi | |
| 43 | ||
| 44 | list.add(f_mi); | |
| 45 | od | |
| 46 | ||
| 47 | for kv in map do | |
| 48 | if kv.value.count <= 1 then | |
| 49 | continue; | |
| 50 | fi | |
| 51 | ||
| 52 | check( | |
| 53 | owner, | |
| 54 | kv.key.name, | |
| 55 | kv.value |> | |
| 56 | map(f_mi => f_mi.function) |> | |
| 57 | filter(f => f.is_instance /\ !f.is_internal) | |
| 58 | ); | |
| 59 | ||
| 60 | check( | |
| 61 | owner, | |
| 62 | kv.key.name, | |
| 63 | kv.value |> | |
| 64 | map(f_mi => f_mi.function) |> | |
| 65 | filter(f => !f.is_instance /\ !f.is_internal) | |
| 66 | ); | |
| 67 | od | |
| 68 | si | |
| 69 | ||
| 70 | check(owner: Symbol, name: string, functions: Iterable[Function]) is | |
| 71 | let map = METHOD_OVERRIDE_MAP(name); | |
| 72 | ||
| 73 | map.add(functions); | |
| 74 | ||
| 75 | for s in map do | |
| 76 | if s.count > 1 then | |
| 77 | for function in s.iterable do | |
| 78 | if function.owner != owner then | |
| 79 | function.hide(); | |
| 80 | fi | |
| 81 | od | |
| 82 | fi | |
| 83 | od | |
| 84 | si | |
| 85 | si | |
| 86 | si |