// public static bool CompatibleSignatureToDelegate(this IMethodSymbol method, INamedTypeSymbol delegateType) // { // //Contract.ThrowIfFalse(delegateType.TypeKind == TypeKind.Delegate); // // var invoke = delegateType.DelegateInvokeMethod; // if (invoke == null) // { // // It's possible to get events with no invoke method from metadata. We will assume // // that no method can be an event handler for one. // return false; // } // // if (method.Parameters.Length != invoke.Parameters.Length) // { // return false; // } // // if (method.ReturnsVoid != invoke.ReturnsVoid) // { // return false; // } // // if (!method.ReturnType.InheritsFromOrEquals(invoke.ReturnType)) // { // return false; // } // // for (int i = 0; i < method.Parameters.Length; i++) // { // if (!invoke.Parameters[i].Type.InheritsFromOrEquals(method.Parameters[i].Type)) // { // return false; // } // } // // return true; // } // public static IMethodSymbol RenameTypeParameters(this IMethodSymbol method, IList <string> newNames) { if (method.TypeParameters.Select(t => t.Name).SequenceEqual(newNames)) { return(method); } var typeGenerator = new TypeGenerator(); var updatedTypeParameters = RenameTypeParameters( method.TypeParameters, newNames, typeGenerator); var mapping = new Dictionary <ITypeSymbol, ITypeSymbol>(); for (int i = 0; i < method.TypeParameters.Length; i++) { mapping.Add(method.TypeParameters[i], updatedTypeParameters[i]); } return(CodeGenerationSymbolFactory.CreateMethodSymbol( method.ContainingType, method.GetAttributes(), method.DeclaredAccessibility, method.GetSymbolModifiers(), method.ReturnType.SubstituteTypes(mapping, typeGenerator), method.ExplicitInterfaceImplementations.FirstOrDefault(), method.Name, updatedTypeParameters, method.Parameters.Select(p => CodeGenerationSymbolFactory.CreateParameterSymbol(p.GetAttributes(), p.RefKind, p.IsParams, p.Type.SubstituteTypes(mapping, typeGenerator), p.Name, p.IsOptional, p.HasExplicitDefaultValue, p.HasExplicitDefaultValue ? p.ExplicitDefaultValue : null)).ToList())); }
public static ITypeSymbol SubstituteTypes <TType1, TType2>( this ITypeSymbol type, IDictionary <TType1, TType2> mapping, TypeGenerator typeGenerator) where TType1 : ITypeSymbol where TType2 : ITypeSymbol { try { return((ITypeSymbol)substituteTypesMethod2.MakeGenericMethod(typeof(TType1), typeof(TType2)).Invoke(null, new object[] { type, mapping, typeGenerator.Instance })); } catch (TargetInvocationException ex) { ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); return(null); } }
private static IList <ITypeParameterSymbol> RenameTypeParameters( IList <ITypeParameterSymbol> typeParameters, IList <string> newNames, TypeGenerator typeGenerator) { // We generate the type parameter in two passes. The first creates the new type // parameter. The second updates the constraints to point at this new type parameter. var newTypeParameters = new List <CodeGenerationTypeParameterSymbol>(); var mapping = new Dictionary <ITypeSymbol, ITypeSymbol>(); for (int i = 0; i < typeParameters.Count; i++) { var typeParameter = typeParameters[i]; var newTypeParameter = new CodeGenerationTypeParameterSymbol( typeParameter.ContainingType, typeParameter.GetAttributes(), typeParameter.Variance, newNames[i], typeParameter.ConstraintTypes, typeParameter.HasConstructorConstraint, typeParameter.HasReferenceTypeConstraint, typeParameter.HasValueTypeConstraint, typeParameter.Ordinal); newTypeParameters.Add(newTypeParameter); mapping.Add(typeParameter, (ITypeSymbol)newTypeParameter.Instance); } // Now we update the constraints. foreach (var newTypeParameter in newTypeParameters) { newTypeParameter.ConstraintTypes = ImmutableArray.CreateRange(newTypeParameter.ConstraintTypes, t => t.SubstituteTypes(mapping, typeGenerator)); } return(newTypeParameters.Cast <ITypeParameterSymbol>().ToList()); }