public readonly TypeArguments TypeArguments;
public readonly MemberName Left;
+ public readonly Location Location;
+
+ public static readonly MemberName Null = new MemberName ("", Location.Null);
- public static readonly MemberName Null = new MemberName ("");
+ bool is_double_colon;
- public MemberName (string name)
+ private MemberName (MemberName left, string name, bool is_double_colon,
+ TypeArguments args, Location loc)
{
this.Name = name;
+ this.Location = loc;
+ this.is_double_colon = is_double_colon;
+ this.TypeArguments = args;
+ this.Left = left;
}
- public MemberName (string name, TypeArguments args)
- : this (name)
+ public MemberName (string name, TypeArguments args, Location loc)
+ : this (name, loc)
{
this.TypeArguments = args;
}
- public MemberName (MemberName left, string name)
- : this (left, name, null)
+ public MemberName (string name, Location loc)
{
+ this.Name = name;
+ this.Location = loc;
}
- public MemberName (MemberName left, string name, TypeArguments args)
- : this (name, args)
+ public MemberName (MemberName left, string name, Location loc)
+ : this (name, loc)
{
this.Left = left;
}
+ public MemberName (MemberName left, string name, TypeArguments args, Location loc)
+ : this (name, args, loc)
+ {
+ this.Left = left;
+ }
+
+ public MemberName (string alias, string name, Location loc)
+ : this (new MemberName (alias, loc), name, true, null, loc)
+ {
+ }
+
public MemberName (MemberName left, MemberName right)
- : this (left, right.Name, right.TypeArguments)
+ : this (left, right, left != null ? left.Location : right != null ? right.Location : Location.Null)
+ {
+ }
+
+ public MemberName (MemberName left, MemberName right, Location loc)
+ : this (null, right.Name, false, right.TypeArguments, loc)
{
- Name = right.Name;
- Left = (right.Left == null) ? left : new MemberName (left, right.Left);
- TypeArguments = right.TypeArguments;
+ 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);
}
static readonly char [] dot_array = { '.' };
- public static MemberName FromDotted (string name)
+ public static MemberName FromDotted (string name, Location loc)
{
string [] elements = name.Split (dot_array);
int count = elements.Length;
int i = 0;
- MemberName n = new MemberName (elements [i++]);
+ MemberName n = new MemberName (elements [i++], loc);
while (i < count)
- n = new MemberName (n, elements [i++]);
+ n = new MemberName (n, elements [i++], loc);
return n;
}
public string GetName ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.GetName () + "." + Name;
+ return Left.GetName () + connect + Name;
else
return Name;
}
public string GetName (bool is_generic)
{
string name = is_generic ? Basename : Name;
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.GetName (is_generic) + "." + name;
+ return Left.GetName (is_generic) + connect + name;
else
return name;
}
public string MethodName {
get {
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.FullName + "." + Name;
+ return Left.FullName + connect + Name;
else
return Name;
}
public string GetTypeName ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.GetTypeName () + "." +
+ return Left.GetTypeName () + connect +
MakeName (Name, TypeArguments);
else
return MakeName (Name, TypeArguments);
return true;
}
- public Expression GetTypeExpression (Location loc)
+ public Expression GetTypeExpression ()
{
if (IsUnbound) {
- if (!CheckUnbound (loc))
+ if (!CheckUnbound (Location))
return null;
- return new UnboundTypeExpression (this, loc);
+ return new UnboundTypeExpression (this, Location);
}
- if (Left != null) {
- Expression lexpr = Left.GetTypeExpression (loc);
-
- return new MemberAccess (lexpr, Name, TypeArguments, loc);
- } else {
+ if (Left == null) {
if (TypeArguments != null)
- return new SimpleName (Basename, TypeArguments, loc);
+ return new SimpleName (Basename, TypeArguments, Location);
else
- return new SimpleName (Name, loc);
+ return new SimpleName (Name, Location);
}
+
+ 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, Location);
+ }
+
+ Expression lexpr = Left.GetTypeExpression ();
+ return new MemberAccess (lexpr, Name, TypeArguments, Location);
}
public MemberName Clone ()
{
- if (Left != null)
- return new MemberName (Left.Clone (), Name, TypeArguments);
- else
- return new MemberName (Name, TypeArguments);
+ MemberName left_clone = Left == null ? null : Left.Clone ();
+ return new MemberName (left_clone, Name, is_double_colon, TypeArguments, Location);
}
public string Basename {
public override string ToString ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.FullName + "." + FullName;
+ return Left.FullName + connect + FullName;
else
return FullName;
}
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))
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;
/// <summary>
/// Location where this declaration happens
/// </summary>
- public readonly Location Location;
+ public Location Location {
+ get { return member_name.Location; }
+ }
/// <summary>
/// XML documentation comment
/// </summary>
internal Flags caching_flags;
- public MemberCore (TypeContainer parent, MemberName name, Attributes attrs,
- Location loc)
+ public MemberCore (TypeContainer parent, MemberName name, Attributes attrs)
: base (attrs)
{
if (parent is PartialContainer && !(this is PartialContainer))
Parent = parent;
member_name = name;
- Location = loc;
caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
}
cached_name = null;
}
- /// <summary>
- /// Tests presence of ObsoleteAttribute and report proper error
- /// </summary>
- protected void CheckUsageOfObsoleteAttribute (Type type)
- {
- if (type == null)
- return;
-
- ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
- if (obsolete_attr == null)
- return;
-
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, Location);
- }
-
public abstract bool Define ();
//
/// </summary>
public virtual void Emit ()
{
- // Hack with Parent == null is for EnumMember
- if (Parent == null || (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent) == null))
- VerifyObsoleteAttribute ();
-
if (!RootContext.VerifyClsCompliance)
return;
VerifyClsCompliance (Parent);
}
+ public virtual EmitContext EmitContext
+ {
+ get {
+ return Parent.EmitContext;
+ }
+ }
+
public bool InUnsafe {
get {
return ((ModFlags & Modifiers.UNSAFE) != 0) || Parent.UnsafeContext;
/// <summary>
/// Returns instance of ObsoleteAttribute for this MemberCore
/// </summary>
- public ObsoleteAttribute GetObsoleteAttribute (DeclSpace ds)
+ public virtual ObsoleteAttribute GetObsoleteAttribute ()
{
// ((flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0) is slower, but why ?
if ((caching_flags & Flags.Obsolete_Undetected) == 0 && (caching_flags & Flags.Obsolete) == 0) {
return null;
Attribute obsolete_attr = OptAttributes.Search (
- TypeManager.obsolete_attribute_type, ds.EmitContext);
+ TypeManager.obsolete_attribute_type, EmitContext);
if (obsolete_attr == null)
return null;
- ObsoleteAttribute obsolete = obsolete_attr.GetObsoleteAttribute (ds.EmitContext);
+ ObsoleteAttribute obsolete = obsolete_attr.GetObsoleteAttribute (EmitContext);
if (obsolete == null)
return null;
return obsolete;
}
+ /// <summary>
+ /// Checks for ObsoleteAttribute presence. It's used for testing of all non-types elements
+ /// </summary>
+ public virtual void CheckObsoleteness (Location loc)
+ {
+ if (Parent != null)
+ Parent.CheckObsoleteness (loc);
+
+ ObsoleteAttribute oa = GetObsoleteAttribute ();
+ if (oa == null) {
+ return;
+ }
+
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ }
+
+ protected void CheckObsoleteType (Expression type)
+ {
+ ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type.Type);
+ if (obsolete_attr == null)
+ return;
+
+ if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute () != null)
+ return;
+
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (type.Type), type.Location);
+ }
+
/// <summary>
/// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
/// </summary>
return true;
}
- protected abstract void VerifyObsoleteAttribute ();
-
//
// Raised (and passed an XmlElement that contains the comment)
// when GenerateDocComment is writing documentation expectedly.
// The emit context for toplevel objects.
protected EmitContext ec;
- public EmitContext EmitContext {
- get { return ec; }
+ public override EmitContext EmitContext {
+ get {
+ return ec;
+ }
}
//
static string[] attribute_targets = new string [] { "type" };
public DeclSpace (NamespaceEntry ns, TypeContainer parent, MemberName name,
- Attributes attrs, Location l)
- : base (parent, name, attrs, l)
+ Attributes attrs)
+ : base (parent, name, attrs)
{
NamespaceEntry = ns;
Basename = name.Basename;
/// </summary>
protected bool AddToContainer (MemberCore symbol, string name)
{
- if (name == Basename && !(this is Interface) && !(this is Enum)) {
+ if (name == MemberName.Name && !(this is Interface) && !(this is Enum)) {
if (symbol is TypeParameter)
Report.Error (694, symbol.Location,
"Type parameter `{0}' has same name as " +
protected TypeExpr ResolveBaseTypeExpr (Expression e, bool silent, Location loc)
{
TypeResolveEmitContext.loc = loc;
- TypeResolveEmitContext.ContainerType = TypeBuilder;
TypeResolveEmitContext.ResolvingTypeTree = true;
if (this is GenericMethod)
TypeResolveEmitContext.ContainerType = Parent.TypeBuilder;
- else
- TypeResolveEmitContext.ContainerType = TypeBuilder;
-
return e.ResolveAsTypeTerminal (TypeResolveEmitContext);
}
public override string[] ValidAttributeTargets {
get { return attribute_targets; }
}
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds)) {
+ return false;
+ }
+
+ IDictionary cache = TypeManager.AllClsTopLevelTypes;
+ string lcase = Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+ if (!cache.Contains (lcase)) {
+ cache.Add (lcase, this);
+ return true;
+ }
+
+ object val = cache [lcase];
+ if (val == null) {
+ Type t = AttributeTester.GetImportedIgnoreCaseClsType (lcase);
+ if (t == null)
+ return true;
+ Report.SymbolRelatedToPreviousError (t);
+ }
+ else {
+ if (val is PartialContainer)
+ return true;
+
+ Report.SymbolRelatedToPreviousError ((DeclSpace)val);
+ }
+ Report.Warning (3005, Location, "Identifier `{0}' differing only in case is not CLS-compliant", GetSignatureForError ());
+ return true;
+ }
}
/// <summary>
// Because the MemberCache holds members from this class and all the base classes,
// we can avoid tons of reflection stuff.
//
- public MemberInfo FindMemberToOverride (Type invocationType, string name, Type [] paramTypes, bool is_property)
+ public MemberInfo FindMemberToOverride (Type invocationType, string name, Type [] paramTypes, GenericMethod genericMethod, bool is_property)
{
ArrayList applicable;
if (method_hash != null && !is_property)
if (!TypeManager.IsEqual (paramTypes [j], cmpAttrs [j]))
goto next;
}
-
+
+ //
+ // check generic arguments for methods
+ //
+ if (mi != null) {
+ Type [] cmpGenArgs = mi.GetGenericArguments ();
+ if (genericMethod != null && cmpGenArgs.Length > 0) {
+ if (genericMethod.TypeParameters.Length != cmpGenArgs.Length)
+ goto next;
+ }
+ else if (! (genericMethod == null && cmpGenArgs.Length == 0))
+ goto next;
+ }
+
//
// get one of the methods because this has the visibility info.
//