1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
5
using System.Collections.Generic;
6
using System.Reflection;
9
namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
11
public class ReflectionClass : DefaultClass
13
const BindingFlags flags = BindingFlags.Instance |
15
BindingFlags.NonPublic |
16
BindingFlags.DeclaredOnly |
19
void InitMembers(Type type)
21
foreach (Type nestedType in type.GetNestedTypes(flags)) {
22
// We cannot use nestedType.IsVisible - that only checks for public types,
23
// but we also need to load protected types.
24
if (nestedType.IsNestedPublic || nestedType.IsNestedFamily || nestedType.IsNestedFamORAssem) {
25
string name = this.FullyQualifiedName + "." + nestedType.Name;
26
InnerClasses.Add(new ReflectionClass(CompilationUnit, nestedType, name, this));
30
foreach (FieldInfo field in type.GetFields(flags)) {
31
if (!field.IsPublic && !field.IsFamily && !field.IsFamilyOrAssembly) continue;
32
if (!field.IsSpecialName) {
33
Fields.Add(new ReflectionField(field, this));
37
foreach (PropertyInfo propertyInfo in type.GetProperties(flags)) {
38
ReflectionProperty prop = new ReflectionProperty(propertyInfo, this);
39
if (prop.IsPublic || prop.IsProtected)
43
foreach (ConstructorInfo constructorInfo in type.GetConstructors(flags)) {
44
if (!constructorInfo.IsPublic && !constructorInfo.IsFamily && !constructorInfo.IsFamilyOrAssembly) continue;
45
Methods.Add(new ReflectionMethod(constructorInfo, this));
48
foreach (MethodInfo methodInfo in type.GetMethods(flags)) {
49
if (!methodInfo.IsPublic && !methodInfo.IsFamily && !methodInfo.IsFamilyOrAssembly) continue;
50
if (!methodInfo.IsSpecialName) {
51
Methods.Add(new ReflectionMethod(methodInfo, this));
54
this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum);
56
foreach (EventInfo eventInfo in type.GetEvents(flags)) {
57
Events.Add(new ReflectionEvent(eventInfo, this));
61
static bool IsDelegate(Type type)
63
return type.IsSubclassOf(typeof(Delegate)) && type != typeof(MulticastDelegate);
66
internal static void AddAttributes(IProjectContent pc, IList<IAttribute> list, IList<CustomAttributeData> attributes)
68
foreach (CustomAttributeData att in attributes) {
69
DefaultAttribute a = new DefaultAttribute(ReflectionReturnType.Create(pc, att.Constructor.DeclaringType));
70
foreach (CustomAttributeTypedArgument arg in att.ConstructorArguments) {
71
a.PositionalArguments.Add(ReplaceTypeByIReturnType(pc, arg.Value));
73
foreach (CustomAttributeNamedArgument arg in att.NamedArguments) {
74
a.NamedArguments.Add(arg.MemberInfo.Name, ReplaceTypeByIReturnType(pc, arg.TypedValue.Value));
80
static object ReplaceTypeByIReturnType(IProjectContent pc, object val)
83
return ReflectionReturnType.Create(pc, (Type)val, forceGenericType: false);
89
internal static void ApplySpecialsFromAttributes(DefaultClass c)
91
foreach (IAttribute att in c.Attributes) {
92
if (att.AttributeType.FullyQualifiedName == "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute"
93
|| att.AttributeType.FullyQualifiedName == "System.Runtime.CompilerServices.CompilerGlobalScopeAttribute")
95
c.ClassType = ClassType.Module;
101
public static string SplitTypeParameterCountFromReflectionName(string reflectionName)
103
int lastBackTick = reflectionName.LastIndexOf('`');
104
if (lastBackTick < 0)
105
return reflectionName;
107
return reflectionName.Substring(0, lastBackTick);
110
public static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)
112
int pos = reflectionName.LastIndexOf('`');
114
typeParameterCount = 0;
115
return reflectionName;
117
string typeCount = reflectionName.Substring(pos + 1);
118
if (int.TryParse(typeCount, out typeParameterCount))
119
return reflectionName.Substring(0, pos);
121
return reflectionName;
125
public static string ConvertReflectionNameToFullName(string reflectionName, out int typeParameterCount)
127
if (reflectionName.IndexOf('+') > 0) {
128
typeParameterCount = 0;
129
StringBuilder newName = new StringBuilder();
130
foreach (string namepart in reflectionName.Split('+')) {
131
if (newName.Length > 0)
133
int partTypeParameterCount;
134
newName.Append(SplitTypeParameterCountFromReflectionName(namepart, out partTypeParameterCount));
135
typeParameterCount += partTypeParameterCount;
137
return newName.ToString();
139
return SplitTypeParameterCountFromReflectionName(reflectionName, out typeParameterCount);
143
public ReflectionClass(ICompilationUnit compilationUnit, Type type, string fullName, IClass declaringType) : base(compilationUnit, declaringType)
145
FullyQualifiedName = SplitTypeParameterCountFromReflectionName(fullName);
148
AddAttributes(compilationUnit.ProjectContent, this.Attributes, CustomAttributeData.GetCustomAttributes(type));
149
} catch (Exception ex) {
150
HostCallback.ShowError("Error reading custom attributes", ex);
154
if (type.IsInterface) {
155
this.ClassType = ClassType.Interface;
156
} else if (type.IsEnum) {
157
this.ClassType = ClassType.Enum;
158
} else if (type.IsValueType) {
159
this.ClassType = ClassType.Struct;
160
} else if (IsDelegate(type)) {
161
this.ClassType = ClassType.Delegate;
163
this.ClassType = ClassType.Class;
164
ApplySpecialsFromAttributes(this);
166
if (type.IsGenericTypeDefinition) {
167
foreach (Type g in type.GetGenericArguments()) {
168
this.TypeParameters.Add(new DefaultTypeParameter(this, g));
171
foreach (Type g in type.GetGenericArguments()) {
172
AddConstraintsFromType(this.TypeParameters[i++], g);
176
ModifierEnum modifiers = ModifierEnum.None;
178
if (type.IsNestedAssembly) {
179
modifiers |= ModifierEnum.Internal;
182
modifiers |= ModifierEnum.Sealed;
184
if (type.IsAbstract) {
185
modifiers |= ModifierEnum.Abstract;
187
if (type.IsSealed && type.IsAbstract) {
188
modifiers |= ModifierEnum.Static;
191
if (type.IsNestedPrivate ) { // I assume that private is used most and public last (at least should be)
192
modifiers |= ModifierEnum.Private;
193
} else if (type.IsNestedFamily ) {
194
modifiers |= ModifierEnum.Protected;
195
} else if (type.IsNestedPublic || type.IsPublic) {
196
modifiers |= ModifierEnum.Public;
197
} else if (type.IsNotPublic) {
198
modifiers |= ModifierEnum.Internal;
199
} else if (type.IsNestedFamORAssem || type.IsNestedFamANDAssem) {
200
modifiers |= ModifierEnum.Protected;
201
modifiers |= ModifierEnum.Internal;
203
this.Modifiers = modifiers;
206
if (type.BaseType != null) { // it's null for System.Object ONLY !!!
207
BaseTypes.Add(ReflectionReturnType.Create(this, type.BaseType));
210
foreach (Type iface in type.GetInterfaces()) {
211
BaseTypes.Add(ReflectionReturnType.Create(this, iface));
217
internal static void AddConstraintsFromType(ITypeParameter tp, Type type)
219
foreach (Type constraint in type.GetGenericParameterConstraints()) {
220
if (tp.Method != null) {
221
tp.Constraints.Add(ReflectionReturnType.Create(tp.Method, constraint));
223
tp.Constraints.Add(ReflectionReturnType.Create(tp.Class, constraint));
228
protected override bool KeepInheritanceTree {