2010-06-21 Atsushi Enomoto <atsushi@ximian.com>
[mcs.git] / mcs / modifiers.cs
blobaf29d7b020c972e8cd3d7c2cc252570b562360e2
1 //
2 // modifiers.cs: Modifier handling.
3 //
4 using System;
5 using System.Reflection;
7 namespace Mono.CSharp
9 [Flags]
10 public enum Modifiers
12 PROTECTED = 0x0001,
13 PUBLIC = 0x0002,
14 PRIVATE = 0x0004,
15 INTERNAL = 0x0008,
16 NEW = 0x0010,
17 ABSTRACT = 0x0020,
18 SEALED = 0x0040,
19 STATIC = 0x0080,
20 READONLY = 0x0100,
21 VIRTUAL = 0x0200,
22 OVERRIDE = 0x0400,
23 EXTERN = 0x0800,
24 VOLATILE = 0x1000,
25 UNSAFE = 0x2000,
26 TOP = 0x4000,
29 // Compiler specific flags
31 PROPERTY_CUSTOM = 0x4000,
32 OVERRIDE_UNCHECKED = 0x8000,
33 PARTIAL = 0x20000,
34 DEFAULT_ACCESS_MODIFER = 0x40000,
35 METHOD_EXTENSION = 0x80000,
36 COMPILER_GENERATED = 0x100000,
37 BACKING_FIELD = 0x200000,
38 DEBUGGER_HIDDEN = 0x400000,
40 AccessibilityMask = PUBLIC | PROTECTED | INTERNAL | PRIVATE,
41 AllowedExplicitImplFlags = UNSAFE | EXTERN,
44 static class ModifiersExtensions
46 public static string AccessibilityName (Modifiers mod)
48 switch (mod & Modifiers.AccessibilityMask) {
49 case Modifiers.PUBLIC:
50 return "public";
51 case Modifiers.PROTECTED:
52 return "protected";
53 case Modifiers.PROTECTED | Modifiers.INTERNAL:
54 return "protected internal";
55 case Modifiers.INTERNAL:
56 return "internal";
57 case Modifiers.PRIVATE:
58 return "private";
59 default:
60 throw new NotImplementedException (mod.ToString ());
64 static public string Name (Modifiers i)
66 string s = "";
68 switch (i) {
69 case Modifiers.NEW:
70 s = "new"; break;
71 case Modifiers.PUBLIC:
72 s = "public"; break;
73 case Modifiers.PROTECTED:
74 s = "protected"; break;
75 case Modifiers.INTERNAL:
76 s = "internal"; break;
77 case Modifiers.PRIVATE:
78 s = "private"; break;
79 case Modifiers.ABSTRACT:
80 s = "abstract"; break;
81 case Modifiers.SEALED:
82 s = "sealed"; break;
83 case Modifiers.STATIC:
84 s = "static"; break;
85 case Modifiers.READONLY:
86 s = "readonly"; break;
87 case Modifiers.VIRTUAL:
88 s = "virtual"; break;
89 case Modifiers.OVERRIDE:
90 s = "override"; break;
91 case Modifiers.EXTERN:
92 s = "extern"; break;
93 case Modifiers.VOLATILE:
94 s = "volatile"; break;
95 case Modifiers.UNSAFE:
96 s = "unsafe"; break;
99 return s;
103 // Used by custom property accessors to check whether @modA is more restrictive than @modB
105 public static bool IsRestrictedModifier (Modifiers modA, Modifiers modB)
107 Modifiers flags = 0;
109 if ((modB & Modifiers.PUBLIC) != 0) {
110 flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
111 } else if ((modB & Modifiers.PROTECTED) != 0) {
112 if ((modB & Modifiers.INTERNAL) != 0)
113 flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
115 flags |= Modifiers.PRIVATE;
116 } else if ((modB & Modifiers.INTERNAL) != 0)
117 flags = Modifiers.PRIVATE;
119 return modB != modA && (modA & (~flags)) == 0;
122 public static TypeAttributes TypeAttr (Modifiers mod_flags, bool is_toplevel)
124 TypeAttributes t = 0;
126 if (is_toplevel){
127 if ((mod_flags & Modifiers.PUBLIC) != 0)
128 t = TypeAttributes.Public;
129 else if ((mod_flags & Modifiers.PRIVATE) != 0)
130 t = TypeAttributes.NotPublic;
131 } else {
132 if ((mod_flags & Modifiers.PUBLIC) != 0)
133 t = TypeAttributes.NestedPublic;
134 else if ((mod_flags & Modifiers.PRIVATE) != 0)
135 t = TypeAttributes.NestedPrivate;
136 else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL))
137 t = TypeAttributes.NestedFamORAssem;
138 else if ((mod_flags & Modifiers.PROTECTED) != 0)
139 t = TypeAttributes.NestedFamily;
140 else if ((mod_flags & Modifiers.INTERNAL) != 0)
141 t = TypeAttributes.NestedAssembly;
144 if ((mod_flags & Modifiers.SEALED) != 0)
145 t |= TypeAttributes.Sealed;
146 if ((mod_flags & Modifiers.ABSTRACT) != 0)
147 t |= TypeAttributes.Abstract;
149 return t;
152 public static FieldAttributes FieldAttr (Modifiers mod_flags)
154 FieldAttributes fa = 0;
156 if ((mod_flags & Modifiers.PUBLIC) != 0)
157 fa |= FieldAttributes.Public;
158 if ((mod_flags & Modifiers.PRIVATE) != 0)
159 fa |= FieldAttributes.Private;
160 if ((mod_flags & Modifiers.PROTECTED) != 0) {
161 if ((mod_flags & Modifiers.INTERNAL) != 0)
162 fa |= FieldAttributes.FamORAssem;
163 else
164 fa |= FieldAttributes.Family;
165 } else {
166 if ((mod_flags & Modifiers.INTERNAL) != 0)
167 fa |= FieldAttributes.Assembly;
170 if ((mod_flags & Modifiers.STATIC) != 0)
171 fa |= FieldAttributes.Static;
172 if ((mod_flags & Modifiers.READONLY) != 0)
173 fa |= FieldAttributes.InitOnly;
175 return fa;
178 public static MethodAttributes MethodAttr (Modifiers mod_flags)
180 MethodAttributes ma = MethodAttributes.HideBySig;
182 switch (mod_flags & Modifiers.AccessibilityMask) {
183 case Modifiers.PUBLIC:
184 ma |= MethodAttributes.Public;
185 break;
186 case Modifiers.PRIVATE:
187 ma |= MethodAttributes.Private;
188 break;
189 case Modifiers.PROTECTED | Modifiers.INTERNAL:
190 ma |= MethodAttributes.FamORAssem;
191 break;
192 case Modifiers.PROTECTED:
193 ma |= MethodAttributes.Family;
194 break;
195 case Modifiers.INTERNAL:
196 ma |= MethodAttributes.Assembly;
197 break;
198 default:
199 throw new NotImplementedException (mod_flags.ToString ());
202 if ((mod_flags & Modifiers.STATIC) != 0)
203 ma |= MethodAttributes.Static;
204 if ((mod_flags & Modifiers.ABSTRACT) != 0) {
205 ma |= MethodAttributes.Abstract | MethodAttributes.Virtual;
207 if ((mod_flags & Modifiers.SEALED) != 0)
208 ma |= MethodAttributes.Final;
210 if ((mod_flags & Modifiers.VIRTUAL) != 0)
211 ma |= MethodAttributes.Virtual;
213 if ((mod_flags & Modifiers.OVERRIDE) != 0) {
214 ma |= MethodAttributes.Virtual;
215 } else {
216 if ((ma & MethodAttributes.Virtual) != 0)
217 ma |= MethodAttributes.NewSlot;
220 return ma;
223 // <summary>
224 // Checks the object @mod modifiers to be in @allowed.
225 // Returns the new mask. Side effect: reports any
226 // incorrect attributes.
227 // </summary>
228 public static Modifiers Check (Modifiers allowed, Modifiers mod, Modifiers def_access, Location l, Report Report)
230 int invalid_flags = (~(int) allowed) & ((int) mod & ((int) Modifiers.TOP - 1));
231 int i;
233 if (invalid_flags == 0){
235 // If no accessibility bits provided
236 // then provide the defaults.
238 if ((mod & Modifiers.AccessibilityMask) == 0) {
239 mod |= def_access;
240 if (def_access != 0)
241 mod |= Modifiers.DEFAULT_ACCESS_MODIFER;
242 return mod;
245 return mod;
248 for (i = 1; i <= (int) Modifiers.TOP; i <<= 1) {
249 if ((i & invalid_flags) == 0)
250 continue;
252 Error_InvalidModifier (l, Name ((Modifiers) i), Report);
255 return allowed & mod;
258 public static void Error_InvalidModifier (Location l, string name, Report Report)
260 Report.Error (106, l, "The modifier `{0}' is not valid for this item", name);