/// <summary> /// Gets the invoke method for a delegate type. /// </summary> /// <remarks> /// Returns null if the type is not a delegate type; or if the invoke method could not be found. /// </remarks> public static IMethod GetDelegateInvokeMethod(this IType type) { if (type == null) { throw new ArgumentNullException("type"); } ITypeDefinition def = type.GetDefinition(); if (def != null && def.ClassType == ClassType.Delegate) { foreach (IMethod method in def.Methods) { if (method.Name == "Invoke") { ParameterizedType pt = type as ParameterizedType; if (pt != null) { SpecializedMethod m = new SpecializedMethod(method); m.SetDeclaringType(pt); var substitution = pt.GetSubstitution(); m.SubstituteTypes(t => new SubstitutionTypeReference(t, substitution)); return(m); } return(method); } } } return(null); }
public void GetIndexDoubleSpecialization() { var testClass = GetTypeDefinition(typeof(GenericClass <,>)); // GenericClass<A, B>.GetIndex<T> var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex"); // GenericClass<B, A>.GetIndex<A> var m1 = new SpecializedMethod(methodDef, new TypeParameterSubstitution( new[] { testClass.TypeParameters[1], testClass.TypeParameters[0] }, new[] { testClass.TypeParameters[0] } )); // GenericClass<string, int>.GetIndex<int> var m2 = new SpecializedMethod(m1, new TypeParameterSubstitution( new[] { compilation.FindType(KnownTypeCode.Int32), compilation.FindType(KnownTypeCode.String) }, null )); // GenericClass<string, int>.GetIndex<int> var m12 = new SpecializedMethod(methodDef, new TypeParameterSubstitution( new[] { compilation.FindType(KnownTypeCode.String), compilation.FindType(KnownTypeCode.Int32) }, new[] { compilation.FindType(KnownTypeCode.Int32) } )); Assert.AreEqual(m12, m2); }
public IParameterizedMember GetBestCandidateWithSubstitutedTypeArguments() { if (bestCandidate == null) { return(null); } IMethod method = bestCandidate.Member as IMethod; if (method != null && method.TypeParameters.Count > 0) { SpecializedMethod sm = method as SpecializedMethod; if (sm != null) { // Do not compose the substitutions, but merge them. // This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce return(new SpecializedMethod( (IMethod)method.MemberDefinition, new TypeParameterSubstitution(sm.Substitution.ClassTypeArguments, bestCandidate.InferredTypes))); } else { return(new SpecializedMethod(method, new TypeParameterSubstitution(null, bestCandidate.InferredTypes))); } } else { return(bestCandidate.Member); } }
public static IMethod CreateTypeCheckMethod(IType type, ICompilation compilation) { IMethod method = new DefaultResolvedMethod(new DefaultUnresolvedMethod(type.GetDefinition().Parts[0], "IsInstanceOfType"), compilation.TypeResolveContext.WithCurrentTypeDefinition(type.GetDefinition())); if (type is ParameterizedType) { method = new SpecializedMethod(method, new TypeParameterSubstitution(classTypeArguments: ((ParameterizedType)type).TypeArguments, methodTypeArguments: null)); } return(method); }
public IEnumerable <IMethod> GetConstructors(ITypeResolveContext context, Predicate <IMethod> filter = null) { Substitution substitution = new Substitution(typeArguments); List <IMethod> methods = genericType.GetConstructors(context, filter).ToList(); for (int i = 0; i < methods.Count; i++) { SpecializedMethod m = new SpecializedMethod(methods[i]); m.SetDeclaringType(this); m.SubstituteTypes(context, substitution); methods[i] = m; } return(methods); }
TypeParameterSubstitution GetSubstitution(Candidate candidate) { SpecializedMethod sm = candidate.Member as SpecializedMethod; if (sm != null) { // Do not compose the substitutions, but merge them. // This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce return(new TypeParameterSubstitution(sm.Substitution.ClassTypeArguments, candidate.InferredTypes)); } else { return(new TypeParameterSubstitution(null, candidate.InferredTypes)); } }
public static IMethod CreateDummyMethodForFieldInitialization(IMember member, ICompilation compilation) { var unresolved = new DefaultUnresolvedMethod(member.DeclaringTypeDefinition.Parts[0], "initialization for " + member.Name) { Parameters = { new DefaultUnresolvedParameter(member.ReturnType.ToTypeReference(), "value") }, IsStatic = member.IsStatic, }; IMethod method = new DefaultResolvedMethod(unresolved, compilation.TypeResolveContext.WithCurrentTypeDefinition(member.DeclaringTypeDefinition)); if (member.DeclaringType is ParameterizedType) { method = new SpecializedMethod(method, new TypeParameterSubstitution(classTypeArguments: ((ParameterizedType)member.DeclaringType).TypeArguments, methodTypeArguments: null)); } return(method); }
public IEnumerable <IMethod> GetMethods(ITypeResolveContext context, Predicate <IMethod> filter = null) { Substitution substitution = new Substitution(typeArguments); Func <ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution); List <IMethod> methods = genericType.GetMethods(context, filter).ToList(); for (int i = 0; i < methods.Count; i++) { SpecializedMethod m = new SpecializedMethod(methods[i]); m.SetDeclaringType(this); m.SubstituteTypes(substitutionFunc); methods[i] = m; } return(methods); }
public void GetIndexSpecializedTypeParameter() { var testClass = GetTypeDefinition(typeof(GenericClass <,>)); var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex"); var m = new SpecializedMethod(methodDef, new TypeParameterSubstitution( new[] { compilation.FindType(KnownTypeCode.Int16), compilation.FindType(KnownTypeCode.Int32) }, null )); Assert.AreEqual("T", m.TypeParameters[0].Name); Assert.AreEqual(EntityType.Method, m.TypeParameters[0].OwnerType); Assert.AreSame(m, m.TypeParameters[0].Owner); ParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First(); Assert.AreEqual("IEquatable", constraint.Name); Assert.AreEqual(1, constraint.TypeParameterCount); Assert.AreEqual(1, constraint.TypeArguments.Count); Assert.AreSame(m.TypeParameters[0], constraint.TypeArguments[0]); }
public void ConvertAllInGenericMethod() { string program = @"using System; class TestClass { static void Method<T>(System.Collections.Generic.List<T> list) { $list.ConvertAll(x => (int)x)$; } }"; var rr = Resolve <CSharpInvocationResolveResult>(program); Assert.IsFalse(rr.IsError); SpecializedMethod m = (SpecializedMethod)rr.Member; Assert.AreEqual("System.Int32", m.TypeArguments[0].ReflectionName); Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", m.Parameters[0].Type.ReflectionName); var crr = (ConversionResolveResult)rr.Arguments[0]; Assert.IsTrue(crr.Conversion.IsAnonymousFunctionConversion); Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", crr.Type.ReflectionName); }
IMember Specialize(IMember member, Func <ITypeReference, ITypeReference> substitution) { IMethod method = member as IMethod; if (method != null) { SpecializedMethod m = new SpecializedMethod(method); m.SetDeclaringType(this); m.SubstituteTypes(substitution); return(m); } IProperty property = member as IProperty; if (property != null) { SpecializedProperty p = new SpecializedProperty(property); p.SetDeclaringType(this); p.SubstituteTypes(substitution); return(p); } IField field = member as IField; if (field != null) { SpecializedField f = new SpecializedField(field); f.SetDeclaringType(this); f.ReturnType = substitution(f.ReturnType); return(f); } IEvent ev = member as IEvent; if (ev != null) { SpecializedEvent e = new SpecializedEvent(ev); e.SetDeclaringType(this); e.ReturnType = substitution(e.ReturnType); return(e); } throw new ArgumentException("Unknown member"); }
public IMethod Specialize(TypeParameterSubstitution substitution) => SpecializedMethod.Create(this, substitution);