//		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()));
        }
示例#2
0
 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());
        }