/// <summary> /// Combines independent resolutions in a disjointed dictionary, resulting in a /// resolution dictionary that has type parameter keys that are not referenced /// in its values. Null mappings are removed in the resulting dictionary. /// Returns the resulting dictionary. /// </summary> private TypeParameterResolutions CombineTypeResolutionDictionary(TypeParameterResolutions independentResolutions) { var combinedBuilder = ImmutableDictionary.CreateBuilder <TypeParameterName, ResolvedType>(); foreach (var(typeParam, paramRes) in independentResolutions) { // Skip any null mappings if (paramRes is null) { continue; } // Contains a lookup of all the keys in the combined resolutions whose value needs to be updated // if a certain type parameter is resolved by the currently processed dictionary. var mayBeReplaced = GetReplaceable(combinedBuilder); // Check that we are not constricting a type parameter to another type parameter of the same callable // both before and after updating the current value with the resolutions processed so far. this.UpdateConstrictionFlag(typeParam, paramRes); var resolvedParamRes = ResolvedType.ResolveTypeParameters(combinedBuilder.ToImmutable(), paramRes); this.UpdateConstrictionFlag(typeParam, resolvedParamRes); // Do any replacements for type parameters that may be replaced with the current resolution. this.UpdatedReplaceableResolutions(mayBeReplaced, combinedBuilder, typeParam, resolvedParamRes); // Add the resolution to the current dictionary. combinedBuilder[typeParam] = resolvedParamRes; } return(combinedBuilder.ToImmutable()); }
/// <summary> /// Uses the given lookup, mayBeReplaced, to determine what records in the combinedBuilder can be updated /// from the given type parameter, typeParam, and its resolution, paramRes. Then updates the combinedBuilder /// appropriately. /// </summary> private void UpdatedReplaceableResolutions( ILookup <TypeParameterName, TypeParameterName> mayBeReplaced, TypeParameterResolutions.Builder combinedBuilder, TypeParameterName typeParam, ResolvedType paramRes) { // Create a dictionary with just the current resolution in it. var singleResolution = new[] { 0 }.ToImmutableDictionary(_ => typeParam, _ => paramRes); // Get all the parameters whose value is dependent on the current resolution's type parameter, // and update their values with this resolution's value. foreach (var keyInCombined in mayBeReplaced[typeParam]) { // Check that we are not constricting a type parameter to another type parameter of the same callable. this.UpdateConstrictionFlag(keyInCombined, paramRes); combinedBuilder[keyInCombined] = ResolvedType.ResolveTypeParameters(singleResolution, combinedBuilder[keyInCombined]); } }