~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Reflection;
 
7
using System.Text;
 
8
 
 
9
namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
 
10
{
 
11
        public class ReflectionClass : DefaultClass
 
12
        {
 
13
                const BindingFlags flags = BindingFlags.Instance  |
 
14
                        BindingFlags.Static    |
 
15
                        BindingFlags.NonPublic |
 
16
                        BindingFlags.DeclaredOnly |
 
17
                        BindingFlags.Public;
 
18
                
 
19
                void InitMembers(Type type)
 
20
                {
 
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));
 
27
                                }
 
28
                        }
 
29
                        
 
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));
 
34
                                }
 
35
                        }
 
36
                        
 
37
                        foreach (PropertyInfo propertyInfo in type.GetProperties(flags)) {
 
38
                                ReflectionProperty prop = new ReflectionProperty(propertyInfo, this);
 
39
                                if (prop.IsPublic || prop.IsProtected)
 
40
                                        Properties.Add(prop);
 
41
                        }
 
42
                        
 
43
                        foreach (ConstructorInfo constructorInfo in type.GetConstructors(flags)) {
 
44
                                if (!constructorInfo.IsPublic && !constructorInfo.IsFamily && !constructorInfo.IsFamilyOrAssembly) continue;
 
45
                                Methods.Add(new ReflectionMethod(constructorInfo, this));
 
46
                        }
 
47
                        
 
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));
 
52
                                }
 
53
                        }
 
54
                        this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum);
 
55
                        
 
56
                        foreach (EventInfo eventInfo in type.GetEvents(flags)) {
 
57
                                Events.Add(new ReflectionEvent(eventInfo, this));
 
58
                        }
 
59
                }
 
60
                
 
61
                static bool IsDelegate(Type type)
 
62
                {
 
63
                        return type.IsSubclassOf(typeof(Delegate)) && type != typeof(MulticastDelegate);
 
64
                }
 
65
                
 
66
                internal static void AddAttributes(IProjectContent pc, IList<IAttribute> list, IList<CustomAttributeData> attributes)
 
67
                {
 
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));
 
72
                                }
 
73
                                foreach (CustomAttributeNamedArgument arg in att.NamedArguments) {
 
74
                                        a.NamedArguments.Add(arg.MemberInfo.Name, ReplaceTypeByIReturnType(pc, arg.TypedValue.Value));
 
75
                                }
 
76
                                list.Add(a);
 
77
                        }
 
78
                }
 
79
                
 
80
                static object ReplaceTypeByIReturnType(IProjectContent pc, object val)
 
81
                {
 
82
                        if (val is Type) {
 
83
                                return ReflectionReturnType.Create(pc, (Type)val, forceGenericType: false);
 
84
                        } else {
 
85
                                return val;
 
86
                        }
 
87
                }
 
88
                
 
89
                internal static void ApplySpecialsFromAttributes(DefaultClass c)
 
90
                {
 
91
                        foreach (IAttribute att in c.Attributes) {
 
92
                                if (att.AttributeType.FullyQualifiedName == "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute"
 
93
                                    || att.AttributeType.FullyQualifiedName == "System.Runtime.CompilerServices.CompilerGlobalScopeAttribute")
 
94
                                {
 
95
                                        c.ClassType = ClassType.Module;
 
96
                                        break;
 
97
                                }
 
98
                        }
 
99
                }
 
100
                
 
101
                public static string SplitTypeParameterCountFromReflectionName(string reflectionName)
 
102
                {
 
103
                        int lastBackTick = reflectionName.LastIndexOf('`');
 
104
                        if (lastBackTick < 0)
 
105
                                return reflectionName;
 
106
                        else
 
107
                                return reflectionName.Substring(0, lastBackTick);
 
108
                }
 
109
                
 
110
                public static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)
 
111
                {
 
112
                        int pos = reflectionName.LastIndexOf('`');
 
113
                        if (pos < 0) {
 
114
                                typeParameterCount = 0;
 
115
                                return reflectionName;
 
116
                        } else {
 
117
                                string typeCount = reflectionName.Substring(pos + 1);
 
118
                                if (int.TryParse(typeCount, out typeParameterCount))
 
119
                                        return reflectionName.Substring(0, pos);
 
120
                                else
 
121
                                        return reflectionName;
 
122
                        }
 
123
                }
 
