/// <summary> /// Reverses the dependencies of type parameters resolving to other type parameters in the given /// dictionary to create a lookup whose keys are type parameters and whose values are all the type /// parameters that can be updated by knowing the resolution of the lookup's associated key. /// </summary> private static ILookup <TypeParameterName, TypeParameterName> GetReplaceable(TypeParameterResolutions.Builder typeParamResolutions) { return(typeParamResolutions .Select(kvp => (kvp.Key, GetTypeParameters.Apply(kvp.Value))) // Get any type parameters in the resolution type. .SelectMany(tup => tup.Item2.Select(value => (tup.Key, value))) // For each type parameter found, match it to the dictionary key. .ToLookup( // Reverse the keys and resulting type parameters to make the lookup. kvp => kvp.value, kvp => kvp.Key)); }
/// <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]); } }