//
-// modifiers.cs: Modifier handling.
-//
+// modifiers.cs: Modifiers handling
+//
+// Authors: Miguel de Icaza (miguel@gnu.org)
+// Marek Safar (marek.safar@gmail.com)
+//
+// Dual licensed under the terms of the MIT X11 or GNU GPL
+//
+// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2004-2010 Novell, Inc
+//
+
using System;
+
+#if STATIC
+using IKVM.Reflection;
+#else
using System.Reflection;
+#endif
namespace Mono.CSharp
{
[Flags]
public enum Modifiers
{
- //
- // The ordering of the following 4 constants
- // has been carefully done.
- //
PROTECTED = 0x0001,
PUBLIC = 0x0002,
PRIVATE = 0x0004,
EXTERN = 0x0800,
VOLATILE = 0x1000,
UNSAFE = 0x2000,
- TOP = 0x4000,
+ ASYNC = 0x4000,
+ TOP = 0x8000,
//
// Compiler specific flags
//
- PROPERTY_CUSTOM = 0x4000,
+ PROPERTY_CUSTOM = 0x10000,
+
PARTIAL = 0x20000,
DEFAULT_ACCESS_MODIFER = 0x40000,
METHOD_EXTENSION = 0x80000,
static class ModifiersExtensions
{
+ public static string AccessibilityName (Modifiers mod)
+ {
+ switch (mod & Modifiers.AccessibilityMask) {
+ case Modifiers.PUBLIC:
+ return "public";
+ case Modifiers.PROTECTED:
+ return "protected";
+ case Modifiers.PROTECTED | Modifiers.INTERNAL:
+ return "protected internal";
+ case Modifiers.INTERNAL:
+ return "internal";
+ case Modifiers.PRIVATE:
+ return "private";
+ default:
+ throw new NotImplementedException (mod.ToString ());
+ }
+ }
+
static public string Name (Modifiers i)
{
string s = "";
s = "volatile"; break;
case Modifiers.UNSAFE:
s = "unsafe"; break;
+ case Modifiers.ASYNC:
+ s = "async"; break;
}
return s;
}
- public static string GetDescription (MethodAttributes ma)
+ //
+ // Used by custom property accessors to check whether @modA is more restrictive than @modB
+ //
+ public static bool IsRestrictedModifier (Modifiers modA, Modifiers modB)
{
- ma &= MethodAttributes.MemberAccessMask;
-
- if (ma == MethodAttributes.Assembly)
- return "internal";
-
- if (ma == MethodAttributes.Family)
- return "protected";
-
- if (ma == MethodAttributes.Public)
- return "public";
+ Modifiers flags = 0;
- if (ma == MethodAttributes.FamORAssem)
- return "protected internal";
+ if ((modB & Modifiers.PUBLIC) != 0) {
+ flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+ } else if ((modB & Modifiers.PROTECTED) != 0) {
+ if ((modB & Modifiers.INTERNAL) != 0)
+ flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
- if (ma == MethodAttributes.Private)
- return "private";
+ flags |= Modifiers.PRIVATE;
+ } else if ((modB & Modifiers.INTERNAL) != 0)
+ flags = Modifiers.PRIVATE;
- throw new NotImplementedException (ma.ToString ());
+ return modB != modA && (modA & (~flags)) == 0;
}
public static TypeAttributes TypeAttr (Modifiers mod_flags, bool is_toplevel)
{
MethodAttributes ma = MethodAttributes.HideBySig;
- if ((mod_flags & Modifiers.PUBLIC) != 0)
+ switch (mod_flags & Modifiers.AccessibilityMask) {
+ case Modifiers.PUBLIC:
ma |= MethodAttributes.Public;
- else if ((mod_flags & Modifiers.PRIVATE) != 0)
+ break;
+ case Modifiers.PRIVATE:
ma |= MethodAttributes.Private;
- else if ((mod_flags & Modifiers.PROTECTED) != 0) {
- if ((mod_flags & Modifiers.INTERNAL) != 0)
- ma |= MethodAttributes.FamORAssem;
- else
- ma |= MethodAttributes.Family;
- } else {
- if ((mod_flags & Modifiers.INTERNAL) != 0)
- ma |= MethodAttributes.Assembly;
+ break;
+ case Modifiers.PROTECTED | Modifiers.INTERNAL:
+ ma |= MethodAttributes.FamORAssem;
+ break;
+ case Modifiers.PROTECTED:
+ ma |= MethodAttributes.Family;
+ break;
+ case Modifiers.INTERNAL:
+ ma |= MethodAttributes.Assembly;
+ break;
+ default:
+ throw new NotImplementedException (mod_flags.ToString ());
}
if ((mod_flags & Modifiers.STATIC) != 0)
if ((mod_flags & Modifiers.VIRTUAL) != 0)
ma |= MethodAttributes.Virtual;
- if ((mod_flags & Modifiers.OVERRIDE) != 0)
+ if ((mod_flags & Modifiers.OVERRIDE) != 0) {
ma |= MethodAttributes.Virtual;
- else {
+ } else {
if ((ma & MethodAttributes.Virtual) != 0)
ma |= MethodAttributes.NewSlot;
}
int i;
if (invalid_flags == 0){
-
- if ((mod & Modifiers.UNSAFE) != 0){
- RootContext.CheckUnsafeOption (l, Report);
- }
-
//
// If no accessibility bits provided
// then provide the defaults.
return mod;
}
- //
- // Make sure that no conflicting accessibility
- // bits have been set. Protected+Internal is
- // allowed, that is why they are placed on bits
- // 1 and 4 (so the shift 3 basically merges them)
- //
- int a = (int) mod;
- a &= 15;
- a |= (a >> 3);
- a = ((a & 2) >> 1) + (a & 5);
- a = ((a & 4) >> 2) + (a & 3);
- if (a > 1)
- Report.Error (107, l, "More than one protection modifier specified", Report);
-
return mod;
}
if ((i & invalid_flags) == 0)
continue;
- Error_InvalidModifier (l, Name ((Modifiers) i), Report);
+ Error_InvalidModifier ((Modifiers)i, l, Report);
}
return allowed & mod;
}
- public static void Error_InvalidModifier (Location l, string name, Report Report)
+ static void Error_InvalidModifier (Modifiers mod, Location l, Report Report)
{
- Report.Error (106, l, "The modifier `" + name + "' is not valid for this item", Report);
+ Report.Error (106, l, "The modifier `{0}' is not valid for this item",
+ Name (mod));
}
}
}