Browse Source

Added special support for 'void' (type without members); implemented ReflectionHelper.ToTypeReference.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
289d6078dc
  1. 1
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  2. 73
      ICSharpCode.NRefactory.Tests/TypeSystem/CecilLoaderTests.cs
  3. 148
      ICSharpCode.NRefactory.Tests/TypeSystem/ReflectionHelperTests.cs
  4. 2
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  5. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  6. 132
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  7. 4
      ICSharpCode.NRefactory/TypeSystem/INamedElement.cs
  8. 15
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  9. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs
  10. 22
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs
  11. 73
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  12. 9
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs
  13. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleConstantValue.cs
  14. 45
      ICSharpCode.NRefactory/TypeSystem/Implementation/VoidTypeDefinition.cs
  15. 13
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs
  16. 54
      ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs

1
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
<Compile Include="FormattingTests\TestTypeLevelIndentation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TypeSystem\CecilLoaderTests.cs" />
<Compile Include="TypeSystem\ReflectionHelperTests.cs" />
<Compile Include="TypeSystem\TestInterningProvider.cs" />
<Compile Include="TypeSystem\TypeSystemTests.cs" />
<Compile Include="TypeSystem\TypeSystemTests.TestCase.cs" />

73
ICSharpCode.NRefactory.Tests/TypeSystem/CecilLoaderTests.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
@ -51,5 +52,77 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -51,5 +52,77 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual("System.Collections.Generic.Comparer", pt.FullName);
Assert.AreSame(c.TypeParameters[0], pt.TypeArguments[0]);
}
[Test]
public void PointerTypeTest()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(IntPtr));
IMethod toPointer = c.Methods.Single(p => p.Name == "ToPointer");
Assert.AreEqual("System.Void*", toPointer.ReturnType.Resolve(ctx).DotNetName);
Assert.IsInstanceOf(typeof(PointerType), toPointer.ReturnType.Resolve(ctx));
Assert.AreEqual("System.Void", toPointer.ReturnType.Resolve(ctx).GetElementType().FullName);
}
[Test]
public void DateTimeDefaultConstructor()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(DateTime));
Assert.IsFalse(c.Methods.Any(m => m.IsConstructor && m.Parameters.Count == 0)); // struct ctor isn't declared
// but it is implicit:
Assert.IsTrue(c.GetConstructors(ctx).Any(m => m.Parameters.Count == 0));
}
[Test]
public void NoEncodingInfoDefaultConstructor()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(EncodingInfo));
// EncodingInfo only has an internal constructor
Assert.IsFalse(c.Methods.Any(m => m.IsConstructor));
// and no implicit ctor should be added:
Assert.AreEqual(0, c.GetConstructors(ctx).Count);
}
[Test]
public void StaticModifierTest()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(Environment));
Assert.IsNotNull(c, "System.Environment not found");
Assert.IsTrue(c.IsAbstract, "class should be abstract");
Assert.IsTrue(c.IsSealed, "class should be sealed");
Assert.IsTrue(c.IsStatic, "class should be static");
}
[Test]
public void InnerClassReferenceTest()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(Environment));
Assert.IsNotNull(c, "System.Environment not found");
ITypeReference rt = c.Methods.First(m => m.Name == "GetFolderPath").Parameters[0].Type;
Assert.AreSame(c.InnerClasses.Single(ic => ic.Name == "SpecialFolder"), rt.Resolve(ctx));
}
[Test]
public void InnerClassesTest()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(Environment.SpecialFolder));
Assert.IsNotNull(c, "c is null");
Assert.AreEqual("System.Environment.SpecialFolder", c.FullName);
Assert.AreEqual("System.Environment+SpecialFolder", c.DotNetName);
}
[Test]
public void VoidTest()
{
ITypeDefinition c = Mscorlib.GetClass(typeof(void));
Assert.IsNotNull(c, "System.Void not found");
Assert.AreEqual(0, c.GetMethods(ctx).Count);
Assert.AreEqual(
new string[] {
"[System.SerializableAttribute]",
"[System.Runtime.InteropServices.StructLayoutAttribute(0, Size=1)]",
"[System.Runtime.InteropServices.ComVisibleAttribute(true)]"
},
c.Attributes.Select(a => a.ToString()).ToArray());
}
}
}

