Browse Source

Implemented support for 'dynamic' type in SharpDevelop.Dom.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5625 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 16 years ago
parent
commit
cd6059fa22
  1. 2
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs
  2. 38
      src/Main/Base/Test/ReflectionLayerTests.cs
  3. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  4. 70
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  5. 55
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DynamicReturnType.cs
  6. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs
  7. 7
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs
  8. 12
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs
  9. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionEvent.cs
  10. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionField.cs
  11. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionMethod.cs
  12. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionParameter.cs
  13. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionProperty.cs
  14. 89
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionReturnType.cs

2
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs

@ -524,7 +524,7 @@ namespace ICSharpCode.FormsDesigner @@ -524,7 +524,7 @@ namespace ICSharpCode.FormsDesigner
{
MethodInfo mInfo = eventType.GetMethod("Invoke");
DefaultMethod m = new DefaultMethod(declaringType, methodName);
m.ReturnType = ReflectionLayer.ReflectionReturnType.Create(m, mInfo.ReturnType, false);
m.ReturnType = ReflectionLayer.ReflectionReturnType.Create(m, mInfo.ReturnType);
foreach (ParameterInfo pInfo in mInfo.GetParameters()) {
m.Parameters.Add(new ReflectionLayer.ReflectionParameter(pInfo, m));
}

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

@ -7,12 +7,13 @@ @@ -7,12 +7,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Linq;
using System.Reflection;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using ICSharpCode.SharpDevelop.Dom.ReflectionLayer;
using NUnit.Framework;
@ -37,6 +38,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -37,6 +38,7 @@ namespace ICSharpCode.SharpDevelop.Tests
protected override IClass GetClass(Type type)
{
ICompilationUnit cu = new ReflectionProjectContent("TestName", "testlocation", new DomAssemblyName[0], AssemblyParserService.DefaultProjectContentRegistry).AssemblyCompilationUnit;
((ReflectionProjectContent)cu.ProjectContent).AddReferencedContent(mscorlib);
IClass c = new ReflectionClass(cu, type, type.FullName, null);
cu.ProjectContent.AddClassToNamespaceList(c);
return c;
@ -73,7 +75,9 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -73,7 +75,9 @@ namespace ICSharpCode.SharpDevelop.Tests
DomPersistence.WriteProjectContent((ReflectionProjectContent)c.ProjectContent, memory);
memory.Position = 0;
return DomPersistence.LoadProjectContent(memory, AssemblyParserService.DefaultProjectContentRegistry).Classes.Single();
ReflectionProjectContent loadedPC = DomPersistence.LoadProjectContent(memory, AssemblyParserService.DefaultProjectContentRegistry);
loadedPC.AddReferencedContent(mscorlib);
return loadedPC.Classes.Single();
}
protected override IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly)
@ -99,8 +103,9 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -99,8 +103,9 @@ namespace ICSharpCode.SharpDevelop.Tests
IProjectContent LoadAssembly(Assembly assembly)
{
IProjectContent pc = CecilReader.LoadAssembly(assembly.Location, AssemblyParserService.DefaultProjectContentRegistry);
var pc = CecilReader.LoadAssembly(assembly.Location, AssemblyParserService.DefaultProjectContentRegistry);
Assert.IsNotNull(pc);
pc.AddReferencedContent(mscorlib);
return pc;
}
@ -330,7 +335,13 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -330,7 +335,13 @@ namespace ICSharpCode.SharpDevelop.Tests
public void GetIndex<T>(T element) where T: IEquatable<T> {}
public int Property { get; protected set; }
public int ReadOnlyPropertyWithPrivateSetter { get; private set; }
public dynamic ReadOnlyPropertyWithPrivateSetter { get; private set; }
public List<dynamic> DynamicGenerics1(Action<object, dynamic[], object> param) { return null; }
public void DynamicGenerics2(Action<object, dynamic, object> param) { }
public void DynamicGenerics3(Action<int, dynamic, object> param) { }
public void DynamicGenerics4(Action<int[], dynamic, object> param) { }
public void DynamicGenerics5(Action<int*[], dynamic, object> param) { }
}
protected abstract IClass GetClass(Type type);
@ -398,6 +409,25 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -398,6 +409,25 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.IsFalse(p.CanSet);
}
[Test]
public void DynamicType()
{
IProperty p = testClass.Properties.Single(pr => pr.Name == "ReadOnlyPropertyWithPrivateSetter");
Assert.IsInstanceOf(typeof(DynamicReturnType), p.ReturnType);
}
[Test]
public void DynamicTypeInGenerics()
{
CSharpAmbience a = new CSharpAmbience();
a.ConversionFlags = ConversionFlags.ShowReturnType | ConversionFlags.ShowParameterList;
Assert.AreEqual("List<dynamic> DynamicGenerics1(Action<object, dynamic[], object>)", a.Convert(testClass.Methods.Single(me => me.Name == "DynamicGenerics1")));
Assert.AreEqual("void DynamicGenerics2(Action<object, dynamic, object>)", a.Convert(testClass.Methods.Single(me => me.Name == "DynamicGenerics2")));
Assert.AreEqual("void DynamicGenerics3(Action<int, dynamic, object>)", a.Convert(testClass.Methods.Single(me => me.Name == "DynamicGenerics3")));
Assert.AreEqual("void DynamicGenerics4(Action<int[], dynamic, object>)", a.Convert(testClass.Methods.Single(me => me.Name == "DynamicGenerics4")));
Assert.AreEqual("void DynamicGenerics5(Action<Int32*[], dynamic, object>)", a.Convert(testClass.Methods.Single(me => me.Name == "DynamicGenerics5")));
}
[Test]
public void AssemblyAttribute()
{

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

@ -92,6 +92,7 @@ @@ -92,6 +92,7 @@
<Compile Include="Src\Implementations\DefaultTypeParameter.cs" />
<Compile Include="Src\Implementations\DefaultUsing.cs" />
<Compile Include="Src\Implementations\DefaultUsingScope.cs" />
<Compile Include="Src\Implementations\DynamicReturnType.cs" />
<Compile Include="Src\Implementations\ElementReturnType.cs" />
<Compile Include="Src\Implementations\GenericReturnType.cs" />
<Compile Include="Src\Implementations\GetClassReturnType.cs" />

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

@ -34,9 +34,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -34,9 +34,11 @@ namespace ICSharpCode.SharpDevelop.Dom
return new CecilProjectContent(asm.Name.FullName, fileName, referencedAssemblies.ToArray(), asm, registry);
}
static void AddAttributes(IProjectContent pc, IList<IAttribute> list, CustomAttributeCollection attributes)
static void AddAttributes(IProjectContent pc, IList<IAttribute> list, ICustomAttributeProvider attributeProvider)
{
foreach (CustomAttribute att in attributes) {
if (!attributeProvider.HasCustomAttributes)
return;
foreach (CustomAttribute att in attributeProvider.CustomAttributes) {
DefaultAttribute a = new DefaultAttribute(CreateType(pc, null, att.Constructor.DeclaringType));
// Currently Cecil returns string instead of TypeReference for typeof() arguments to attributes
var parameters = att.Constructor.Parameters;
@ -74,7 +76,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -74,7 +76,13 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary>
/// Create a SharpDevelop return type from a Cecil type reference.
/// </summary>
internal static IReturnType CreateType(IProjectContent pc, IEntity member, TypeReference type)
internal static IReturnType CreateType(IProjectContent pc, IEntity member, TypeReference type, ICustomAttributeProvider attributeProvider = null)
{
int typeIndex = 0;
return CreateType(pc, member, type, attributeProvider, ref typeIndex);
}
static IReturnType CreateType(IProjectContent pc, IEntity member, TypeReference type, ICustomAttributeProvider attributeProvider, ref int typeIndex)
{
while (type is ModType) {
type = (type as ModType).ElementType;
@ -85,18 +93,22 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -85,18 +93,22 @@ namespace ICSharpCode.SharpDevelop.Dom
}
if (type is ReferenceType) {
// TODO: Use ByRefRefReturnType
return CreateType(pc, member, (type as ReferenceType).ElementType);
return CreateType(pc, member, (type as ReferenceType).ElementType, attributeProvider, ref typeIndex);
} else if (type is PointerType) {
return new PointerReturnType(CreateType(pc, member, (type as PointerType).ElementType));
typeIndex++;
return new PointerReturnType(CreateType(pc, member, (type as PointerType).ElementType, attributeProvider, ref typeIndex));
} else if (type is ArrayType) {
return new ArrayReturnType(pc, CreateType(pc, member, (type as ArrayType).ElementType), (type as ArrayType).Rank);
typeIndex++;
return new ArrayReturnType(pc, CreateType(pc, member, (type as ArrayType).ElementType, attributeProvider, ref typeIndex), (type as ArrayType).Rank);
} else if (type is GenericInstanceType) {
GenericInstanceType gType = (GenericInstanceType)type;
IReturnType baseType = CreateType(pc, member, gType.ElementType, attributeProvider, ref typeIndex);
IReturnType[] para = new IReturnType[gType.GenericArguments.Count];
for (int i = 0; i < para.Length; ++i) {
para[i] = CreateType(pc, member, gType.GenericArguments[i]);
typeIndex++;
para[i] = CreateType(pc, member, gType.GenericArguments[i], attributeProvider, ref typeIndex);
}
return new ConstructedReturnType(CreateType(pc, member, gType.ElementType), para);
return new ConstructedReturnType(baseType, para);
} else if (type is GenericParameter) {
GenericParameter typeGP = type as GenericParameter;
if (typeGP.Owner is MethodDefinition) {
@ -137,6 +149,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -137,6 +149,9 @@ namespace ICSharpCode.SharpDevelop.Dom
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
}
if (typeParameterCount == 0 && name == "System.Object" && HasDynamicAttribute(attributeProvider, typeIndex))
return new DynamicReturnType(pc);
IClass c = pc.GetClass(name, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
@ -148,6 +163,23 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -148,6 +163,23 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
{
if (attributeProvider == null || attributeProvider.HasCustomAttributes == false)
return false;
foreach (CustomAttribute a in attributeProvider.CustomAttributes) {
if (a.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.DynamicAttribute") {
if (a.ConstructorParameters.Count == 1) {
object[] values = a.ConstructorParameters[0] as object[];
if (values != null && typeIndex < values.Length && values[typeIndex] is bool)
return (bool)values[typeIndex];
}
return true;
}
}
return false;
}
private sealed class CecilProjectContent : ReflectionProjectContent
{
public CecilProjectContent(string fullName, string fileName, DomAssemblyName[] referencedAssemblies,
@ -157,7 +189,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -157,7 +189,7 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (ModuleDefinition module in assembly.Modules) {
AddTypes(module.Types);
}
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly.CustomAttributes);
AddAttributes(this, this.AssemblyCompilationUnit.Attributes, assembly);
InitializeSpecialClasses();
this.AssemblyCompilationUnit.Freeze();
}
@ -203,7 +235,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -203,7 +235,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
this.FullyQualifiedName = fullName;
AddAttributes(compilationUnit.ProjectContent, this.Attributes, td.CustomAttributes);
AddAttributes(compilationUnit.ProjectContent, this.Attributes, td);
// set classtype
if (td.IsInterface) {
@ -297,8 +329,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -297,8 +329,8 @@ namespace ICSharpCode.SharpDevelop.Dom
if (IsVisible(field.Attributes) && !field.IsSpecialName) {
DefaultField f = new DefaultField(this, field.Name);
f.Modifiers = TranslateModifiers(field);
f.ReturnType = CreateType(this.ProjectContent, this, field.FieldType);
AddAttributes(CompilationUnit.ProjectContent, f.Attributes, field.CustomAttributes);
f.ReturnType = CreateType(this.ProjectContent, this, field.FieldType, field);
AddAttributes(CompilationUnit.ProjectContent, f.Attributes, field);
Fields.Add(f);
}
}
@ -315,8 +347,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -315,8 +347,8 @@ namespace ICSharpCode.SharpDevelop.Dom
} else {
e.Modifiers = TranslateModifiers(eventDef);
}
e.ReturnType = CreateType(this.ProjectContent, this, eventDef.EventType);
AddAttributes(CompilationUnit.ProjectContent, e.Attributes, eventDef.CustomAttributes);
e.ReturnType = CreateType(this.ProjectContent, this, eventDef.EventType, eventDef);
AddAttributes(CompilationUnit.ProjectContent, e.Attributes, eventDef);
Events.Add(e);
}
}
@ -343,7 +375,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -343,7 +375,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} else {
p.Modifiers = TranslateModifiers(property);
}
p.ReturnType = CreateType(this.ProjectContent, this, property.PropertyType);
p.ReturnType = CreateType(this.ProjectContent, this, property.PropertyType, property);
p.CanGet = property.GetMethod != null && IsVisible(property.GetMethod.Attributes);
p.CanSet = property.SetMethod != null && IsVisible(property.SetMethod.Attributes);
if (p.CanGet)
@ -354,7 +386,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -354,7 +386,7 @@ namespace ICSharpCode.SharpDevelop.Dom
p.IsIndexer = true;
}
AddParameters(p, property.Parameters);
AddAttributes(CompilationUnit.ProjectContent, p.Attributes, property.CustomAttributes);
AddAttributes(CompilationUnit.ProjectContent, p.Attributes, property);
Properties.Add(p);
}
}
@ -386,8 +418,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -386,8 +418,8 @@ namespace ICSharpCode.SharpDevelop.Dom
if (method.IsConstructor)
m.ReturnType = this.DefaultReturnType;
else
m.ReturnType = CreateType(this.ProjectContent, m, method.ReturnType.ReturnType);
AddAttributes(CompilationUnit.ProjectContent, m.Attributes, method.CustomAttributes);
m.ReturnType = CreateType(this.ProjectContent, m, method.ReturnType.ReturnType, method.ReturnType);
AddAttributes(CompilationUnit.ProjectContent, m.Attributes, method);
if (this.ClassType == ClassType.Interface) {
m.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract;
} else {
@ -416,7 +448,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -416,7 +448,7 @@ namespace ICSharpCode.SharpDevelop.Dom
void AddParameters(IMethodOrProperty target, ParameterDefinitionCollection plist)
{
foreach (ParameterDefinition par in plist) {
IReturnType pReturnType = CreateType(this.ProjectContent, target, par.ParameterType);
IReturnType pReturnType = CreateType(this.ProjectContent, target, par.ParameterType, par);
DefaultParameter p = new DefaultParameter(par.Name, pReturnType, DomRegion.Empty);
if (par.ParameterType is ReferenceType) {
if ((par.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out) {

55
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DynamicReturnType.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
// <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.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
public class DynamicReturnType : AbstractReturnType
{
readonly IProjectContent pc;
public DynamicReturnType(IProjectContent pc)
{
if (pc == null)
throw new ArgumentNullException("pc");
this.pc = pc;
}
public override IClass GetUnderlyingClass()
{
return null;
}
public override List<IMethod> GetMethods()
{
return new List<IMethod>();
}
public override List<IProperty> GetProperties()
{
return new List<IProperty>();
}
public override List<IField> GetFields()
{
return new List<IField>();
}
public override List<IEvent> GetEvents()
{
return new List<IEvent>();
}
public override string Name {
get { return "dynamic"; }
}
public override string FullyQualifiedName {
get { return "dynamic"; }
set { throw new NotSupportedException(); }
}
}
}

3
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs

@ -47,6 +47,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -47,6 +47,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference();
}
if (reference.Type == "dynamic")
return new DynamicReturnType(projectContent);
bool useLazyReturnType = (options & ReturnTypeOptions.Lazy) == ReturnTypeOptions.Lazy;
bool isBaseTypeReference = (options & ReturnTypeOptions.BaseTypeReference) == ReturnTypeOptions.BaseTypeReference;

7
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 = 25;
public const short FileVersion = 26;
ProjectContentRegistry registry;
string cacheDirectory;
@ -592,6 +592,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -592,6 +592,7 @@ namespace ICSharpCode.SharpDevelop.Dom
const int NullRTReferenceCode = -5;
const int VoidRTCode = -6;
const int PointerRTCode = -7;
const int DynamicRTCode = -8;
void WriteType(IReturnType rt)
{
@ -603,6 +604,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -603,6 +604,8 @@ namespace ICSharpCode.SharpDevelop.Dom
string name = rt.FullyQualifiedName;
if (name == "System.Void") {
writer.Write(VoidRTCode);
} else if (name == "dynamic") {
writer.Write(DynamicRTCode);
} else {
writer.Write(classIndices[new ClassNameTypeCountPair(rt)]);
}
@ -660,6 +663,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -660,6 +663,8 @@ namespace ICSharpCode.SharpDevelop.Dom
return new VoidReturnType(pc);
case PointerRTCode:
return new PointerReturnType(ReadType());
case DynamicRTCode:
return new DynamicReturnType(pc);
default:
return types[index];
}

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

@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
internal static void AddAttributes(IProjectContent pc, IList<IAttribute> list, IList<CustomAttributeData> attributes)
{
foreach (CustomAttributeData att in attributes) {
DefaultAttribute a = new DefaultAttribute(ReflectionReturnType.Create(pc, null, att.Constructor.DeclaringType, false));
DefaultAttribute a = new DefaultAttribute(ReflectionReturnType.Create(pc, att.Constructor.DeclaringType));
foreach (CustomAttributeTypedArgument arg in att.ConstructorArguments) {
a.PositionalArguments.Add(ReplaceTypeByIReturnType(pc, arg.Value));
}
@ -84,7 +84,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -84,7 +84,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, false);
return ReflectionReturnType.Create(pc, (Type)val, forceGenericType: false);
} else {
return val;
}
@ -208,11 +208,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -208,11 +208,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
// set base classes
if (type.BaseType != null) { // it's null for System.Object ONLY !!!
BaseTypes.Add(ReflectionReturnType.Create(this, type.BaseType, false));
BaseTypes.Add(ReflectionReturnType.Create(this, type.BaseType));
}
foreach (Type iface in type.GetInterfaces()) {
BaseTypes.Add(ReflectionReturnType.Create(this, iface, false));
BaseTypes.Add(ReflectionReturnType.Create(this, iface));
}
InitMembers(type);
@ -222,9 +222,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -222,9 +222,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
foreach (Type constraint in type.GetGenericParameterConstraints()) {
if (tp.Method != null) {
tp.Constraints.Add(ReflectionReturnType.Create(tp.Method, constraint, false));
tp.Constraints.Add(ReflectionReturnType.Create(tp.Method, constraint));
} else {
tp.Constraints.Add(ReflectionReturnType.Create(tp.Class, constraint, false));
tp.Constraints.Add(ReflectionReturnType.Create(tp.Class, constraint));
}
}
}

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

@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
public ReflectionEvent(EventInfo eventInfo, IClass declaringType) : base(declaringType, eventInfo.Name)
{
this.ReturnType = ReflectionReturnType.Create(this, eventInfo.EventHandlerType, false);
this.ReturnType = ReflectionReturnType.Create(this, eventInfo.EventHandlerType, attributeProvider: eventInfo);
// get modifiers
MethodInfo methodBase = null;

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

@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
public ReflectionField(FieldInfo fieldInfo, IClass declaringType) : base(declaringType, fieldInfo.Name)
{
this.ReturnType = ReflectionReturnType.Create(this, fieldInfo.FieldType, false);
this.ReturnType = ReflectionReturnType.Create(this, fieldInfo.FieldType, attributeProvider: fieldInfo);
ModifierEnum modifiers = ModifierEnum.None;
if (fieldInfo.IsInitOnly) {

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

@ -30,7 +30,8 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -30,7 +30,8 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
: base(declaringType, methodBase is ConstructorInfo ? "#ctor" : methodBase.Name)
{
if (methodBase is MethodInfo) {
this.ReturnType = ReflectionReturnType.Create(this, ((MethodInfo)methodBase).ReturnType, false);
MethodInfo m = ((MethodInfo)methodBase);
this.ReturnType = ReflectionReturnType.Create(this, m.ReturnType, attributeProvider: m.ReturnTypeCustomAttributes);
} else if (methodBase is ConstructorInfo) {
this.ReturnType = DeclaringType.DefaultReturnType;
}

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

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
Type type = parameterInfo.ParameterType;
this.ReturnType = ReflectionReturnType.Create(member, type, false);
this.ReturnType = ReflectionReturnType.Create(member, type, attributeProvider: parameterInfo);
if (type.IsByRef && parameterInfo.IsOut) {
this.Modifiers = ParameterModifiers.Out;

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

@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
public ReflectionProperty(PropertyInfo propertyInfo, IClass declaringType) : base(declaringType, propertyInfo.Name)
{
this.ReturnType = ReflectionReturnType.Create(this, propertyInfo.PropertyType, false);
this.ReturnType = ReflectionReturnType.Create(this, propertyInfo.PropertyType, attributeProvider: propertyInfo);
CanGet = propertyInfo.CanRead;
CanSet = propertyInfo.CanWrite;

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

@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
@ -90,47 +92,69 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -90,47 +92,69 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
}
#endregion
public static IReturnType Create(IClass @class, Type type, bool createLazyReturnType)
{
return Create(@class.ProjectContent, @class, type, createLazyReturnType);
}
public static IReturnType Create(IMember member, Type type, bool createLazyReturnType)
{
return Create(member.DeclaringType.ProjectContent, member, type, createLazyReturnType);
}
public static IReturnType Create(IProjectContent pc, IEntity member, Type type, bool createLazyReturnType)
{
return Create(pc, member, type, createLazyReturnType, true);
}
/// <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="entity">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)
/// <param name="attributeProvider">Attribute provider for lookup of [Dynamic] attribute</param>
public static IReturnType Create(IProjectContent pc, Type type,
IEntity entity = null,
bool createLazyReturnType = false,
bool forceGenericType = true,
ICustomAttributeProvider attributeProvider = null)
{
if (pc == null)
throw new ArgumentNullException("pc");
if (type == null)
throw new ArgumentNullException("type");
int typeIndex = 0;
return Create(pc, type, entity, createLazyReturnType, attributeProvider, ref typeIndex, forceGenericType);
}
public static IReturnType Create(IEntity entity, Type type,
bool createLazyReturnType = false,
bool forceGenericType = true,
ICustomAttributeProvider attributeProvider = null)
{
if (entity == null)
throw new ArgumentNullException("entity");
if (type == null)
throw new ArgumentNullException("type");
int typeIndex = 0;
return Create(entity.ProjectContent, type, entity, createLazyReturnType, attributeProvider, ref typeIndex, forceGenericType);
}
static IReturnType Create(IProjectContent pc, Type type,
IEntity member,
bool createLazyReturnType,
ICustomAttributeProvider attributeProvider,
ref int typeIndex,
bool forceGenericType = true)
{
if (type.IsByRef) {
// TODO: Use ByRefRefReturnType
return Create(pc, member, type.GetElementType(), createLazyReturnType);
return Create(pc, type.GetElementType(), member, createLazyReturnType, attributeProvider, ref typeIndex);
} else if (type.IsPointer) {
return new PointerReturnType(Create(pc, member, type.GetElementType(), createLazyReturnType));
typeIndex++;
return new PointerReturnType(Create(pc, type.GetElementType(), member, createLazyReturnType, attributeProvider, ref typeIndex));
} else if (type.IsArray) {
return new ArrayReturnType(pc, Create(pc, member, type.GetElementType(), createLazyReturnType), type.GetArrayRank());
typeIndex++;
return new ArrayReturnType(pc, Create(pc, type.GetElementType(), member, createLazyReturnType, attributeProvider, ref typeIndex), type.GetArrayRank());
} else if (type.IsGenericType && (forceGenericType || !type.IsGenericTypeDefinition)) {
IReturnType baseType = Create(pc, type.GetGenericTypeDefinition(), member, createLazyReturnType, attributeProvider, ref typeIndex, forceGenericType: false);
Type[] args = type.GetGenericArguments();
List<IReturnType> para = new List<IReturnType>(args.Length);
for (int i = 0; i < args.Length; ++i) {
para.Add(Create(pc, member, args[i], createLazyReturnType));
typeIndex++;
para.Add(Create(pc, args[i], member, createLazyReturnType, attributeProvider, ref typeIndex));
}
return new ConstructedReturnType(Create(pc, member, type.GetGenericTypeDefinition(), createLazyReturnType, false), para);
return new ConstructedReturnType(baseType, para);
} else if (type.IsGenericParameter) {
IClass c = (member is IClass) ? (IClass)member : (member is IMember) ? ((IMember)member).DeclaringType : null;
if (c != null && type.GenericParameterPosition < c.TypeParameters.Count) {
@ -154,6 +178,10 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -154,6 +178,10 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
throw new ApplicationException("type.FullName returned null. Type: " + type.ToString());
int typeParameterCount;
name = ReflectionClass.ConvertReflectionNameToFullName(name, out typeParameterCount);
if (typeParameterCount == 0 && name == "System.Object" && HasDynamicAttribute(attributeProvider, typeIndex))
return new DynamicReturnType(pc);
if (!createLazyReturnType) {
IClass c = pc.GetClass(name, typeParameterCount);
if (c != null)
@ -164,5 +192,22 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -164,5 +192,22 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
return new GetClassReturnType(pc, name, typeParameterCount);
}
}
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
{
if (attributeProvider == null)
return false;
object[] attributes = attributeProvider.GetCustomAttributes(typeof(DynamicAttribute), false);
if (attributes.Length == 0)
return false;
DynamicAttribute attr = attributes[0] as DynamicAttribute;
if (attr != null) {
var transformFlags = attr.TransformFlags;
if (transformFlags != null && typeIndex < transformFlags.Count)
return transformFlags[typeIndex];
return true;
}
return false;
}
}
}

Loading…
Cancel
Save