public virtual void Emit ()
{
// Hack with Parent == null is for EnumMember
- if (Parent == null || (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null))
+ if (Parent == null || (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent) == null))
VerifyObsoleteAttribute ();
if (!RootContext.VerifyClsCompliance)
VerifyClsCompliance (Parent);
}
+ public bool InUnsafe {
+ get {
+ return ((ModFlags & Modifiers.UNSAFE) != 0) || Parent.UnsafeContext;
+ }
+ }
+
//
// Whehter is it ok to use an unsafe pointer in this type container
//
}
// <summary>
- // Looks up the type, as parsed into the expression `e'
+ // Looks up the type, as parsed into the expression `e'.
// </summary>
+ //[Obsolete ("This method is going away soon")]
public Type ResolveType (Expression e, bool silent, Location loc)
{
- if (type_resolve_ec == null)
- type_resolve_ec = GetTypeResolveEmitContext (Parent, loc);
- type_resolve_ec.loc = loc;
- type_resolve_ec.ContainerType = TypeBuilder;
-
- int errors = Report.Errors;
- TypeExpr d = e.ResolveAsTypeTerminal (type_resolve_ec);
-
- if (d == null || d.eclass != ExprClass.Type){
- if (!silent && errors == Report.Errors){
- Report.Error (246, loc, "Cannot find type `"+ e.ToString () +"'");
- }
- return null;
- }
-
- if (!d.CheckAccessLevel (this)) {
- Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", d.Name);
- return null;
- }
-
- return d.Type;
+ TypeExpr d = ResolveTypeExpr (e, silent, loc);
+ return d == null ? null : d.Type;
}
// <summary>
// Resolves the expression `e' for a type, and will recursively define
- // types.
+ // types. This should only be used for resolving base types.
// </summary>
public TypeExpr ResolveTypeExpr (Expression e, bool silent, Location loc)
{
type_resolve_ec.loc = loc;
type_resolve_ec.ContainerType = TypeBuilder;
- TypeExpr d = e.ResolveAsTypeTerminal (type_resolve_ec);
-
- if (d == null || d.eclass != ExprClass.Type){
- if (!silent){
- Report.Error (246, loc, "Cannot find type `"+ e +"'");
- }
- return null;
- }
-
- return d;
+ return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
}
- public bool CheckAccessLevel (Type check_type)
+ public bool CheckAccessLevel (Type check_type)
{
if (check_type == TypeBuilder)
return true;
TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
-
+
//
// Broken Microsoft runtime, return public for arrays, no matter what
// the accessibility is for their underlying class, and they return
if (check_type.IsArray || check_type.IsPointer)
return CheckAccessLevel (TypeManager.GetElementType (check_type));
+ if (TypeBuilder == null)
+ // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
+ // However, this is invoked again later -- so safe to return true.
+ // May also be null when resolving top-level attributes.
+ return true;
+
switch (check_attr){
case TypeAttributes.Public:
return true;
case TypeAttributes.NotPublic:
-
- // In same cases is null.
- if (TypeBuilder == null)
- return true;
-
//
// This test should probably use the declaringtype.
//
return true;
case TypeAttributes.NestedPrivate:
- string check_type_name = check_type.FullName;
- string type_name = TypeBuilder.FullName;
-
- int cio = check_type_name.LastIndexOf ('+');
- string container = check_type_name.Substring (0, cio);
-
- //
- // Check if the check_type is a nested class of the current type
- //
- if (check_type_name.StartsWith (type_name + "+")){
- return true;
- }
-
- if (type_name.StartsWith (container)){
- return true;
- }
-
- return false;
+ return NestedAccessible (check_type);
case TypeAttributes.NestedFamily:
- //
- // Only accessible to methods in current type or any subtypes
- //
return FamilyAccessible (check_type);
case TypeAttributes.NestedFamANDAssem:
}
- protected bool FamilyAccessible (Type check_type)
+ protected bool NestedAccessible (Type check_type)
{
- Type declaring = check_type.DeclaringType;
- if (TypeBuilder.IsSubclassOf (declaring))
- return true;
-
string check_type_name = check_type.FullName;
-
+
+ // At this point, we already know check_type is a nested class.
int cio = check_type_name.LastIndexOf ('+');
- string container = check_type_name.Substring (0, cio);
-
- //
- // Check if the check_type is a nested class of the current type
- //
- if (check_type_name.StartsWith (container + "+"))
+
+ // Ensure that the string 'container' has a '+' in it to avoid false matches
+ string container = check_type_name.Substring (0, cio + 1);
+
+ // Ensure that type_name ends with a '+' so that it can match 'container', if necessary
+ string type_name = TypeBuilder.FullName + "+";
+
+ // If the current class is nested inside the container of check_type,
+ // we can access check_type even if it is private or protected.
+ return type_name.StartsWith (container);
+ }
+
+ protected bool FamilyAccessible (Type check_type)
+ {
+ Type declaring = check_type.DeclaringType;
+ if (TypeBuilder == declaring ||
+ TypeBuilder.IsSubclassOf (declaring))
return true;
- return false;
+ return NestedAccessible (check_type);
}
// Access level of a type.
// Does exist easier way how to detect indexer ?
if ((entry.EntryType & EntryType.Property) != 0) {
Type[] arg_types = TypeManager.GetArgumentTypes ((PropertyInfo)entry.Member);
- if (arg_types.Length == 1)
+ if (arg_types.Length > 0)
continue;
}
}