X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdecl.cs;h=7cda8d43c43b634a1970b5ea6193a1014bf1b258;hb=2a8b79ec1d4685a5d62630e2ce930a3df6c387a4;hp=8e2628f6f3dd20f197c5b41d5ba6203d143688bf;hpb=84c53cecc2b904602b4b11e8cbe24f6c40f34318;p=mono.git diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index 8e2628f6f3d..7cda8d43c43 100644 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -8,11 +8,14 @@ // // Copyright 2001 Ximian, Inc (http://www.ximian.com) // Copyright 2004-2008 Novell, Inc +// Copyright 2011 Xamarin Inc // // using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Text; #if NET_2_1 using XmlElement = System.Object; @@ -33,146 +36,118 @@ namespace Mono.CSharp { // // Better name would be DottenName // - public class MemberName { + [DebuggerDisplay ("{GetSignatureForError()}")] + public class MemberName + { + public static readonly MemberName Null = new MemberName (""); + public readonly string Name; - public TypeArguments TypeArguments; + public TypeParameters TypeParameters; + public readonly FullNamedExpression ExplicitInterface; + public readonly Location Location; public readonly MemberName Left; - public readonly Location Location; - public static readonly MemberName Null = new MemberName (""); + public MemberName (string name) + : this (name, Location.Null) + { } - bool is_double_colon; + public MemberName (string name, Location loc) + : this (null, name, loc) + { } - private MemberName (MemberName left, string name, bool is_double_colon, - Location loc) + public MemberName (string name, TypeParameters tparams, Location loc) { this.Name = name; this.Location = loc; - this.is_double_colon = is_double_colon; - this.Left = left; + + this.TypeParameters = tparams; } - private MemberName (MemberName left, string name, bool is_double_colon, - TypeArguments args, Location loc) - : this (left, name, is_double_colon, loc) + public MemberName (string name, TypeParameters tparams, FullNamedExpression explicitInterface, Location loc) + : this (name, tparams, loc) { - if (args != null && args.Count > 0) - this.TypeArguments = args; + this.ExplicitInterface = explicitInterface; } - public MemberName (string name) - : this (name, Location.Null) - { } - - public MemberName (string name, Location loc) - : this (null, name, false, loc) - { } - - public MemberName (string name, TypeArguments args, Location loc) - : this (null, name, false, args, loc) - { } - - public MemberName (MemberName left, string name) - : this (left, name, left != null ? left.Location : Location.Null) - { } - public MemberName (MemberName left, string name, Location loc) - : this (left, name, false, loc) - { } - - public MemberName (MemberName left, string name, TypeArguments args, Location loc) - : this (left, name, false, args, loc) - { } - - public MemberName (string alias, string name, TypeArguments args, Location loc) - : this (new MemberName (alias, loc), name, true, args, loc) - { } - - public MemberName (MemberName left, MemberName right) - : this (left, right, right.Location) - { } + { + this.Name = name; + this.Location = loc; + this.Left = left; + } - public MemberName (MemberName left, MemberName right, Location loc) - : this (null, right.Name, false, right.TypeArguments, loc) + public MemberName (MemberName left, string name, FullNamedExpression explicitInterface, Location loc) + : this (left, name, loc) { - if (right.is_double_colon) - throw new InternalErrorException ("Cannot append double_colon member name"); - this.Left = (right.Left == null) ? left : new MemberName (left, right.Left); + this.ExplicitInterface = explicitInterface; } - // TODO: Remove - public string GetName () + public MemberName (MemberName left, MemberName right) { - return GetName (false); + this.Name = right.Name; + this.Location = right.Location; + this.TypeParameters = right.TypeParameters; + this.Left = left; } public int Arity { get { - return TypeArguments == null ? 0 : TypeArguments.Count; + return TypeParameters == null ? 0 : TypeParameters.Count; } } public bool IsGeneric { get { - if (TypeArguments != null) - return true; - else if (Left != null) - return Left.IsGeneric; - else - return false; + return TypeParameters != null; } } - public string GetName (bool is_generic) - { - string name = is_generic ? Basename : Name; - if (Left != null) - return Left.GetName (is_generic) + (is_double_colon ? "::" : ".") + name; - - return name; + public string Basename { + get { + if (TypeParameters != null) + return MakeName (Name, TypeParameters); + return Name; + } } - public ATypeNameExpression GetTypeExpression () + public void CreateMetadataName (StringBuilder sb) { - if (Left == null) { - if (TypeArguments != null) - return new SimpleName (Name, TypeArguments, Location); - - return new SimpleName (Name, Location); - } + if (Left != null) + Left.CreateMetadataName (sb); - if (is_double_colon) { - if (Left.Left != null) - throw new InternalErrorException ("The left side of a :: should be an identifier"); - return new QualifiedAliasMember (Left.Name, Name, TypeArguments, Location); + if (sb.Length != 0) { + sb.Append ("."); } - Expression lexpr = Left.GetTypeExpression (); - return new MemberAccess (lexpr, Name, TypeArguments, Location); + sb.Append (Basename); } - public MemberName Clone () + public string GetSignatureForDocumentation () { - MemberName left_clone = Left == null ? null : Left.Clone (); - return new MemberName (left_clone, Name, is_double_colon, TypeArguments, Location); - } + var s = Basename; - public string Basename { - get { - if (TypeArguments != null) - return MakeName (Name, TypeArguments); - return Name; - } + if (ExplicitInterface != null) + s = ExplicitInterface.GetSignatureForError () + "." + s; + + if (Left == null) + return s; + + return Left.GetSignatureForDocumentation () + "." + s; } public string GetSignatureForError () { - string append = TypeArguments == null ? "" : "<" + TypeArguments.GetSignatureForError () + ">"; + string s = TypeParameters == null ? null : "<" + TypeParameters.GetSignatureForError () + ">"; + s = Name + s; + + if (ExplicitInterface != null) + s = ExplicitInterface.GetSignatureForError () + "." + s; + if (Left == null) - return Name + append; - string connect = is_double_colon ? "::" : "."; - return Left.GetSignatureForError () + connect + Name + append; + return s; + + return Left.GetSignatureForError () + "." + s; } public override bool Equals (object other) @@ -186,14 +161,12 @@ namespace Mono.CSharp { return true; if (other == null || Name != other.Name) return false; - if (is_double_colon != other.is_double_colon) - return false; - if ((TypeArguments != null) && - (other.TypeArguments == null || TypeArguments.Count != other.TypeArguments.Count)) + if ((TypeParameters != null) && + (other.TypeParameters == null || TypeParameters.Count != other.TypeParameters.Count)) return false; - if ((TypeArguments == null) && (other.TypeArguments != null)) + if ((TypeParameters == null) && (other.TypeParameters != null)) return false; if (Left == null) @@ -207,27 +180,14 @@ namespace Mono.CSharp { int hash = Name.GetHashCode (); for (MemberName n = Left; n != null; n = n.Left) hash ^= n.Name.GetHashCode (); - if (is_double_colon) - hash ^= 0xbadc01d; - if (TypeArguments != null) - hash ^= TypeArguments.Count << 5; + if (TypeParameters != null) + hash ^= TypeParameters.Count << 5; return hash & 0x7FFFFFFF; } - public int CountTypeArguments { - get { - if (TypeArguments != null) - return TypeArguments.Count; - else if (Left != null) - return Left.CountTypeArguments; - else - return 0; - } - } - - public static string MakeName (string name, TypeArguments args) + public static string MakeName (string name, TypeParameters args) { if (args == null) return name; @@ -260,20 +220,6 @@ namespace Mono.CSharp { [System.Diagnostics.DebuggerDisplay ("{GetSignatureForError()}")] public abstract class MemberCore : Attributable, IMemberContext, IMemberDefinition { - /// - /// Public name - /// - - protected string cached_name; - // TODO: Remove in favor of MemberName - public string Name { - get { - if (cached_name == null) - cached_name = MemberName.GetName (!(this is GenericMethod) && !(this is Method)); - return cached_name; - } - } - string IMemberDefinition.Name { get { return member_name.Name; @@ -344,7 +290,9 @@ namespace Mono.CSharp { IsAssigned = 1 << 12, // Field is assigned HasExplicitLayout = 1 << 13, PartialDefinitionExists = 1 << 14, // Set when corresponding partial method definition exists - HasStructLayout = 1 << 15 // Has StructLayoutAttribute + HasStructLayout = 1 << 15, // Has StructLayoutAttribute + HasInstanceConstructor = 1 << 16, + HasUserOperators = 1 << 17 } /// @@ -352,9 +300,9 @@ namespace Mono.CSharp { /// internal Flags caching_flags; - public MemberCore (DeclSpace parent, MemberName name, Attributes attrs) + public MemberCore (TypeContainer parent, MemberName name, Attributes attrs) { - this.Parent = parent as TypeContainer; + this.Parent = parent; member_name = name; caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected; AddAttributes (attrs, this); @@ -363,7 +311,11 @@ namespace Mono.CSharp { protected virtual void SetMemberName (MemberName new_name) { member_name = new_name; - cached_name = null; + } + + public virtual void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); } protected bool CheckAbstractAndExtern (bool has_block) @@ -385,7 +337,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; @@ -448,10 +400,11 @@ namespace Mono.CSharp { // public virtual string GetSignatureForError () { - if (Parent == null || Parent.Parent == null) + var parent = Parent.GetSignatureForError (); + if (parent == null) return member_name.GetSignatureForError (); - return Parent.GetSignatureForError () + "." + member_name.GetSignatureForError (); + return parent + "." + member_name.GetSignatureForError (); } /// @@ -459,7 +412,7 @@ namespace Mono.CSharp { /// public virtual void Emit () { - if (!RootContext.VerifyClsCompliance) + if (!Compiler.Settings.VerifyClsCompliance) return; VerifyClsCompliance (); @@ -502,6 +455,26 @@ namespace Mono.CSharp { caching_flags |= Flags.IsAssigned; } + public void SetConstraints (List constraints_list) + { + var tparams = member_name.TypeParameters; + if (tparams == null) { + Report.Error (80, Location, "Constraints are not allowed on non-generic declarations"); + return; + } + + foreach (var c in constraints_list) { + var tp = tparams.Find (c.TypeParameter.Value); + if (tp == null) { + Report.Error (699, c.Location, "`{0}': A constraint references nonexistent type parameter `{1}'", + GetSignatureForError (), c.TypeParameter.Value); + continue; + } + + tp.Constraints = c; + } + } + /// /// Returns instance of ObsoleteAttribute for this MemberCore /// @@ -583,7 +556,7 @@ namespace Mono.CSharp { case Modifiers.PROTECTED: if (al == Modifiers.PROTECTED) { - same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent); + same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent); break; } @@ -592,8 +565,8 @@ namespace Mono.CSharp { // When type is private and any of its parents derives from // protected type then the type is accessible // - while (mc.Parent != null) { - if (mc.Parent.IsBaseTypeDefinition (p_parent)) + while (mc.Parent != null && mc.Parent.PartialContainer != null) { + if (mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent)) same_access_restrictions = true; mc = mc.Parent; } @@ -605,7 +578,7 @@ namespace Mono.CSharp { if (al == Modifiers.INTERNAL) same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL)) - same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); + same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly); else goto case Modifiers.PROTECTED; @@ -619,7 +592,7 @@ namespace Mono.CSharp { var decl = mc.Parent; do { same_access_restrictions = decl.CurrentType == p_parent; - } while (!same_access_restrictions && !decl.IsTopLevel && (decl = decl.Parent) != null); + } while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null); } break; @@ -654,7 +627,7 @@ namespace Mono.CSharp { return true; } - if (Parent.PartialContainer.IsClsComplianceRequired ()) { + if (Parent.IsClsComplianceRequired ()) { caching_flags |= Flags.ClsCompliant; return true; } @@ -673,56 +646,76 @@ namespace Mono.CSharp { public bool IsExposedFromAssembly () { if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0) - return false; + return this is NamespaceContainer; - DeclSpace parentContainer = Parent.PartialContainer; - while (parentContainer != null && parentContainer.ModFlags != 0) { + var parentContainer = Parent.PartialContainer; + while (parentContainer != null) { if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0) return false; - parentContainer = parentContainer.Parent; + + parentContainer = parentContainer.Parent.PartialContainer; } + return true; } - public virtual IList LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope) + // + // Does extension methods look up to find a method which matches name and extensionType. + // Search starts from this namespace and continues hierarchically up to top level. + // + public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity) { - return Parent.LookupExtensionMethod (extensionType, name, arity, ref scope); + var m = Parent; + do { + var ns = m as NamespaceContainer; + if (ns != null) + return ns.LookupExtensionMethod (this, extensionType, name, arity, ns, 0); + + m = m.Parent; + } while (m != null); + + return null; } public virtual FullNamedExpression LookupNamespaceAlias (string name) { - return Parent.NamespaceEntry.LookupNamespaceAlias (name); + return Parent.LookupNamespaceAlias (name); } - public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104) + public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc) { - return Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104); + return Parent.LookupNamespaceOrType (name, arity, mode, loc); } /// /// 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; + + return (caching_flags & Flags.ClsCompliantAttributeFalse) == 0; + } - caching_flags &= ~Flags.HasCompliantAttribute_Undetected; + caching_flags &= ~Flags.HasCompliantAttribute_Undetected; - if (OptAttributes != null) { - Attribute cls_attribute = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant); - if (cls_attribute != null) { - caching_flags |= Flags.HasClsCompliantAttribute; - if (cls_attribute.GetClsCompliantAttributeValue ()) - return false; + 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 true; + caching_flags |= Flags.ClsCompliantAttributeFalse; + return false; + } } - } - return false; + return null; + } } /// @@ -730,10 +723,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; } } @@ -775,7 +765,7 @@ namespace Mono.CSharp { } if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) { - if (Parent.Kind == MemberKind.Interface && Parent.IsClsComplianceRequired ()) { + if (Parent is Interface && Parent.IsClsComplianceRequired ()) { Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ()); } else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired ()) { Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ()); @@ -784,7 +774,7 @@ namespace Mono.CSharp { return false; } - if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) { + if (Parent.Kind != MemberKind.Namespace && Parent.Kind != 0 && !Parent.IsClsComplianceRequired ()) { 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 ()); @@ -794,45 +784,55 @@ namespace Mono.CSharp { if (!IsExposedFromAssembly ()) return false; - if (!Parent.PartialContainer.IsClsComplianceRequired ()) + if (!Parent.IsClsComplianceRequired ()) return false; } if (member_name.Name [0] == '_') { - Report.Warning (3008, 1, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () ); + Warning_IdentifierNotCompliant (); } + if (member_name.TypeParameters != null) + member_name.TypeParameters.VerifyClsCompliance (); + return true; } - // - // Raised (and passed an XmlElement that contains the comment) - // when GenerateDocComment is writing documentation expectedly. - // - internal virtual void OnGenerateDocComment (XmlElement intermediateNode) + protected void Warning_IdentifierNotCompliant () { + Report.Warning (3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError ()); } // // Returns a string that represents the signature for this // member which should be used in XML documentation. // - public virtual string GetDocCommentName (DeclSpace ds) + public abstract string GetSignatureForDocumentation (); + + public virtual void GetCompletionStartingWith (string prefix, List results) { - if (ds == null || this is DeclSpace) - return DocCommentHeader + Name; - else - return String.Concat (DocCommentHeader, ds.Name, ".", Name); + Parent.GetCompletionStartingWith (prefix, results); } // // Generates xml doc comments (if any), and if required, // handle warning report. // - internal virtual void GenerateDocComment (DeclSpace ds) + internal virtual void GenerateDocComment (DocumentationBuilder builder) { + if (DocComment == null) { + if (IsExposedFromAssembly ()) { + Constructor c = this as Constructor; + if (c == null || !c.IsDefault ()) + Report.Warning (1591, 4, Location, + "Missing XML comment for publicly visible type or member `{0}'", GetSignatureForError ()); + } + + return; + } + try { - DocUtil.GenerateDocComment (this, ds, Report); + builder.GenerateDocumentationForMember (this); } catch (Exception e) { throw new InternalErrorException (this, e); } @@ -841,7 +841,9 @@ namespace Mono.CSharp { #region IMemberContext Members public virtual CompilerContext Compiler { - get { return Parent.Compiler; } + get { + return Module.Compiler; + } } public virtual TypeSpec CurrentType { @@ -852,14 +854,10 @@ namespace Mono.CSharp { get { return this; } } - public virtual TypeParameter[] CurrentTypeParameters { + public virtual TypeParameters CurrentTypeParameters { get { return null; } } - public virtual bool HasUnresolvedConstraints { - get { return false; } - } - public bool IsObsolete { get { if (GetAttributeObsolete () != null) @@ -903,6 +901,7 @@ namespace Mono.CSharp { MissingDependency_Undetected = 1 << 4, MissingDependency = 1 << 5, HasDynamicElement = 1 << 6, + ConstraintsChecked = 1 << 7, IsAccessor = 1 << 9, // Method is an accessor IsGeneric = 1 << 10, // Member contains type arguments @@ -912,7 +911,12 @@ namespace Mono.CSharp { PendingMemberCacheMembers = 1 << 14, PendingBaseTypeInflate = 1 << 15, InterfacesExpanded = 1 << 16, - IsNotRealProperty = 1 << 17, + IsNotCSharpCompatible = 1 << 17, + SpecialRuntimeType = 1 << 18, + InflatedExpressionType = 1 << 19, + InflatedNullableType = 1 << 20, + GenericIterateInterface = 1 << 21, + GenericTask = 1 << 22 } protected Modifiers modifiers; @@ -1000,6 +1004,18 @@ namespace Mono.CSharp { } } + // + // Returns true for imported members which are not compatible with C# language + // + public bool IsNotCSharpCompatible { + get { + return (state & StateFlags.IsNotCSharpCompatible) != 0; + } + set { + state = value ? state | StateFlags.IsNotCSharpCompatible : state & ~StateFlags.IsNotCSharpCompatible; + } + } + public bool IsPrivate { get { return (modifiers & Modifiers.PRIVATE) != 0; } } @@ -1061,15 +1077,28 @@ namespace Mono.CSharp { public abstract List ResolveMissingDependencies (); - protected virtual bool IsNotCLSCompliant () + protected virtual bool IsNotCLSCompliant (out bool attrValue) { - return MemberDefinition.IsNotCLSCompliant (); + var cls = MemberDefinition.CLSAttributeValue; + attrValue = cls ?? false; + return cls == false; + } + + public virtual string GetSignatureForDocumentation () + { + return DeclaringType.GetSignatureForDocumentation () + "." + Name; } public virtual string GetSignatureForError () { var bf = MemberDefinition as Property.BackingField; - var name = bf == null ? Name : bf.OriginalName; + string name; + if (bf == null) { + name = Name; + } else { + name = bf.OriginalProperty.MemberName.Name; + } + return DeclaringType.GetSignatureForError () + "." + name; } @@ -1086,32 +1115,32 @@ namespace Mono.CSharp { } // - // Is this member accessible from invocationType + // Is this member accessible from invocation context // - public bool IsAccessible (TypeSpec invocationType) + public bool IsAccessible (IMemberContext ctx) { var ma = Modifiers & Modifiers.AccessibilityMask; if (ma == Modifiers.PUBLIC) return true; var parentType = /* this as TypeSpec ?? */ DeclaringType; + var ctype = ctx.CurrentType; - // 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.PRIVATE) { + if (ctype == null) + return false; + // + // It's only accessible to the current class or children + // + if (parentType.MemberDefinition == ctype.MemberDefinition) + return true; + + return TypeManager.IsNestedChildOf (ctype, parentType.MemberDefinition); + } if ((ma & Modifiers.INTERNAL) != 0) { bool b; - var assembly = invocationType == InternalType.FakeInternalType ? - RootContext.ToplevelTypes.DeclaringAssembly : - invocationType.MemberDefinition.DeclaringAssembly; + var assembly = ctype == null ? ctx.Module.DeclaringAssembly : ctype.MemberDefinition.DeclaringAssembly; if (parentType == null) { b = ((ITypeDefinition) MemberDefinition).IsInternalAsPublic (assembly); @@ -1123,11 +1152,18 @@ namespace Mono.CSharp { return b; } - // PROTECTED - if (!TypeManager.IsNestedFamilyAccessible (invocationType, parentType)) - return false; + // + // Checks whether `ctype' is a subclass or nested child of `parentType'. + // + while (ctype != null) { + if (TypeManager.IsFamilyAccessible (ctype, parentType)) + return true; - return true; + // Handle nested types. + ctype = ctype.DeclaringType; // TODO: Untested ??? + } + + return false; } // @@ -1138,14 +1174,16 @@ 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 { - compliant = ((ITypeDefinition) MemberDefinition).DeclaringAssembly.IsCLSCompliant; + if (!compliant) { + if (DeclaringType != null) { + compliant = DeclaringType.IsCLSCompliant (); + } else { + compliant = ((ITypeDefinition) MemberDefinition).DeclaringAssembly.IsCLSCompliant; + } } if (compliant) @@ -1155,7 +1193,7 @@ namespace Mono.CSharp { return (state & StateFlags.CLSCompliant) != 0; } - public bool IsConditionallyExcluded (Location loc) + public bool IsConditionallyExcluded (IMemberContext ctx, Location loc) { if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0) return false; @@ -1164,9 +1202,18 @@ namespace Mono.CSharp { if (conditions == null) return false; - foreach (var condition in conditions) { - if (loc.CompilationUnit.IsConditionalDefined (condition)) - return false; + var m = ctx.CurrentMemberDefinition; + CompilationSourceFile unit = null; + while (m != null && unit == null) { + unit = m as CompilationSourceFile; + m = m.Parent; + } + + if (unit != null) { + foreach (var condition in conditions) { + if (unit.IsConditionalDefined (condition)) + return false; + } } return true; @@ -1184,12 +1231,12 @@ namespace Mono.CSharp { // public interface IMemberDefinition { + bool? CLSAttributeValue { get; } string Name { get; } bool IsImported { get; } string[] ConditionalConditions (); ObsoleteAttribute GetAttributeObsolete (); - bool IsNotCLSCompliant (); void SetIsAssigned (); void SetIsUsed (); } @@ -1203,297 +1250,4 @@ namespace Mono.CSharp { { TypeSpec MemberType { get; } } - - // - // Base type container declaration. It exists to handle partial types - // which share same definition (PartialContainer) but have different - // resolve scopes - // - public abstract class DeclSpace : MemberCore { - /// - /// This points to the actual definition that is being - /// created with System.Reflection.Emit - /// - public TypeBuilder TypeBuilder; - - // - // This is the namespace in which this typecontainer - // was declared. We use this to resolve names. - // - public NamespaceEntry NamespaceEntry; - - public readonly string Basename; - - protected Dictionary defined_names; - - public TypeContainer PartialContainer; - - protected readonly bool is_generic; - readonly int count_type_params; - protected TypeParameter[] type_params; - TypeParameter[] type_param_list; - - // - // Whether we are Generic - // - public bool IsGeneric { - get { - if (is_generic) - return true; - else if (Parent != null) - return Parent.IsGeneric; - else - return false; - } - } - - static string[] attribute_targets = new string [] { "type" }; - - public DeclSpace (NamespaceEntry ns, DeclSpace parent, MemberName name, - Attributes attrs) - : base (parent, name, attrs) - { - NamespaceEntry = ns; - Basename = name.Basename; - defined_names = new Dictionary (); - PartialContainer = null; - if (name.TypeArguments != null) { - is_generic = true; - count_type_params = name.TypeArguments.Count; - } - if (parent != null) - count_type_params += parent.count_type_params; - } - - /// - /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts - /// - protected virtual bool AddToContainer (MemberCore symbol, string name) - { - MemberCore mc; - if (!defined_names.TryGetValue (name, out mc)) { - defined_names.Add (name, symbol); - return true; - } - - if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) - return true; - - if (symbol.EnableOverloadChecks (mc)) - return true; - - InterfaceMemberBase im = mc as InterfaceMemberBase; - if (im != null && im.IsExplicitImpl) - return true; - - Report.SymbolRelatedToPreviousError (mc); - if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) { - Error_MissingPartialModifier (symbol); - return false; - } - - if (this is ModuleContainer) { - Report.Error (101, symbol.Location, - "The namespace `{0}' already contains a definition for `{1}'", - ((DeclSpace)symbol).NamespaceEntry.GetSignatureForError (), symbol.MemberName.Name); - } else if (symbol is TypeParameter) { - Report.Error (692, symbol.Location, - "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); - } else { - Report.Error (102, symbol.Location, - "The type `{0}' already contains a definition for `{1}'", - GetSignatureForError (), symbol.MemberName.Name); - } - - return false; - } - - protected void RemoveFromContainer (string name) - { - defined_names.Remove (name); - } - - /// - /// Returns the MemberCore associated with a given name in the declaration - /// space. It doesn't return method based symbols !! - /// - /// - public MemberCore GetDefinition (string name) - { - MemberCore mc = null; - defined_names.TryGetValue (name, out mc); - return mc; - } - - // - // root_types contains all the types. All TopLevel types - // hence have a parent that points to `root_types', that is - // why there is a non-obvious test down here. - // - public bool IsTopLevel { - get { return (Parent != null && Parent.Parent == null); } - } - - public virtual bool IsUnmanagedType () - { - return false; - } - - protected virtual TypeAttributes TypeAttr { - get { return Module.DefaultCharSetType; } - } - - /// - /// Should be overriten by the appropriate declaration space - /// - public abstract void DefineType (); - - protected void Error_MissingPartialModifier (MemberCore type) - { - Report.Error (260, type.Location, - "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists", - type.GetSignatureForError ()); - } - - public override string GetSignatureForError () - { - return MemberName.GetSignatureForError (); - } - - TypeParameter[] initialize_type_params () - { - if (type_param_list != null) - return type_param_list; - - DeclSpace the_parent = Parent; - if (this is GenericMethod) - the_parent = null; - - var list = new List (); - if (the_parent != null && the_parent.IsGeneric) { - // FIXME: move generics info out of DeclSpace - TypeParameter[] parent_params = the_parent.TypeParameters; - list.AddRange (parent_params); - } - - int count = type_params != null ? type_params.Length : 0; - for (int i = 0; i < count; i++) { - TypeParameter param = type_params [i]; - list.Add (param); - if (Parent.CurrentTypeParameters != null) { - foreach (TypeParameter tp in Parent.CurrentTypeParameters) { - if (tp.Name != param.Name) - continue; - - Report.SymbolRelatedToPreviousError (tp.Location, null); - Report.Warning (693, 3, param.Location, - "Type parameter `{0}' has the same name as the type parameter from outer type `{1}'", - param.Name, Parent.GetSignatureForError ()); - } - } - } - - type_param_list = new TypeParameter [list.Count]; - list.CopyTo (type_param_list, 0); - return type_param_list; - } - - public virtual void SetParameterInfo (List constraints_list) - { - if (!is_generic) { - if (constraints_list != null) { - Report.Error ( - 80, Location, "Constraints are not allowed " + - "on non-generic declarations"); - } - - return; - } - - TypeParameterName[] names = MemberName.TypeArguments.GetDeclarations (); - type_params = new TypeParameter [names.Length]; - - // - // Register all the names - // - for (int i = 0; i < type_params.Length; i++) { - TypeParameterName name = names [i]; - - Constraints constraints = null; - if (constraints_list != null) { - int total = constraints_list.Count; - for (int ii = 0; ii < total; ++ii) { - Constraints constraints_at = (Constraints)constraints_list[ii]; - // TODO: it is used by iterators only - if (constraints_at == null) { - constraints_list.RemoveAt (ii); - --total; - continue; - } - if (constraints_at.TypeParameter.Value == name.Name) { - constraints = constraints_at; - constraints_list.RemoveAt(ii); - break; - } - } - } - - Variance variance = name.Variance; - if (name.Variance != Variance.None && !(this is Delegate || this is Interface)) { - Report.Error (1960, name.Location, "Variant type parameters can only be used with interfaces and delegates"); - variance = Variance.None; - } - - type_params [i] = new TypeParameter ( - Parent, i, new MemberName (name.Name, Location), constraints, name.OptAttributes, variance); - - AddToContainer (type_params [i], name.Name); - } - - if (constraints_list != null && constraints_list.Count > 0) { - foreach (Constraints constraint in constraints_list) { - Report.Error(699, constraint.Location, "`{0}': A constraint references nonexistent type parameter `{1}'", - GetSignatureForError (), constraint.TypeParameter.Value); - } - } - } - - protected TypeParameter[] TypeParameters { - get { - if (!IsGeneric) - throw new InvalidOperationException (); - if ((PartialContainer != null) && (PartialContainer != this)) - return PartialContainer.TypeParameters; - if (type_param_list == null) - initialize_type_params (); - - return type_param_list; - } - } - - public int CountTypeParameters { - get { - return count_type_params; - } - } - - public override string[] ValidAttributeTargets { - get { return attribute_targets; } - } - - protected override bool VerifyClsCompliance () - { - if (!base.VerifyClsCompliance ()) { - return false; - } - - if (type_params != null) { - foreach (TypeParameter tp in type_params) { - tp.VerifyClsCompliance (); - } - } - - return true; - } - } }