using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
-using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Mono.CompilerServices.SymbolWriter;
#if NET_2_1
using XmlElement = System.Object;
namespace Mono.CSharp
{
-
- public interface ITypesContainer
+ //
+ // General types container, used as a base class for all constructs which can hold types
+ //
+ public abstract class TypeContainer : MemberCore
{
- Location Location { get; }
- MemberName MemberName { get; }
+ public readonly MemberKind Kind;
+ public readonly string Basename;
+
+ protected List<TypeContainer> containers;
+
+ TypeDefinition main_container;
+
+ protected Dictionary<string, MemberCore> defined_names;
+
+ protected bool is_defined;
+
+ public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+ : base (parent, name, attrs)
+ {
+ this.Kind = kind;
+ if (name != null)
+ this.Basename = name.Basename;
+
+ defined_names = new Dictionary<string, MemberCore> ();
+ }
+
+ public override TypeSpec CurrentType {
+ get {
+ return null;
+ }
+ }
+
+ public Dictionary<string, MemberCore> DefinedNames {
+ get {
+ return defined_names;
+ }
+ }
+
+ public TypeDefinition PartialContainer {
+ get {
+ return main_container;
+ }
+ protected set {
+ main_container = value;
+ }
+ }
+
+ public IList<TypeContainer> Containers {
+ get {
+ return containers;
+ }
+ }
+
+ //
+ // Any unattached attributes during parsing get added here. User
+ // by FULL_AST mode
+ //
+ public Attributes UnattachedAttributes {
+ get; set;
+ }
+
+ public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
+ {
+ containers.Add (c);
+ }
+
+ public virtual void AddPartial (TypeDefinition next_part)
+ {
+ MemberCore mc;
+ (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
+
+ AddPartial (next_part, mc as TypeDefinition);
+ }
+
+ protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
+ {
+ next_part.ModFlags |= Modifiers.PARTIAL;
+
+ if (existing == null) {
+ AddTypeContainer (next_part);
+ return;
+ }
+
+ if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
+ if (existing.Kind != next_part.Kind) {
+ AddTypeContainer (next_part);
+ } else {
+ Report.SymbolRelatedToPreviousError (next_part);
+ Error_MissingPartialModifier (existing);
+ }
+
+ return;
+ }
+
+ if (existing.Kind != next_part.Kind) {
+ Report.SymbolRelatedToPreviousError (existing);
+ Report.Error (261, next_part.Location,
+ "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
+ next_part.GetSignatureForError ());
+ }
+
+ if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
+ ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
+ (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
+ Report.SymbolRelatedToPreviousError (existing);
+ Report.Error (262, next_part.Location,
+ "Partial declarations of `{0}' have conflicting accessibility modifiers",
+ next_part.GetSignatureForError ());
+ }
+
+ var tc_names = existing.CurrentTypeParameters;
+ if (tc_names != null) {
+ for (int i = 0; i < tc_names.Count; ++i) {
+ var tp = next_part.MemberName.TypeParameters[i];
+ if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
+ Report.SymbolRelatedToPreviousError (existing.Location, "");
+ Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
+ next_part.GetSignatureForError ());
+ break;
+ }
+
+ if (tc_names[i].Variance != tp.Variance) {
+ Report.SymbolRelatedToPreviousError (existing.Location, "");
+ Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
+ next_part.GetSignatureForError ());
+ break;
+ }
+ }
+ }
+
+ if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+ } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+ existing.ModFlags |= next_part.ModFlags;
+ } else {
+ existing.ModFlags |= next_part.ModFlags;
+ }
+
+ existing.Definition.Modifiers = existing.ModFlags;
+
+ if (next_part.attributes != null) {
+ if (existing.attributes == null)
+ existing.attributes = next_part.attributes;
+ else
+ existing.attributes.AddAttributes (next_part.attributes.Attrs);
+ }
+
+ next_part.PartialContainer = existing;
+
+ if (containers == null)
+ containers = new List<TypeContainer> ();
+
+ containers.Add (next_part);
+ }
+
+ public virtual void AddTypeContainer (TypeContainer tc)
+ {
+ containers.Add (tc);
+
+ var tparams = tc.MemberName.TypeParameters;
+ if (tparams != null && tc.PartialContainer != null) {
+ var td = (TypeDefinition) tc;
+ for (int i = 0; i < tparams.Count; ++i) {
+ var tp = tparams[i];
+ if (tp.MemberName == null)
+ continue;
+
+ td.AddNameToContainer (tp, tp.Name);
+ }
+ }
+ }
+
+ public virtual void CloseContainer ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.CloseContainer ();
+ }
+ }
+ }
+
+ public virtual void CreateMetadataName (StringBuilder sb)
+ {
+ if (Parent != null && Parent.MemberName != null)
+ Parent.CreateMetadataName (sb);
+
+ MemberName.CreateMetadataName (sb);
+ }
+
+ public virtual bool CreateContainer ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.CreateContainer ();
+ }
+ }
+
+ return true;
+ }
+
+ public override bool Define ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.Define ();
+ }
+ }
+
+ // Release cache used by parser only
+ if (Module.Evaluator == null) {
+ defined_names = null;
+ } else {
+ defined_names.Clear ();
+ }
+
+ return true;
+ }
+
+ public virtual void PrepareEmit ()
+ {
+ if (containers != null) {
+ foreach (var t in containers) {
+ try {
+ t.PrepareEmit ();
+ } catch (Exception e) {
+ if (MemberName == MemberName.Null)
+ throw;
+
+ throw new InternalErrorException (t, e);
+ }
+ }
+ }
+ }
+
+ public virtual bool DefineContainer ()
+ {
+ if (is_defined)
+ return true;
+
+ is_defined = true;
+
+ DoDefineContainer ();
+
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ try {
+ tc.DefineContainer ();
+ } catch (Exception e) {
+ if (MemberName == MemberName.Null)
+ throw;
+
+ throw new InternalErrorException (tc, e);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public virtual void ExpandBaseInterfaces ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.ExpandBaseInterfaces ();
+ }
+ }
+ }
+
+ protected virtual void DefineNamespace ()
+ {
+ if (containers != null) {
+ foreach (var tc in containers) {
+ try {
+ tc.DefineNamespace ();
+ } catch (Exception e) {
+ throw new InternalErrorException (tc, e);
+ }
+ }
+ }
+ }
+
+ protected virtual void DoDefineContainer ()
+ {
+ }
+
+ public virtual void EmitContainer ()
+ {
+ if (containers != null) {
+ for (int i = 0; i < containers.Count; ++i)
+ containers[i].EmitContainer ();
+ }
+ }
+
+ 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 GetSignatureForDocumentation ()
+ {
+ if (Parent != null && Parent.MemberName != null)
+ return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
+
+ return MemberName.GetSignatureForDocumentation ();
+ }
+
+ public override string GetSignatureForError ()
+ {
+ if (Parent != null && Parent.MemberName != null)
+ return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
+
+ return MemberName.GetSignatureForError ();
+ }
+
+ public string GetSignatureForMetadata ()
+ {
+#if STATIC
+ if (Parent is TypeDefinition) {
+ return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
+ }
+
+ var sb = new StringBuilder ();
+ CreateMetadataName (sb);
+ return sb.ToString ();
+#else
+ throw new NotImplementedException ();
+#endif
+ }
+
+ public virtual void RemoveContainer (TypeContainer cont)
+ {
+ if (containers != null)
+ containers.Remove (cont);
+
+ var tc = Parent == Module ? Module : this;
+ tc.defined_names.Remove (cont.Basename);
+ }
+
+ public virtual void VerifyMembers ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers)
+ tc.VerifyMembers ();
+ }
+ }
+
+ public override void WriteDebugSymbol (MonoSymbolFile file)
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.WriteDebugSymbol (file);
+ }
+ }
+ }
}
- /// <summary>
- /// This is the base class for structs and classes.
- /// </summary>
- public abstract class TypeContainer : MemberCore, ITypeDefinition, ITypesContainer
+ public abstract class TypeDefinition : TypeContainer, ITypeDefinition
{
//
// Different context is needed when resolving type container base
HasStaticFieldInitializer = 1 << 2
}
-
- // Whether this is a struct, class or interface
- public readonly MemberKind Kind;
-
- // Holds a list of classes and structures
- protected List<TypeContainer> types;
-
- List<MemberCore> ordered_explicit_member_list;
- List<MemberCore> ordered_member_list;
-
- // Holds the list of properties
- List<MemberCore> properties;
-
- // Holds the list of constructors
- protected List<Constructor> instance_constructors;
-
- // Holds the list of fields
- protected List<FieldBase> fields;
+ readonly List<MemberCore> members;
// Holds a list of fields that have initializers
protected List<FieldInitializer> initialized_fields;
// Holds a list of static fields that have initializers
protected List<FieldInitializer> initialized_static_fields;
- // Holds the list of constants
- protected List<MemberCore> constants;
-
- // Holds the methods.
- List<MemberCore> methods;
-
- // Holds the events
- protected List<MemberCore> events;
-
- // Holds the indexers
- List<MemberCore> indexers;
-
- // Holds the operators
- List<MemberCore> operators;
-
- // Holds the compiler generated classes
- protected List<CompilerGeneratedClass> compiler_generated;
-
Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
- protected Dictionary<string, MemberCore> defined_names;
Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
- //
- // Pointers to the default constructor and the default static constructor
- //
- protected Constructor default_constructor;
- protected Constructor default_static_constructor;
-
//
// Points to the first non-static field added to the container.
//
// This is an arbitrary choice. We are interested in looking at _some_ non-static field,
// and the first one's as good as any.
//
- FieldBase first_nonstatic_field;
+ protected FieldBase first_nonstatic_field;
//
// This one is computed after we can distinguish interfaces
protected List<FullNamedExpression> type_bases;
- bool members_defined;
- bool members_defined_ok;
- bool type_defined;
-
- TypeContainer InTransit;
- public TypeContainer PartialContainer;
+ TypeDefinition InTransit;
public TypeBuilder TypeBuilder;
GenericTypeParameterBuilder[] all_tp_builders;
//
TypeParameters all_type_parameters;
- //
- // This is the namespace in which this typecontainer
- // was declared. We use this to resolve names.
- //
- public NamespaceContainer NamespaceEntry;
-
- public readonly string Basename;
public const string DefaultIndexerName = "Item";
- private bool seen_normal_indexers = false;
- private string indexer_name = DefaultIndexerName;
+ bool has_normal_indexers;
+ string indexer_name;
protected bool requires_delayed_unmanagedtype_check;
bool error;
+ bool members_defined;
+ bool members_defined_ok;
+ protected bool has_static_constructor;
private CachedMethods cached_method;
protected TypeSpec spec;
TypeSpec current_type;
- List<TypeContainer> partial_parts;
-
public int DynamicSitesCounter;
+ public int AnonymousMethodsCounter;
+ public int MethodGroupsCounter;
static readonly string[] attribute_targets = new string[] { "type" };
/// </remarks>
PendingImplementation pending;
- public TypeContainer (NamespaceContainer ns, TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
- : base (parent, name, attrs)
+ public TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+ : base (parent, name, attrs, kind)
{
- if (parent != null && parent.NamespaceEntry != ns)
- throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
-
- this.Kind = kind;
- this.PartialContainer = this;
- this.Basename = name.Basename;
- this.NamespaceEntry = ns;
-
- defined_names = new Dictionary<string, MemberCore> ();
+ PartialContainer = this;
+ members = new List<MemberCore> ();
}
#region Properties
IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
get {
- return Module.DeclaringAssembly;
+ return Module.DeclaringAssembly;
+ }
+ }
+
+ public TypeSpec Definition {
+ get {
+ return spec;
+ }
+ }
+
+ public bool HasMembersDefined {
+ get {
+ return members_defined;
+ }
+ }
+
+ public bool HasInstanceConstructor {
+ get {
+ return (caching_flags & Flags.HasInstanceConstructor) != 0;
+ }
+ set {
+ caching_flags |= Flags.HasInstanceConstructor;
+ }
+ }
+
+ // Indicated whether container has StructLayout attribute set Explicit
+ public bool HasExplicitLayout {
+ get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
+ set { caching_flags |= Flags.HasExplicitLayout; }
+ }
+
+ public bool HasOperators {
+ get {
+ return (caching_flags & Flags.HasUserOperators) != 0;
+ }
+ set {
+ caching_flags |= Flags.HasUserOperators;
+ }
+ }
+
+ public bool HasStructLayout {
+ get { return (caching_flags & Flags.HasStructLayout) != 0; }
+ set { caching_flags |= Flags.HasStructLayout; }
+ }
+
+ public TypeSpec[] Interfaces {
+ get {
+ return iface_exprs;
+ }
+ }
+
+ public bool IsGenericOrParentIsGeneric {
+ get {
+ return all_type_parameters != null;
+ }
+ }
+
+ public bool IsTopLevel {
+ get {
+ return !(Parent is TypeDefinition);
}
}
- public TypeSpec Definition {
+ public bool IsPartial {
get {
- return spec;
+ return (ModFlags & Modifiers.PARTIAL) != 0;
}
}
- public bool HasMembersDefined {
+ bool ITypeDefinition.IsTypeForwarder {
get {
- return members_defined;
+ return false;
}
}
- public TypeSpec[] Interfaces {
+ //
+ // Returns true for secondary partial containers
+ //
+ bool IsPartialPart {
get {
- return iface_exprs;
+ return PartialContainer != this;
}
}
- public bool IsGenericOrParentIsGeneric {
+ public MemberCache MemberCache {
get {
- return all_type_parameters != null;
+ return spec.MemberCache;
}
}
- //
- // 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 {
+ public List<MemberCore> Members {
get {
- return Parent != null && Parent.Parent == null;
+ return members;
}
}
string ITypeDefinition.Namespace {
get {
- return NamespaceEntry.NS.MemberName.GetSignatureForError ();
+ var p = Parent;
+ while (p.Kind != MemberKind.Namespace)
+ p = p.Parent;
+
+ return p.MemberName == null ? null : p.GetSignatureForError ();
}
}
visitor.Visit (this);
}
- public bool AddMember (MemberCore symbol)
+ public void AddMember (MemberCore symbol)
{
- return AddToContainer (symbol, symbol.MemberName.Basename);
- }
+ if (symbol.MemberName.ExplicitInterface != null) {
+ if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
+ Report.Error (541, symbol.Location,
+ "`{0}': explicit interface declaration can only be declared in a class or struct",
+ symbol.GetSignatureForError ());
+ }
+ }
- public bool AddMember (MemberCore symbol, string name)
- {
- return AddToContainer (symbol, name);
+ AddNameToContainer (symbol, symbol.MemberName.Basename);
+ members.Add (symbol);
}
- protected virtual bool AddMemberType (TypeContainer ds)
+ public override void AddTypeContainer (TypeContainer tc)
{
- return AddToContainer (ds, ds.Basename);
- }
+ AddNameToContainer (tc, tc.Basename);
- protected virtual void RemoveMemberType (TypeContainer ds)
- {
- defined_names.Remove (ds.Basename);
+ if (containers == null)
+ containers = new List<TypeContainer> ();
+
+ members.Add (tc);
+ base.AddTypeContainer (tc);
}
- public void AddConstant (Const constant)
+ public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
{
- if (!AddMember (constant))
- return;
+ members.Add (c);
- if (constants == null)
- constants = new List<MemberCore> ();
-
- constants.Add (constant);
+ if (containers == null)
+ containers = new List<TypeContainer> ();
+
+ base.AddCompilerGeneratedClass (c);
}
//
// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
//
- protected virtual bool AddToContainer (MemberCore symbol, string name)
+ public virtual void AddNameToContainer (MemberCore symbol, string name)
{
+ if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
+ return;
+
MemberCore mc;
- if (!defined_names.TryGetValue (name, out mc)) {
- defined_names.Add (name, symbol);
- return true;
+ if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
+ PartialContainer.defined_names.Add (name, symbol);
+ return;
}
- if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
- return true;
-
if (symbol.EnableOverloadChecks (mc))
- return true;
+ return;
InterfaceMemberBase im = mc as InterfaceMemberBase;
if (im != null && im.IsExplicitImpl)
- return true;
+ return;
Report.SymbolRelatedToPreviousError (mc);
if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
Error_MissingPartialModifier (symbol);
- return false;
+ return;
}
if (symbol is TypeParameter) {
GetSignatureForError (), name);
}
- return false;
- }
-
- public TypeContainer AddTypeContainer (TypeContainer tc)
- {
- if (!AddMemberType (tc))
- return tc;
-
- var tparams = tc.MemberName.TypeParameters;
- if (tparams != null) {
- for (int i = 0; i < tparams.Count; ++i) {
- var tp = tparams[i];
- if (tp.MemberName == null)
- continue;
-
- tc.AddMember (tp, tp.Name);
- }
- }
-
- if (types == null)
- types = new List<TypeContainer> ();
-
- types.Add (tc);
- return tc;
- }
-
- public virtual TypeContainer AddPartial (TypeContainer next_part)
- {
- return AddPartial (next_part, next_part.Basename);
- }
-
- protected TypeContainer AddPartial (TypeContainer next_part, string name)
- {
- next_part.ModFlags |= Modifiers.PARTIAL;
- TypeContainer tc = GetDefinition (name) as TypeContainer;
- if (tc == null)
- return AddTypeContainer (next_part);
-
- if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
- Report.SymbolRelatedToPreviousError (next_part);
- Error_MissingPartialModifier (tc);
- }
-
- if (tc.Kind != next_part.Kind) {
- Report.SymbolRelatedToPreviousError (tc);
- Report.Error (261, next_part.Location,
- "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
- next_part.GetSignatureForError ());
- }
-
- if ((tc.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
- ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
- (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
- Report.SymbolRelatedToPreviousError (tc);
- Report.Error (262, next_part.Location,
- "Partial declarations of `{0}' have conflicting accessibility modifiers",
- next_part.GetSignatureForError ());
- }
-
- var tc_names = tc.CurrentTypeParameters;
- if (tc_names != null) {
- for (int i = 0; i < tc_names.Count; ++i) {
- var tp = next_part.MemberName.TypeParameters[i];
- if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
- Report.SymbolRelatedToPreviousError (tc.Location, "");
- Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
- next_part.GetSignatureForError ());
- break;
- }
-
- if (tc_names[i].Variance != tp.Variance) {
- Report.SymbolRelatedToPreviousError (tc.Location, "");
- Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
- next_part.GetSignatureForError ());
- break;
- }
- }
- }
-
- if (tc.partial_parts == null)
- tc.partial_parts = new List<TypeContainer> (1);
-
- if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
- tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
- } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
- tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
- tc.ModFlags |= next_part.ModFlags;
- } else {
- tc.ModFlags |= next_part.ModFlags;
- }
-
- tc.spec.Modifiers = tc.ModFlags;
-
- if (next_part.attributes != null) {
- if (tc.attributes == null)
- tc.attributes = next_part.attributes;
- else
- tc.attributes.AddAttributes (next_part.attributes.Attrs);
- }
-
- next_part.PartialContainer = tc;
- tc.partial_parts.Add (next_part);
- return tc;
- }
-
- public virtual void RemoveTypeContainer (TypeContainer next_part)
- {
- if (types != null)
- types.Remove (next_part);
-
- Cache.Remove (next_part.Basename);
- RemoveMemberType (next_part);
- }
-
- public void AddDelegate (Delegate d)
- {
- AddTypeContainer (d);
- }
-
- private void AddMemberToList (InterfaceMemberBase mc, List<MemberCore> alist)
- {
- if (ordered_explicit_member_list == null) {
- ordered_explicit_member_list = new List<MemberCore> ();
- ordered_member_list = new List<MemberCore> ();
- }
-
- if (mc.IsExplicitImpl) {
- if (Kind == MemberKind.Interface) {
- Report.Error (541, mc.Location,
- "`{0}': explicit interface declaration can only be declared in a class or struct",
- mc.GetSignatureForError ());
- }
-
- ordered_explicit_member_list.Add (mc);
- alist.Insert (0, mc);
- } else {
- ordered_member_list.Add (mc);
- alist.Add (mc);
- }
-
+ return;
}
-
- public void AddMethod (MethodOrOperator method)
+
+ public void AddConstructor (Constructor c)
{
- if (!AddToContainer (method, method.MemberName.Basename))
- return;
-
- if (methods == null)
- methods = new List<MemberCore> ();
-
- AddMemberToList (method, methods);
+ AddConstructor (c, false);
}
- public void AddConstructor (Constructor c)
+ public void AddConstructor (Constructor c, bool isDefault)
{
bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
- if (!AddToContainer (c, is_static ? Constructor.ConstructorName : Constructor.TypeConstructorName))
- return;
-
- if (is_static && c.ParameterInfo.IsEmpty){
- if (default_static_constructor != null) {
- Report.SymbolRelatedToPreviousError (default_static_constructor);
- Report.Error (111, c.Location,
- "A member `{0}' is already defined. Rename this member or use different parameter types",
- c.GetSignatureForError ());
- return;
- }
+ if (!isDefault)
+ AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
- default_static_constructor = c;
+ if (is_static && c.ParameterInfo.IsEmpty) {
+ PartialContainer.has_static_constructor = true;
} else {
- if (c.ParameterInfo.IsEmpty)
- default_constructor = c;
-
- if (instance_constructors == null)
- instance_constructors = new List<Constructor> ();
-
- instance_constructors.Add (c);
+ PartialContainer.HasInstanceConstructor = true;
}
+
+ members.Add (c);
}
public bool AddField (FieldBase field)
{
- if (!AddMember (field))
- return false;
-
- if (fields == null)
- fields = new List<FieldBase> ();
-
- fields.Add (field);
+ AddMember (field);
if ((field.ModFlags & Modifiers.STATIC) != 0)
return true;
- if (first_nonstatic_field == null) {
- first_nonstatic_field = field;
+ var first_field = PartialContainer.first_nonstatic_field;
+ if (first_field == null) {
+ PartialContainer.first_nonstatic_field = field;
return true;
}
- if (Kind == MemberKind.Struct && first_nonstatic_field.Parent != field.Parent) {
- Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
+ if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
+ Report.SymbolRelatedToPreviousError (first_field.Parent);
Report.Warning (282, 3, field.Location,
"struct instance field `{0}' found in different declaration from instance field `{1}'",
- field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
+ field.GetSignatureForError (), first_field.GetSignatureForError ());
}
return true;
}
- public void AddProperty (Property prop)
- {
- if (!AddMember (prop))
- return;
-
- if (properties == null)
- properties = new List<MemberCore> ();
-
- AddMemberToList (prop, properties);
- }
-
- public void AddEvent (Event e)
- {
- if (!AddMember (e))
- return;
-
- if (events == null)
- events = new List<MemberCore> ();
-
- events.Add (e);
- }
-
/// <summary>
/// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
/// </summary>
public void AddIndexer (Indexer i)
{
- if (indexers == null)
- indexers = new List<MemberCore> ();
-
- AddMemberToList (i, indexers);
+ members.Add (i);
}
public void AddOperator (Operator op)
{
- if (!AddMember (op))
- return;
-
- if (operators == null)
- operators = new List<MemberCore> ();
-
- operators.Add (op);
- }
-
- public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
- {
- if (compiler_generated == null)
- compiler_generated = new List<CompilerGeneratedClass> ();
-
- compiler_generated.Add (c);
+ PartialContainer.HasOperators = true;
+ AddMember (op);
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
- if (a.Type == pa.DefaultMember) {
- if (Indexers != null) {
- Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
- return;
- }
+ if (has_normal_indexers && a.Type == pa.DefaultMember) {
+ Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
+ return;
}
if (a.Type == pa.Required) {
}
}
- public IList<TypeContainer> Types {
- get {
- return types;
- }
- }
-
- public IList<MemberCore> Methods {
- get {
- return methods;
- }
- }
-
- public IList<MemberCore> Constants {
- get {
- return constants;
- }
- }
-
public TypeSpec BaseType {
get {
return spec.BaseType;
}
}
- public IList<FieldBase> Fields {
- get {
- return fields;
- }
- }
-
- public IList<Constructor> InstanceConstructors {
- get {
- return instance_constructors;
- }
- }
-
- public IList<MemberCore> Properties {
- get {
- return properties;
- }
- }
-
- public IList<MemberCore> Events {
- get {
- return events;
- }
- }
-
- public IList<MemberCore> Indexers {
- get {
- return indexers;
- }
- }
-
- public IList<MemberCore> Operators {
- get {
- return operators;
- }
- }
-
protected virtual TypeAttributes TypeAttr {
get {
return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
public string GetAttributeDefaultMember ()
{
- return indexers == null ? DefaultIndexerName : indexer_name;
+ return indexer_name ?? DefaultIndexerName;
}
public bool IsComImport {
public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
+ if (IsPartialPart)
+ PartialContainer.RegisterFieldForInitialization (field, expression);
+
if ((field.ModFlags & Modifiers.STATIC) != 0){
if (initialized_static_fields == null) {
- PartialContainer.HasStaticFieldInitializer = true;
+ HasStaticFieldInitializer = true;
initialized_static_fields = new List<FieldInitializer> (4);
}
public void ResolveFieldInitializers (BlockContext ec)
{
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts) {
- part.DoResolveFieldInitializers (ec);
- }
- }
- DoResolveFieldInitializers (ec);
- }
+ Debug.Assert (!IsPartialPart);
- void DoResolveFieldInitializers (BlockContext ec)
- {
if (ec.IsStatic) {
if (initialized_static_fields == null)
return;
internal override void GenerateDocComment (DocumentationBuilder builder)
{
- base.GenerateDocComment (builder);
-
- if (DefaultStaticConstructor != null)
- DefaultStaticConstructor.GenerateDocComment (builder);
-
- if (InstanceConstructors != null)
- foreach (Constructor c in InstanceConstructors)
- c.GenerateDocComment (builder);
-
- if (Types != null)
- foreach (TypeContainer tc in Types)
- tc.GenerateDocComment (builder);
-
- if (Constants != null)
- foreach (Const c in Constants)
- c.GenerateDocComment (builder);
-
- if (Fields != null)
- foreach (FieldBase f in Fields)
- f.GenerateDocComment (builder);
-
- if (Events != null)
- foreach (Event e in Events)
- e.GenerateDocComment (builder);
-
- if (Indexers != null)
- foreach (Indexer ix in Indexers)
- ix.GenerateDocComment (builder);
-
- if (Properties != null)
- foreach (Property p in Properties)
- p.GenerateDocComment (builder);
+ if (IsPartialPart)
+ return;
- if (Methods != null)
- foreach (MethodOrOperator m in Methods)
- m.GenerateDocComment (builder);
+ base.GenerateDocComment (builder);
- if (Operators != null)
- foreach (Operator o in Operators)
- o.GenerateDocComment (builder);
+ foreach (var member in members)
+ member.GenerateDocComment (builder);
}
public TypeSpec GetAttributeCoClass ()
return a.GetAttributeUsageAttribute ();
}
- public virtual void AddBasesForPart (TypeContainer part, List<FullNamedExpression> bases)
+ public virtual CompilationSourceFile GetCompilationSourceFile ()
+ {
+ TypeContainer ns = Parent;
+ while (true) {
+ var sf = ns as CompilationSourceFile;
+ if (sf != null)
+ return sf;
+
+ ns = ns.Parent;
+ }
+ }
+
+ public virtual void AddBasesForPart (List<FullNamedExpression> bases)
{
- part.type_bases = bases;
+ type_bases = bases;
}
/// <summary>
}
ifaces [j++] = fne_resolved;
- }
-
- return ifaces;
- }
-
- //
- // Returns the MemberCore associated with a given name in the declaration
- // space. It doesn't return method based symbols !!
- //
- // TODO: protected or private
- //
- public MemberCore GetDefinition (string name)
- {
- MemberCore mc = null;
- defined_names.TryGetValue (name, out mc);
- return mc;
- }
-
- TypeSpec[] GetNormalPartialBases ()
- {
- var ifaces = new List<TypeSpec> (0);
- if (iface_exprs != null)
- ifaces.AddRange (iface_exprs);
-
- foreach (TypeContainer part in partial_parts) {
- FullNamedExpression new_base_class;
- var new_ifaces = part.ResolveBaseTypes (out new_base_class);
- if (new_base_class != null) {
- if (base_type_expr != null && part.base_type != base_type) {
- Report.SymbolRelatedToPreviousError (new_base_class.Location, "");
- Report.Error (263, part.Location,
- "Partial declarations of `{0}' must not specify different base classes",
- part.GetSignatureForError ());
- } else {
- base_type_expr = new_base_class;
- base_type = part.base_type;
- }
- }
-
- if (new_ifaces == null)
- continue;
-
- foreach (var iface in new_ifaces) {
- if (ifaces.Contains (iface))
- continue;
-
- ifaces.Add (iface);
- }
- }
-
- if (ifaces.Count == 0)
- return null;
-
- return ifaces.ToArray ();
- }
-
- public override string GetSignatureForDocumentation ()
- {
- return MemberName.GetName (true);
- }
-
- public override string GetSignatureForError ()
- {
- return MemberName.GetSignatureForError ();
+ }
+
+ return ifaces;
}
//
void CheckPairedOperators ()
{
bool has_equality_or_inequality = false;
- var operators = this.operators.ToArray ();
- bool[] has_pair = new bool[operators.Length];
+ List<Operator.OpType> found_matched = new List<Operator.OpType> ();
- for (int i = 0; i < operators.Length; ++i) {
- if (operators[i] == null)
+ for (int i = 0; i < members.Count; ++i) {
+ var o_a = members[i] as Operator;
+ if (o_a == null)
continue;
- Operator o_a = (Operator) operators[i];
- Operator.OpType o_type = o_a.OperatorType;
+ var o_type = o_a.OperatorType;
if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
has_equality_or_inequality = true;
- Operator.OpType matching_type = o_a.GetMatchingOperator ();
+ if (found_matched.Contains (o_type))
+ continue;
+
+ var matching_type = o_a.GetMatchingOperator ();
if (matching_type == Operator.OpType.TOP) {
- operators[i] = null;
continue;
}
- for (int ii = 0; ii < operators.Length; ++ii) {
- Operator o_b = (Operator) operators[ii];
+ bool pair_found = false;
+ for (int ii = i + 1; ii < members.Count; ++ii) {
+ var o_b = members[ii] as Operator;
if (o_b == null || o_b.OperatorType != matching_type)
continue;
if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
continue;
- operators[i] = null;
-
- //
- // Used to ignore duplicate user conversions
- //
- has_pair[ii] = true;
+ found_matched.Add (matching_type);
+ pair_found = true;
+ break;
}
- }
-
- for (int i = 0; i < operators.Length; ++i) {
- if (operators[i] == null || has_pair[i])
- continue;
- Operator o = (Operator) operators [i];
- Report.Error (216, o.Location,
- "The operator `{0}' requires a matching operator `{1}' to also be defined",
- o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
+ if (!pair_found) {
+ Report.Error (216, o_a.Location,
+ "The operator `{0}' requires a matching operator `{1}' to also be defined",
+ o_a.GetSignatureForError (), Operator.GetName (matching_type));
+ }
}
if (has_equality_or_inequality) {
- if (Methods == null || !HasEquals)
+ if (!HasEquals)
Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
GetSignatureForError ());
- if (Methods == null || !HasGetHashCode)
+ if (!HasGetHashCode)
Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
GetSignatureForError ());
}
}
+
+ public override void CreateMetadataName (StringBuilder sb)
+ {
+ if (Parent.MemberName != null) {
+ Parent.CreateMetadataName (sb);
+
+ if (sb.Length != 0) {
+ sb.Append (".");
+ }
+ }
+
+ sb.Append (MemberName.Basename);
+ }
bool CreateTypeBuilder ()
{
//
// Sets .size to 1 for structs with no instance fields
//
- int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
+ int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
- if (IsTopLevel) {
- TypeBuilder = Module.CreateBuilder (MemberName.GetName (true), TypeAttr, type_size);
+ var parent_def = Parent as TypeDefinition;
+ if (parent_def == null) {
+ var sb = new StringBuilder ();
+ CreateMetadataName (sb);
+ TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
} else {
- TypeBuilder = Parent.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
+ TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
}
if (DeclaringAssembly.Importer != null)
spec.SetMetaInfo (TypeBuilder);
spec.MemberCache = new MemberCache (this);
- spec.DeclaringType = Parent.CurrentType;
- if (!IsTopLevel)
- Parent.MemberCache.AddMember (spec);
+ TypeParameters parentAllTypeParameters = null;
+ if (parent_def != null) {
+ spec.DeclaringType = Parent.CurrentType;
+ parent_def.MemberCache.AddMember (spec);
+ parentAllTypeParameters = parent_def.all_type_parameters;
+ }
- if (MemberName.TypeParameters != null || Parent.IsGenericOrParentIsGeneric) {
- var tparam_names = CreateTypeParameters ();
+ if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
+ var tparam_names = CreateTypeParameters (parentAllTypeParameters);
all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
return true;
}
- string[] CreateTypeParameters ()
+ string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
{
string[] names;
int parent_offset = 0;
- var parent_all = Parent.all_type_parameters;
- if (parent_all != null) {
+ if (parentAllTypeParameters != null) {
if (CurrentTypeParameters == null) {
- all_type_parameters = Parent.all_type_parameters;
- return Parent.all_tp_builders.Select (l => l.Name).ToArray ();
+ all_type_parameters = parentAllTypeParameters;
+ return parentAllTypeParameters.GetAllNames ();
}
- names = new string[parent_all.Count + CurrentTypeParameters.Count];
+ names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
all_type_parameters = new TypeParameters (names.Length);
- all_type_parameters.Add (Parent.all_type_parameters);
+ all_type_parameters.Add (parentAllTypeParameters);
parent_offset = all_type_parameters.Count;
for (int i = 0; i < parent_offset; ++i)
}
+ public SourceMethodBuilder CreateMethodSymbolEntry ()
+ {
+ if (Module.DeclaringAssembly.SymbolWriter == null)
+ return null;
+
+ var source_file = GetCompilationSourceFile ();
+ if (source_file == null)
+ return null;
+
+ return new SourceMethodBuilder (source_file.SymbolUnitEntry);
+ }
+
//
// Creates a proxy base method call inside this container for hoisted base member calls
//
}
if (proxy_method == null) {
- string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
- var base_parameters = new Parameter[method.Parameters.Count];
- for (int i = 0; i < base_parameters.Length; ++i) {
- var base_param = method.Parameters.FixedParameters[i];
- base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location),
- base_param.Name, base_param.ModFlags, null, Location);
- base_parameters[i].Resolve (this, i);
- }
-
- var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
- if (method.Parameters.HasArglist) {
- cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
- cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
- }
+ string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
MemberName member_name;
TypeArguments targs = null;
+ TypeSpec return_type = method.ReturnType;
+ var local_param_types = method.Parameters.Types;
+
if (method.IsGeneric) {
//
// Copy all base generic method type parameters info
targs.Arguments = new TypeSpec[hoisted_tparams.Length];
for (int i = 0; i < hoisted_tparams.Length; ++i) {
var tp = hoisted_tparams[i];
- tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null));
+ var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
+ tparams.Add (local_tp);
targs.Add (new SimpleName (tp.Name, Location));
- targs.Arguments[i] = tp;
+ targs.Arguments[i] = local_tp.Type;
}
member_name = new MemberName (name, tparams, Location);
+
+ //
+ // Mutate any method type parameters from original
+ // to newly created hoisted version
+ //
+ var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
+ return_type = mutator.Mutate (return_type);
+ local_param_types = mutator.Mutate (local_param_types);
} else {
member_name = new MemberName (name);
}
+ var base_parameters = new Parameter[method.Parameters.Count];
+ for (int i = 0; i < base_parameters.Length; ++i) {
+ var base_param = method.Parameters.FixedParameters[i];
+ base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
+ base_param.Name, base_param.ModFlags, null, Location);
+ base_parameters[i].Resolve (this, i);
+ }
+
+ var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
+ if (method.Parameters.HasArglist) {
+ cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
+ cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
+ }
+
// Compiler generated proxy
- proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location),
+ proxy_method = new Method (this, new TypeExpression (return_type, Location),
Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
member_name, cloned_params, null);
- var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location);
+ var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
+ IsCompilerGenerated = true
+ };
var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
block.AddStatement (statement);
proxy_method.Block = block;
- methods.Add (proxy_method);
+ members.Add (proxy_method);
proxy_method.Define ();
hoisted_base_call_proxies.Add (method, proxy_method);
return proxy_method.Spec;
}
- bool DefineBaseTypes ()
+ protected bool DefineBaseTypes ()
{
iface_exprs = ResolveBaseTypes (out base_type_expr);
- if (partial_parts != null) {
- iface_exprs = GetNormalPartialBases ();
+ bool set_base_type;
+
+ if (IsPartialPart) {
+ set_base_type = false;
+
+ if (base_type_expr != null) {
+ if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
+ Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
+ Report.Error (263, Location,
+ "Partial declarations of `{0}' must not specify different base classes",
+ GetSignatureForError ());
+ } else {
+ PartialContainer.base_type_expr = base_type_expr;
+ PartialContainer.base_type = base_type;
+ set_base_type = true;
+ }
+ }
+
+ if (iface_exprs != null) {
+ if (PartialContainer.iface_exprs == null)
+ PartialContainer.iface_exprs = iface_exprs;
+ else {
+ var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
+ foreach (var iface_partial in iface_exprs) {
+ if (ifaces.Contains (iface_partial))
+ continue;
+
+ ifaces.Add (iface_partial);
+ }
+
+ PartialContainer.iface_exprs = ifaces.ToArray ();
+ }
+ }
+
+ PartialContainer.members.AddRange (members);
+ if (containers != null) {
+ if (PartialContainer.containers == null)
+ PartialContainer.containers = new List<TypeContainer> ();
+
+ PartialContainer.containers.AddRange (containers);
+ }
+
+ members_defined = members_defined_ok = true;
+ caching_flags |= Flags.CloseTypeCreated;
+ } else {
+ set_base_type = true;
}
var cycle = CheckRecursiveDefinition (this);
GetSignatureForError (), cycle.GetSignatureForError ());
iface_exprs = null;
+ PartialContainer.iface_exprs = null;
} else {
Report.Error (146, Location,
"Circular base class dependency involving `{0}' and `{1}'",
GetSignatureForError (), cycle.GetSignatureForError ());
base_type = null;
+ PartialContainer.base_type = null;
}
}
continue;
TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
-
- // Ensure the base is always setup
- var compiled_iface = iface_type.MemberDefinition as Interface;
- if (compiled_iface != null) {
- // TODO: Need DefineBaseType only
- compiled_iface.DefineType ();
- }
-
- if (iface_type.Interfaces != null) {
- var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
- for (int i = 0; i < base_ifaces.Count; ++i) {
- var ii_iface_type = base_ifaces[i];
- if (spec.AddInterfaceDefined (ii_iface_type)) {
- TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
-
- if (ii_iface_type.Interfaces != null)
- base_ifaces.AddRange (ii_iface_type.Interfaces);
- }
- }
- }
}
}
return true;
}
- if (base_type != null) {
- spec.BaseType = base_type;
+ if (set_base_type) {
+ if (base_type != null) {
+ spec.BaseType = base_type;
- // Set base type after type creation
- TypeBuilder.SetParent (base_type.GetMetaInfo ());
- } else {
- TypeBuilder.SetParent (null);
+ // Set base type after type creation
+ TypeBuilder.SetParent (base_type.GetMetaInfo ());
+ } else {
+ TypeBuilder.SetParent (null);
+ }
}
return true;
}
- public virtual void DefineConstants ()
+ public override void ExpandBaseInterfaces ()
{
- if (constants != null) {
- foreach (Const c in constants) {
- c.DefineValue ();
- }
- }
+ if (!IsPartialPart)
+ DoExpandBaseInterfaces ();
+
+ base.ExpandBaseInterfaces ();
+ }
+
+ public void DoExpandBaseInterfaces ()
+ {
+ if ((caching_flags & Flags.InterfacesExpanded) != 0)
+ return;
+
+ caching_flags |= Flags.InterfacesExpanded;
+
+ //
+ // Expand base interfaces. It cannot be done earlier because all partial
+ // interface parts need to be defined before the type they are used from
+ //
+ if (iface_exprs != null) {
+ foreach (var iface in iface_exprs) {
+ if (iface == null)
+ continue;
- if (instance_constructors != null) {
- foreach (MethodCore m in instance_constructors) {
- var p = m.ParameterInfo;
- if (!p.IsEmpty) {
- p.ResolveDefaultValues (m);
+ var td = iface.MemberDefinition as TypeDefinition;
+ if (td != null)
+ td.DoExpandBaseInterfaces ();
+
+ if (iface.Interfaces == null)
+ continue;
+
+ foreach (var biface in iface.Interfaces) {
+ if (spec.AddInterfaceDefined (biface)) {
+ TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
+ }
}
}
}
- if (methods != null) {
- foreach (MethodCore m in methods) {
- var p = m.ParameterInfo;
- if (!p.IsEmpty) {
- p.ResolveDefaultValues (m);
+ //
+ // Include all base type interfaces too, see ImportTypeBase for details
+ //
+ if (base_type != null) {
+ var td = base_type.MemberDefinition as TypeDefinition;
+ if (td != null)
+ td.DoExpandBaseInterfaces ();
+
+ //
+ // Simply use base interfaces only, they are all expanded which makes
+ // it easy to handle generic type argument propagation with single
+ // inflator only.
+ //
+ // interface IA<T> : IB<T>
+ // interface IB<U> : IC<U>
+ // interface IC<V>
+ //
+ if (base_type.Interfaces != null) {
+ foreach (var iface in base_type.Interfaces) {
+ spec.AddInterfaceDefined (iface);
}
}
}
+ }
+
+ public override void PrepareEmit ()
+ {
+ if ((caching_flags & Flags.CloseTypeCreated) != 0)
+ return;
+
+ foreach (var member in members) {
+ var pm = member as IParametersMember;
+ if (pm != null) {
+
+ var p = pm.Parameters;
+ if (p.IsEmpty)
+ continue;
- if (indexers != null) {
- foreach (Indexer i in indexers) {
- i.ParameterInfo.ResolveDefaultValues (i);
+ ((ParametersCompiled) p).ResolveDefaultValues (member);
}
- }
- if (types != null) {
- foreach (var t in types)
- t.DefineConstants ();
+ var c = member as Const;
+ if (c != null)
+ c.DefineValue ();
}
+
+ base.PrepareEmit ();
}
//
// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
//
- public bool CreateType ()
+ public override bool CreateContainer ()
{
if (TypeBuilder != null)
return !error;
if (error)
return false;
- if (!CreateTypeBuilder ()) {
- error = true;
- return false;
- }
-
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts) {
- part.spec = spec;
- part.current_type = current_type;
- part.TypeBuilder = TypeBuilder;
- part.all_type_parameters = all_type_parameters;
- part.all_tp_builders = all_tp_builders;
- }
- }
-
- if (Types != null) {
- foreach (TypeContainer tc in Types) {
- tc.CreateType ();
+ if (IsPartialPart) {
+ spec = PartialContainer.spec;
+ TypeBuilder = PartialContainer.TypeBuilder;
+ all_tp_builders = PartialContainer.all_tp_builders;
+ all_type_parameters = PartialContainer.all_type_parameters;
+ } else {
+ if (!CreateTypeBuilder ()) {
+ error = true;
+ return false;
}
}
- return true;
+ return base.CreateContainer ();
}
- public void DefineType ()
+ protected override void DoDefineContainer ()
{
- if (error)
- return;
- if (type_defined)
- return;
-
- type_defined = true;
-
- // Nested type share same namespace
- if (IsTopLevel && !IsCompilerGenerated) {
- NamespaceEntry.Define ();
- if (partial_parts != null) {
- foreach (var part in partial_parts)
- part.NamespaceEntry.Define ();
- }
- }
-
- if (!DefineBaseTypes ()) {
- error = true;
- return;
- }
+ DefineBaseTypes ();
- if (!DefineNestedTypes ()) {
- error = true;
- return;
- }
+ DoResolveTypeParameters ();
}
//
current_type = null;
}
- void UpdateTypeParameterConstraints (TypeContainer part)
+ void UpdateTypeParameterConstraints (TypeDefinition part)
{
for (int i = 0; i < CurrentTypeParameters.Count; i++) {
if (CurrentTypeParameters[i].AddPartialConstraints (part, part.MemberName.TypeParameters[i]))
}
}
- public bool ResolveTypeParameters ()
+ public override void RemoveContainer (TypeContainer cont)
{
- if (!DoResolveTypeParameters ())
- return false;
-
- if (types != null) {
- foreach (var type in types)
- if (!type.ResolveTypeParameters ())
- return false;
- }
-
- if (compiler_generated != null) {
- foreach (CompilerGeneratedClass c in compiler_generated)
- if (!c.ResolveTypeParameters ())
- return false;
- }
-
- return true;
+ base.RemoveContainer (cont);
+ Members.Remove (cont);
+ Cache.Remove (cont.Basename);
}
protected virtual bool DoResolveTypeParameters ()
if (tparams == null)
return true;
- if (PartialContainer != this)
- throw new InternalErrorException ();
-
var base_context = new BaseContext (this);
for (int i = 0; i < tparams.Count; ++i) {
var tp = tparams[i];
}
}
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts)
- UpdateTypeParameterConstraints (part);
- }
-
- return true;
- }
-
- protected virtual bool DefineNestedTypes ()
- {
- if (Types != null) {
- foreach (TypeContainer tc in Types)
- tc.DefineType ();
+ if (IsPartialPart) {
+ PartialContainer.UpdateTypeParameterConstraints (this);
}
return true;
}
- TypeSpec CheckRecursiveDefinition (TypeContainer tc)
+ TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
{
if (InTransit != null)
return spec;
InTransit = tc;
if (base_type != null) {
- var ptc = base_type.MemberDefinition as TypeContainer;
+ var ptc = base_type.MemberDefinition as TypeDefinition;
if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
return base_type;
}
members_defined_ok = DoDefineMembers ();
members_defined = true;
- if (types != null) {
- foreach (var nested in types)
- nested.Define ();
- }
+ base.Define ();
return members_defined_ok;
}
protected virtual bool DoDefineMembers ()
{
+ Debug.Assert (!IsPartialPart);
+
if (iface_exprs != null) {
foreach (var iface_type in iface_exprs) {
if (iface_type == null)
if (compiled_iface != null)
compiled_iface.Define ();
- if (Kind == MemberKind.Interface)
- MemberCache.AddInterface (iface_type);
-
ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
if (oa != null && !IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
}
if (iface_type.IsGenericOrParentIsGeneric) {
- if (spec.Interfaces != null) {
- foreach (var prev_iface in iface_exprs) {
- if (prev_iface == iface_type)
- break;
-
- if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
- continue;
-
- Report.Error (695, Location,
- "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
- GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
- }
+ foreach (var prev_iface in iface_exprs) {
+ if (prev_iface == iface_type || prev_iface == null)
+ break;
+
+ if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
+ continue;
+
+ Report.Error (695, Location,
+ "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+ GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
}
}
}
+
+ if (Kind == MemberKind.Interface) {
+ foreach (var iface in spec.Interfaces) {
+ MemberCache.AddInterface (iface);
+ }
+ }
}
if (base_type != null) {
}
}
- if (base_type.Interfaces != null) {
- foreach (var iface in base_type.Interfaces)
- spec.AddInterface (iface);
- }
-
var baseContainer = base_type.MemberDefinition as ClassOrStruct;
if (baseContainer != null) {
baseContainer.Define ();
}
}
- DefineContainerMembers (constants);
- DefineContainerMembers (fields);
-
if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
pending = PendingImplementation.GetPendingImplementations (this);
+ }
- if (requires_delayed_unmanagedtype_check) {
- requires_delayed_unmanagedtype_check = false;
- foreach (FieldBase f in fields) {
- if (f.MemberType != null && f.MemberType.IsPointer)
- TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
- }
+ var count = members.Count;
+ for (int i = 0; i < count; ++i) {
+ var mc = members[i] as InterfaceMemberBase;
+ if (mc == null || !mc.IsExplicitImpl)
+ continue;
+
+ try {
+ mc.Define ();
+ } catch (Exception e) {
+ throw new InternalErrorException (mc, e);
}
}
-
- //
- // Constructors are not in the defined_names array
- //
- DefineContainerMembers (instance_constructors);
-
- DefineContainerMembers (events);
- DefineContainerMembers (ordered_explicit_member_list);
- DefineContainerMembers (ordered_member_list);
- if (operators != null) {
- DefineContainerMembers (operators);
+ for (int i = 0; i < count; ++i) {
+ var mc = members[i] as InterfaceMemberBase;
+ if (mc != null && mc.IsExplicitImpl)
+ continue;
+
+ if (members[i] is TypeContainer)
+ continue;
+
+ try {
+ members[i].Define ();
+ } catch (Exception e) {
+ throw new InternalErrorException (members[i], e);
+ }
+ }
+
+ if (HasOperators) {
CheckPairedOperators ();
}
+ if (requires_delayed_unmanagedtype_check) {
+ requires_delayed_unmanagedtype_check = false;
+ foreach (var member in members) {
+ var f = member as Field;
+ if (f != null && f.MemberType != null && f.MemberType.IsPointer)
+ TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
+ }
+ }
+
ComputeIndexerName();
- CheckEqualsAndGetHashCode();
+
+ if (HasEquals && !HasGetHashCode) {
+ Report.Warning (659, 3, Location,
+ "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
+ }
if (Kind == MemberKind.Interface && iface_exprs != null) {
MemberCache.RemoveHiddenMembers (spec);
return true;
}
- protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList<MemberCore>
- {
- if (mcal != null) {
- for (int i = 0; i < mcal.Count; ++i) {
- MemberCore mc = (MemberCore) mcal[i];
- try {
- mc.Define ();
- } catch (Exception e) {
- throw new InternalErrorException (mc, e);
- }
- }
- }
- }
-
- protected virtual void ComputeIndexerName ()
+ void ComputeIndexerName ()
{
+ var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
if (indexers == null)
return;
string class_indexer_name = null;
//
- // If there's both an explicit and an implicit interface implementation, the
- // explicit one actually implements the interface while the other one is just
- // a normal indexer. See bug #37714.
+ // Check normal indexers for consistent name, explicit interface implementation
+ // indexers are ignored
//
-
- // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
- foreach (Indexer i in indexers) {
- if (i.InterfaceType != null) {
- if (seen_normal_indexers)
- throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
+ foreach (var indexer in indexers) {
+ //
+ // FindMembers can return unfiltered full hierarchy names
+ //
+ if (indexer.DeclaringType != spec)
continue;
- }
- seen_normal_indexers = true;
+ has_normal_indexers = true;
if (class_indexer_name == null) {
- class_indexer_name = i.ShortName;
- continue;
- }
-
- if (i.ShortName != class_indexer_name)
- Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
- }
-
- if (class_indexer_name != null)
- indexer_name = class_indexer_name;
- }
-
- void EmitIndexerName ()
- {
- if (!seen_normal_indexers)
- return;
-
- var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
- if (ctor == null)
- return;
-
- var encoder = new AttributeEncoder ();
- encoder.Encode (GetAttributeDefaultMember ());
- encoder.EncodeEmptyNamedArguments ();
-
- TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
- }
-
- protected virtual void CheckEqualsAndGetHashCode ()
- {
- if (methods == null)
- return;
-
- if (HasEquals && !HasGetHashCode) {
- Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
- }
- }
-
- // Indicated whether container has StructLayout attribute set Explicit
- public bool HasExplicitLayout {
- get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
- set { caching_flags |= Flags.HasExplicitLayout; }
- }
-
- public bool HasStructLayout {
- get { return (caching_flags & Flags.HasStructLayout) != 0; }
- set { caching_flags |= Flags.HasStructLayout; }
- }
+ indexer_name = class_indexer_name = indexer.Name;
+ continue;
+ }
- public MemberCache MemberCache {
- get {
- return spec.MemberCache;
+ if (indexer.Name != class_indexer_name)
+ Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
+ "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
}
}
- void CheckMemberUsage (List<MemberCore> al, string member_type)
+ void EmitIndexerName ()
{
- if (al == null)
+ if (!has_normal_indexers)
return;
- foreach (MemberCore mc in al) {
- if ((mc.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE)
- continue;
+ var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
+ if (ctor == null)
+ return;
- if ((mc.ModFlags & Modifiers.PARTIAL) != 0)
- continue;
+ var encoder = new AttributeEncoder ();
+ encoder.Encode (GetAttributeDefaultMember ());
+ encoder.EncodeEmptyNamedArguments ();
- if (!mc.IsUsed && (mc.caching_flags & Flags.Excluded) == 0) {
- Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
- }
- }
+ TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
}
- public virtual void VerifyMembers ()
+ public override void VerifyMembers ()
{
//
// Check for internal or private fields that were never assigned
//
- if (Report.WarningLevel >= 3) {
- if (Compiler.Settings.EnhancedWarnings) {
- CheckMemberUsage (properties, "property");
- CheckMemberUsage (methods, "method");
- CheckMemberUsage (constants, "constant");
- }
-
- if (fields != null){
- bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
- foreach (FieldBase f in fields) {
- if ((f.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
- if (is_type_exposed)
- continue;
-
- f.SetIsUsed ();
- }
-
- if (!f.IsUsed){
- if ((f.caching_flags & Flags.IsAssigned) == 0)
- Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
- else {
- Report.Warning (414, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
- f.GetSignatureForError ());
- }
- continue;
- }
-
- if ((f.caching_flags & Flags.IsAssigned) != 0)
- continue;
-
+ if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
+ bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
+ foreach (var member in members) {
+ if (member is Event) {
//
- // Only report 649 on level 4
+ // An event can be assigned from same class only, so we can report
+ // this warning for all accessibility modes
//
- if (Report.WarningLevel < 4)
- continue;
+ if (!member.IsUsed)
+ Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
- //
- // Don't be pendatic over serializable attributes
- //
- if (f.OptAttributes != null || PartialContainer.HasStructLayout)
+ continue;
+ }
+
+ if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
+ if (is_type_exposed)
continue;
-
- Constant c = New.Constantify (f.MemberType, f.Location);
- string value;
- if (c != null) {
- value = c.GetValueAsLiteral ();
- } else if (TypeSpec.IsReferenceType (f.MemberType)) {
- value = "null";
- } else {
- // Ignore this warning for struct value fields (they are always initialized)
- if (f.MemberType.IsStruct)
- continue;
- value = null;
+ member.SetIsUsed ();
+ }
+
+ var f = member as Field;
+ if (f == null)
+ continue;
+
+ if (!member.IsUsed) {
+ if ((member.caching_flags & Flags.IsAssigned) == 0) {
+ Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
+ } else {
+ Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
+ member.GetSignatureForError ());
}
+ continue;
+ }
- if (value != null)
- value = " `" + value + "'";
+ if ((f.caching_flags & Flags.IsAssigned) != 0)
+ continue;
+
+ //
+ // Only report 649 on level 4
+ //
+ if (Compiler.Settings.WarningLevel < 4)
+ continue;
+
+ //
+ // Don't be pedantic when type requires specific layout
+ //
+ if (f.OptAttributes != null || PartialContainer.HasStructLayout)
+ continue;
- Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
- f.GetSignatureForError (), value);
+ Constant c = New.Constantify (f.MemberType, f.Location);
+ string value;
+ if (c != null) {
+ value = c.GetValueAsLiteral ();
+ } else if (TypeSpec.IsReferenceType (f.MemberType)) {
+ value = "null";
+ } else {
+ value = null;
}
+
+ if (value != null)
+ value = " `" + value + "'";
+
+ Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
+ f.GetSignatureForError (), value);
}
}
+
+ base.VerifyMembers ();
}
public override void Emit ()
{
- if (!IsTopLevel) {
- MemberSpec candidate;
- bool overrides = false;
- var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
- if (conflict_symbol == null && candidate == null) {
- if ((ModFlags & Modifiers.NEW) != 0)
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
- GetSignatureForError ());
- } else {
- if ((ModFlags & Modifiers.NEW) == 0) {
- if (candidate == null)
- candidate = conflict_symbol;
+ if (OptAttributes != null)
+ OptAttributes.Emit ();
- Report.SymbolRelatedToPreviousError (candidate);
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), candidate.GetSignatureForError ());
+ if (!IsCompilerGenerated) {
+ if (!IsTopLevel) {
+ MemberSpec candidate;
+ bool overrides = false;
+ var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
+ if (conflict_symbol == null && candidate == null) {
+ if ((ModFlags & Modifiers.NEW) != 0)
+ Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+ GetSignatureForError ());
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ if (candidate == null)
+ candidate = conflict_symbol;
+
+ Report.SymbolRelatedToPreviousError (candidate);
+ Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+ GetSignatureForError (), candidate.GetSignatureForError ());
+ }
}
}
- }
- // Run constraints check on all possible generic types
- if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
+ // Run constraints check on all possible generic types
if (base_type != null && base_type_expr != null) {
ConstraintChecker.Check (this, base_type, base_type_expr.Location);
}
#endif
base.Emit ();
- }
-
- // TODO: move to ClassOrStruct
- void EmitConstructors ()
- {
- if (instance_constructors == null)
- return;
-
- if (spec.IsAttribute && IsExposedFromAssembly () && Compiler.Settings.VerifyClsCompliance && IsClsComplianceRequired ()) {
- bool has_compliant_args = false;
- foreach (Constructor c in instance_constructors) {
- try {
- c.Emit ();
- }
- catch (Exception e) {
- throw new InternalErrorException (c, e);
- }
+ for (int i = 0; i < members.Count; i++)
+ members[i].Emit ();
- if (has_compliant_args)
- continue;
+ EmitIndexerName ();
+ CheckAttributeClsCompliance ();
- has_compliant_args = c.HasCompliantArgs;
- }
- if (!has_compliant_args)
- Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
- } else {
- foreach (Constructor c in instance_constructors) {
- try {
- c.Emit ();
- }
- catch (Exception e) {
- throw new InternalErrorException (c, e);
- }
- }
- }
+ if (pending != null)
+ pending.VerifyPendingMethods ();
}
- /// <summary>
- /// Emits the code, this step is performed after all
- /// the types, enumerations, constructors
- /// </summary>
- public virtual void EmitType ()
+
+ void CheckAttributeClsCompliance ()
{
- if ((caching_flags & Flags.CloseTypeCreated) != 0)
+ if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
return;
- if (OptAttributes != null)
- OptAttributes.Emit ();
-
- Emit ();
-
- EmitConstructors ();
-
- if (constants != null)
- foreach (Const con in constants)
- con.Emit ();
-
- if (default_static_constructor != null)
- default_static_constructor.Emit ();
-
- if (operators != null)
- foreach (Operator o in operators)
- o.Emit ();
-
- if (properties != null)
- foreach (Property p in properties)
- p.Emit ();
-
- if (indexers != null) {
- foreach (Indexer indx in indexers)
- indx.Emit ();
- EmitIndexerName ();
- }
-
- if (events != null){
- foreach (Event e in Events)
- e.Emit ();
- }
-
- if (methods != null) {
- for (int i = 0; i < methods.Count; ++i)
- ((MethodOrOperator) methods [i]).Emit ();
- }
-
- if (fields != null)
- foreach (FieldBase f in fields)
- f.Emit ();
+ foreach (var m in members) {
+ var c = m as Constructor;
+ if (c == null)
+ continue;
- if (types != null) {
- foreach (TypeContainer t in types)
- t.EmitType ();
+ if (c.HasCompliantArgs)
+ return;
}
- if (pending != null)
- pending.VerifyPendingMethods ();
-
- if (Report.Errors > 0)
- return;
-
- if (compiler_generated != null) {
- for (int i = 0; i < compiler_generated.Count; ++i)
- compiler_generated [i].EmitType ();
- }
+ Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
}
- protected void Error_MissingPartialModifier (MemberCore type)
+ public sealed override void EmitContainer ()
{
- Report.Error (260, type.Location,
- "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
- type.GetSignatureForError ());
+ if ((caching_flags & Flags.CloseTypeCreated) != 0)
+ return;
+
+ Emit ();
}
- public virtual void CloseType ()
+ public override void CloseContainer ()
{
if ((caching_flags & Flags.CloseTypeCreated) != 0)
return;
if (spec.BaseType != null) {
var btype = spec.BaseType.MemberDefinition as TypeContainer;
if (btype != null) {
- btype.CloseType ();
+ btype.CloseContainer ();
if ((caching_flags & Flags.CloseTypeCreated) != 0)
return;
try {
caching_flags |= Flags.CloseTypeCreated;
TypeBuilder.CreateType ();
- } catch (TypeLoadException){
+ } catch (TypeLoadException) {
//
// This is fine, the code still created the type
//
-// Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
-// Console.WriteLine (e.Message);
} catch (Exception e) {
throw new InternalErrorException (this, e);
}
-
- if (Types != null){
- foreach (TypeContainer tc in Types)
- tc.CloseType ();
- }
- if (compiler_generated != null)
- foreach (CompilerGeneratedClass c in compiler_generated)
- c.CloseType ();
+ base.CloseContainer ();
- types = null;
+ containers = null;
initialized_fields = null;
initialized_static_fields = null;
- constants = null;
- ordered_explicit_member_list = null;
- ordered_member_list = null;
- methods = null;
- events = null;
- indexers = null;
- operators = null;
- compiler_generated = null;
- default_constructor = null;
- default_static_constructor = null;
type_bases = null;
OptAttributes = null;
}
return ok;
}
- public Constructor DefaultStaticConstructor {
- get { return default_static_constructor; }
- }
-
protected override bool VerifyClsCompliance ()
{
if (!base.VerifyClsCompliance ())
return false;
- // Check this name against other containers
- NamespaceEntry.NS.VerifyClsCompliance ();
-
// Check all container names for user classes
if (Kind != MemberKind.Delegate)
MemberCache.VerifyClsCompliance (Definition, Report);
return false;
}
+ public override bool IsClsComplianceRequired ()
+ {
+ if (IsPartialPart)
+ return PartialContainer.IsClsComplianceRequired ();
+
+ return base.IsClsComplianceRequired ();
+ }
+
bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
{
return Module.DeclaringAssembly == assembly;
if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
e = new TypeExpression (t, Location.Null);
- else if (Parent != null) {
+ else {
e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
- } else {
- int errors = Report.Errors;
-
- e = NamespaceEntry.LookupNamespaceOrType (name, arity, mode, loc);
-
- if (errors != Report.Errors)
- return e;
}
}
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;
-
return MemberCache.FindNestedType (container, name, arity);
}
cached_method |= CachedMethods.GetHashCode;
}
+ public override void WriteDebugSymbol (MonoSymbolFile file)
+ {
+ if (IsPartialPart)
+ return;
+
+ foreach (var m in members) {
+ m.WriteDebugSymbol (file);
+ }
+ }
+
/// <summary>
/// Method container contains Equals method
/// </summary>
}
}
- public abstract class ClassOrStruct : TypeContainer
+ public abstract class ClassOrStruct : TypeDefinition
{
+ public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
+
SecurityType declarative_security;
- public ClassOrStruct (NamespaceContainer ns, TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
- : base (ns, parent, name, attrs, kind)
+ public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+ : base (parent, name, attrs, kind)
{
}
- protected override bool AddToContainer (MemberCore symbol, string name)
+ protected override TypeAttributes TypeAttr {
+ get {
+ TypeAttributes ta = base.TypeAttr;
+ if (!has_static_constructor)
+ ta |= TypeAttributes.BeforeFieldInit;
+
+ if (Kind == MemberKind.Class) {
+ ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
+ if (IsStatic)
+ ta |= StaticClassAttribute;
+ } else {
+ ta |= TypeAttributes.SequentialLayout;
+ }
+
+ return ta;
+ }
+ }
+
+ public override void AddNameToContainer (MemberCore symbol, string name)
{
if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
if (symbol is TypeParameter) {
Report.Error (694, symbol.Location,
"Type parameter `{0}' has same name as containing type, or method",
symbol.GetSignatureForError ());
- return false;
+ return;
}
InterfaceMemberBase imb = symbol as InterfaceMemberBase;
Report.SymbolRelatedToPreviousError (this);
Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
symbol.GetSignatureForError ());
- return false;
- }
- }
-
- return base.AddToContainer (symbol, name);
- }
-
- public override void VerifyMembers ()
- {
- base.VerifyMembers ();
-
- if ((events != null) && Report.WarningLevel >= 3) {
- foreach (Event e in events){
- // Note: The event can be assigned from same class only, so we can report
- // this warning for all accessibility modes
- if ((e.caching_flags & Flags.IsUsed) == 0)
- Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
+ return;
}
}
- if (types != null) {
- foreach (var t in types)
- t.VerifyMembers ();
- }
+ base.AddNameToContainer (symbol, name);
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
/// <summary>
/// Defines the default constructors
/// </summary>
- protected void DefineDefaultConstructor (bool is_static)
+ protected virtual Constructor DefineDefaultConstructor (bool is_static)
{
// The default instance constructor is public
// If the class is abstract, the default constructor is protected
mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
}
- Constructor c = new Constructor (this, MemberName.Name, mods,
- null, ParametersCompiled.EmptyReadOnlyParameters, Location);
+ var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
c.Initializer = new GeneratedBaseInitializer (Location);
- AddConstructor (c);
- c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
+ AddConstructor (c, true);
+ c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
+ IsCompilerGenerated = true
+ };
+
+ return c;
}
protected override bool DoDefineMembers ()
base.DoDefineMembers ();
- if (default_static_constructor != null)
- default_static_constructor.Define ();
-
return true;
}
public override void Emit ()
{
- if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) {
- DefineDefaultConstructor (true);
- default_static_constructor.Define ();
+ if (!has_static_constructor && HasStaticFieldInitializer) {
+ var c = DefineDefaultConstructor (true);
+ c.Define ();
}
base.Emit ();
}
}
}
-
- public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
- {
- if (Parent != null) {
- var methods = NamespaceEntry.NS.LookupExtensionMethod (this, extensionType, name, arity);
- if (methods != null) {
- return new ExtensionMethodCandidates (methods, NamespaceEntry, NamespaceEntry.NS) {
- HasUninspectedMembers = true
- };
- }
- }
-
- return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity);
- }
-
- protected override TypeAttributes TypeAttr {
- get {
- if (default_static_constructor == null)
- return base.TypeAttr | TypeAttributes.BeforeFieldInit;
-
- return base.TypeAttr;
- }
- }
}
- // TODO: should be sealed
- public class Class : ClassOrStruct {
+ public sealed class Class : ClassOrStruct
+ {
const Modifiers AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
Modifiers.STATIC |
Modifiers.UNSAFE;
- public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
-
- public Class (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
- : base (ns, parent, name, attrs, MemberKind.Class)
+ public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+ : base (parent, name, attrs, MemberKind.Class)
{
- var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+ var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
spec = new TypeSpec (Kind, null, this, null, ModFlags);
}
visitor.Visit (this);
}
- public override void AddBasesForPart (TypeContainer part, List<FullNamedExpression> bases)
+ public override void AddBasesForPart (List<FullNamedExpression> bases)
{
- var pmn = part.MemberName;
- if (pmn.Name == "Object" && pmn.Left != null && pmn.Left.Name == "System" && pmn.TypeParameters == null)
- Report.Error (537, part.Location,
+ var pmn = MemberName;
+ if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
+ Report.Error (537, Location,
"The class System.Object cannot have a base class or implement an interface.");
- base.AddBasesForPart (part, bases);
+
+ base.AddBasesForPart (bases);
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
return;
}
- if (a.Type.IsConditionallyExcluded (Compiler, Location))
+ if (a.Type.IsConditionallyExcluded (this, Location))
return;
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
}
}
- protected override void DefineContainerMembers (System.Collections.IList list)
- {
- if (list == null)
- return;
-
- if (!IsStatic) {
- base.DefineContainerMembers (list);
- return;
- }
-
- foreach (MemberCore m in list) {
- if (m is Operator) {
- Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
- continue;
- }
-
- if (m is Destructor) {
- Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
- continue;
- }
-
- if (m is Indexer) {
- Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
- continue;
- }
-
- if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
- continue;
-
- if (m is Constructor) {
- Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
- continue;
- }
-
- Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
- }
-
- base.DefineContainerMembers (list);
- }
-
protected override bool DoDefineMembers ()
{
if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
}
- if (InstanceConstructors == null && !IsStatic)
- DefineDefaultConstructor (false);
+ if (IsStatic) {
+ foreach (var m in Members) {
+ if (m is Operator) {
+ Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
+ continue;
+ }
+
+ if (m is Destructor) {
+ Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
+ continue;
+ }
+
+ if (m is Indexer) {
+ Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
+ continue;
+ }
+
+ if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
+ continue;
+
+ if (m is Constructor) {
+ Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
+ continue;
+ }
+
+ Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
+ }
+ } else {
+ if (!PartialContainer.HasInstanceConstructor)
+ DefineDefaultConstructor (false);
+ }
return base.DoDefineMembers ();
}
caching_flags |= Flags.Excluded;
return conditions;
}
-
- //
- // FIXME: How do we deal with the user specifying a different
- // layout?
- //
- protected override TypeAttributes TypeAttr {
- get {
- TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
- if (IsStatic)
- ta |= StaticClassAttribute;
- return ta;
- }
- }
}
- public sealed class Struct : ClassOrStruct {
-
+ public sealed class Struct : ClassOrStruct
+ {
bool is_unmanaged, has_unmanaged_check_done;
bool InTransit;
Modifiers.UNSAFE |
Modifiers.PRIVATE;
- public Struct (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
- : base (ns, parent, name, attrs, MemberKind.Struct)
+ public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+ : base (parent, name, attrs, MemberKind.Struct)
{
- var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+ var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
spec = new TypeSpec (Kind, null, this, null, ModFlags);
}
// set CharSet, its value has to be propagated to compiler generated
// fixed types
//
- if (a.Type == pa.StructLayout && Fields != null) {
+ if (a.Type == pa.StructLayout) {
var value = a.GetNamedValue ("CharSet");
if (value == null)
return;
- for (int i = 0; i < Fields.Count; ++i) {
- FixedField ff = Fields [i] as FixedField;
+ for (int i = 0; i < Members.Count; ++i) {
+ FixedField ff = Members [i] as FixedField;
if (ff == null)
continue;
}
}
- bool CheckStructCycles (Struct s)
+ bool CheckStructCycles ()
{
- if (s.Fields == null)
- return true;
-
- if (s.InTransit)
+ if (InTransit)
return false;
- s.InTransit = true;
- foreach (FieldBase field in s.Fields) {
+ InTransit = true;
+ foreach (var member in Members) {
+ var field = member as Field;
+ if (field == null)
+ continue;
+
TypeSpec ftype = field.Spec.MemberType;
if (!ftype.IsStruct)
continue;
//
// Static fields of exactly same type are allowed
//
- if (field.IsStatic && ftype == s.CurrentType)
+ if (field.IsStatic && ftype == CurrentType)
continue;
if (!CheckFieldTypeCycle (ftype)) {
}
}
- s.InTransit = false;
+ InTransit = false;
return true;
}
- bool CheckFieldTypeCycle (TypeSpec ts)
+ static bool CheckFieldTypeCycle (TypeSpec ts)
{
var fts = ts.MemberDefinition as Struct;
if (fts == null)
return true;
- return CheckStructCycles (fts);
+ return fts.CheckStructCycles ();
}
public override void Emit ()
{
- CheckStructCycles (this);
+ CheckStructCycles ();
base.Emit ();
}
if (requires_delayed_unmanagedtype_check)
return true;
- if (Parent != null && Parent.IsGenericOrParentIsGeneric) {
+ var parent_def = Parent.PartialContainer;
+ if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
has_unmanaged_check_done = true;
return false;
}
- if (fields != null) {
+ if (first_nonstatic_field != null) {
requires_delayed_unmanagedtype_check = true;
- foreach (FieldBase f in fields) {
+ foreach (var member in Members) {
+ var f = member as Field;
+ if (f == null)
+ continue;
+
if (f.IsStatic)
continue;
return ifaces;
}
- protected override TypeAttributes TypeAttr {
- get {
- const TypeAttributes DefaultTypeAttributes =
- TypeAttributes.SequentialLayout |
- TypeAttributes.Sealed;
-
- return base.TypeAttr | DefaultTypeAttributes;
- }
- }
-
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
if ((field.ModFlags & Modifiers.STATIC) == 0) {
/// <summary>
/// Interfaces
/// </summary>
- public sealed class Interface : TypeContainer {
+ public sealed class Interface : TypeDefinition {
/// <summary>
/// Modifiers allowed in a class declaration
Modifiers.UNSAFE |
Modifiers.PRIVATE;
- public Interface (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
- : base (ns, parent, name, attrs, MemberKind.Interface)
+ public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+ : base (parent, name, attrs, MemberKind.Interface)
{
- var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+ var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
spec = new TypeSpec (Kind, null, this, null, ModFlags);
//
// If true, this is an explicit interface implementation
//
- public bool IsExplicitImpl;
+ public readonly bool IsExplicitImpl;
protected bool is_external_implementation;
readonly Modifiers explicit_mod_flags;
public MethodAttributes flags;
- public InterfaceMemberBase (TypeContainer parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
+ public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
: base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
{
- IsInterface = parent.PartialContainer.Kind == MemberKind.Interface;
+ IsInterface = parent.Kind == MemberKind.Interface;
IsExplicitImpl = (MemberName.ExplicitInterface != null);
explicit_mod_flags = mod;
}
{
// for extern static method must be specified either DllImport attribute or MethodImplAttribute.
// We are more strict than csc and report this as an error because SRE does not allow emit that
- if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
+ if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
if (this is Constructor) {
Report.Warning (824, 1, Location,
"Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
get { return IsExplicitImpl || base.IsUsed; }
}
+ public override void SetConstraints (List<Constraints> constraints_list)
+ {
+ if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
+ Report.Error (460, Location,
+ "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
+ GetSignatureForError ());
+ }
+
+ base.SetConstraints (constraints_list);
+ }
}
public abstract class MemberBase : MemberCore
{
protected FullNamedExpression type_expr;
protected TypeSpec member_type;
+ public new TypeDefinition Parent;
- protected MemberBase (TypeContainer parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
+ protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
: base (parent, name, attrs)
{
+ this.Parent = parent;
this.type_expr = type;
- ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
+
+ if (name != MemberName.Null)
+ ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
}
#region Properties