add SafeSerializationEventArgs
[mcs.git] / mcs / modifiers.cs
blob788c1f891e001036adb75aead377ccb82673af5e
1 //
2 // modifiers.cs: Modifier handling.
3 //
4 using System;
5 using System.Reflection;
7 namespace Mono.CSharp
9 [Flags]
10 public enum Modifiers
13 // The ordering of the following 4 constants
14 // has been carefully done.
16 PROTECTED = 0x0001,
17 PUBLIC = 0x0002,
18 PRIVATE = 0x0004,
19 INTERNAL = 0x0008,
20 NEW = 0x0010,
21 ABSTRACT = 0x0020,
22 SEALED = 0x0040,
23 STATIC = 0x0080,
24 READONLY = 0x0100,
25 VIRTUAL = 0x0200,
26 OVERRIDE = 0x0400,
27 EXTERN = 0x0800,
28 VOLATILE = 0x1000,
29 UNSAFE = 0x2000,
30 TOP = 0x4000,
33 // Compiler specific flags
35 PROPERTY_CUSTOM = 0x4000,
36 OVERRIDE_UNCHECKED = 0x8000,
37 PARTIAL = 0x20000,
38 DEFAULT_ACCESS_MODIFER = 0x40000,
39 METHOD_EXTENSION = 0x80000,
40 COMPILER_GENERATED = 0x100000,
41 BACKING_FIELD = 0x200000,
42 DEBUGGER_HIDDEN = 0x400000,
44 AccessibilityMask = PUBLIC | PROTECTED | INTERNAL | PRIVATE,
45 AllowedExplicitImplFlags = UNSAFE | EXTERN,
48 static class ModifiersExtensions
50 public static string AccessibilityName (Modifiers mod)
52 switch (mod & Modifiers.AccessibilityMask) {
53 case Modifiers.PUBLIC:
54 return "public";
55 case Modifiers.PROTECTED:
56 return "protected";
57 case Modifiers.PROTECTED | Modifiers.INTERNAL:
58 return "protected internal";
59 case Modifiers.INTERNAL:
60 return "internal";
61 case Modifiers.PRIVATE:
62 return "private";
63 default:
64 throw new NotImplementedException (mod.ToString ());
68 static public string Name (Modifiers i)
70 string s = "";
72 switch (i) {
73 case Modifiers.NEW:
74 s = "new"; break;
75 case Modifiers.PUBLIC:
76 s = "public"; break;
77 case Modifiers.PROTECTED:
78 s = "protected"; break;
79 case Modifiers.INTERNAL:
80 s = "internal"; break;
81 case Modifiers.PRIVATE:
82 s = "private"; break;
83 case Modifiers.ABSTRACT:
84 s = "abstract"; break;
85 case Modifiers.SEALED:
86 s = "sealed"; break;
87 case Modifiers.STATIC:
88 s = "static"; break;
89 case Modifiers.READONLY:
90 s = "readonly"; break;
91 case Modifiers.VIRTUAL:
92 s = "virtual"; break;
93 case Modifiers.OVERRIDE:
94 s = "override"; break;
95 case Modifiers.EXTERN:
96 s = "extern"; break;
97 case Modifiers.VOLATILE:
98 s = "volatile"; break;
99 case Modifiers.UNSAFE:
100 s = "unsafe"; break;
103 return s;
107 // Used by custom property accessors to check whether @modA is more restrictive than @modB
109 public static bool IsRestrictedModifier (Modifiers modA, Modifiers modB)
111 Modifiers flags = 0;
113 if ((modB & Modifiers.PUBLIC) != 0) {
114 flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
115 } else if ((modB & Modifiers.PROTECTED) != 0) {
116 if ((modB & Modifiers.INTERNAL) != 0)
117 flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
119 flags |= Modifiers.PRIVATE;
120 } else if ((modB & Modifiers.INTERNAL) != 0)
121 flags = Modifiers.PRIVATE;
123 return modB != modA && (modA & (~flags)) == 0;
126 public static TypeAttributes TypeAttr (Modifiers mod_flags, bool is_toplevel)
128 TypeAttributes t = 0;
130 if (is_toplevel){
131 if ((mod_flags & Modifiers.PUBLIC) != 0)
132 t = TypeAttributes.Public;
133 else if ((mod_flags & Modifiers.PRIVATE) != 0)
134 t = TypeAttributes.NotPublic;
135 } else {
136 if ((mod_flags & Modifiers.PUBLIC) != 0)
137 t = TypeAttributes.NestedPublic;
138 else if ((mod_flags & Modifiers.PRIVATE) != 0)
139 t = TypeAttributes.NestedPrivate;
140 else if ((mod_flags & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL))
141 t = TypeAttributes.NestedFamORAssem;
142 else if ((mod_flags & Modifiers.PROTECTED) != 0)
143 t = TypeAttributes.NestedFamily;
144 else if ((mod_flags & Modifiers.INTERNAL) != 0)
145 t = TypeAttributes.NestedAssembly;
148 if ((mod_flags & Modifiers.SEALED) != 0)
149 t |= TypeAttributes.Sealed;
150 if ((mod_flags & Modifiers.ABSTRACT) != 0)
151 t |= TypeAttributes.Abstract;
153 return t;
156 public static FieldAttributes FieldAttr (Modifiers mod_flags)
158 FieldAttributes fa = 0;
160 if ((mod_flags & Modifiers.PUBLIC) != 0)
161 fa |= FieldAttributes.Public;
162 if ((mod_flags & Modifiers.PRIVATE) != 0)
163 fa |= FieldAttributes.Private;
164 if ((mod_flags & Modifiers.PROTECTED) != 0) {
165 if ((mod_flags & Modifiers.INTERNAL) != 0)
166 fa |= FieldAttributes.FamORAssem;
167 else
168 fa |= FieldAttributes.Family;
169 } else {
170 if ((mod_flags & Modifiers.INTERNAL) != 0)
171 fa |= FieldAttributes.Assembly;
174 if ((mod_flags & Modifiers.STATIC) != 0)
175 fa |= FieldAttributes.Static;
176 if ((mod_flags & Modifiers.READONLY) != 0)
177 fa |= FieldAttributes.InitOnly;
179 return fa;
182 public static MethodAttributes MethodAttr (Modifiers mod_flags)
184 MethodAttributes ma = MethodAttributes.HideBySig;
186 switch (mod_flags & Modifiers.AccessibilityMask) {
187 case Modifiers.PUBLIC:
188 ma |= MethodAttributes.Public;
189 break;
190 case Modifiers.PRIVATE:
191 ma |= MethodAttributes.Private;
192 break;
193 case Modifiers.PROTECTED | Modifiers.INTERNAL:
194 ma |= MethodAttributes.FamORAssem;
195 break;
196 case Modifiers.PROTECTED:
197 ma |= MethodAttributes.Family;
198 break;
199 case Modifiers.INTERNAL:
200 ma |= MethodAttributes.Assembly;
201 break;
202 default:
203 throw new NotImplementedException (mod_flags.ToString ());
206 if ((mod_flags & Modifiers.STATIC) != 0)
207 ma |= MethodAttributes.Static;
208 if ((mod_flags & Modifiers.ABSTRACT) != 0) {
209 ma |= MethodAttributes.Abstract | MethodAttributes.Virtual;
211 if ((mod_flags & Modifiers.SEALED) != 0)
212 ma |= MethodAttributes.Final;
214 if ((mod_flags & Modifiers.VIRTUAL) != 0)
215 ma |= MethodAttributes.Virtual;
217 if ((mod_flags & Modifiers.OVERRIDE) != 0) {
218 ma |= MethodAttributes.Virtual;
219 } else {
220 if ((ma & MethodAttributes.Virtual) != 0)
221 ma |= MethodAttributes.NewSlot;
224 return ma;
227 // <summary>
228 // Checks the object @mod modifiers to be in @allowed.
229 // Returns the new mask. Side effect: reports any
230 // incorrect attributes.
231 // </summary>
232 public static Modifiers Check (Modifiers allowed, Modifiers mod, Modifiers def_access, Location l, Report Report)
234 int invalid_flags = (~(int) allowed) & ((int) mod & ((int) Modifiers.TOP - 1));
235 int i;
237 if (invalid_flags == 0){
239 if ((mod & Modifiers.UNSAFE) != 0){
240 RootContext.CheckUnsafeOption (l, Report);
244 // If no accessibility bits provided
245 // then provide the defaults.
247 if ((mod & Modifiers.AccessibilityMask) == 0) {
248 mod |= def_access;
249 if (def_access != 0)
250 mod |= Modifiers.DEFAULT_ACCESS_MODIFER;
251 return mod;
255 // Make sure that no conflicting accessibility
256 // bits have been set. Protected+Internal is
257 // allowed, that is why they are placed on bits
258 // 1 and 4 (so the shift 3 basically merges them)
260 int a = (int) mod;
261 a &= 15;
262 a |= (a >> 3);
263 a = ((a & 2) >> 1) + (a & 5);
264 a = ((a & 4) >> 2) + (a & 3);
265 if (a > 1)
266 Report.Error (107, l, "More than one protection modifier specified");
268 return mod;
271 for (i = 1; i <= (int) Modifiers.TOP; i <<= 1) {
272 if ((i & invalid_flags) == 0)
273 continue;
275 Error_InvalidModifier (l, Name ((Modifiers) i), Report);
278 return allowed & mod;
281 public static void Error_InvalidModifier (Location l, string name, Report Report)
283 Report.Error (106, l, "The modifier `{0}' is not valid for this item", name);