Updated list
[mono.git] / mcs / mbas / modifiers.cs
1 //\r
2 // modifiers.cs: Modifier handling.\r
3 // \r
4 using System;\r
5 using System.Reflection;\r
6 \r
7 namespace Mono.CSharp {\r
8         public class Modifiers {\r
9 \r
10                 //\r
11                 // The ordering of the following 4 constants\r
12                 // has been carefully done.\r
13                 //\r
14                 public const int PROTECTED = 0x0001;\r
15                 public const int PUBLIC    = 0x0002;\r
16                 public const int PRIVATE   = 0x0004;\r
17                 public const int INTERNAL  = 0x0008;\r
18                 public const int NEW       = 0x0010;\r
19                 public const int ABSTRACT  = 0x0020;\r
20                 public const int SEALED    = 0x0040;\r
21                 public const int STATIC    = 0x0080;\r
22                 public const int READONLY  = 0x0100;\r
23                 public const int VIRTUAL   = 0x0200;\r
24                 public const int OVERRIDE  = 0x0400;\r
25                 public const int EXTERN    = 0x0800;\r
26                 public const int VOLATILE  = 0x1000;\r
27                 public const int UNSAFE    = 0x2000;\r
28                 public const int TOP       = 0x2000;\r
29 \r
30                 public const int Accessibility =\r
31                         PUBLIC | PROTECTED | INTERNAL | PRIVATE;\r
32                 \r
33                 static public string Name (int i)\r
34                 {\r
35                         string s = "";\r
36                         \r
37                         switch (i) {\r
38                         case Modifiers.NEW:\r
39                                 s = "new"; break;\r
40                         case Modifiers.PUBLIC:\r
41                                 s = "public"; break;\r
42                         case Modifiers.PROTECTED:\r
43                                 s = "protected"; break;\r
44                         case Modifiers.INTERNAL:\r
45                                 s = "internal"; break;\r
46                         case Modifiers.PRIVATE:\r
47                                 s = "private"; break;\r
48                         case Modifiers.ABSTRACT:\r
49                                 s = "abstract"; break;\r
50                         case Modifiers.SEALED:\r
51                                 s = "sealed"; break;\r
52                         case Modifiers.STATIC:\r
53                                 s = "static"; break;\r
54                         case Modifiers.READONLY:\r
55                                 s = "readonly"; break;\r
56                         case Modifiers.VIRTUAL:\r
57                                 s = "virtual"; break;\r
58                         case Modifiers.OVERRIDE:\r
59                                 s = "override"; break;\r
60                         case Modifiers.EXTERN:\r
61                                 s = "extern"; break;\r
62                         case Modifiers.VOLATILE:\r
63                                 s = "volatile"; break;\r
64                         }\r
65 \r
66                         return s;\r
67                 }\r
68 \r
69                 public static TypeAttributes TypeAttr (int mod_flags, TypeContainer caller)\r
70                 {\r
71                         TypeAttributes t = 0;\r
72                         bool top_level = caller.IsTopLevel;\r
73                         \r
74                         if (top_level){\r
75                                 if ((mod_flags & PUBLIC) != 0)\r
76                                         t |= TypeAttributes.Public;\r
77                                 if ((mod_flags & PRIVATE) != 0)\r
78                                         t |= TypeAttributes.NotPublic;\r
79                         } else {\r
80                                 if ((mod_flags & PUBLIC) != 0)\r
81                                         t |= TypeAttributes.NestedPublic;\r
82                                 if ((mod_flags & PRIVATE) != 0)\r
83                                         t |= TypeAttributes.NestedPrivate;\r
84                                 if ((mod_flags & PROTECTED) != 0 && (mod_flags & INTERNAL) != 0)\r
85                                         t |= TypeAttributes.NestedFamORAssem;\r
86                                 if ((mod_flags & PROTECTED) != 0)\r
87                                         t |= TypeAttributes.NestedFamily;\r
88                                 if ((mod_flags & INTERNAL) != 0)\r
89                                         t |= TypeAttributes.NestedAssembly;\r
90                         }\r
91                         \r
92                         if ((mod_flags & SEALED) != 0)\r
93                                 t |= TypeAttributes.Sealed;\r
94                         if ((mod_flags & ABSTRACT) != 0)\r
95                                 t |= TypeAttributes.Abstract;\r
96 \r
97                         // If we do not have static constructors, static methods\r
98                         // can be invoked without initializing the type.\r
99                         if (!caller.HaveStaticConstructor)\r
100                                 t |= TypeAttributes.BeforeFieldInit;\r
101                                 \r
102                         return t;\r
103                 }\r
104 \r
105                 public static FieldAttributes FieldAttr (int mod_flags)\r
106                 {\r
107                         FieldAttributes fa = 0;\r
108 \r
109                         if ((mod_flags & PUBLIC) != 0)\r
110                                 fa |= FieldAttributes.Public;\r
111                         if ((mod_flags & PRIVATE) != 0)\r
112                                 fa |= FieldAttributes.Private;\r
113                         if ((mod_flags & PROTECTED) != 0 && (mod_flags & INTERNAL) != 0)\r
114                                 fa |= FieldAttributes.FamORAssem;\r
115                         if ((mod_flags & PROTECTED) != 0)\r
116                                 fa |= FieldAttributes.Family;\r
117                         if ((mod_flags & INTERNAL) != 0)\r
118                                 fa |= FieldAttributes.Assembly;\r
119                         \r
120                         if ((mod_flags & STATIC) != 0)\r
121                                 fa |= FieldAttributes.Static;\r
122                         if ((mod_flags & READONLY) != 0)\r
123                                 fa |= FieldAttributes.InitOnly;\r
124 \r
125                         return fa;\r
126                 }\r
127 \r
128                 public static MethodAttributes MethodAttr (int mod_flags)\r
129                 {\r
130                         MethodAttributes ma = 0;\r
131 \r
132                         if ((mod_flags & PUBLIC) != 0)\r
133                                 ma |= MethodAttributes.Public;\r
134                         if ((mod_flags & PRIVATE) != 0)\r
135                                 ma |= MethodAttributes.Private;\r
136                         if ((mod_flags & PROTECTED) != 0 && (mod_flags & INTERNAL) != 0)\r
137                                 ma |= MethodAttributes.FamORAssem;\r
138                         if ((mod_flags & PROTECTED) != 0)\r
139                                 ma |= MethodAttributes.Family;\r
140                         if ((mod_flags & INTERNAL) != 0)\r
141                                 ma |= MethodAttributes.Assembly;\r
142                         \r
143 \r
144                         if ((mod_flags & STATIC) != 0)\r
145                                 ma |= MethodAttributes.Static;\r
146                         if ((mod_flags & ABSTRACT) != 0){\r
147                                 ma |= MethodAttributes.Abstract | MethodAttributes.Virtual |\r
148                                         MethodAttributes.HideBySig;\r
149                         }\r
150                         if ((mod_flags & SEALED) != 0)\r
151                                 ma |= MethodAttributes.Final;\r
152                         if ((mod_flags & VIRTUAL) != 0)\r
153                                 ma |= MethodAttributes.Virtual;\r
154 \r
155                         if ((mod_flags & OVERRIDE) != 0)\r
156                                 ma |= MethodAttributes.Virtual | MethodAttributes.HideBySig;\r
157                         else {\r
158                                 if ((ma & MethodAttributes.Virtual) != 0)\r
159                                         ma |= MethodAttributes.NewSlot;\r
160                         }\r
161                         \r
162                         if ((mod_flags & NEW) != 0)\r
163                                 ma |= MethodAttributes.HideBySig;\r
164                         \r
165                         return ma;\r
166                 }\r
167 \r
168                 // <summary>\r
169                 //   Checks the object @mod modifiers to be in @allowed.\r
170                 //   Returns the new mask.  Side effect: reports any\r
171                 //   incorrect attributes. \r
172                 // </summary>\r
173                 public static int Check (int allowed, int mod, int def_access, Location l)\r
174                 {\r
175                         int invalid_flags  = (~allowed) & mod;\r
176                         int i;\r
177 \r
178                         if (invalid_flags == 0){\r
179                                 int a = mod;\r
180 \r
181                                 if ((mod & Modifiers.UNSAFE) != 0){\r
182                                         if (!RootContext.Unsafe){\r
183                                                 Report.Error (227, l,\r
184                                                               "Unsafe code requires the --unsafe command " +\r
185                                                               "line option to be specified");\r
186                                         }\r
187                                 }\r
188                                 \r
189                                 //\r
190                                 // If no accessibility bits provided\r
191                                 // then provide the defaults.\r
192                                 //\r
193                                 if ((mod & Accessibility) == 0){\r
194                                         mod |= def_access;\r
195                                         return mod;\r
196                                 }\r
197 \r
198                                 //\r
199                                 // Make sure that no conflicting accessibility\r
200                                 // bits have been set.  Protected+Internal is\r
201                                 // allowed, that is why they are placed on bits\r
202                                 // 1 and 4 (so the shift 3 basically merges them)\r
203                                 //\r
204                                 a &= 15;\r
205                                 a |= (a >> 3);\r
206                                 a = ((a & 2) >> 1) + (a & 5);\r
207                                 a = ((a & 4) >> 2) + (a & 3);\r
208                                 if (a > 1)\r
209                                         Report.Error (107, l, "More than one protection modifier specified");\r
210                                 \r
211                                 return mod;\r
212                         }\r
213                         \r
214                         for (i = 1; i < TOP; i <<= 1){\r
215                                 if ((i & invalid_flags) == 0)\r
216                                         continue;\r
217 \r
218                                 Report.Error (106, l, "the modifier `" + Name (i) +\r
219                                               "' is not valid for this item");\r
220                         }\r
221 \r
222                         return allowed & mod;\r
223                 }\r
224         }\r
225 }\r