Browse Source

Fixed SD2-735: Assemblies with methods having a "where T: IEquatable<T>" constraint crash SharpDevelop

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1251 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
69df449dd5
  1. 5
      src/Libraries/NRefactory/Project/Src/Output/SpecialNodesInserter.cs
  2. 22
      src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs
  3. 10
      src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs
  4. 32
      src/Main/Base/Test/ReflectionLayerTests.cs
  5. 7
      src/Main/StartUp/Project/SharpDevelop.exe.config

5
src/Libraries/NRefactory/Project/Src/Output/SpecialNodesInserter.cs

@ -123,15 +123,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -123,15 +123,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
/// <summary>
/// Registers a new SpecialNodesInserter with the output visitor.
/// Make sure to call Finish() on the returned SpecialNodesInserter when the output
/// is finished.
/// Make sure to call Finish() (or Dispose()) on the returned SpecialNodesInserter
/// when the output is finished.
/// </summary>
public static SpecialNodesInserter Install(IEnumerable<ISpecial> specials, IOutputASTVisitor outputVisitor)
{
SpecialNodesInserter sni = new SpecialNodesInserter(specials, new SpecialOutputVisitor(outputVisitor.OutputFormatter));
outputVisitor.NodeTracker.NodeVisiting += sni.AcceptNodeStart;
outputVisitor.NodeTracker.NodeVisited += sni.AcceptNodeEnd;
outputVisitor.NodeTracker.NodeChildrenVisited += sni.AcceptNodeEnd;
return sni;
}
}

22
src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs

@ -192,7 +192,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -192,7 +192,7 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
private sealed class ReadWriteHelper
public sealed class ReadWriteHelper
{
ReflectionProjectContent pc;
@ -526,6 +526,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -526,6 +526,8 @@ namespace ICSharpCode.SharpDevelop.Dom
classIndices.Add(pair, externalTypes.Count + classCount);
externalTypes.Add(pair);
}
} else if (rt is GenericReturnType) {
// ignore
} else if (rt.ArrayDimensions > 0) {
AddExternalType(rt.ArrayElementType, externalTypes, classCount);
} else if (rt.TypeArguments != null) {
@ -533,8 +535,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -533,8 +535,6 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IReturnType typeArgument in rt.TypeArguments) {
AddExternalType(typeArgument, externalTypes, classCount);
}
} else if (rt is GenericReturnType) {
// ignore
} else {
LoggingService.Warn("Unknown return type: " + rt.ToString());
}
@ -560,6 +560,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -560,6 +560,14 @@ namespace ICSharpCode.SharpDevelop.Dom
} else {
writer.Write(classIndices[new ClassNameTypeCountPair(rt)]);
}
} else if (rt is GenericReturnType) {
GenericReturnType grt = (GenericReturnType)rt;
if (grt.TypeParameter.Method != null) {
writer.Write(MethodGenericRTCode);
} else {
writer.Write(TypeGenericRTCode);
}
writer.Write(grt.TypeParameter.Index);
} else if (rt.ArrayDimensions > 0) {
writer.Write(ArrayRTCode);
writer.Write(rt.ArrayDimensions);
@ -571,14 +579,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -571,14 +579,6 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IReturnType typeArgument in rt.TypeArguments) {
WriteType(typeArgument);
}
} else if (rt is GenericReturnType) {
GenericReturnType grt = (GenericReturnType)rt;
if (grt.TypeParameter.Method != null) {
writer.Write(MethodGenericRTCode);
} else {
writer.Write(TypeGenericRTCode);
}
writer.Write(grt.TypeParameter.Index);
} else {
writer.Write(NullRTReferenceCode);
LoggingService.Warn("Unknown return type: " + rt.ToString());

10
src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs

@ -181,13 +181,9 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -181,13 +181,9 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
ConvertAst(p.CompilationUnit, specials);
SpecialNodesInserter sni = new SpecialNodesInserter(specials,
new SpecialOutputVisitor(outputVisitor.OutputFormatter));
outputVisitor.NodeTracker.NodeVisiting += sni.AcceptNodeStart;
outputVisitor.NodeTracker.NodeVisited += sni.AcceptNodeEnd;
outputVisitor.NodeTracker.NodeChildrenVisited += sni.AcceptNodeEnd;
outputVisitor.Visit(p.CompilationUnit, null);
sni.Finish();
using (SpecialNodesInserter.Install(specials, outputVisitor)) {
outputVisitor.Visit(p.CompilationUnit, null);
}
p.Dispose();

32
src/Main/Base/Test/ReflectionLayerTests.cs

@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
@ -104,14 +106,31 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -104,14 +106,31 @@ namespace ICSharpCode.SharpDevelop.Tests
class TestClass<A, B> where A : B {
public void TestMethod<K, V>(string param) where V: K where K: IComparable {}
public void GetIndex<T>(T element) where T: IEquatable<T> {}
}
[Test]
public void ReflectionParserTest()
{
DefaultCompilationUnit cu = new DefaultCompilationUnit(new DefaultProjectContent());
ICompilationUnit cu = new ReflectionProjectContent("TestName", "testlocation", new AssemblyName[0]).AssemblyCompilationUnit;
IClass c = new ReflectionClass(cu, typeof(TestClass<,>), typeof(TestClass<,>).FullName, null);
cu.ProjectContent.AddClassToNamespaceList(c);
CheckClass(c);
MemoryStream memory = new MemoryStream();
DomPersistence.ReadWriteHelper helper = new DomPersistence.ReadWriteHelper(new BinaryWriter(memory));
helper.WriteProjectContent((ReflectionProjectContent)cu.ProjectContent);
memory.Position = 0;
helper = new DomPersistence.ReadWriteHelper(new BinaryReader(memory));
foreach (IClass c2 in helper.ReadProjectContent().Classes) {
CheckClass(c2);
}
}
void CheckClass(IClass c)
{
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);
@ -126,6 +145,17 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -126,6 +145,17 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual("IComparable", m.TypeParameters[0].Constraints[0].Name);
GenericReturnType kConst = (GenericReturnType)m.TypeParameters[1].Constraints[0];
Assert.AreSame(m.TypeParameters[0], kConst.TypeParameter);
m = c.Methods.Find(delegate(IMethod me) { return me.Name == "GetIndex"; });
Assert.IsNotNull(m);
Assert.AreEqual("T", m.TypeParameters[0].Name);
Assert.AreSame(m, m.TypeParameters[0].Method);
Assert.AreEqual("IEquatable", m.TypeParameters[0].Constraints[0].Name);
Assert.AreEqual(1, m.TypeParameters[0].Constraints[0].TypeParameterCount);
Assert.AreEqual(1, m.TypeParameters[0].Constraints[0].TypeArguments.Count);
GenericReturnType grt = (GenericReturnType)m.TypeParameters[0].Constraints[0].TypeArguments[0];
Assert.AreSame(m.TypeParameters[0], grt.TypeParameter);
}
}
}

7
src/Main/StartUp/Project/SharpDevelop.exe.config

@ -49,6 +49,13 @@ @@ -49,6 +49,13 @@
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="SharpDevelopLog.txt" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level- %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ColoredConsoleAppender" />

Loading…
Cancel
Save