Browse Source

Update to Mono.Cecil revision 134535.

Fixed handling of type attribute arguments when loading with Mono.Cecil.
Fixed handling of unbound generic types in type attribute arguments when loading with Reflection.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4096 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
324fab013a
  1. BIN
      src/Libraries/Mono.Cecil/Mono.Cecil.dll
  2. 44
      src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs
  3. 110
      src/Main/Base/Test/ReflectionLayerTests.cs
  4. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  5. 19
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  6. 13
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs
  7. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs
  8. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs
  9. 84
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionReturnType.cs
  10. 35
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionTypeNameSyntaxError.cs

BIN
src/Libraries/Mono.Cecil/Mono.Cecil.dll

Binary file not shown.

44
src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs

@ -239,6 +239,15 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
void PathChanged(object sender, EventArgs e) void PathChanged(object sender, EventArgs e)
{ {
string solution = solutionNameTextBox.Text.Trim();
string name = nameTextBox.Text.Trim();
string location = locationTextBox.Text.Trim();
string projectNameError = CheckProjectName(solution, name, location);
if (projectNameError != null) {
createInLabel.Text = StringParser.Parse(projectNameError).Replace("\n", " ").Replace("\r", "");
return;
}
string solutionPath; string solutionPath;
try { try {
solutionPath = NewProjectDirectory; solutionPath = NewProjectDirectory;
@ -274,6 +283,25 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
public string NewProjectLocation; public string NewProjectLocation;
public string NewSolutionLocation; public string NewSolutionLocation;
string CheckProjectName(string solution, string name, string location)
{
if (name.Length == 0 || !char.IsLetter(name[0]) && name[0] != '_') {
return "${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustStartWithLetter}";
}
if (!FileUtility.IsValidDirectoryName(solution)
|| !FileUtility.IsValidDirectoryName(name))
{
return "${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.IllegalProjectNameError}";
}
if (name.EndsWith(".")) {
return "${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustNotEndWithDot}";
}
if (!FileUtility.IsValidPath(location) || !Path.IsPathRooted(location)) {
return "${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.SpecifyValidLocation}";
}
return null;
}
void OpenEvent(object sender, EventArgs e) void OpenEvent(object sender, EventArgs e)
{ {
@ -287,19 +315,9 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
string solution = solutionNameTextBox.Text.Trim(); string solution = solutionNameTextBox.Text.Trim();
string name = nameTextBox.Text.Trim(); string name = nameTextBox.Text.Trim();
string location = locationTextBox.Text.Trim(); string location = locationTextBox.Text.Trim();
if (!FileUtility.IsValidDirectoryName(solution) string projectNameError = CheckProjectName(solution, name, location);
|| !FileUtility.IsValidDirectoryName(name) if (projectNameError != null) {
|| !FileUtility.IsValidPath(location)) MessageService.ShowError(projectNameError);
{
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.IllegalProjectNameError}");
return;
}
if (!char.IsLetter(name[0]) && name[0] != '_') {
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustStartWithLetter}");
return;
}
if (name.EndsWith(".")) {
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustNotEndWithDot}");
return; return;
} }

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

@ -16,14 +16,22 @@ using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.ReflectionLayer; using ICSharpCode.SharpDevelop.Dom.ReflectionLayer;
using NUnit.Framework; using NUnit.Framework;
[assembly: ICSharpCode.SharpDevelop.Tests.TypeTestAttribute(
42, typeof(System.Action<>), typeof(IDictionary<string, IList<TestAttribute>>))]
namespace ICSharpCode.SharpDevelop.Tests namespace ICSharpCode.SharpDevelop.Tests
{ {
public class TypeTestAttribute : Attribute
{
public TypeTestAttribute(int a1, Type a2, Type a3) {}
}
[TestFixture] [TestFixture]
public class ReflectionLayerTests : ReflectionOrCecilLayerTests public class ReflectionLayerTests : ReflectionOrCecilLayerTests
{ {
public ReflectionLayerTests() public ReflectionLayerTests()
{ {
pc = ParserService.DefaultProjectContentRegistry.Mscorlib; mscorlib = ParserService.DefaultProjectContentRegistry.Mscorlib;
} }
protected override IClass GetClass(Type type) protected override IClass GetClass(Type type)
@ -33,6 +41,13 @@ namespace ICSharpCode.SharpDevelop.Tests
cu.ProjectContent.AddClassToNamespaceList(c); cu.ProjectContent.AddClassToNamespaceList(c);
return c; return c;
} }
protected override IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly)
{
var pc = new ReflectionProjectContent("TestName", "testlocation", new DomAssemblyName[0], ParserService.DefaultProjectContentRegistry);
pc.AddAssemblyAttributes(assembly);
return pc.GetAssemblyAttributes();
}
} }
[TestFixture] [TestFixture]
@ -40,12 +55,12 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
public ReflectionWithRoundTripLayerTests() public ReflectionWithRoundTripLayerTests()
{ {
pc = ParserService.DefaultProjectContentRegistry.Mscorlib; mscorlib = ParserService.DefaultProjectContentRegistry.Mscorlib;
MemoryStream memory = new MemoryStream(); MemoryStream memory = new MemoryStream();
DomPersistence.WriteProjectContent((ReflectionProjectContent)pc, memory); DomPersistence.WriteProjectContent((ReflectionProjectContent)mscorlib, memory);
memory.Position = 0; memory.Position = 0;
pc = DomPersistence.LoadProjectContent(memory, ParserService.DefaultProjectContentRegistry); mscorlib = DomPersistence.LoadProjectContent(memory, ParserService.DefaultProjectContentRegistry);
} }
protected override IClass GetClass(Type type) protected override IClass GetClass(Type type)
@ -60,6 +75,18 @@ namespace ICSharpCode.SharpDevelop.Tests
memory.Position = 0; memory.Position = 0;
return DomPersistence.LoadProjectContent(memory, ParserService.DefaultProjectContentRegistry).Classes.Single(); return DomPersistence.LoadProjectContent(memory, ParserService.DefaultProjectContentRegistry).Classes.Single();
} }
protected override IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly)
{
var pc = new ReflectionProjectContent("TestName", "testlocation", new DomAssemblyName[0], ParserService.DefaultProjectContentRegistry);
pc.AddAssemblyAttributes(assembly);
MemoryStream memory = new MemoryStream();
DomPersistence.WriteProjectContent(pc, memory);
memory.Position = 0;
return DomPersistence.LoadProjectContent(memory, ParserService.DefaultProjectContentRegistry).GetAssemblyAttributes();
}
} }
[TestFixture] [TestFixture]
@ -67,27 +94,38 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
public CecilLayerTests() public CecilLayerTests()
{ {
pc = CecilReader.LoadAssembly(typeof(object).Assembly.Location, ParserService.DefaultProjectContentRegistry); mscorlib = CecilReader.LoadAssembly(typeof(object).Assembly.Location, ParserService.DefaultProjectContentRegistry);
}
IProjectContent LoadAssembly(Assembly assembly)
{
IProjectContent pc = CecilReader.LoadAssembly(assembly.Location, ParserService.DefaultProjectContentRegistry);
Assert.IsNotNull(pc);
return pc;
} }
protected override IClass GetClass(Type type) protected override IClass GetClass(Type type)
{ {
IProjectContent pc = CecilReader.LoadAssembly(type.Assembly.Location, ParserService.DefaultProjectContentRegistry); IClass c = LoadAssembly(type.Assembly).GetClassByReflectionName(type.FullName, false);
IClass c = pc.GetClassByReflectionName(type.FullName, false);
Assert.IsNotNull(c); Assert.IsNotNull(c);
return c; return c;
} }
protected override IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly)
{
return LoadAssembly(assembly).GetAssemblyAttributes();
}
} }
public abstract class ReflectionOrCecilLayerTests public abstract class ReflectionOrCecilLayerTests
{ {
protected IProjectContent pc; protected IProjectContent mscorlib;
[Test] [Test]
public void InheritanceTest() public void InheritanceTest()
{ {
IClass c = pc.GetClass("System.SystemException", 0); IClass c = mscorlib.GetClass("System.SystemException", 0);
IClass c2 = pc.GetClass("System.Exception", 0); IClass c2 = mscorlib.GetClass("System.Exception", 0);
Assert.IsNotNull(c, "c is null"); Assert.IsNotNull(c, "c is null");
Assert.IsNotNull(c2, "c2 is null"); Assert.IsNotNull(c2, "c2 is null");
//Assert.AreEqual(3, c.BaseTypes.Count); // Inherited interfaces are not reported by Cecil //Assert.AreEqual(3, c.BaseTypes.Count); // Inherited interfaces are not reported by Cecil
@ -116,7 +154,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void GenericPropertyTest() public void GenericPropertyTest()
{ {
IClass c = pc.GetClass("System.Collections.Generic.Comparer", 1); IClass c = mscorlib.GetClass("System.Collections.Generic.Comparer", 1);
IProperty def = c.Properties.First(p => p.Name == "Default"); IProperty def = c.Properties.First(p => p.Name == "Default");
ConstructedReturnType crt = def.ReturnType.CastToConstructedReturnType(); ConstructedReturnType crt = def.ReturnType.CastToConstructedReturnType();
Assert.AreEqual("System.Collections.Generic.Comparer", crt.FullyQualifiedName); Assert.AreEqual("System.Collections.Generic.Comparer", crt.FullyQualifiedName);
@ -126,7 +164,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void PointerTypeTest() public void PointerTypeTest()
{ {
IClass c = pc.GetClass("System.IntPtr", 1); IClass c = mscorlib.GetClass("System.IntPtr", 1);
IMethod toPointer = c.Methods.First(p => p.Name == "ToPointer"); IMethod toPointer = c.Methods.First(p => p.Name == "ToPointer");
Assert.AreEqual("System.Void*", toPointer.ReturnType.DotNetName); Assert.AreEqual("System.Void*", toPointer.ReturnType.DotNetName);
PointerReturnType prt = toPointer.ReturnType.CastToDecoratingReturnType<PointerReturnType>(); PointerReturnType prt = toPointer.ReturnType.CastToDecoratingReturnType<PointerReturnType>();
@ -136,8 +174,8 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void ParameterComparisonTest() public void ParameterComparisonTest()
{ {
DefaultParameter p1 = new DefaultParameter("a", pc.GetClass("System.String", 0).DefaultReturnType, DomRegion.Empty); DefaultParameter p1 = new DefaultParameter("a", mscorlib.GetClass("System.String", 0).DefaultReturnType, DomRegion.Empty);
DefaultParameter p2 = new DefaultParameter("b", new GetClassReturnType(pc, "System.String", 0), DomRegion.Empty); DefaultParameter p2 = new DefaultParameter("b", new GetClassReturnType(mscorlib, "System.String", 0), DomRegion.Empty);
IList<IParameter> a1 = new List<IParameter>(); IList<IParameter> a1 = new List<IParameter>();
IList<IParameter> a2 = new List<IParameter>(); IList<IParameter> a2 = new List<IParameter>();
a1.Add(p1); a1.Add(p1);
@ -145,8 +183,9 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual(0, DiffUtility.Compare(a1, a2)); Assert.AreEqual(0, DiffUtility.Compare(a1, a2));
} }
DefaultMethod GetMethod(IClass c, string name) { DefaultMethod GetMethod(IClass c, string name)
IMethod result = c.Methods.FirstOrDefault(delegate(IMethod m) { return m.Name == name; }); {
IMethod result = c.Methods.FirstOrDefault(m => m.Name == name);
Assert.IsNotNull(result, "Method " + name + " not found"); Assert.IsNotNull(result, "Method " + name + " not found");
return (DefaultMethod)result; return (DefaultMethod)result;
} }
@ -154,7 +193,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void GenericDocumentationTagNamesTest() public void GenericDocumentationTagNamesTest()
{ {
DefaultClass c = (DefaultClass)pc.GetClass("System.Collections.Generic.List", 1); DefaultClass c = (DefaultClass)mscorlib.GetClass("System.Collections.Generic.List", 1);
Assert.AreEqual("T:System.Collections.Generic.List`1", Assert.AreEqual("T:System.Collections.Generic.List`1",
c.DocumentationTag); c.DocumentationTag);
Assert.AreEqual("M:System.Collections.Generic.List`1.Add(`0)", Assert.AreEqual("M:System.Collections.Generic.List`1.Add(`0)",
@ -168,7 +207,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void StaticModifierTest() public void StaticModifierTest()
{ {
IClass c = pc.GetClass("System.Environment", 0); IClass c = mscorlib.GetClass("System.Environment", 0);
Assert.IsNotNull(c, "System.Environment not found"); Assert.IsNotNull(c, "System.Environment not found");
Assert.IsTrue(c.IsAbstract, "class should be abstract"); Assert.IsTrue(c.IsAbstract, "class should be abstract");
Assert.IsTrue(c.IsSealed, "class should be sealed"); Assert.IsTrue(c.IsSealed, "class should be sealed");
@ -178,7 +217,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void InnerClassReferenceTest() public void InnerClassReferenceTest()
{ {
IClass c = pc.GetClass("System.Environment", 0); IClass c = mscorlib.GetClass("System.Environment", 0);
Assert.IsNotNull(c, "System.Environment not found"); Assert.IsNotNull(c, "System.Environment not found");
IReturnType rt = GetMethod(c, "GetFolderPath").Parameters[0].ReturnType; IReturnType rt = GetMethod(c, "GetFolderPath").Parameters[0].ReturnType;
Assert.IsNotNull(rt, "ReturnType is null"); Assert.IsNotNull(rt, "ReturnType is null");
@ -191,7 +230,7 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void InnerClassesTest() public void InnerClassesTest()
{ {
IClass c = pc.GetClass("System.Environment.SpecialFolder", 0); IClass c = mscorlib.GetClass("System.Environment.SpecialFolder", 0);
Assert.IsNotNull(c, "c is null"); Assert.IsNotNull(c, "c is null");
Assert.AreEqual("System.Environment.SpecialFolder", c.FullyQualifiedName); Assert.AreEqual("System.Environment.SpecialFolder", c.FullyQualifiedName);
} }
@ -199,19 +238,19 @@ namespace ICSharpCode.SharpDevelop.Tests
[Test] [Test]
public void VoidTest() public void VoidTest()
{ {
IClass c = pc.GetClass("System.Void", 0); IClass c = mscorlib.GetClass("System.Void", 0);
Assert.IsNotNull(c, "System.Void not found"); Assert.IsNotNull(c, "System.Void not found");
Assert.AreSame(c.DefaultReturnType, pc.SystemTypes.Void, "pc.SystemTypes.Void is c.DefaultReturnType"); Assert.AreSame(c.DefaultReturnType, mscorlib.SystemTypes.Void, "pc.SystemTypes.Void is c.DefaultReturnType");
} }
[Test] [Test]
public void NestedClassInGenericClassTest() public void NestedClassInGenericClassTest()
{ {
IClass dictionary = pc.GetClass("System.Collections.Generic.Dictionary", 2); IClass dictionary = mscorlib.GetClass("System.Collections.Generic.Dictionary", 2);
Assert.IsNotNull(dictionary); Assert.IsNotNull(dictionary);
IClass valueCollection = pc.GetClass("System.Collections.Generic.Dictionary.ValueCollection", 2); IClass valueCollection = mscorlib.GetClass("System.Collections.Generic.Dictionary.ValueCollection", 2);
Assert.IsNotNull(valueCollection); Assert.IsNotNull(valueCollection);
var dictionaryRT = new ConstructedReturnType(dictionary.DefaultReturnType, new[] { pc.SystemTypes.String, pc.SystemTypes.Int32 }); var dictionaryRT = new ConstructedReturnType(dictionary.DefaultReturnType, new[] { mscorlib.SystemTypes.String, mscorlib.SystemTypes.Int32 });
IProperty valueProperty = dictionaryRT.GetProperties().Find(p => p.Name == "Values"); IProperty valueProperty = dictionaryRT.GetProperties().Find(p => p.Name == "Values");
Assert.AreSame(valueCollection, valueProperty.ReturnType.GetUnderlyingClass()); Assert.AreSame(valueCollection, valueProperty.ReturnType.GetUnderlyingClass());
} }
@ -223,6 +262,7 @@ namespace ICSharpCode.SharpDevelop.Tests
} }
protected abstract IClass GetClass(Type type); protected abstract IClass GetClass(Type type);
protected abstract IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly);
[Test] [Test]
public void ReflectionParserTest() public void ReflectionParserTest()
@ -260,5 +300,25 @@ namespace ICSharpCode.SharpDevelop.Tests
GenericReturnType grt = (GenericReturnType)m.TypeParameters[0].Constraints[0].CastToConstructedReturnType().TypeArguments[0]; GenericReturnType grt = (GenericReturnType)m.TypeParameters[0].Constraints[0].CastToConstructedReturnType().TypeArguments[0];
Assert.AreSame(m.TypeParameters[0], grt.TypeParameter); Assert.AreSame(m.TypeParameters[0], grt.TypeParameter);
} }
[Test]
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);
}
} }
} }

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj

@ -138,6 +138,7 @@
<Compile Include="Src\FilePosition.cs" /> <Compile Include="Src\FilePosition.cs" />
<Compile Include="Src\FoldingRegion.cs" /> <Compile Include="Src\FoldingRegion.cs" />
<Compile Include="Src\IComment.cs" /> <Compile Include="Src\IComment.cs" />
<Compile Include="Src\ReflectionLayer\ReflectionTypeNameSyntaxError.cs" />
<Compile Include="Src\XmlDoc.cs" /> <Compile Include="Src\XmlDoc.cs" />
<Compile Include="Src\Tag.cs" /> <Compile Include="Src\Tag.cs" />
<Compile Include="Src\ResolveResult.cs" /> <Compile Include="Src\ResolveResult.cs" />

19
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs

@ -38,8 +38,20 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
foreach (CustomAttribute att in attributes) { foreach (CustomAttribute att in attributes) {
DefaultAttribute a = new DefaultAttribute(CreateType(pc, null, att.Constructor.DeclaringType)); DefaultAttribute a = new DefaultAttribute(CreateType(pc, null, att.Constructor.DeclaringType));
foreach (object o in att.ConstructorParameters) { // Currently Cecil returns string instead of TypeReference for typeof() arguments to attributes
a.PositionalArguments.Add(o); var parameters = att.Constructor.Parameters;
for (int i = 0; i < Math.Min(parameters.Count, att.ConstructorParameters.Count); i++) {
object o = att.ConstructorParameters[i];
if (parameters[i].ParameterType.FullName == "System.Type" && o is string) {
try {
a.PositionalArguments.Add(ReflectionReturnType.Parse(pc, (string)o));
} catch (ReflectionTypeNameSyntaxError ex) {
LoggingService.Warn(ex);
a.PositionalArguments.Add(o);
}
} else {
a.PositionalArguments.Add(o);
}
} }
foreach (DictionaryEntry entry in att.Properties) { foreach (DictionaryEntry entry in att.Properties) {
a.NamedArguments.Add(entry.Key.ToString(), entry.Value); a.NamedArguments.Add(entry.Key.ToString(), entry.Value);
@ -142,11 +154,12 @@ namespace ICSharpCode.SharpDevelop.Dom
AssemblyDefinition assembly, ProjectContentRegistry registry) AssemblyDefinition assembly, ProjectContentRegistry registry)
: base(fullName, fileName, referencedAssemblies, registry) : base(fullName, fileName, referencedAssemblies, registry)
{ {
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly.CustomAttributes);
foreach (ModuleDefinition module in assembly.Modules) { foreach (ModuleDefinition module in assembly.Modules) {
AddTypes(module.Types); AddTypes(module.Types);
} }
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly.CustomAttributes);
InitializeSpecialClasses(); InitializeSpecialClasses();
this.AssemblyCompilationUnit.Freeze();
} }
void AddTypes(TypeDefinitionCollection types) void AddTypes(TypeDefinitionCollection types)

13
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs

@ -84,8 +84,19 @@ namespace ICSharpCode.SharpDevelop.Dom
AddClassToNamespaceListInternal(new ReflectionClass(assemblyCompilationUnit, type, name, null)); AddClassToNamespaceListInternal(new ReflectionClass(assemblyCompilationUnit, type, name, null));
} }
} }
ReflectionClass.AddAttributes(this, assemblyCompilationUnit.Attributes, CustomAttributeData.GetCustomAttributes(assembly));
InitializeSpecialClasses(); InitializeSpecialClasses();
AddAssemblyAttributes(assembly);
assemblyCompilationUnit.Freeze();
}
/// <summary>
/// Adds assembly attributes from the specified assembly.
///
/// The constructor already does this, this method is meant for unit tests only!
/// </summary>
public void AddAssemblyAttributes(Assembly assembly)
{
ReflectionClass.AddAttributes(this, assemblyCompilationUnit.Attributes, CustomAttributeData.GetCustomAttributes(assembly));
} }
public ReflectionProjectContent(string assemblyFullName, string assemblyLocation, DomAssemblyName[] referencedAssemblies, ProjectContentRegistry registry) public ReflectionProjectContent(string assemblyFullName, string assemblyLocation, DomAssemblyName[] referencedAssemblies, ProjectContentRegistry registry)

