Appearance
| 1 | namespace Semantic.Symbols is | |
| 2 | use Collections.List | |
| 3 | use Collections.LIST | |
| 4 | use Collections.MAP | |
| 5 | ||
| 6 | use Types.Type | |
| 7 | ||
| 8 | use Ghul.Pipes | |
| 9 | ||
| 10 | // Two declarations of the same generic method have type parameters | |
| 11 | // that are distinct symbols, so nothing relates one declaration's | |
| 12 | // `T` to the other's except the position each was declared in. | |
| 13 | // Reading one side's types in the other's terms is what lets the | |
| 14 | // two be compared at all - by the arguments they take, by the type | |
| 15 | // they return, and by anything else built from those parameters. | |
| 16 | class GENERIC_PARAMETER_ALIGNMENT is | |
| 17 | // `type`, as it reads where `ours` are the type parameters in | |
| 18 | // scope: each of `theirs` is replaced by whichever of `ours` | |
| 19 | // stands at the same position. Unchanged where either side | |
| 20 | // declares none, or where the two declare different numbers, | |
| 21 | // which is not an override in the first place. | |
| 22 | rewrite(type: Type, ours: List[Type], theirs: List[Type]) -> Type static is | |
| 23 | let substitution = _substitution(ours, theirs) | |
| 24 | ||
| 25 | if substitution.count == 0 then | |
| 26 | return type | |
| 27 | fi | |
| 28 | ||
| 29 | return type.specialize(substitution) | |
| 30 | si | |
| 31 | ||
| 32 | rewrite_all(types: List[Type], ours: List[Type], theirs: List[Type]) | |
| 33 | -> List[Type] static | |
| 34 | is | |
| 35 | let substitution = _substitution(ours, theirs) | |
| 36 | ||
| 37 | if substitution.count == 0 then | |
| 38 | return types | |
| 39 | fi | |
| 40 | ||
| 41 | return types |> map(t => t.specialize(substitution)) |> collect() | |
| 42 | si | |
| 43 | ||
| 44 | _substitution(ours: List[Type], theirs: List[Type]) | |
| 45 | -> Collections.Map[Symbol, Type] static | |
| 46 | is | |
| 47 | let result = MAP[Symbol, Type]() | |
| 48 | ||
| 49 | if ours.count == 0 \/ ours.count != theirs.count then | |
| 50 | return result | |
| 51 | fi | |
| 52 | ||
| 53 | for i in 0..ours.count do | |
| 54 | if let their_symbol = theirs[i].symbol then | |
| 55 | result[their_symbol] = ours[i] | |
| 56 | fi | |
| 57 | od | |
| 58 | ||
| 59 | return result | |
| 60 | si | |
| 61 | si | |
| 62 | si |