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 16 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 @@ -239,6 +239,15 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
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;
try {
solutionPath = NewProjectDirectory;
@ -274,6 +283,25 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs @@ -274,6 +283,25 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
public string NewProjectLocation;
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)
{
@ -287,19 +315,9 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs @@ -287,19 +315,9 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs
string solution = solutionNameTextBox.Text.Trim();
string name = nameTextBox.Text.Trim();
string location = locationTextBox.Text.Trim();
if (!FileUtility.IsValidDirectoryName(solution)
|| !FileUtility.IsValidDirectoryName(name)
|| !FileUtility.IsValidPath(location))
{
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}");
string projectNameError = CheckProjectName(solution, name, location);
if (projectNameError != null) {
MessageService.ShowError(projectNameError);
return;
}

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

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

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

@ -38,8 +38,20 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -38,8 +38,20 @@ namespace ICSharpCode.SharpDevelop.Dom
{
foreach (CustomAttribute att in attributes) {
DefaultAttribute a = new DefaultAttribute(CreateType(pc, null, att.Constructor.DeclaringType));
foreach (object o in att.ConstructorParameters) {
a.PositionalArguments.Add(o);
// Currently Cecil returns string instead of TypeReference for typeof() arguments to attributes
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) {
a.NamedArguments.Add(entry.Key.ToString(), entry.Value);
@ -142,11 +154,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -142,11 +154,12 @@ namespace ICSharpCode.SharpDevelop.Dom
AssemblyDefinition assembly, ProjectContentRegistry registry)
: base(fullName, fileName, referencedAssemblies, registry)
{
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly.CustomAttributes);
foreach (ModuleDefinition module in assembly.Modules) {
AddTypes(module.Types);
}
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly.CustomAttributes);
InitializeSpecialClasses();
this.AssemblyCompilationUnit.Freeze();
}
void AddTypes(TypeDefinitionCollection types)

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

@ -84,8 +84,19 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -84,8 +84,19 @@ namespace ICSharpCode.SharpDevelop.Dom
AddClassToNamespaceListInternal(new ReflectionClass(assemblyCompilationUnit, type, name, null));
}
}
ReflectionClass.AddAttributes(this, assemblyCompilationUnit.Attributes, CustomAttributeData.GetCustomAttributes(assembly));
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)

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

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

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

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

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

@ -18,6 +18,78 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -18,6 +18,78 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
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)
{
return Create(@class.ProjectContent, @class, type, createLazyReturnType);
@ -33,7 +105,17 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -33,7 +105,17 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
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) {
// TODO: Use ByRefRefReturnType

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

@ -0,0 +1,35 @@ @@ -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