/// <summary> /// Substitute types, and return the results without duplicates, preserving the original order. /// Note, all occurrences of 'dynamic' in resulting types will be replaced with 'object'. /// </summary> internal void SubstituteConstraintTypesDistinctWithoutModifiers( TypeParameterSymbol owner, ImmutableArray <TypeWithAnnotations> original, ArrayBuilder <TypeWithAnnotations> result, HashSet <TypeParameterSymbol> ignoreTypesDependentOnTypeParametersOpt) { DynamicTypeEraser dynamicEraser = null; if (original.Length == 0) { return; } else if (original.Length == 1) { var type = original[0]; if (ignoreTypesDependentOnTypeParametersOpt == null || !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt)) { result.Add(substituteConstraintType(type)); } } else { var map = PooledDictionary <TypeSymbol, int> .GetInstance(); foreach (var type in original) { if (ignoreTypesDependentOnTypeParametersOpt == null || !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt)) { var substituted = substituteConstraintType(type); if (!map.TryGetValue(substituted.Type, out int mergeWith)) { map.Add(substituted.Type, result.Count); result.Add(substituted); } else { result[mergeWith] = ConstraintsHelper.ConstraintWithMostSignificantNullability(result[mergeWith], substituted); } } } map.Free(); } TypeWithAnnotations substituteConstraintType(TypeWithAnnotations type) { if (dynamicEraser == null) { dynamicEraser = new DynamicTypeEraser(owner.ContainingAssembly.CorLibrary.GetSpecialType(SpecialType.System_Object)); } TypeWithAnnotations substituted = SubstituteType(type); return(substituted.WithTypeAndModifiers(dynamicEraser.EraseDynamic(substituted.Type), substituted.CustomModifiers)); } }
/// <summary> /// Substitute types, and return the results without duplicates, preserving the original order. /// </summary> internal void SubstituteConstraintTypesDistinctWithoutModifiers( ImmutableArray <TypeWithAnnotations> original, ArrayBuilder <TypeWithAnnotations> result, HashSet <TypeParameterSymbol> ignoreTypesDependentOnTypeParametersOpt) { if (original.Length == 0) { return; } else if (original.Length == 1) { var type = original[0]; if (ignoreTypesDependentOnTypeParametersOpt == null || !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt)) { result.Add(SubstituteType(type)); } } else { var map = PooledDictionary <TypeSymbol, int> .GetInstance(); foreach (var type in original) { if (ignoreTypesDependentOnTypeParametersOpt == null || !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt)) { var substituted = SubstituteType(type); if (!map.TryGetValue(substituted.Type, out int mergeWith)) { map.Add(substituted.Type, result.Count); result.Add(substituted); } else { result[mergeWith] = ConstraintsHelper.ConstraintWithMostSignificantNullability(result[mergeWith], substituted); } } } map.Free(); } }