public void GenericMethodWithConstraintsTest() { // Test that constaints can reference other type parameters. ICompilationUnit cu = Parse(@" using System; class X { public static A Method<A, B>(A p1, B p2) where A : IComparable<B> where B : IComparable<A> { } } "); IMethod method = cu.Classes[0].Methods[0]; Assert.AreEqual(2, method.TypeParameters.Count); ITypeParameter a = method.TypeParameters[0]; ITypeParameter b = method.TypeParameters[1]; Assert.AreSame(a, method.ReturnType.CastToGenericReturnType().TypeParameter); Assert.AreSame(a, method.Parameters[0].ReturnType.CastToGenericReturnType().TypeParameter); Assert.AreSame(b, method.Parameters[1].ReturnType.CastToGenericReturnType().TypeParameter); Assert.AreEqual(1, a.Constraints.Count); ConstructedReturnType crt = a.Constraints[0].CastToConstructedReturnType(); Assert.AreEqual("IComparable", crt.Name); Assert.AreSame(b, crt.TypeArguments[0].CastToGenericReturnType().TypeParameter); Assert.AreEqual(1, b.Constraints.Count); crt = b.Constraints[0].CastToConstructedReturnType(); Assert.AreEqual("IComparable", crt.Name); Assert.AreSame(a, crt.TypeArguments[0].CastToGenericReturnType().TypeParameter); }
public void TypeParameterPassedToBaseClassSameClass() { IReturnType[] stringArr = { msc.SystemTypes.String }; IReturnType rrt = new ConstructedReturnType(EnumerableClass.DefaultReturnType, stringArr); IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(rrt, EnumerableClass, 0); Assert.AreEqual("System.String", res.FullyQualifiedName); }
public void GenericPropertyTest() { IClass c = mscorlib.GetClass("System.Collections.Generic.Comparer", 1); IProperty def = c.Properties.First(p => p.Name == "Default"); ConstructedReturnType crt = def.ReturnType.CastToConstructedReturnType(); Assert.AreEqual("System.Collections.Generic.Comparer", crt.FullyQualifiedName); Assert.IsTrue(crt.TypeArguments[0].IsGenericReturnType); }
public void TypeParameterPassedToBaseClassTestDictionary() { IReturnType[] stringInt = { msc.SystemTypes.String, msc.SystemTypes.Int32 }; IReturnType rrt = new ConstructedReturnType(DictionaryRT, stringInt); IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(rrt, EnumerableClass, 0); Assert.AreEqual("System.Collections.Generic.KeyValuePair", res.FullyQualifiedName); ConstructedReturnType resc = res.CastToConstructedReturnType(); Assert.AreEqual("System.String", resc.TypeArguments[0].FullyQualifiedName); Assert.AreEqual("System.Int32", resc.TypeArguments[1].FullyQualifiedName); }
public void TypeParameterPassedToBaseClassTestGenericClassDerivingFromList() { DefaultClass listDerivingClass = CreateGenericClassDerivingFromList(); ConstructedReturnType testType = new ConstructedReturnType(listDerivingClass.DefaultReturnType, new IReturnType[] { msc.SystemTypes.String }); IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(testType, EnumerableClass, 0); Assert.AreEqual("System.String", res.FullyQualifiedName); }
static IReturnType Parse(IProjectContent pc, IEnumerator <string> tokenizer) { string typeName = tokenizer.Current; if (typeName == null) { throw new ReflectionTypeNameSyntaxError("Unexpected end of type name"); } tokenizer.MoveNext(); int typeParameterCount; typeName = ReflectionClass.SplitTypeParameterCountFromReflectionName(typeName, out typeParameterCount); IReturnType rt = new GetClassReturnType(pc, typeName, typeParameterCount); if (tokenizer.Current == "[") { // this is a constructed type List <IReturnType> typeArguments = new List <IReturnType>(); do { tokenizer.MoveNext(); if (tokenizer.Current != "[") { throw new ReflectionTypeNameSyntaxError("Expected '['"); } tokenizer.MoveNext(); typeArguments.Add(Parse(pc, tokenizer)); if (tokenizer.Current != "]") { throw new ReflectionTypeNameSyntaxError("Expected ']' after generic argument"); } tokenizer.MoveNext(); } while (tokenizer.Current == ","); if (tokenizer.Current != "]") { throw new ReflectionTypeNameSyntaxError("Expected ']' after generic argument list"); } tokenizer.MoveNext(); rt = new ConstructedReturnType(rt, typeArguments); } while (tokenizer.Current == ",") { tokenizer.MoveNext(); string token = tokenizer.Current; if (token != null && token != "," && token != "[" && token != "]") { tokenizer.MoveNext(); } } return(rt); }
public void NestedClassInGenericClassTest() { IClass dictionary = mscorlib.GetClass("System.Collections.Generic.Dictionary", 2); Assert.IsNotNull(dictionary); IClass valueCollection = mscorlib.GetClass("System.Collections.Generic.Dictionary.ValueCollection", 2); Assert.IsNotNull(valueCollection); var dictionaryRT = new ConstructedReturnType(dictionary.DefaultReturnType, new[] { mscorlib.SystemTypes.String, mscorlib.SystemTypes.Int32 }); IProperty valueProperty = dictionaryRT.GetProperties().Find(p => p.Name == "Values"); Assert.AreSame(valueCollection, valueProperty.ReturnType.GetUnderlyingClass()); }
void UnpackNestedType(StringBuilder builder, IReturnType returnType) { if (returnType.IsArrayReturnType) { ArrayReturnType art = returnType.CastToArrayReturnType(); builder.Append('('); UnpackNestedType(builder, art.ArrayElementType); if (art.ArrayDimensions > 1) { builder.Append(','); builder.Append(art.ArrayDimensions); } builder.Append(')'); } else if (returnType.IsConstructedReturnType) { ConstructedReturnType crt = returnType.CastToConstructedReturnType(); UnpackNestedType(builder, crt.UnboundType); builder.Append("[of "); for (int i = 0; i < crt.TypeArguments.Count; ++i) { if (i > 0) { builder.Append(", "); } builder.Append(Convert(crt.TypeArguments[i])); } builder.Append(']'); } else { string fullName = returnType.FullyQualifiedName; if (fullName != null && typeConversionTable.ContainsKey(fullName)) { builder.Append(typeConversionTable[fullName].ToString()); } else { if (UseFullyQualifiedTypeNames) { builder.Append(fullName); } else { builder.Append(returnType.Name); } } } }
bool IsIEnumerableCollectionOrList(ConstructedReturnType rt) { if (rt == null || rt.TypeArgumentCount != 1) { return(false); } switch (rt.UnboundType.FullyQualifiedName) { case "System.Collections.Generic.IList": case "System.Collections.Generic.ICollection": case "System.Collections.Generic.IEnumerable": return(true); default: return(false); } }
/// <summary> /// Make exact inference from U for V. /// </summary> void MakeExactInference(IReturnType U, IReturnType V) { Log(" MakeExactInference from " + U + " for " + V); if (U == null || V == null) { return; } // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.Fixed == false) { Log(" Add bound '" + U.DotNetName + "' to " + tp); tp.Bounds.Add(U); return; } // Otherwise if U is an array type Ue[…] and V is an array type Ve[…] of the same rank // then an exact inference from Ue to Ve is made ArrayReturnType arrU = U.CastToArrayReturnType(); ArrayReturnType arrV = V.CastToArrayReturnType(); if (arrU != null && arrV != null && arrU.ArrayDimensions == arrV.ArrayDimensions) { MakeExactInference(arrU.ArrayElementType, arrV.ArrayElementType); return; } // Otherwise if V is a constructed type C<V1…Vk> and U is a constructed // type C<U1…Uk> then an exact inference is made from each Ui to the corresponding Vi. ConstructedReturnType CU = U.CastToConstructedReturnType(); ConstructedReturnType CV = V.CastToConstructedReturnType(); if (CU != null && CV != null && object.Equals(CU.UnboundType, CV.UnboundType) && CU.TypeArgumentCount == CV.TypeArgumentCount && CU.TypeArguments.Count == CU.TypeArgumentCount && CV.TypeArguments.Count == CV.TypeArgumentCount) { for (int i = 0; i < CU.TypeArgumentCount; i++) { MakeExactInference(CU.TypeArguments[i], CV.TypeArguments[i]); } return; } }
public void NestedInterfaceInGenericClass() { // See SD2-1626 DefaultProjectContent pc = new DefaultProjectContent(); pc.ReferencedContents.Add(SharedProjectContentRegistryForTests.Instance.Mscorlib); DefaultCompilationUnit cu = new DefaultCompilationUnit(pc); DefaultClass container = new DefaultClass(cu, "TestClass"); container.TypeParameters.Add(new DefaultTypeParameter(container, "T", 0)); DefaultClass innerClass = new DefaultClass(cu, container); innerClass.FullyQualifiedName = "TestClass.INestedInterface"; innerClass.ClassType = ClassType.Interface; innerClass.TypeParameters.Add(new DefaultTypeParameter(innerClass, "T", 0)); innerClass.Properties.Add(new DefaultProperty(innerClass, "P") { ReturnType = new GenericReturnType(innerClass.TypeParameters[0]), CanGet = true }); container.InnerClasses.Add(innerClass); pc.AddClassToNamespaceList(container); DefaultClass targetClass = new DefaultClass(cu, "TargetClass"); List <AbstractNode> nodes = new List <AbstractNode>(); IReturnType interf = new SearchClassReturnType(pc, targetClass, 0, 0, "TestClass.INestedInterface", 1); interf = new ConstructedReturnType(interf, new IReturnType[] { SharedProjectContentRegistryForTests.Instance.Mscorlib.GetClass("System.String", 0).DefaultReturnType }); CSharpCodeGenerator codeGen = new CSharpCodeGenerator(); codeGen.ImplementInterface(nodes, interf, true, targetClass); Assert.AreEqual(1, nodes.Count); CSharpOutputVisitor output = new CSharpOutputVisitor(); output.Options.IndentationChar = ' '; output.Options.IndentSize = 2; nodes[0].AcceptVisitor(output, null); Assert.AreEqual("string TestClass<string>.INestedInterface.P {\n get {\n throw new NotImplementedException();\n }\n}", output.Text.Replace("\r", "").Trim()); }
public void AssemblyAttribute() { var attributes = GetAssemblyAttributes(typeof(TypeTestAttribute).Assembly); var typeTest = attributes.First(a => a.AttributeType.FullyQualifiedName == typeof(TypeTestAttribute).FullName); Assert.AreEqual(3, typeTest.PositionalArguments.Count); // first argument is (int)42 Assert.AreEqual(42, (int)typeTest.PositionalArguments[0]); // second argument is typeof(System.Action<>) IReturnType rt = (IReturnType)typeTest.PositionalArguments[1]; Assert.IsNull(rt.CastToConstructedReturnType()); // rt must not be constructed - it's just an unbound type Assert.AreEqual("System.Action", rt.FullyQualifiedName); Assert.AreEqual(1, rt.TypeArgumentCount); // third argument is typeof(IDictionary<string, IList<TestAttribute>>) ConstructedReturnType crt = ((IReturnType)typeTest.PositionalArguments[2]).CastToConstructedReturnType(); Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullyQualifiedName); Assert.AreEqual("System.String", crt.TypeArguments[0].FullyQualifiedName); Assert.AreEqual("System.Collections.Generic.IList{NUnit.Framework.TestAttribute}", crt.TypeArguments[1].DotNetName); }
/// <summary> /// Gets whether this type parameter occurs in the specified return type. /// </summary> public bool OccursIn(IReturnType rt) { ArrayReturnType art = rt.CastToArrayReturnType(); if (art != null) { return(OccursIn(art.ArrayElementType)); } ConstructedReturnType crt = rt.CastToConstructedReturnType(); if (crt != null) { return(crt.TypeArguments.Any(ta => OccursIn(ta))); } GenericReturnType grt = rt.CastToGenericReturnType(); if (grt != null) { return(this.TypeParameter.Equals(grt.TypeParameter)); } return(false); }
public void NestedInterfaceInGenericClass() { // See SD2-1626 DefaultProjectContent pc = new DefaultProjectContent(); pc.ReferencedContents.Add(SharedProjectContentRegistryForTests.Instance.Mscorlib); DefaultCompilationUnit cu = new DefaultCompilationUnit(pc); DefaultClass container = new DefaultClass(cu, "TestClass"); container.TypeParameters.Add(new DefaultTypeParameter(container, "T", 0)); DefaultClass innerClass = new DefaultClass(cu, container); innerClass.FullyQualifiedName = "TestClass.INestedInterface"; innerClass.ClassType = ClassType.Interface; innerClass.TypeParameters.Add(new DefaultTypeParameter(innerClass, "T", 0)); innerClass.Properties.Add(new DefaultProperty(innerClass, "P") { ReturnType = new GenericReturnType(innerClass.TypeParameters[0]), CanGet = true }); container.InnerClasses.Add(innerClass); pc.AddClassToNamespaceList(container); DefaultClass targetClass = new DefaultClass(cu, "TargetClass"); List<AbstractNode> nodes = new List<AbstractNode>(); IReturnType interf = new SearchClassReturnType(pc, targetClass, 0, 0, "TestClass.INestedInterface", 1); interf = new ConstructedReturnType(interf, new IReturnType[] { SharedProjectContentRegistryForTests.Instance.Mscorlib.GetClass("System.String", 0).DefaultReturnType }); CSharpCodeGenerator codeGen = new CSharpCodeGenerator(); codeGen.ImplementInterface(nodes, interf, true, targetClass); Assert.AreEqual(1, nodes.Count); CSharpOutputVisitor output = new CSharpOutputVisitor(); output.Options.IndentationChar = ' '; output.Options.IndentSize = 2; nodes[0].AcceptVisitor(output, null); Assert.AreEqual("string TestClass<string>.INestedInterface.P {\n get {\n throw new NotImplementedException();\n }\n}", output.Text.Replace("\r", "").Trim()); }
static IReturnType Parse(IProjectContent pc, IEnumerator<string> tokenizer) { string typeName = tokenizer.Current; if (typeName == null) throw new ReflectionTypeNameSyntaxError("Unexpected end of type name"); tokenizer.MoveNext(); int typeParameterCount; typeName = ReflectionClass.SplitTypeParameterCountFromReflectionName(typeName, out typeParameterCount); IReturnType rt = new GetClassReturnType(pc, typeName, typeParameterCount); if (tokenizer.Current == "[") { // this is a constructed type List<IReturnType> typeArguments = new List<IReturnType>(); do { tokenizer.MoveNext(); if (tokenizer.Current != "[") throw new ReflectionTypeNameSyntaxError("Expected '['"); tokenizer.MoveNext(); typeArguments.Add(Parse(pc, tokenizer)); if (tokenizer.Current != "]") throw new ReflectionTypeNameSyntaxError("Expected ']' after generic argument"); tokenizer.MoveNext(); } while (tokenizer.Current == ","); if (tokenizer.Current != "]") throw new ReflectionTypeNameSyntaxError("Expected ']' after generic argument list"); tokenizer.MoveNext(); rt = new ConstructedReturnType(rt, typeArguments); } while (tokenizer.Current == ",") { tokenizer.MoveNext(); string token = tokenizer.Current; if (token != null && token != "," && token != "[" && token != "]") tokenizer.MoveNext(); } return rt; }
internal static IMethod GetDelegateOrExpressionTreeSignature(IReturnType rt, bool allowExpressionTree) { if (rt == null) { return(null); } IClass c = rt.GetUnderlyingClass(); if (allowExpressionTree && c != null && c.FullyQualifiedName == "System.Linq.Expressions.Expression") { ConstructedReturnType crt = rt.CastToConstructedReturnType(); if (crt != null && crt.TypeArguments.Count == 1) { // get delegate type from expression type rt = crt.TypeArguments[0]; c = rt != null?rt.GetUnderlyingClass() : null; } } if (c != null && c.ClassType == ClassType.Delegate) { return(rt.GetMethods().FirstOrDefault((IMethod m) => m.Name == "Invoke")); } return(null); }
static IMethod ApplyTypeArgumentsToMethod(IMethod genericMethod, IList <IReturnType> typeArguments) { if (typeArguments != null && typeArguments.Count > 0) { // apply inferred type arguments IMethod method = (IMethod)genericMethod.CreateSpecializedMember(); method.ReturnType = ConstructedReturnType.TranslateType(method.ReturnType, typeArguments, true); for (int i = 0; i < method.Parameters.Count; ++i) { method.Parameters[i].ReturnType = ConstructedReturnType.TranslateType(method.Parameters[i].ReturnType, typeArguments, true); } for (int i = 0; i < Math.Min(typeArguments.Count, method.TypeParameters.Count); i++) { var tp = new BoundTypeParameter(method.TypeParameters[i], method.DeclaringType, method); tp.BoundTo = typeArguments[i]; method.TypeParameters[i] = tp; } return(method); } else { return(genericMethod); } }
public static IReturnType CreateReturnType(TypeReference reference, IClass callingClass, IMember callingMember, int caretLine, int caretColumn, IProjectContent projectContent, bool useLazyReturnType) { if (reference == null) return null; if (reference.IsNull) return null; if (reference is InnerClassTypeReference) { reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference(); } LanguageProperties languageProperties = projectContent.Language; IReturnType t = null; if (callingClass != null && !reference.IsGlobal) { foreach (ITypeParameter tp in callingClass.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.SystemType)) { t = new GenericReturnType(tp); break; } } if (t == null && callingMember is IMethod && (callingMember as IMethod).TypeParameters != null) { foreach (ITypeParameter tp in (callingMember as IMethod).TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.SystemType)) { t = new GenericReturnType(tp); break; } } } } if (t == null) { if (reference.Type != reference.SystemType) { // keyword-type like void, int, string etc. IClass c = projectContent.GetClass(reference.SystemType); if (c != null) t = c.DefaultReturnType; else t = new GetClassReturnType(projectContent, reference.SystemType, 0); } else { int typeParameterCount = reference.GenericTypes.Count; if (useLazyReturnType) { if (reference.IsGlobal) t = new GetClassReturnType(projectContent, reference.SystemType, typeParameterCount); else if (callingClass != null) t = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.SystemType, typeParameterCount); } else { IClass c; if (reference.IsGlobal) { c = projectContent.GetClass(reference.SystemType, typeParameterCount); t = (c != null) ? c.DefaultReturnType : null; } else if (callingClass != null) { t = projectContent.SearchType(new SearchTypeRequest(reference.SystemType, typeParameterCount, callingClass, caretLine, caretColumn)).Result; } if (t == null) { if (reference.GenericTypes.Count == 0 && !reference.IsArrayType) { // reference to namespace is possible if (reference.IsGlobal) { if (projectContent.NamespaceExists(reference.Type)) return new NamespaceReturnType(reference.Type); } else { string name = projectContent.SearchNamespace(reference.Type, callingClass, (callingClass == null) ? null : callingClass.CompilationUnit, caretLine, caretColumn); if (name != null) return new NamespaceReturnType(name); } } return null; } } } } if (reference.GenericTypes.Count > 0) { List<IReturnType> para = new List<IReturnType>(reference.GenericTypes.Count); for (int i = 0; i < reference.GenericTypes.Count; ++i) { para.Add(CreateReturnType(reference.GenericTypes[i], callingClass, callingMember, caretLine, caretColumn, projectContent, useLazyReturnType)); } t = new ConstructedReturnType(t, para); } return WrapArray(projectContent, t, reference); }
public static IReturnType CreateReturnType(TypeReference reference, IClass callingClass, IMember callingMember, int caretLine, int caretColumn, IProjectContent projectContent, bool useLazyReturnType) { if (reference == null) { return(null); } if (reference.IsNull) { return(null); } if (reference is InnerClassTypeReference) { reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference(); } LanguageProperties languageProperties = projectContent.Language; IReturnType t = null; if (callingClass != null && !reference.IsGlobal) { foreach (ITypeParameter tp in callingClass.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.SystemType)) { t = new GenericReturnType(tp); break; } } if (t == null && callingMember is IMethod && (callingMember as IMethod).TypeParameters != null) { foreach (ITypeParameter tp in (callingMember as IMethod).TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.SystemType)) { t = new GenericReturnType(tp); break; } } } } if (t == null) { if (reference.Type != reference.SystemType) { // keyword-type like void, int, string etc. IClass c = projectContent.GetClass(reference.SystemType); if (c != null) { t = c.DefaultReturnType; } else { t = new GetClassReturnType(projectContent, reference.SystemType, 0); } } else { int typeParameterCount = reference.GenericTypes.Count; if (useLazyReturnType) { if (reference.IsGlobal) { t = new GetClassReturnType(projectContent, reference.SystemType, typeParameterCount); } else if (callingClass != null) { t = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.SystemType, typeParameterCount); } } else { IClass c; if (reference.IsGlobal) { c = projectContent.GetClass(reference.SystemType, typeParameterCount); t = (c != null) ? c.DefaultReturnType : null; } else if (callingClass != null) { t = projectContent.SearchType(new SearchTypeRequest(reference.SystemType, typeParameterCount, callingClass, caretLine, caretColumn)).Result; } if (t == null) { if (reference.GenericTypes.Count == 0 && !reference.IsArrayType) { // reference to namespace is possible if (reference.IsGlobal) { if (projectContent.NamespaceExists(reference.Type)) { return(new NamespaceReturnType(reference.Type)); } } else { string name = projectContent.SearchNamespace(reference.Type, callingClass, (callingClass == null) ? null : callingClass.CompilationUnit, caretLine, caretColumn); if (name != null) { return(new NamespaceReturnType(name)); } } } return(null); } } } } if (reference.GenericTypes.Count > 0) { List <IReturnType> para = new List <IReturnType>(reference.GenericTypes.Count); for (int i = 0; i < reference.GenericTypes.Count; ++i) { para.Add(CreateReturnType(reference.GenericTypes[i], callingClass, callingMember, caretLine, caretColumn, projectContent, useLazyReturnType)); } t = new ConstructedReturnType(t, para); } return(WrapArray(projectContent, t, reference)); }
public static IReturnType CreateReturnType(AST.TypeReference reference, IClass callingClass, IMethodOrProperty callingMember, int caretLine, int caretColumn, IProjectContent projectContent) { System.Diagnostics.Debug.Assert(projectContent != null); if (reference == null) { return(GetDefaultReturnType(projectContent)); } if (reference is AST.ArrayTypeReference) { AST.ArrayTypeReference arr = (AST.ArrayTypeReference)reference; return(new ArrayReturnType(projectContent, CreateReturnType(arr.ElementType, callingClass, callingMember, caretLine, caretColumn, projectContent), (arr.Rank != null) ? (int)arr.Rank.Value : 1)); } else if (reference is AST.SimpleTypeReference) { string name = ((AST.SimpleTypeReference)reference).Name; IReturnType rt; int typeParameterCount = (reference is AST.GenericTypeReference) ? ((AST.GenericTypeReference)reference).GenericArguments.Count : 0; if (name == "duck") { rt = new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType; } else if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name)) { rt = new GetClassReturnType(projectContent, BooAmbience.ReverseTypeConversionTable[name], typeParameterCount); } else if (callingClass == null) { rt = new GetClassReturnType(projectContent, name, typeParameterCount); } else { rt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, name, typeParameterCount); } if (typeParameterCount > 0) { AST.TypeReferenceCollection arguments = ((AST.GenericTypeReference)reference).GenericArguments; // GenericTypeReference derives from SimpleTypeReference IReturnType[] typeArguments = new IReturnType[arguments.Count]; for (int i = 0; i < typeArguments.Length; i++) { typeArguments[i] = CreateReturnType(arguments[i], callingClass, callingMember, caretLine, caretColumn, projectContent); } rt = new ConstructedReturnType(rt, typeArguments); } return(rt); } else if (reference is AST.CallableTypeReference) { AST.CallableTypeReference ctr = (AST.CallableTypeReference)reference; AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(new DefaultCompilationUnit(projectContent)); if (ctr.ReturnType != null) { amrt.MethodReturnType = CreateReturnType(ctr.ReturnType, callingClass, callingMember, caretLine, caretColumn, projectContent); } amrt.MethodParameters = new List <IParameter>(); AddParameters(ctr.Parameters, amrt.MethodParameters, callingMember, callingClass ?? new DefaultClass(new DefaultCompilationUnit(projectContent), "__Dummy")); return(amrt); } else { throw new NotSupportedException("unknown reference type: " + reference.ToString()); } }
IReturnType SubstituteFixedTypes(IReturnType rt) { return(ConstructedReturnType.TranslateType( rt, typeParameters.Select(tp => tp.FixedTo).ToList(), true)); }
/// <summary> /// Make lower bound inference from U for V. /// </summary> void MakeLowerBoundInference(IReturnType U, IReturnType V) { Log(" MakeLowerBoundInference from " + U + " for " + V); if (U == null || V == null) { return; } // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.Fixed == false) { Log(" Add bound '" + U.DotNetName + "' to " + tp); tp.Bounds.Add(U); return; } // Otherwise if U is an array type Ue[…] and V is either an array type Ve[…]of the // same rank, or if U is a onedimensional array type Ue[]and V is one of // IEnumerable<Ve>, ICollection<Ve> or IList<Ve> then ArrayReturnType arrU = U.CastToArrayReturnType(); ArrayReturnType arrV = V.CastToArrayReturnType(); ConstructedReturnType CV = V.CastToConstructedReturnType(); if (arrU != null && (arrV != null && arrU.ArrayDimensions == arrV.ArrayDimensions || (arrU.ArrayDimensions == 1 && IsIEnumerableCollectionOrList(CV)))) { IReturnType Ue = arrU.ArrayElementType; IReturnType Ve = arrV != null ? arrV.ArrayElementType : CV.TypeArguments[0]; // If Ue is known to be a reference type then a lowerbound inference from Ue to Ve is made if (IsReferenceType(Ue) ?? false) { MakeLowerBoundInference(Ue, Ve); } else { // Otherwise an exact inference from Ue to Ve is made MakeExactInference(Ue, Ve); } return; } // Otherwise if V is a constructed type C<V1…Vk> and there is a unique set of // types U1…Uk such that a standard implicit conversion exists from U to C<U1…Uk> // then an exact inference is made from each Ui for the corresponding Vi. if (CV != null) { foreach (IReturnType U2 in MemberLookupHelper.GetTypeInheritanceTree(U)) { ConstructedReturnType CU2 = U2.CastToConstructedReturnType(); if (CU2 != null && object.Equals(CU2.UnboundType, CV.UnboundType) && CU2.TypeArgumentCount == CV.TypeArgumentCount && CU2.TypeArguments.Count == CU2.TypeArgumentCount && // unfortunately these might not be the same... CV.TypeArguments.Count == CV.TypeArgumentCount) { for (int i = 0; i < CU2.TypeArgumentCount; i++) { MakeExactInference(CU2.TypeArguments[i], CV.TypeArguments[i]); } return; } } } }
public static IReturnType CreateReturnType(TypeReference reference, IClass callingClass, IMember callingMember, int caretLine, int caretColumn, IProjectContent projectContent, ReturnTypeOptions options) { if (reference == null) return null; if (reference.IsNull) return null; if (reference is InnerClassTypeReference) { reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference(); } bool useLazyReturnType = (options & ReturnTypeOptions.Lazy) == ReturnTypeOptions.Lazy; bool isBaseTypeReference = (options & ReturnTypeOptions.BaseTypeReference) == ReturnTypeOptions.BaseTypeReference; LanguageProperties languageProperties = projectContent.Language; IReturnType t = null; if (callingClass != null && !reference.IsGlobal) { foreach (ITypeParameter tp in callingClass.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.Type)) { t = new GenericReturnType(tp); break; } } IMethod callingMethod = callingMember as IMethod; if (t == null && callingMethod != null) { foreach (ITypeParameter tp in callingMethod.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.Type)) { t = new GenericReturnType(tp); break; } } } } if (t == null) { int typeParameterCount = reference.GenericTypes.Count; if (reference.IsKeyword) { // keyword-type like void, int, string etc. IClass c = projectContent.GetClass(reference.Type, typeParameterCount); if (c != null) t = c.DefaultReturnType; else t = new GetClassReturnType(projectContent, reference.Type, typeParameterCount); } else { if (useLazyReturnType || isBaseTypeReference) { if (reference.IsGlobal) { t = new GetClassReturnType(projectContent, reference.Type, typeParameterCount); } else if (callingClass != null) { SearchClassReturnType scrt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.Type, typeParameterCount); if (isBaseTypeReference) scrt.LookForInnerClassesInDeclaringClass = false; t = scrt; } } else { IClass c; if (reference.IsGlobal) { c = projectContent.GetClass(reference.Type, typeParameterCount); t = (c != null) ? c.DefaultReturnType : null; } else if (callingClass != null) { t = projectContent.SearchType(new SearchTypeRequest(reference.Type, typeParameterCount, callingClass, caretLine, caretColumn)).Result; } if (t == null) { return null; } } } } if (reference.GenericTypes.Count > 0) { IReturnType[] para = new IReturnType[reference.GenericTypes.Count]; for (int i = 0; i < reference.GenericTypes.Count; ++i) { para[i] = CreateReturnType(reference.GenericTypes[i], callingClass, callingMember, caretLine, caretColumn, projectContent, options); } t = new ConstructedReturnType(t, para); } for (int i = 0; i < reference.PointerNestingLevel; i++) { t = new PointerReturnType(t); } return WrapArray(projectContent, t, reference); }
bool IsIEnumerableCollectionOrList(ConstructedReturnType rt) { if (rt == null || rt.TypeArgumentCount != 1) return false; switch (rt.UnboundType.FullyQualifiedName) { case "System.Collections.Generic.IList": case "System.Collections.Generic.ICollection": case "System.Collections.Generic.IEnumerable": return true; default: return false; } }
public static IReturnType CreateReturnType(TypeReference reference, IClass callingClass, IMember callingMember, int caretLine, int caretColumn, IProjectContent projectContent, ReturnTypeOptions options) { if (reference == null) { return(null); } if (reference.IsNull) { return(null); } if (reference is InnerClassTypeReference) { reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference(); } bool useLazyReturnType = (options & ReturnTypeOptions.Lazy) == ReturnTypeOptions.Lazy; bool isBaseTypeReference = (options & ReturnTypeOptions.BaseTypeReference) == ReturnTypeOptions.BaseTypeReference; LanguageProperties languageProperties = projectContent.Language; IReturnType t = null; if (callingClass != null && !reference.IsGlobal) { foreach (ITypeParameter tp in callingClass.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.Type)) { t = new GenericReturnType(tp); break; } } IMethod callingMethod = callingMember as IMethod; if (t == null && callingMethod != null) { foreach (ITypeParameter tp in callingMethod.TypeParameters) { if (languageProperties.NameComparer.Equals(tp.Name, reference.Type)) { t = new GenericReturnType(tp); break; } } } } if (t == null && reference.Type == "dynamic") { t = new DynamicReturnType(projectContent); } if (t == null) { int typeParameterCount = reference.GenericTypes.Count; if (reference.IsKeyword) { // keyword-type like void, int, string etc. IClass c = projectContent.GetClass(reference.Type, typeParameterCount); if (c != null) { t = c.DefaultReturnType; } else { t = new GetClassReturnType(projectContent, reference.Type, typeParameterCount); } } else { if (useLazyReturnType || isBaseTypeReference) { if (reference.IsGlobal) { t = new GetClassReturnType(projectContent, reference.Type, typeParameterCount); } else if (callingClass != null) { SearchClassReturnType scrt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.Type, typeParameterCount); if (isBaseTypeReference) { scrt.LookForInnerClassesInDeclaringClass = false; } t = scrt; } } else { IClass c; if (reference.IsGlobal) { c = projectContent.GetClass(reference.Type, typeParameterCount); t = (c != null) ? c.DefaultReturnType : null; } else if (callingClass != null) { t = projectContent.SearchType(new SearchTypeRequest(reference.Type, typeParameterCount, callingClass, caretLine, caretColumn)).Result; } if (t == null) { return(null); } } } } if (reference.GenericTypes.Count > 0) { IReturnType[] para = new IReturnType[reference.GenericTypes.Count]; for (int i = 0; i < reference.GenericTypes.Count; ++i) { para[i] = CreateReturnType(reference.GenericTypes[i], callingClass, callingMember, caretLine, caretColumn, projectContent, options); } t = new ConstructedReturnType(t, para); } for (int i = 0; i < reference.PointerNestingLevel; i++) { t = new PointerReturnType(t); } return(WrapArray(projectContent, t, reference)); }