public class MemberName {
public readonly string Name;
public readonly MemberName Left;
+ public readonly Location Location;
+
+ bool is_double_colon;
public static readonly MemberName Null = new MemberName ("");
- public MemberName (string name)
+ private MemberName (MemberName left, string name, bool is_double_colon, Location loc)
{
this.Name = name;
+ this.Location = loc;
+ this.is_double_colon = is_double_colon;
+ this.Left = left;
+ }
+
+ public MemberName (string name)
+ : this (null, name, false, Location.Null)
+ {
}
public MemberName (MemberName left, string name)
- : this (name)
+ : this (left, name, false, left != null ? left.Location : Location.Null)
+ {
+ }
+
+ public MemberName (string name, Location loc)
+ : this (null, name, false, loc)
+ {
+ }
+
+ public MemberName (MemberName left, string name, Location loc)
+ : this (left, name, false, loc)
+ {
+ }
+
+ public MemberName (string alias, string name, Location loc)
+ : this (new MemberName (alias), name, true, loc)
{
- this.Left = left;
}
public MemberName (MemberName left, MemberName right)
+ : this (left, right, right.Location)
{
- Name = right.Name;
- Left = (right.Left == null) ? left : new MemberName (left, right.Left);
+ }
+
+ public MemberName (MemberName left, MemberName right, Location loc)
+ : this (null, right.Name, false, 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);
}
static readonly char [] dot_array = { '.' };
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 GetPartialName ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.GetPartialName () + "." + Name;
+ return Left.GetPartialName () + connect + Name;
else
return Name;
}
public string GetTypeName ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left.GetTypeName () + "." + Name;
+ return Left.GetTypeName () + connect + Name;
else
return Name;
}
- public Expression GetTypeExpression (Location loc)
+ public Expression GetTypeExpression ()
{
- if (Left != null) {
- Expression lexpr = Left.GetTypeExpression (loc);
-
- return new MemberAccess (lexpr, Name, loc);
- } else {
- return new SimpleName (Name, loc);
+ if (Left == null)
+ 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, Location);
}
public MemberName Clone ()
{
- if (Left != null)
- return new MemberName (Left.Clone (), Name);
- else
- return new MemberName (Name);
+ MemberName left_clone = Left == null ? null : Left.Clone ();
+ return new MemberName (left_clone, Name, is_double_colon, Location);
}
public string Basename {
- get {
- return Name;
- }
+ get { return Name; }
}
public override string ToString ()
{
+ string connect = is_double_colon ? "::" : ".";
if (Left != null)
- return Left + "." + Name;
+ return Left + connect + Name;
else
return Name;
}
return true;
if (other == null || Name != other.Name)
return false;
+ if (is_double_colon != other.is_double_colon)
+ return false;
#if NET_2_0
if (TypeArguments == null)
return other.TypeArguments == null;
int hash = Name.GetHashCode ();
for (MemberName n = Left; n != null; n = n.Left)
hash ^= n.Name.GetHashCode ();
-
+ if (is_double_colon)
+ hash ^= 0xbadc01d;
#if NET_2_0
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
Excluded_Undetected = 1 << 8, // Conditional attribute has not been detected yet
Excluded = 1 << 9, // Method is conditional
TestMethodDuplication = 1 << 10, // Test for duplication must be performed
- IsUsed = 1 << 11
+ IsUsed = 1 << 11,
+ IsAssigned = 1 << 12 // Field is assigned
}
/// <summary>
/// </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.
/// provides the common foundation for managing those name
/// spaces.
/// </remarks>
- public abstract class DeclSpace : MemberCore, IAlias {
+ public abstract class DeclSpace : MemberCore {
/// <summary>
/// This points to the actual definition that is being
/// created with System.Reflection.Emit
// 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.Name;
if (symbol.MarkForDuplicationCheck () && mc.MarkForDuplicationCheck ())
return true;
- if (this is RootTypes) {
- // TODO: It should not reach this once we merge RecordDecl to AddTo
- return true;
+ Report.SymbolRelatedToPreviousError (mc);
+ if (symbol is PartialContainer || mc is PartialContainer) {
+ Report.Error (260, symbol.Location,
+ "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
+ name);
+ return false;
}
- Report.SymbolRelatedToPreviousError (mc);
- Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'",
- GetSignatureForError (), symbol.MemberName.Name);
+ if (this is RootTypes) {
+ Report.Error (101, symbol.Location,
+ "The namespace `{0}' already contains a definition for `{1}'",
+ ((DeclSpace)symbol).NamespaceEntry.GetSignatureForError (), symbol.MemberName.Name);
+ } else {
+ Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'",
+ GetSignatureForError (), symbol.MemberName.Name);
+ }
return false;
}
// why there is a non-obvious test down here.
//
public bool IsTopLevel {
- get {
- return (Parent != null && Parent.Parent == null);
- }
+ get { return (Parent != null && Parent.Parent == null); }
}
public virtual void CloseType ()
}
protected virtual TypeAttributes TypeAttr {
- get {
- return CodeGen.Module.DefaultCharSetType;
- }
+ get { return CodeGen.Module.DefaultCharSetType; }
}
/// <remarks>
return ~ (~ mAccess | pAccess) == 0;
}
- public static void Error_AmbiguousTypeReference (Location loc, string name, string t1, string t2)
- {
- Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
- name, t1, t2);
- }
-
//
// Return the nested type with name @name. Ensures that the nested type
// is defined if necessary. Do _not_ use this when you have a MemberCache handy.
}
//
- // Public function used to locate types, this can only
- // be used after the ResolveTree function has been invoked.
+ // Public function used to locate types.
//
// Set 'ignore_cs0104' to true if you want to ignore cs0104 errors.
//
}
public override string[] ValidAttributeTargets {
- get {
- return attribute_targets;
- }
+ get { return attribute_targets; }
}
- bool IAlias.IsType {
- get { return true; }
- }
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds)) {
+ return false;
+ }
- string IAlias.Name {
- get { return Name; }
- }
+ IDictionary cache = TypeManager.AllClsTopLevelTypes;
+ string lcase = Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+ if (!cache.Contains (lcase)) {
+ cache.Add (lcase, this);
+ return true;
+ }
- TypeExpr IAlias.ResolveAsType (EmitContext ec)
- {
- if (TypeBuilder == null)
- throw new InvalidOperationException ();
+ 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;
- return new TypeExpression (TypeBuilder, Location);
+ Report.SymbolRelatedToPreviousError ((DeclSpace)val);
+ }
+ Report.Error (3005, Location, "Identifier `{0}' differing only in case is not CLS-compliant", GetSignatureForError ());
+ return true;
}
}