// Licensed under the terms of the GNU GPL
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
//
// TODO: Move the method verification stuff from the class.cs and interface.cs here
//
using System.Globalization;
using System.Reflection.Emit;
using System.Reflection;
+using System.Xml;
namespace Mono.CSharp {
public string GetMethodName ()
{
if (Left != null)
- return Left.GetPartialName () + "." + Name;
+ return Left.GetTypeName () + "." + Name;
else
return Name;
}
- ///
- /// This returns exclusively the name as seen on the source code
- /// it is not the fully qualifed type after resolution
- ///
- public string GetPartialName ()
- {
- string full_name;
- if (TypeArguments != null)
- full_name = Name + "<" + TypeArguments + ">";
- else
- full_name = Name;
- if (Left != null)
- return Left.GetPartialName () + "." + full_name;
- else
- return full_name;
- }
-
public static string MakeName (string name, TypeArguments args)
{
if (args == null)
}
}
- public readonly MemberName MemberName;
+ // Is not readonly because of IndexerName attribute
+ public MemberName MemberName;
/// <summary>
/// Modifier flags that the user specified in the source code
/// </summary>
public readonly Location Location;
+ /// <summary>
+ /// XML documentation comment
+ /// </summary>
+ public string DocComment;
+
+ /// <summary>
+ /// Represents header string for documentation comment
+ /// for each member types.
+ /// </summary>
+ public abstract string DocCommentHeader { get; }
+
[Flags]
public enum Flags {
Obsolete_Undetected = 1, // Obsolete attribute has not been detected yet
/// <summary>
/// Returns true when MemberCore is exposed from assembly.
/// </summary>
- protected bool IsExposedFromAssembly (DeclSpace ds)
+ public bool IsExposedFromAssembly (DeclSpace ds)
{
if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
return false;
bool GetClsCompliantAttributeValue (DeclSpace ds)
{
if (OptAttributes != null) {
- Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ds.EmitContext);
+ Attribute cls_attribute = OptAttributes.Search (
+ TypeManager.cls_compliant_attribute_type, ds.EmitContext);
if (cls_attribute != null) {
caching_flags |= Flags.HasClsCompliantAttribute;
return cls_attribute.GetClsCompliantAttributeValue (ds);
protected abstract void VerifyObsoleteAttribute ();
+ //
+ // Raised (and passed an XmlElement that contains the comment)
+ // when GenerateDocComment is writing documentation expectedly.
+ //
+ internal virtual void OnGenerateDocComment (DeclSpace ds, XmlElement intermediateNode)
+ {
+ }
+
+ //
+ // Returns a string that represents the signature for this
+ // member which should be used in XML documentation.
+ //
+ public virtual string GetDocCommentName (DeclSpace ds)
+ {
+ if (ds == null || this is DeclSpace)
+ return DocCommentHeader + Name;
+ else
+ return String.Concat (DocCommentHeader, ds.Name, ".", Name);
+ }
+
+ //
+ // Generates xml doc comments (if any), and if required,
+ // handle warning report.
+ //
+ internal virtual void GenerateDocComment (DeclSpace ds)
+ {
+ DocUtil.GenerateDocComment (this, ds);
+ }
}
/// <summary>
/// currently defining. We need to lookup members on this
/// instead of the TypeBuilder.
/// </summary>
- public TypeExpr CurrentType;
+ public Type CurrentType;
//
// This is the namespace in which this typecontainer
return type_resolve_ec;
}
- // <summary>
- // 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)
- {
- TypeExpr d = ResolveTypeExpr (e, silent, loc);
- return d == null ? null : d.Type;
- }
-
public Type ResolveNestedType (Type t, Location loc)
{
TypeContainer tc = TypeManager.LookupTypeContainer (t);
else
args = TypeParameters;
- ConstructedType ctype = new ConstructedType (t, args, loc);
- t = ctype.ResolveType (ec);
+ TypeExpr ctype = new ConstructedType (t, args, loc);
+ ctype = ctype.ResolveAsTypeTerminal (ec);
+ if (ctype == null)
+ return null;
+
+ t = ctype.Type;
}
return t;
// Resolves the expression `e' for a type, and will recursively define
// types. This should only be used for resolving base types.
// </summary>
- public TypeExpr ResolveTypeExpr (Expression e, bool silent, Location loc)
+ public TypeExpr ResolveTypeExpr (Expression e, Location loc)
{
if (type_resolve_ec == null)
type_resolve_ec = GetTypeResolveEmitContext (Parent, loc);
else
type_resolve_ec.ContainerType = TypeBuilder;
- return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
+ return e.ResolveAsTypeTerminal (type_resolve_ec);
}
public bool CheckAccessLevel (Type check_type)
return true; // FIXME
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
case TypeAttributes.NotPublic:
- if (TypeBuilder == null)
+ 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;
- //
- // This test should probably use the declaringtype.
- //
+ return true;
+ //
+ // This test should probably use the declaringtype.
+ //
return check_type.Assembly == TypeBuilder.Assembly;
case TypeAttributes.NestedPublic:
caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
if (OptAttributes != null) {
- Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ec);
+ Attribute cls_attribute = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, ec);
if (cls_attribute != null) {
caching_flags |= Flags.HasClsCompliantAttribute;
if (cls_attribute.GetClsCompliantAttributeValue (this)) {
get { return Name; }
}
- TypeExpr IAlias.Type
+ TypeExpr IAlias.ResolveAsType (EmitContext ec)
{
- get {
- if (TypeBuilder == null)
- throw new InvalidOperationException ();
-
- if (CurrentType != null)
- return CurrentType;
+ if (TypeBuilder == null)
+ throw new InvalidOperationException ();
+ if (CurrentType != null)
+ return new TypeExpression (CurrentType, Location);
+ else
return new TypeExpression (TypeBuilder, Location);
- }
}
public override string[] ValidAttributeTargets {
/// This is used when creating the member cache for a class to get all
/// members from the parent class.
/// </summary>
- IMemberContainer ParentContainer {
+ MemberCache ParentCache {
get;
}
public readonly IMemberContainer Container;
protected Hashtable member_hash;
protected Hashtable method_hash;
-
+
/// <summary>
/// Create a new MemberCache for the given IMemberContainer `container'.
/// </summary>
- public MemberCache (IMemberContainer container, bool setup_inherited_interfaces)
+ public MemberCache (IMemberContainer container)
{
this.Container = container;
Timer.IncrementCounter (CounterType.MemberCache);
Timer.StartTimer (TimerType.CacheInit);
-
-
// If we have a parent class (we have a parent class unless we're
// TypeManager.object_type), we deep-copy its MemberCache here.
- if (Container.IsInterface) {
- MemberCache parent;
-
- if (Container.ParentContainer != null)
- parent = Container.ParentContainer.MemberCache;
- else
- parent = null;
- member_hash = SetupCacheForInterface (parent, setup_inherited_interfaces);
- } else if (Container.ParentContainer != null)
- member_hash = SetupCache (Container.ParentContainer.MemberCache);
+ if (Container.ParentCache != null)
+ member_hash = SetupCache (Container.ParentCache);
else
member_hash = new Hashtable ();
Timer.StopTimer (TimerType.CacheInit);
}
+ public MemberCache (Type[] ifaces)
+ {
+ //
+ // The members of this cache all belong to other caches.
+ // So, 'Container' will not be used.
+ //
+ this.Container = null;
+
+ member_hash = new Hashtable ();
+ if (ifaces == null)
+ return;
+
+ foreach (Type itype in ifaces)
+ AddCacheContents (TypeManager.LookupMemberCache (itype));
+ }
+
/// <summary>
/// Bootstrap this member cache by doing a deep-copy of our parent.
/// </summary>
Hashtable SetupCache (MemberCache parent)
{
Hashtable hash = new Hashtable ();
+
if (parent == null)
return hash;
IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
while (it.MoveNext ()) {
hash [it.Key] = ((ArrayList) it.Value).Clone ();
- }
+ }
return hash;
}
-
/// <summary>
- /// Add the contents of `new_hash' to `hash'.
+ /// Add the contents of `cache' to the member_hash.
/// </summary>
- void AddHashtable (Hashtable hash, MemberCache cache)
+ void AddCacheContents (MemberCache cache)
{
- Hashtable new_hash = cache.member_hash;
- IDictionaryEnumerator it = new_hash.GetEnumerator ();
+ IDictionaryEnumerator it = cache.member_hash.GetEnumerator ();
while (it.MoveNext ()) {
- ArrayList list = (ArrayList) hash [it.Key];
+ ArrayList list = (ArrayList) member_hash [it.Key];
if (list == null)
- hash [it.Key] = list = new ArrayList ();
+ member_hash [it.Key] = list = new ArrayList ();
+
+ ArrayList entries = (ArrayList) it.Value;
+ for (int i = entries.Count-1; i >= 0; i--) {
+ CacheEntry entry = (CacheEntry) entries [i];
- foreach (CacheEntry entry in (ArrayList) it.Value) {
if (entry.Container != cache.Container)
break;
list.Add (entry);
}
}
- /// <summary>
- /// Bootstrap the member cache for an interface type.
- /// Type.GetMembers() won't return any inherited members for interface types,
- /// so we need to do this manually. Interfaces also inherit from System.Object.
- /// </summary>
- Hashtable SetupCacheForInterface (MemberCache parent, bool deep_setup)
- {
- Hashtable hash = SetupCache (parent);
-
- if (!deep_setup)
- return hash;
-
- Type [] ifaces = TypeManager.GetInterfaces (Container.Type);
-
- foreach (Type itype in ifaces) {
- IMemberContainer iface_container =
- TypeManager.LookupMemberContainer (itype);
-
- MemberCache iface_cache = iface_container.MemberCache;
-
- AddHashtable (hash, iface_cache);
- }
-
- return hash;
- }
-
/// <summary>
/// Add all members from class `container' to the cache.
/// </summary>
// We need to call AddMembers() with a single member type at a time
// to get the member type part of CacheEntry.EntryType right.
if (!container.IsInterface) {
- AddMembers (MemberTypes.Constructor, container);
- AddMembers (MemberTypes.Field, container);
+ AddMembers (MemberTypes.Constructor, container);
+ AddMembers (MemberTypes.Field, container);
}
AddMembers (MemberTypes.Method, container);
AddMembers (MemberTypes.Property, container);
/// number to speed up the searching process.
/// </summary>
[Flags]
- protected internal enum EntryType {
+ protected enum EntryType {
None = 0x000,
Instance = 0x001,
MaskType = Constructor|Event|Field|Method|Property|NestedType
}
- protected internal struct CacheEntry {
+ protected struct CacheEntry {
public readonly IMemberContainer Container;
public readonly EntryType EntryType;
public readonly MemberInfo Member;
this.Member = member;
this.EntryType = GetEntryType (mt, bf);
}
+
+ public override string ToString ()
+ {
+ return String.Format ("CacheEntry ({0}:{1}:{2})", Container.Name,
+ EntryType, Member);
+ }
}
/// <summary>