X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdecl.cs;h=a1e127ad22aed33a86e4e066ec74214c44d4ac26;hb=3bc6741c3037000eebd46b91efad54e5e6915c74;hp=33de6a2c6921823b968a6517c4ec4cc278a9504a;hpb=7b25356adab16ccb5fe944191e3ef012d76a652d;p=mono.git diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index 33de6a2c692..a1e127ad22a 100644 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -12,11 +12,7 @@ // using System; -using System.Text; using System.Collections.Generic; -using System.Globalization; -using System.Reflection.Emit; -using System.Reflection; #if NET_2_1 using XmlElement = System.Object; @@ -24,6 +20,14 @@ using XmlElement = System.Object; using System.Xml; #endif +#if STATIC +using IKVM.Reflection; +using IKVM.Reflection.Emit; +#else +using System.Reflection; +using System.Reflection.Emit; +#endif + namespace Mono.CSharp { // @@ -297,6 +301,12 @@ namespace Mono.CSharp { } } + public virtual ModuleContainer Module { + get { + return Parent.Module; + } + } + public /*readonly*/ TypeContainer Parent; /// @@ -350,10 +360,6 @@ namespace Mono.CSharp { AddAttributes (attrs, this); } - public virtual Assembly Assembly { - get { return Parent.Module.Assembly; } - } - protected virtual void SetMemberName (MemberName new_name) { member_name = new_name; @@ -379,7 +385,7 @@ namespace Mono.CSharp { } } else { if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.PARTIAL)) == 0 && !(Parent is Delegate)) { - if (RootContext.Version >= LanguageVersion.V_3) { + if (Compiler.Settings.Version >= LanguageVersion.V_3) { Property.PropertyMethod pm = this as Property.PropertyMethod; if (pm is Indexer.GetIndexerMethod || pm is Indexer.SetIndexerMethod) pm = null; @@ -453,7 +459,7 @@ namespace Mono.CSharp { /// public virtual void Emit () { - if (!RootContext.VerifyClsCompliance) + if (!Compiler.Settings.VerifyClsCompliance) return; VerifyClsCompliance (); @@ -475,7 +481,9 @@ namespace Mono.CSharp { } public virtual bool IsUsed { - get { return (caching_flags & Flags.IsUsed) != 0; } + get { + return (caching_flags & Flags.IsUsed) != 0; + } } protected Report Report { @@ -507,7 +515,7 @@ namespace Mono.CSharp { if (OptAttributes == null) return null; - Attribute obsolete_attr = OptAttributes.Search (PredefinedAttributes.Get.Obsolete); + Attribute obsolete_attr = OptAttributes.Search (Module.PredefinedAttributes.Obsolete); if (obsolete_attr == null) return null; @@ -569,7 +577,7 @@ namespace Mono.CSharp { switch (pAccess) { case Modifiers.INTERNAL: if (al == Modifiers.PRIVATE || al == Modifiers.INTERNAL) - same_access_restrictions = TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly); + same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); break; @@ -595,12 +603,12 @@ namespace Mono.CSharp { case Modifiers.PROTECTED | Modifiers.INTERNAL: if (al == Modifiers.INTERNAL) - same_access_restrictions = TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly); - else if (al == Modifiers.PROTECTED) - same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent); + same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL)) - same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) && - TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly); + same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); + else + goto case Modifiers.PROTECTED; + break; case Modifiers.PRIVATE: @@ -676,9 +684,9 @@ namespace Mono.CSharp { return true; } - public virtual ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc) + public virtual IList LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope) { - return Parent.LookupExtensionMethod (extensionType, name, arity, loc); + return Parent.LookupExtensionMethod (extensionType, name, arity, ref scope); } public virtual FullNamedExpression LookupNamespaceAlias (string name) @@ -695,26 +703,31 @@ namespace Mono.CSharp { /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute. /// If no is attribute exists then assembly CLSCompliantAttribute is returned. /// - public bool IsNotCLSCompliant () - { - if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0) - return (caching_flags & Flags.ClsCompliantAttributeFalse) != 0; + public bool? CLSAttributeValue { + get { + if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0) { + if ((caching_flags & Flags.HasClsCompliantAttribute) == 0) + return null; - caching_flags &= ~Flags.HasCompliantAttribute_Undetected; + return (caching_flags & Flags.ClsCompliantAttributeFalse) == 0; + } - if (OptAttributes != null) { - Attribute cls_attribute = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); - if (cls_attribute != null) { - caching_flags |= Flags.HasClsCompliantAttribute; - if (cls_attribute.GetClsCompliantAttributeValue ()) - return false; + caching_flags &= ~Flags.HasCompliantAttribute_Undetected; - caching_flags |= Flags.ClsCompliantAttributeFalse; - return true; + if (OptAttributes != null) { + Attribute cls_attribute = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant); + if (cls_attribute != null) { + caching_flags |= Flags.HasClsCompliantAttribute; + if (cls_attribute.GetClsCompliantAttributeValue ()) + return true; + + caching_flags |= Flags.ClsCompliantAttributeFalse; + return false; + } } - } - return false; + return null; + } } /// @@ -722,10 +735,7 @@ namespace Mono.CSharp { /// protected bool HasClsCompliantAttribute { get { - if ((caching_flags & Flags.HasCompliantAttribute_Undetected) != 0) - IsNotCLSCompliant (); - - return (caching_flags & Flags.HasClsCompliantAttribute) != 0; + return CLSAttributeValue.HasValue; } } @@ -746,8 +756,8 @@ namespace Mono.CSharp { protected virtual bool VerifyClsCompliance () { if (HasClsCompliantAttribute) { - if (CodeGen.Assembly.ClsCompliantAttribute == null) { - Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + if (!Module.DeclaringAssembly.HasCLSCompliantAttribute) { + Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant); if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) { Report.Warning (3021, 2, a.Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", @@ -761,7 +771,7 @@ namespace Mono.CSharp { } if (!IsExposedFromAssembly ()) { - Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant); Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ()); return false; } @@ -777,7 +787,7 @@ namespace Mono.CSharp { } if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) { - Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant); Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'", GetSignatureForError (), Parent.GetSignatureForError ()); return false; @@ -886,12 +896,15 @@ namespace Mono.CSharp { public abstract class MemberSpec { [Flags] - protected enum StateFlags + public enum StateFlags { Obsolete_Undetected = 1, // Obsolete attribute has not been detected yet Obsolete = 1 << 1, // Member has obsolete attribute - CLSCompliant_Undetected = 1 << 3, // CLSCompliant attribute has not been detected yet - CLSCompliant = 1 << 4, // Member is CLS Compliant + CLSCompliant_Undetected = 1 << 2, // CLSCompliant attribute has not been detected yet + CLSCompliant = 1 << 3, // Member is CLS Compliant + MissingDependency_Undetected = 1 << 4, + MissingDependency = 1 << 5, + HasDynamicElement = 1 << 6, IsAccessor = 1 << 9, // Method is an accessor IsGeneric = 1 << 10, // Member contains type arguments @@ -905,7 +918,7 @@ namespace Mono.CSharp { } protected Modifiers modifiers; - protected StateFlags state; + public StateFlags state; protected IMemberDefinition definition; public readonly MemberKind Kind; protected TypeSpec declaringType; @@ -922,17 +935,11 @@ namespace Mono.CSharp { this.definition = definition; this.modifiers = modifiers; - state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected; + state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected; } #region Properties - public Assembly Assembly { - get { - return definition.Assembly; - } - } - public virtual int Arity { get { return 0; @@ -999,6 +1006,10 @@ namespace Mono.CSharp { get { return (modifiers & Modifiers.PRIVATE) != 0; } } + public bool IsPublic { + get { return (modifiers & Modifiers.PUBLIC) != 0; } + } + public bool IsStatic { get { return (modifiers & Modifiers.STATIC) != 0; @@ -1021,9 +1032,42 @@ namespace Mono.CSharp { return oa; } - protected virtual bool IsNotCLSCompliant () + // + // Returns a list of missing dependencies of this member. The list + // will contain types only but it can have numerous values for members + // like methods where both return type and all parameters are checked + // + public List GetMissingDependencies () + { + if ((state & (StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected)) == 0) + return null; + + state &= ~StateFlags.MissingDependency_Undetected; + + var imported = definition as ImportedDefinition; + List missing; + if (imported != null) { + missing = ResolveMissingDependencies (); + } else if (this is ElementTypeSpec) { + missing = ((ElementTypeSpec) this).Element.GetMissingDependencies (); + } else { + missing = null; + } + + if (missing != null) { + state |= StateFlags.MissingDependency; + } + + return missing; + } + + public abstract List ResolveMissingDependencies (); + + protected virtual bool IsNotCLSCompliant (out bool attrValue) { - return MemberDefinition.IsNotCLSCompliant (); + var cls = MemberDefinition.CLSAttributeValue; + attrValue = cls ?? false; + return cls == false; } public virtual string GetSignatureForError () @@ -1037,14 +1081,59 @@ namespace Mono.CSharp { { var inflated = (MemberSpec) MemberwiseClone (); inflated.declaringType = inflator.TypeInstance; - inflated.state |= StateFlags.PendingMetaInflate; + if (DeclaringType.IsGenericOrParentIsGeneric) + inflated.state |= StateFlags.PendingMetaInflate; #if DEBUG - if (inflated.ID > 0) - inflated.ID = -inflated.ID; + inflated.ID += 1000000; #endif return inflated; } + // + // Is this member accessible from invocationType + // + public bool IsAccessible (TypeSpec invocationType) + { + var ma = Modifiers & Modifiers.AccessibilityMask; + if (ma == Modifiers.PUBLIC) + return true; + + var parentType = /* this as TypeSpec ?? */ DeclaringType; + + // It's null for module context + if (invocationType == null) + invocationType = InternalType.FakeInternalType; + + // + // If only accessible to the current class or children + // + if (ma == Modifiers.PRIVATE) + return invocationType.MemberDefinition == parentType.MemberDefinition || + TypeManager.IsNestedChildOf (invocationType, parentType.MemberDefinition); + + if ((ma & Modifiers.INTERNAL) != 0) { + bool b; + var assembly = invocationType == InternalType.FakeInternalType ? + RootContext.ToplevelTypes.DeclaringAssembly : + invocationType.MemberDefinition.DeclaringAssembly; + + if (parentType == null) { + b = ((ITypeDefinition) MemberDefinition).IsInternalAsPublic (assembly); + } else { + b = DeclaringType.MemberDefinition.IsInternalAsPublic (assembly); + } + + if (b || ma == Modifiers.INTERNAL) + return b; + } + + // PROTECTED + if (!TypeManager.IsNestedFamilyAccessible (invocationType, parentType)) + return false; + + return true; + } + // // Returns member CLS compliance based on full member hierarchy // @@ -1053,19 +1142,15 @@ namespace Mono.CSharp { if ((state & StateFlags.CLSCompliant_Undetected) != 0) { state &= ~StateFlags.CLSCompliant_Undetected; - if (IsNotCLSCompliant ()) + bool compliant; + if (IsNotCLSCompliant (out compliant)) return false; - bool compliant; - if (DeclaringType != null) { - compliant = DeclaringType.IsCLSCompliant (); - } else { - // TODO: NEED AssemblySpec - if (MemberDefinition.IsImported) { - var attr = MemberDefinition.Assembly.GetCustomAttributes (typeof (CLSCompliantAttribute), false); - compliant = attr.Length > 0 && ((CLSCompliantAttribute) attr[0]).IsCompliant; + if (!compliant) { + if (DeclaringType != null) { + compliant = DeclaringType.IsCLSCompliant (); } else { - compliant = CodeGen.Assembly.IsClsCompliant; + compliant = ((ITypeDefinition) MemberDefinition).DeclaringAssembly.IsCLSCompliant; } } @@ -1105,13 +1190,12 @@ namespace Mono.CSharp { // public interface IMemberDefinition { - Assembly Assembly { get; } + bool? CLSAttributeValue { get; } string Name { get; } bool IsImported { get; } string[] ConditionalConditions (); ObsoleteAttribute GetAttributeObsolete (); - bool IsNotCLSCompliant (); void SetIsAssigned (); void SetIsUsed (); } @@ -1144,8 +1228,6 @@ namespace Mono.CSharp { // public NamespaceEntry NamespaceEntry; - private Dictionary Cache = new Dictionary (); - public readonly string Basename; protected Dictionary defined_names; @@ -1263,14 +1345,12 @@ namespace Mono.CSharp { return false; } - protected virtual TypeAttributes TypeAttr { - get { return Module.DefaultCharSetType; } - } + protected abstract TypeAttributes TypeAttr { get; } /// /// Should be overriten by the appropriate declaration space /// - public abstract TypeBuilder DefineType (); + public abstract void DefineType (); protected void Error_MissingPartialModifier (MemberCore type) { @@ -1284,119 +1364,6 @@ namespace Mono.CSharp { return MemberName.GetSignatureForError (); } - public bool CheckAccessLevel (TypeSpec check_type) - { - TypeSpec tb = PartialContainer.Definition; - check_type = check_type.GetDefinition (); - - var check_attr = check_type.Modifiers & Modifiers.AccessibilityMask; - - switch (check_attr){ - case Modifiers.PUBLIC: - return true; - - case Modifiers.INTERNAL: - return TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly); - - case Modifiers.PRIVATE: - TypeSpec declaring = check_type.DeclaringType; - return tb == declaring.GetDefinition () || TypeManager.IsNestedChildOf (tb, declaring); - - case Modifiers.PROTECTED: - // - // Only accessible to methods in current type or any subtypes - // - return TypeManager.IsNestedFamilyAccessible (tb, check_type.DeclaringType); - - case Modifiers.PROTECTED | Modifiers.INTERNAL: - if (TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly)) - return true; - - goto case Modifiers.PROTECTED; - } - - throw new NotImplementedException (check_attr.ToString ()); - } - - private TypeSpec LookupNestedTypeInHierarchy (string name, int arity) - { - // TODO: GenericMethod only - if (PartialContainer == null) - return null; - - // Has any nested type - // Does not work, because base type can have - //if (PartialContainer.Types == null) - // return null; - - var container = PartialContainer.CurrentType; - - // Is not Root container - if (container == null) - return null; - - var t = MemberCache.FindNestedType (container, name, arity); - if (t == null) - return null; - - // FIXME: Breaks error reporting - if (!CheckAccessLevel (t)) - return null; - - return t; - } - - // - // Public function used to locate types. - // - // Set 'ignore_cs0104' to true if you want to ignore cs0104 errors. - // - // Returns: Type or null if they type can not be found. - // - public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104) - { - FullNamedExpression e; - if (arity == 0 && Cache.TryGetValue (name, out e)) - return e; - - e = null; - int errors = Report.Errors; - - if (arity == 0) { - TypeParameter[] tp = CurrentTypeParameters; - if (tp != null) { - TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name); - if (tparam != null) - e = new TypeParameterExpr (tparam, Location.Null); - } - } - - if (e == null) { - TypeSpec t = LookupNestedTypeInHierarchy (name, arity); - - if (t != null) - e = new TypeExpression (t, Location.Null); - else if (Parent != null) - e = Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104); - else - e = NamespaceEntry.LookupNamespaceOrType (name, arity, loc, ignore_cs0104); - } - - // TODO MemberCache: How to cache arity stuff ? - if (errors == Report.Errors && arity == 0) - Cache [name] = e; - - return e; - } - - public override Assembly Assembly { - get { return Module.Assembly; } - } - - public virtual ModuleContainer Module { - get { return Parent.Module; } - } - TypeParameter[] initialize_type_params () { if (type_param_list != null)