148
ICSharpCode.NRefactory.Tests/TypeSystem/ReflectionHelperTests.cs

@ -0,0 +1,148 @@ @@ -0,0 +1,148 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.TypeSystem
{
[TestFixture]
public class ReflectionHelperTests
{
void TestGetClass(Type type)
{
ITypeDefinition t = CecilLoaderTests.Mscorlib.GetClass(type);
Assert.NotNull(t, type.FullName);
Assert.AreEqual(type.FullName, t.DotNetName);
}
[Test]
public void TestGetInnerClass()
{
TestGetClass(typeof(Environment.SpecialFolder));
}
[Test]
public void TestGetGenericClass1()
{
TestGetClass(typeof(Action<>));
}
[Test]
public void TestGetGenericClass2()
{
TestGetClass(typeof(Action<,>));
}
[Test]
public void TestGetInnerClassInGenericClass1()
{
TestGetClass(typeof(Dictionary<,>.ValueCollection));
}
[Test]
public void TestGetInnerClassInGenericClass2()
{
TestGetClass(typeof(Dictionary<,>.ValueCollection.Enumerator));
}
[Test]
public void TestToTypeReferenceInnerClass()
{
Assert.AreEqual("System.Environment+SpecialFolder",
typeof(Environment.SpecialFolder).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceUnboundGenericClass()
{
Assert.AreEqual("System.Action`1",
typeof(Action<>).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
Assert.AreEqual("System.Action`2",
typeof(Action<,>).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceBoundGenericClass()
{
Assert.AreEqual("System.Action`1[[System.String]]",
typeof(Action<string>).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
Assert.AreEqual("System.Action`2[[System.Int32],[System.Int16]]",
typeof(Action<int, short>).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceNullableType()
{
Assert.AreEqual("System.Nullable`1[[System.Int32]]",
typeof(int?).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceInnerClassInUnboundGenericType()
{
Assert.AreEqual("System.Collections.Generic.Dictionary`2+ValueCollection[[`0],[`1]]",
typeof(Dictionary<,>.ValueCollection).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceInnerClassInBoundGenericType()
{
Assert.AreEqual("System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]",
typeof(Dictionary<string, int>.KeyCollection).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceArrayType()
{
Assert.AreEqual(typeof(int[]).FullName,
typeof(int[]).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceMultidimensionalArrayType()
{
Assert.AreEqual(typeof(int[,]).FullName,
typeof(int[,]).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceJaggedMultidimensionalArrayType()
{
Assert.AreEqual(typeof(int[,][,,]).FullName,
typeof(int[,][,,]).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferencePointerType()
{
Assert.AreEqual(typeof(int*).FullName,
typeof(int*).ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceByReferenceType()
{
Assert.AreEqual(typeof(int).MakeByRefType().FullName,
typeof(int).MakeByRefType().ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
[Test]
public void TestToTypeReferenceGenericType()
{
MethodInfo convertAllInfo = typeof(List<>).GetMethod("ConvertAll");
Type parameterType = convertAllInfo.GetParameters()[0].ParameterType; // Converter[[`0],[``0]]
// cannot resolve generic types without knowing the parent entity:
Assert.AreEqual("System.Converter`2[[?],[?]]",
parameterType.ToTypeReference().Resolve(CecilLoaderTests.Mscorlib).DotNetName);
// now try with parent entity:
IMethod convertAll = CecilLoaderTests.Mscorlib.GetClass(typeof(List<>)).Methods.Single(m => m.Name == "ConvertAll");
Assert.AreEqual("System.Converter`2[[`0],[``0]]",
parameterType.ToTypeReference(entity: convertAll).Resolve(CecilLoaderTests.Mscorlib).DotNetName);
}
}
}

2
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -89,7 +89,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -89,7 +89,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName);
Assert.AreEqual("System.String", crt.TypeArguments[0].FullName);
// ? for NUnit.TestAttribute (because that assembly isn't in ctx)
Assert.AreEqual("System.Collections.Generic.IList[[?]]", crt.TypeArguments[1].DotNetName);
Assert.AreEqual("System.Collections.Generic.IList`1[[?]]", crt.TypeArguments[1].DotNetName);
}
}
}

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -183,6 +183,7 @@ @@ -183,6 +183,7 @@
<Compile Include="TypeSystem\Implementation\SpecializedProperty.cs" />
<Compile Include="TypeSystem\Implementation\TypeStorage.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />
<Compile Include="TypeSystem\Implementation\VoidTypeDefinition.cs" />
<Compile Include="TypeSystem\INamedElement.cs" />
<Compile Include="TypeSystem\IParameter.cs" />
<Compile Include="TypeSystem\IParameterizedMember.cs" />

132
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Mono.Cecil;
@ -40,7 +41,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -40,7 +41,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeResolveContext oldEarlyBindContext = this.EarlyBindContext;
try {
List<IAttribute> assemblyAttributes = new List<IAttribute>();
AddAttributes(assemblyDefinition, assemblyAttributes);
foreach (var attr in assemblyDefinition.CustomAttributes) {
assemblyAttributes.Add(ReadAttribute(attr));
}
TypeStorage typeStorage = new TypeStorage();
CecilProjectContent pc = new CecilProjectContent(typeStorage, assemblyDefinition.Name.FullName, assemblyAttributes.AsReadOnly());
@ -52,13 +55,20 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -52,13 +55,20 @@ namespace ICSharpCode.NRefactory.TypeSystem
string name = td.FullName;
if (name.Length == 0 || name[0] == '<')
continue;
types.Add(new CecilTypeDefinition(pc, td));
if (name == "System.Void") {
var c = new VoidTypeDefinition(pc);
AddAttributes(td, c);
typeStorage.UpdateType(c);
} else {
CecilTypeDefinition c = new CecilTypeDefinition(pc, td);
types.Add(c);
typeStorage.UpdateType(c);
}
}
}
}
foreach (CecilTypeDefinition c in types) {
c.Init(this);
typeStorage.UpdateType(c);
}
return pc;
} finally {
@ -278,10 +288,81 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -278,10 +288,81 @@ namespace ICSharpCode.NRefactory.TypeSystem
#endregion
#region Read Attributes
void AddAttributes(ICustomAttributeProvider attributeProvider, IList<IAttribute> outputList)
void AddAttributes(ICustomAttributeProvider customAttributeProvider, IEntity targetEntity)
{
if (customAttributeProvider.HasCustomAttributes) {
foreach (var cecilAttribute in customAttributeProvider.CustomAttributes) {
targetEntity.Attributes.Add(ReadAttribute(cecilAttribute));
}
}
}
void AddAttributes(ParameterDefinition parameter, DefaultParameter targetParameter)
{
foreach (var cecilAttribute in attributeProvider.CustomAttributes) {
outputList.Add(ReadAttribute(cecilAttribute));
if (parameter.HasCustomAttributes) {
foreach (var cecilAttribute in parameter.CustomAttributes) {
targetParameter.Attributes.Add(ReadAttribute(cecilAttribute));
}
}
}
static readonly DefaultAttribute serializableAttribute = new DefaultAttribute(typeof(SerializableAttribute).ToTypeReference());
void AddAttributes(TypeDefinition typeDefinition, ITypeDefinition targetEntity)
{
#region SerializableAttribute
if (typeDefinition.IsSerializable)
targetEntity.Attributes.Add(serializableAttribute);
#endregion
#region StructLayoutAttribute
LayoutKind layoutKind = LayoutKind.Auto;
switch (typeDefinition.Attributes & TypeAttributes.LayoutMask) {
case TypeAttributes.SequentialLayout:
layoutKind = LayoutKind.Sequential;
break;
case TypeAttributes.ExplicitLayout:
layoutKind = LayoutKind.Explicit;
break;
}
CharSet charSet = CharSet.None;
switch (typeDefinition.Attributes & TypeAttributes.StringFormatMask) {
case TypeAttributes.AnsiClass:
charSet = CharSet.Ansi;
break;
case TypeAttributes.AutoClass:
charSet = CharSet.Auto;
break;
case TypeAttributes.UnicodeClass:
charSet = CharSet.Unicode;
break;
}
if (layoutKind != LayoutKind.Auto || charSet != CharSet.Ansi || typeDefinition.PackingSize > 0 || typeDefinition.ClassSize > 0) {
DefaultAttribute structLayout = new DefaultAttribute(typeof(StructLayoutAttribute).ToTypeReference());
structLayout.PositionalArguments.Add(new SimpleConstantValue(typeof(LayoutKind).ToTypeReference(), (int)layoutKind));
if (charSet != CharSet.Ansi) {
structLayout.NamedArguments.Add(new KeyValuePair<string, IConstantValue>(
"CharSet",
new SimpleConstantValue(typeof(CharSet).ToTypeReference(), (int)charSet)));
}
if (typeDefinition.PackingSize > 0) {
structLayout.NamedArguments.Add(new KeyValuePair<string, IConstantValue>(
"Pack",
new SimpleConstantValue(typeof(int).ToTypeReference(), (int)typeDefinition.PackingSize)));
}
if (typeDefinition.ClassSize > 0) {
structLayout.NamedArguments.Add(new KeyValuePair<string, IConstantValue>(
"Size",
new SimpleConstantValue(typeof(int).ToTypeReference(), (int)typeDefinition.ClassSize)));
}
targetEntity.Attributes.Add(structLayout);
}
#endregion
if (typeDefinition.HasCustomAttributes) {
foreach (var cecilAttribute in typeDefinition.CustomAttributes) {
targetEntity.Attributes.Add(ReadAttribute(cecilAttribute));
}
}
}
@ -336,12 +417,25 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -336,12 +417,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
: base(pc, typeDefinition.Namespace, ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeDefinition.Name))
{
this.typeDefinition = typeDefinition;
InitTypeParameters();
}
public CecilTypeDefinition(CecilTypeDefinition parentType, string name, TypeDefinition typeDefinition)
: base(parentType, name)
{
this.typeDefinition = typeDefinition;
InitTypeParameters();
}
void InitTypeParameters()
{
// Type parameters are initialized within the constructor so that the class can be put into the type storage
// before the rest of the initialization runs - this allows it to be available for early binding as soon as possible.
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
if (typeDefinition.GenericParameters[i].Position != i)
throw new InvalidOperationException("g.Position != i");
this.TypeParameters.Add(new DefaultTypeParameter(this, i, typeDefinition.GenericParameters[i].Name));
}
}
public void Init(CecilLoader loader)
@ -349,11 +443,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -349,11 +443,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
InitModifiers();
if (typeDefinition.HasGenericParameters) {
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
if (typeDefinition.GenericParameters[i].Position != i)
throw new InvalidOperationException("g.Position != i");
this.TypeParameters.Add(new DefaultTypeParameter(this, i, typeDefinition.GenericParameters[i].Name));
}
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
loader.AddConstraints((DefaultTypeParameter)this.TypeParameters[i], typeDefinition.GenericParameters[i]);
}
@ -362,7 +451,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -362,7 +451,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
InitNestedTypes(loader); // nested types can be initialized only after generic parameters were created
if (typeDefinition.HasCustomAttributes) {
loader.AddAttributes(typeDefinition, this.Attributes);
loader.AddAttributes(typeDefinition, this);
}
// set base classes
@ -543,10 +632,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -543,10 +632,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
else
m.ReturnType = ReadTypeReference(method.ReturnType, typeAttributes: method, entity: m);
if (method.HasCustomAttributes) {
AddAttributes(method, m.Attributes);
}
AddAttributes(method, m);
TranslateModifiers(method, m);
if (method.HasParameters) {
@ -620,8 +706,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -620,8 +706,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
var type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter, entity: parentMember);
DefaultParameter p = new DefaultParameter(type, parameter.Name);
if (parameter.HasCustomAttributes)
AddAttributes(parameter, p.Attributes);
AddAttributes(parameter, p);
if (parameter.ParameterType is Mono.Cecil.ByReferenceType) {
if (parameter.IsOut)
@ -671,9 +756,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -671,9 +756,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (field.HasConstant) {
f.ConstantValue = ReadConstantValue(new CustomAttributeArgument(field.FieldType, field.Constant));
}
if (field.HasCustomAttributes) {
AddAttributes(field, f.Attributes);
}
AddAttributes(field, f);
RequiredModifierType modreq = field.FieldType as RequiredModifierType;
if (modreq != null && modreq.ModifierType.FullName == typeof(IsVolatile).FullName) {
f.IsVolatile = true;
@ -749,8 +833,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -749,8 +833,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
p.Parameters.Add(ReadParameter(par, parentMember: p));
}
}
if (property.HasCustomAttributes)
AddAttributes(property, p.Attributes);
AddAttributes(property, p);
return p;
}
@ -779,8 +862,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -779,8 +862,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (e.CanInvoke)
e.InvokeAccessibility = GetAccessibility(ev.InvokeMethod.Attributes);
if (ev.HasCustomAttributes)
AddAttributes(ev, e.Attributes);
AddAttributes(ev, e);
return e;
}

4
ICSharpCode.NRefactory/TypeSystem/INamedElement.cs

@ -15,6 +15,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -15,6 +15,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <returns>
/// "System.Int32[]" for int[]<br/>
/// "System.Collections.Generic.List" for List&lt;string&gt;
/// "System.Environment.SpecialFolder" for Environment.SpecialFolder
/// </returns>
string FullName {
get;
@ -26,6 +27,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,6 +27,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <returns>
/// "Int32[]" for int[]<br/>
/// "List" for List&lt;string&gt;
/// "SpecialFolder" for Environment.SpecialFolder
/// </returns>
string Name {
get;
@ -37,6 +39,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -37,6 +39,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <returns>
/// "System" for int[]<br/>
/// "System.Collections.Generic" for List&lt;string&gt;
/// "System" for Environment.SpecialFolder
/// </returns>
string Namespace {
get;
@ -49,6 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -49,6 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// "System.Int32[]" for int[]<br/>
/// "System.Int32[][,]" for C# int[,][]<br/>
/// "System.Collections.Generic.List`1[[System.String]]" for List&lt;string&gt;
/// "System.Environment+SpecialFolder" for Environment.SpecialFolder
/// </returns>
string DotNetName {
get;

15
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -74,9 +74,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -74,9 +74,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Gets all methods that can be called on this return type.
/// </summary>
/// <remarks>The list does not include constructors.</remarks>
/// <returns>A new mutable list</returns>
IList<IMethod> GetMethods(ITypeResolveContext context);
/// <summary>
/// Gets all instance constructors for this type.
/// </summary>
/// <remarks>This list does not include constructors in base classes or static constructors.</remarks>
/// <returns>A new mutable list</returns>
IList<IMethod> GetConstructors(ITypeResolveContext context);
/// <summary>
/// Gets all properties that can be called on this return type.
/// </summary>
@ -135,6 +143,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -135,6 +143,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
return null;
}
IList<IMethod> IType.GetConstructors(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IList<IMethod>>() != null);
return null;
}
IList<IProperty> IType.GetProperties(ITypeResolveContext context)
{
Contract.Requires(context != null);

5
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs

@ -76,6 +76,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -76,6 +76,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return EmptyList<IMethod>.Instance;
}
public virtual IList<IMethod> GetConstructors(ITypeResolveContext context)
{
return EmptyList<IMethod>.Instance;
}
public virtual IList<IProperty> GetProperties(ITypeResolveContext context)
{
return EmptyList<IProperty>.Instance;

22
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
@ -74,7 +75,26 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -74,7 +75,26 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override string ToString()
{
return "[" + attributeType + "]";
StringBuilder b = new StringBuilder();
b.Append('[');
b.Append(attributeType.ToString());
if (this.PositionalArguments.Count + this.NamedArguments.Count > 0) {
b.Append('(');
bool first = true;
foreach (var element in this.PositionalArguments) {
if (first) first = false; else b.Append(", ");
b.Append(element.ToString());
}
foreach (var pair in this.NamedArguments) {
if (first) first = false; else b.Append(", ");
b.Append(pair.Key);
b.Append('=');
b.Append(pair.Value.ToString());
}
b.Append(')');
}
b.Append(']');
return b.ToString();
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)

73
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

@ -196,15 +196,19 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -196,15 +196,19 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
combinedName = declaringTypeDefinition.DotNetName + "+" + this.Name + "`" + tpCount.ToString(CultureInfo.InvariantCulture);
else
combinedName = declaringTypeDefinition.DotNetName + "+" + this.Name;
Contract.Assume(!string.IsNullOrEmpty(combinedName)); // help out the static checker
return combinedName;
} else {
int tpCount = this.TypeParameterCount;
if (string.IsNullOrEmpty(ns)) {
return this.Name;
if (tpCount > 0)
return this.Name + "`" + tpCount.ToString(CultureInfo.InvariantCulture);
else
return this.Name;
} else {
string combinedName = this.Namespace + "." + this.Name;
Contract.Assume(!string.IsNullOrEmpty(combinedName)); // help out the static checker
return combinedName;
if (tpCount > 0)
return this.Namespace + "." + this.Name + "`" + tpCount.ToString(CultureInfo.InvariantCulture);
else
return this.Namespace + "." + this.Name;
}
}
}
@ -357,8 +361,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -357,8 +361,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return this;
}
public IList<IType> GetNestedTypes(ITypeResolveContext context)
public virtual IList<IType> GetNestedTypes(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetNestedTypes(context);
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
IList<IType> nestedTypes = null;
@ -388,8 +396,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -388,8 +396,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
public IList<IMethod> GetMethods(ITypeResolveContext context)
public virtual IList<IMethod> GetMethods(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetMethods(context);
List<IMethod> methods = new List<IMethod>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
@ -400,14 +412,45 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -400,14 +412,45 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
methods.AddRange(baseType.GetMethods(context));
}
}
methods.AddRange(this.Methods);
methods.AddRange(this.Methods.Where(m => !m.IsConstructor));
}
}
return methods;
}
public IList<IProperty> GetProperties(ITypeResolveContext context)
public virtual IList<IMethod> GetConstructors(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetConstructors(context);
List<IMethod> methods = new List<IMethod>();
methods.AddRange(this.Methods.Where(m => m.IsConstructor && !m.IsStatic));
if (this.AddDefaultConstructorIfRequired) {
if (this.ClassType == ClassType.Class && methods.Count == 0
|| this.ClassType == ClassType.Enum || this.ClassType == ClassType.Struct)
{
DomRegion region = new DomRegion(this.Region.FileName, this.Region.BeginLine, this.Region.BeginColumn);
methods.Add(new DefaultMethod(this, ".ctor") {
EntityType = EntityType.Constructor,
Accessibility = IsAbstract ? Accessibility.Protected : Accessibility.Public,
IsSynthetic = true,
Region = region,
BodyRegion = region,
ReturnType = this
});
}
}
return methods;
}
public virtual IList<IProperty> GetProperties(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetProperties(context);
List<IProperty> properties = new List<IProperty>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
@ -424,8 +467,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -424,8 +467,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return properties;
}
public IList<IField> GetFields(ITypeResolveContext context)
public virtual IList<IField> GetFields(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetFields(context);
List<IField> fields = new List<IField>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
@ -442,8 +489,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -442,8 +489,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return fields;
}
public IList<IEvent> GetEvents(ITypeResolveContext context)
public virtual IList<IEvent> GetEvents(ITypeResolveContext context)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetEvents(context);
List<IEvent> events = new List<IEvent>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {

9
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs

@ -62,6 +62,15 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -62,6 +62,15 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return name; }
}
public override string DotNetName {
get {
if (parent is IMethod)
return "``" + index.ToString();
else
return "`" + index.ToString();
}
}
public override bool? IsReferenceType {
get {
switch (flags.Data & (FlagReferenceTypeConstraint | FlagValueTypeConstraint)) {

2
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleConstantValue.cs

@ -38,6 +38,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -38,6 +38,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
if (value == null)
return "null";
else if (value is bool)
return value.ToString().ToLowerInvariant();
else
return value.ToString();
}

45
ICSharpCode.NRefactory/TypeSystem/Implementation/VoidTypeDefinition.cs

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@

using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Special type definition for 'void'.
/// </summary>
public class VoidTypeDefinition : DefaultTypeDefinition
{
public VoidTypeDefinition(IProjectContent projectContent)
: base(projectContent, "System", "Void")
{
this.ClassType = ClassType.Struct;
this.Accessibility = Accessibility.Public;
this.IsSealed = true;
}
public override IList<IMethod> GetConstructors(ITypeResolveContext context)
{
return new List<IMethod>();
}
public override IList<IEvent> GetEvents(ITypeResolveContext context)
{
return new List<IEvent>();
}
public override IList<IField> GetFields(ITypeResolveContext context)
{
return new List<IField>();
}
public override IList<IMethod> GetMethods(ITypeResolveContext context)
{
return new List<IMethod>();
}
public override IList<IProperty> GetProperties(ITypeResolveContext context)
{
return new List<IProperty>();
}
}
}

13
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -192,6 +192,19 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -192,6 +192,19 @@ namespace ICSharpCode.NRefactory.TypeSystem
return methods;
}
public IList<IMethod> GetConstructors(ITypeResolveContext context)
{
Substitution substitution = new Substitution(typeArguments);
IList<IMethod> methods = genericType.GetConstructors(context);
for (int i = 0; i < methods.Count; i++) {
SpecializedMethod m = new SpecializedMethod(methods[i]);
m.SetDeclaringType(this);
m.SubstituteTypes(context, substitution);
methods[i] = m;
}
return methods;
}
public IList<IProperty> GetProperties(ITypeResolveContext context)
{
Substitution substitution = new Substitution(typeArguments);

54
ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -21,6 +22,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -21,6 +22,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (declaringType != null) {
int typeParameterCount;
string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
typeParameterCount += declaringType.TypeParameterCount;
foreach (ITypeDefinition innerClass in declaringType.InnerClasses) {
if (innerClass.Name == name && innerClass.TypeParameterCount == typeParameterCount) {
return innerClass;
@ -35,6 +37,58 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -35,6 +37,58 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
/// <summary>
/// Creates a reference to the specified type.
/// </summary>
/// <param name="type">The type to be converted.</param>
/// <param name="entity">The parent entity, used to fetch the ITypeParameter for generic types.</param>
/// <returns>Returns the class; or null if it is not found.</returns>
public static ITypeReference ToTypeReference(this Type type, IEntity entity = null)
{
if (type.IsGenericType && !type.IsGenericTypeDefinition) {
ITypeReference def = ToTypeReference(type.GetGenericTypeDefinition(), entity);
Type[] arguments = type.GetGenericArguments();
ITypeReference[] args = new ITypeReference[arguments.Length];
for (int i = 0; i < arguments.Length; i++) {
args[i] = ToTypeReference(arguments[i], entity);
}
return new ParameterizedTypeReference(def, args);
} else if (type.IsArray) {
return new ArrayTypeReference(ToTypeReference(type.GetElementType(), entity), type.GetArrayRank());
} else if (type.IsPointer) {
return new PointerTypeReference(ToTypeReference(type.GetElementType(), entity));
} else if (type.IsByRef) {
return new ByReferenceTypeReference(ToTypeReference(type.GetElementType(), entity));
} else if (type.IsGenericParameter) {
if (type.DeclaringMethod != null) {
IMethod method = entity as IMethod;
if (method != null) {
if (type.GenericParameterPosition < method.TypeParameters.Count) {
return method.TypeParameters[type.GenericParameterPosition];
}
}
return SharedTypes.UnknownType;
} else {
ITypeDefinition c = (entity as ITypeDefinition) ?? (entity is IMember ? ((IMember)entity).DeclaringTypeDefinition : null);
if (c != null && type.GenericParameterPosition < c.TypeParameters.Count) {
if (c.TypeParameters[type.GenericParameterPosition].Name == type.Name) {
return c.TypeParameters[type.GenericParameterPosition];
}
}
return SharedTypes.UnknownType;
}
} else if (type.DeclaringType != null) {
ITypeReference baseTypeRef = ToTypeReference(type.DeclaringType, entity);
int typeParameterCount;
string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
return new NestedTypeReference(baseTypeRef, name, typeParameterCount);
} else {
int typeParameterCount;
string name = SplitTypeParameterCountFromReflectionName(type.FullName, out typeParameterCount);
return new GetClassTypeReference(name, typeParameterCount);
}
}
/// <summary>
/// Removes the ` with type parameter count from the reflection name.
/// </summary>

Loading…
Cancel
Save