3
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public const long FileMagic = 0x11635233ED2F428C; public const long FileMagic = 0x11635233ED2F428C;
public const long IndexFileMagic = 0x11635233ED2F427D; public const long IndexFileMagic = 0x11635233ED2F427D;
public const short FileVersion = 21; public const short FileVersion = 22;
ProjectContentRegistry registry; ProjectContentRegistry registry;
string cacheDirectory; string cacheDirectory;
@ -179,6 +179,7 @@ namespace ICSharpCode.SharpDevelop.Dom
pc = new ReadWriteHelper(reader).ReadProjectContent(registry); pc = new ReadWriteHelper(reader).ReadProjectContent(registry);
if (pc != null) { if (pc != null) {
pc.InitializeSpecialClasses(); pc.InitializeSpecialClasses();
pc.AssemblyCompilationUnit.Freeze();
} }
return pc; return pc;
} catch (EndOfStreamException) { } catch (EndOfStreamException) {

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
static object ReplaceTypeByIReturnType(IProjectContent pc, object val) static object ReplaceTypeByIReturnType(IProjectContent pc, object val)
{ {
if (val is Type) { if (val is Type) {
return ReflectionReturnType.Create(pc, null, (Type)val, false); return ReflectionReturnType.Create(pc, null, (Type)val, false, false);
} else { } else {
return val; return val;
} }

84
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionReturnType.cs

@ -18,6 +18,78 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
return !type.IsArray && !type.IsGenericType && !type.IsGenericParameter; return !type.IsArray && !type.IsGenericType && !type.IsGenericParameter;
} }
#region Parse Reflection Type Name
public static IReturnType Parse(IProjectContent pc, string reflectionTypeName)
{
if (pc == null)
throw new ArgumentNullException("pc");
using (var tokenizer = Tokenize(reflectionTypeName)) {
tokenizer.MoveNext();
IReturnType result = Parse(pc, tokenizer);
if (tokenizer.Current != null)
throw new ReflectionTypeNameSyntaxError("Expected end of type name, but found " + tokenizer.Current);
return result;
}
}
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;
}
static IEnumerator<string> Tokenize(string reflectionTypeName)
{
StringBuilder currentText = new StringBuilder();
for (int i = 0; i < reflectionTypeName.Length; i++) {
char c = reflectionTypeName[i];
if (c == ',' || c == '[' || c == ']') {
if (currentText.Length > 0) {
yield return currentText.ToString();
currentText.Length = 0;
}
yield return c.ToString();
} else {
currentText.Append(c);
}
}
if (currentText.Length > 0)
yield return currentText.ToString();
yield return null;
}
#endregion
public static IReturnType Create(IClass @class, Type type, bool createLazyReturnType) public static IReturnType Create(IClass @class, Type type, bool createLazyReturnType)
{ {
return Create(@class.ProjectContent, @class, type, createLazyReturnType); return Create(@class.ProjectContent, @class, type, createLazyReturnType);
@ -33,7 +105,17 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
return Create(pc, member, type, createLazyReturnType, true); return Create(pc, member, type, createLazyReturnType, true);
} }
static IReturnType Create(IProjectContent pc, IEntity member, Type type, bool createLazyReturnType, bool forceGenericType) /// <summary>
/// Creates a IReturnType from the reflection type.
/// </summary>
/// <param name="pc">The project content used as context.</param>
/// <param name="member">The member used as context (e.g. as GenericReturnType)</param>
/// <param name="type">The reflection return type that should be converted</param>
/// <param name="createLazyReturnType">Set this parameter to false to create a direct return type
/// (without GetClassReturnType indirection) where possible</param>
/// <param name="forceGenericType">Set this parameter to false to allow unbound generic types</param>
/// <returns>The IReturnType</returns>
public static IReturnType Create(IProjectContent pc, IEntity member, Type type, bool createLazyReturnType, bool forceGenericType)
{ {
if (type.IsByRef) { if (type.IsByRef) {
// TODO: Use ByRefRefReturnType // TODO: Use ByRefRefReturnType

35
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionTypeNameSyntaxError.cs

@ -0,0 +1,35 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
/// <summary>
/// Thrown if there is a syntax error in a type name.
/// </summary>
[Serializable]
public class ReflectionTypeNameSyntaxError : Exception
{
public ReflectionTypeNameSyntaxError() : base()
{
}
public ReflectionTypeNameSyntaxError(string message) : base(message)
{
}
public ReflectionTypeNameSyntaxError(string message, Exception innerException) : base(message, innerException)
{
}
protected ReflectionTypeNameSyntaxError(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
Loading…
Cancel
Save