From 97321958945efd5976cb7e98fac957b13282bec5 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 20 Nov 2005 14:51:05 +0000 Subject: [PATCH] Fixed exception when loading referenced assembly using Reflection when a type parameter constraint on a method referenced another type parameter from the same method. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@780 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Implementations/DefaultTypeParameter.cs | 13 +++++++--- .../Dom/ReflectionLayer/ReflectionClass.cs | 4 +++ .../Dom/ReflectionLayer/ReflectionMethod.cs | 4 +++ .../ReflectionLayer/ReflectionReturnType.cs | 3 +++ src/Main/Base/Test/ReflectionLayerTests.cs | 26 +++++++++++++++++++ 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/Main/Base/Project/Src/Dom/Implementations/DefaultTypeParameter.cs b/src/Main/Base/Project/Src/Dom/Implementations/DefaultTypeParameter.cs index 97c6756d17..4a84bd47ca 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/DefaultTypeParameter.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/DefaultTypeParameter.cs @@ -89,8 +89,16 @@ namespace ICSharpCode.SharpDevelop.Dom this.targetClass = method.DeclaringType; this.name = type.Name; this.index = type.GenericParameterPosition; + } + + public void AddConstraintsFromType(Type type) + { foreach (Type constraint in type.GetGenericParameterConstraints()) { - constraints.Add(ReflectionReturnType.Create(targetClass, constraint, false)); + if (method != null) { + constraints.Add(ReflectionReturnType.Create(method, constraint, false)); + } else { + constraints.Add(ReflectionReturnType.Create(targetClass, constraint, false)); + } } } @@ -106,9 +114,6 @@ namespace ICSharpCode.SharpDevelop.Dom this.targetClass = targetClass; this.name = type.Name; this.index = type.GenericParameterPosition; - foreach (Type constraint in type.GetGenericParameterConstraints()) { - constraints.Add(ReflectionReturnType.Create(targetClass, constraint, false)); - } } public override bool Equals(object obj) diff --git a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionClass.cs b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionClass.cs index cdb28e04e4..5a36c52233 100644 --- a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionClass.cs +++ b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionClass.cs @@ -121,6 +121,10 @@ namespace ICSharpCode.SharpDevelop.Dom foreach (Type g in type.GetGenericArguments()) { this.TypeParameters.Add(new DefaultTypeParameter(this, g)); } + int i = 0; + foreach (Type g in type.GetGenericArguments()) { + ((DefaultTypeParameter)this.TypeParameters[i++]).AddConstraintsFromType(g); + } } ModifierEnum modifiers = ModifierEnum.None; diff --git a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionMethod.cs b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionMethod.cs index 603d6f8735..1bd7c6efc4 100644 --- a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionMethod.cs +++ b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionMethod.cs @@ -34,6 +34,10 @@ namespace ICSharpCode.SharpDevelop.Dom foreach (Type g in methodBase.GetGenericArguments()) { this.TypeParameters.Add(new DefaultTypeParameter(this, g)); } + int i = 0; + foreach (Type g in methodBase.GetGenericArguments()) { + ((DefaultTypeParameter)this.TypeParameters[i++]).AddConstraintsFromType(g); + } } if (methodBase.IsStatic) { diff --git a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs index 8973458c93..8cecde6d7d 100644 --- a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs @@ -178,6 +178,9 @@ namespace ICSharpCode.SharpDevelop.Dom if (type.DeclaringMethod != null) { IMethod method = member as IMethod; if (method != null) { + if (type.GenericParameterPosition < method.TypeParameters.Count) { + return new GenericReturnType(method.TypeParameters[type.GenericParameterPosition]); + } return new GenericReturnType(new DefaultTypeParameter(method, type)); } } diff --git a/src/Main/Base/Test/ReflectionLayerTests.cs b/src/Main/Base/Test/ReflectionLayerTests.cs index a2e9da795e..7b6e7156f8 100644 --- a/src/Main/Base/Test/ReflectionLayerTests.cs +++ b/src/Main/Base/Test/ReflectionLayerTests.cs @@ -101,5 +101,31 @@ namespace ICSharpCode.SharpDevelop.Tests Assert.IsNotNull(c, "System.Void not found"); Assert.AreSame(c.DefaultReturnType, ReflectionReturnType.Void, "ReflectionReturnType.Void is c.DefaultReturnType"); } + + class TestClass where A : B { + public void TestMethod(string param) where V: K where K: IComparable {} + } + + [Test] + public void ReflectionParserTest() + { + DefaultCompilationUnit cu = new DefaultCompilationUnit(new DefaultProjectContent()); + IClass c = new ReflectionClass(cu, typeof(TestClass<,>), typeof(TestClass<,>).FullName, null); + + Assert.AreSame(c, c.TypeParameters[0].Class); + Assert.AreSame(c, c.TypeParameters[1].Class); + Assert.AreSame(c.TypeParameters[1], ((GenericReturnType)c.TypeParameters[0].Constraints[0]).TypeParameter); + + IMethod m = c.Methods.Find(delegate(IMethod me) { return me.Name == "TestMethod"; }); + Assert.IsNotNull(m); + Assert.AreEqual("K", m.TypeParameters[0].Name); + Assert.AreEqual("V", m.TypeParameters[1].Name); + Assert.AreSame(m, m.TypeParameters[0].Method); + Assert.AreSame(m, m.TypeParameters[1].Method); + + Assert.AreEqual("IComparable", m.TypeParameters[0].Constraints[0].Name); + GenericReturnType kConst = (GenericReturnType)m.TypeParameters[1].Constraints[0]; + Assert.AreSame(m.TypeParameters[0], kConst.TypeParameter); + } } }