124
                
 
125
                public static string ConvertReflectionNameToFullName(string reflectionName, out int typeParameterCount)
 
126
                {
 
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)
 
132
                                                newName.Append('.');
 
133
                                        int partTypeParameterCount;
 
134
                                        newName.Append(SplitTypeParameterCountFromReflectionName(namepart, out partTypeParameterCount));
 
135
                                        typeParameterCount += partTypeParameterCount;
 
136
                                }
 
137
                                return newName.ToString();
 
138
                        } else {
 
139
                                return SplitTypeParameterCountFromReflectionName(reflectionName, out typeParameterCount);
 
140
                        }
 
141
                }
 
142
                
 
143
                public ReflectionClass(ICompilationUnit compilationUnit, Type type, string fullName, IClass declaringType) : base(compilationUnit, declaringType)
 
144
                {
 
145
                        FullyQualifiedName = SplitTypeParameterCountFromReflectionName(fullName);
 
146
                        
 
147
                        try {
 
148
                                AddAttributes(compilationUnit.ProjectContent, this.Attributes, CustomAttributeData.GetCustomAttributes(type));
 
149
                        } catch (Exception ex) {
 
150
                                HostCallback.ShowError("Error reading custom attributes", ex);
 
151
                        }
 
152
                        
 
153
                        // set classtype
 
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;
 
162
                        } else {
 
163
                                this.ClassType = ClassType.Class;
 
164
                                ApplySpecialsFromAttributes(this);
 
165
                        }
 
166
                        if (type.IsGenericTypeDefinition) {
 
167
                                foreach (Type g in type.GetGenericArguments()) {
 
168
                                        this.TypeParameters.Add(new DefaultTypeParameter(this, g));
 
169
                                }
 
170
                                int i = 0;
 
171
                                foreach (Type g in type.GetGenericArguments()) {
 
172
                                        AddConstraintsFromType(this.TypeParameters[i++], g);
 
173
                                }
 
174
                        }
 
175
                        
 
176
                        ModifierEnum modifiers  = ModifierEnum.None;
 
177
                        
 
178
                        if (type.IsNestedAssembly) {
 
179
                                modifiers |= ModifierEnum.Internal;
 
180
                        }
 
181
                        if (type.IsSealed) {
 
182
                                modifiers |= ModifierEnum.Sealed;
 
183
                        }
 
184
                        if (type.IsAbstract) {
 
185
                                modifiers |= ModifierEnum.Abstract;
 
186
                        }
 
187
                        if (type.IsSealed && type.IsAbstract) {
 
188
                                modifiers |= ModifierEnum.Static;
 
189
                        }
 
190
                        
 
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;
 
202
                        }
 
203
                        this.Modifiers = modifiers;
 
204
                        
 
205
                        // set base classes
 
206
                        if (type.BaseType != null) { // it's null for System.Object ONLY !!!
 
207
                                BaseTypes.Add(ReflectionReturnType.Create(this, type.BaseType));
 
208
                        }
 
209
                        
 
210
                        foreach (Type iface in type.GetInterfaces()) {
 
211
                                BaseTypes.Add(ReflectionReturnType.Create(this, iface));
 
212
                        }
 
213
                        
 
214
                        InitMembers(type);
 
215
                }
 
216
                
 
217
                internal static void AddConstraintsFromType(ITypeParameter tp, Type type)
 
218
                {
 
219
                        foreach (Type constraint in type.GetGenericParameterConstraints()) {
 
220
                                if (tp.Method != null) {
 
221
                                        tp.Constraints.Add(ReflectionReturnType.Create(tp.Method, constraint));
 
222
                                } else {
 
223
                                        tp.Constraints.Add(ReflectionReturnType.Create(tp.Class, constraint));
 
224
                                }
 
225
                        }
 
226
                }
 
227
                
 
228
                protected override bool KeepInheritanceTree {
 
229
                        get { return true; }
 
230
                }
 
231
        }
 
232
}