// basenames in the defined_names array.
//
//
-#define CACHE
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Security.Permissions;
using System.Text;
-#if BOOTSTRAP_WITH_OLDLIB
+#if BOOTSTRAP_WITH_OLDLIB || NET_2_1
using XmlElement = System.Object;
#else
using System.Xml;
}
}
- public class MethodArrayList : MemberCoreArrayList
- {
- [Flags]
- enum CachedMethods {
- Equals = 1,
- GetHashCode = 1 << 1
- }
-
- CachedMethods cached_method;
- TypeContainer container;
-
- public MethodArrayList (TypeContainer container)
- {
- this.container = container;
- }
-
- /// <summary>
- /// Method container contains Equals method
- /// </summary>
- public bool HasEquals {
- set {
- cached_method |= CachedMethods.Equals;
- }
-
- get {
- return (cached_method & CachedMethods.Equals) != 0;
- }
- }
-
- /// <summary>
- /// Method container contains GetHashCode method
- /// </summary>
- public bool HasGetHashCode {
- set {
- cached_method |= CachedMethods.GetHashCode;
- }
-
- get {
- return (cached_method & CachedMethods.GetHashCode) != 0;
- }
- }
-
- public override void DefineContainerMembers ()
- {
- base.DefineContainerMembers ();
-
- if (HasEquals && !HasGetHashCode) {
- Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
- }
- }
- }
-
- public sealed class IndexerArrayList : MemberCoreArrayList
- {
- /// <summary>
- /// The indexer name for this container
- /// </summary>
- public string IndexerName = DefaultIndexerName;
-
- bool seen_normal_indexers = false;
-
- TypeContainer container;
-
- public IndexerArrayList (TypeContainer container)
- {
- this.container = container;
- }
-
- /// <summary>
- /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
- /// class is consistent. Either it is `Item' or it is the name defined by all the
- /// indexers with the `IndexerName' attribute.
- ///
- /// Turns out that the IndexerNameAttribute is applied to each indexer,
- /// but it is never emitted, instead a DefaultMember attribute is attached
- /// to the class.
- /// </summary>
- public override void DefineContainerMembers()
- {
- base.DefineContainerMembers ();
-
- 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.
- //
-
- // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
- foreach (Indexer i in this) {
- if (i.InterfaceType != null) {
- if (seen_normal_indexers)
- throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
- continue;
- }
-
- seen_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)
- IndexerName = class_indexer_name;
- }
-
- public override void Emit ()
- {
- base.Emit ();
-
- if (!seen_normal_indexers)
- return;
-
- CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
- container.TypeBuilder.SetCustomAttribute (cb);
- }
- }
-
public class OperatorArrayList: MemberCoreArrayList
{
TypeContainer container;
oe.op.GetSignatureForError (), s);
}
- if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
- if (container.Methods == null || !container.Methods.HasEquals)
+ if (has_equality_or_inequality && Report.WarningLevel > 2) {
+ if (container.Methods == null || !container.HasEquals)
Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
- if (container.Methods == null || !container.Methods.HasGetHashCode)
+ if (container.Methods == null || !container.HasGetHashCode)
Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
}
}
}
}
+ [Flags]
+ enum CachedMethods
+ {
+ Equals = 1,
+ GetHashCode = 1 << 1,
+ HasStaticFieldInitializer = 1 << 2
+ }
+
// Whether this is a struct, class or interface
public readonly Kind Kind;
// Holds a list of classes and structures
protected ArrayList types;
+ MemberCoreArrayList ordered_explicit_member_list;
+ MemberCoreArrayList ordered_member_list;
+
// Holds the list of properties
MemberCoreArrayList properties;
protected ArrayList initialized_static_fields;
// Holds the list of constants
- MemberCoreArrayList constants;
-
- // Holds the list of
- MemberCoreArrayList interfaces;
+ protected MemberCoreArrayList constants;
// Holds the methods.
- MethodArrayList methods;
+ MemberCoreArrayList methods;
// Holds the events
protected MemberCoreArrayList events;
// Holds the indexers
- IndexerArrayList indexers;
+ ArrayList indexers;
// Holds the operators
MemberCoreArrayList operators;
// The base member cache and our member cache
MemberCache base_cache;
- MemberCache member_cache;
+ protected MemberCache member_cache;
public const string DefaultIndexerName = "Item";
+ private bool seen_normal_indexers = false;
+ private string indexer_name = DefaultIndexerName;
+
+ private CachedMethods cached_method;
+
#if GMCS_SOURCE
GenericTypeParameterBuilder[] gen_params;
#endif
constants.Add (constant);
}
- public TypeContainer AddTypeContainer (TypeContainer tc, bool is_interface)
+ public TypeContainer AddTypeContainer (TypeContainer tc)
{
if (!AddMemberType (tc))
return tc;
- if (is_interface) {
- if (interfaces == null)
- interfaces = new MemberCoreArrayList ();
- interfaces.Add (tc);
- } else {
- if (types == null)
- types = new ArrayList (2);
- types.Add (tc);
- }
+ if (types == null)
+ types = new MemberCoreArrayList ();
+ types.Add (tc);
+
return tc;
}
- public virtual TypeContainer AddPartial (TypeContainer nextPart, bool is_interface)
+ public virtual TypeContainer AddPartial (TypeContainer next_part)
{
- return AddPartial (nextPart, nextPart.Basename, is_interface);
+ return AddPartial (next_part, next_part.Basename);
}
- protected TypeContainer AddPartial (TypeContainer nextPart, string name, bool is_interface)
+ protected TypeContainer AddPartial (TypeContainer next_part, string name)
{
- nextPart.ModFlags |= Modifiers.PARTIAL;
+ next_part.ModFlags |= Modifiers.PARTIAL;
TypeContainer tc = defined_names [name] as TypeContainer;
if (tc == null)
- return AddTypeContainer (nextPart, is_interface);
+ return AddTypeContainer (next_part);
if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
Report.SymbolRelatedToPreviousError (tc);
- Error_MissingPartialModifier (nextPart);
- return tc;
+ Error_MissingPartialModifier (next_part);
}
- if (tc.Kind != nextPart.Kind) {
+ if (tc.Kind != next_part.Kind) {
Report.SymbolRelatedToPreviousError (tc);
- Report.Error (261, nextPart.Location,
+ Report.Error (261, next_part.Location,
"Partial declarations of `{0}' must be all classes, all structs or all interfaces",
- nextPart.GetSignatureForError ());
- return tc;
+ next_part.GetSignatureForError ());
}
- if ((tc.ModFlags & Modifiers.Accessibility) != (nextPart.ModFlags & Modifiers.Accessibility) &&
+ if ((tc.ModFlags & Modifiers.Accessibility) != (next_part.ModFlags & Modifiers.Accessibility) &&
((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
- (nextPart.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
+ (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
Report.SymbolRelatedToPreviousError (tc);
- Report.Error (262, nextPart.Location,
+ Report.Error (262, next_part.Location,
"Partial declarations of `{0}' have conflicting accessibility modifiers",
- nextPart.GetSignatureForError ());
- return tc;
+ next_part.GetSignatureForError ());
}
if (tc.MemberName.IsGeneric) {
TypeParameter[] tc_names = tc.TypeParameters;
- TypeParameterName[] part_names = nextPart.MemberName.TypeArguments.GetDeclarations ();
+ TypeParameterName[] part_names = next_part.MemberName.TypeArguments.GetDeclarations ();
for (int i = 0; i < tc_names.Length; ++i) {
if (tc_names[i].Name == part_names[i].Name)
Report.SymbolRelatedToPreviousError (part_names[i].Location, "");
Report.Error (264, tc.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
tc.GetSignatureForError ());
- return tc;
}
}
if (tc.partial_parts == null)
tc.partial_parts = new ArrayList (1);
- tc.ModFlags |= nextPart.ModFlags;
- if (nextPart.attributes != null) {
+ if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.Accessibility);
+ } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.Accessibility);
+ tc.ModFlags |= next_part.ModFlags;
+ } else {
+ tc.ModFlags |= next_part.ModFlags;
+ }
+
+ if (next_part.attributes != null) {
if (tc.attributes == null)
- tc.attributes = nextPart.attributes;
+ tc.attributes = next_part.attributes;
else
- tc.attributes.AddAttributes (nextPart.attributes.Attrs);
+ tc.attributes.AddAttributes (next_part.attributes.Attrs);
}
- nextPart.PartialContainer = tc;
- tc.partial_parts.Add (nextPart);
+ next_part.PartialContainer = tc;
+ tc.partial_parts.Add (next_part);
return tc;
}
delegates.Add (d);
}
+ private void AddMemberToList (MemberCore mc, ArrayList alist, bool isexplicit)
+ {
+ if (ordered_explicit_member_list == null) {
+ ordered_explicit_member_list = new MemberCoreArrayList ();
+ ordered_member_list = new MemberCoreArrayList ();
+ }
+
+ if(isexplicit) {
+ ordered_explicit_member_list.Add (mc);
+ alist.Insert (0, mc);
+ }
+ else {
+ ordered_member_list.Add (mc);
+ alist.Add (mc);
+ }
+
+ }
+
public void AddMethod (Method method)
{
- if (!AddMember (method))
+ MemberName mn = method.MemberName;
+ if (!AddToContainer (method, mn.IsGeneric ? mn.Basename : mn.MethodName))
return;
-
- if (methods == null)
- methods = new MethodArrayList (this);
- if (method.MemberName.Left != null)
- methods.Insert (0, method);
+ if (methods == null)
+ methods = new MemberCoreArrayList ();
+
+ if (method.MemberName.Left != null)
+ AddMemberToList (method, methods, true);
else
- methods.Add (method);
+ AddMemberToList (method, methods, false);
}
//
return;
if (methods == null)
- methods = new MethodArrayList (this);
+ methods = new MemberCoreArrayList ();
- methods.Add (method);
+ AddMemberToList (method, methods, false);
}
public void AddConstructor (Constructor c)
}
bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
+ if (!AddToContainer (c, is_static ?
+ ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
+ return;
if (is_static){
if (default_static_constructor != null) {
- Report.SymbolRelatedToPreviousError (default_static_constructor);
- Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
- return;
+ 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;
}
default_static_constructor = c;
} else {
- if (c.Parameters.Empty){
- if (default_constructor != null) {
- Report.SymbolRelatedToPreviousError (default_constructor);
- Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
- return;
- }
+ if (c.Parameters.Empty)
default_constructor = c;
- }
if (instance_constructors == null)
instance_constructors = new MemberCoreArrayList ();
}
}
- internal static string Error111 {
- get {
- return "`{0}' is already defined. Rename this member or use different parameter types";
- }
- }
-
- public void AddField (FieldBase field)
+ public bool AddField (FieldBase field)
{
if (!AddMember (field))
- return;
+ return false;
if (fields == null)
fields = new MemberCoreArrayList ();
fields.Add (field);
if ((field.ModFlags & Modifiers.STATIC) != 0)
- return;
+ return true;
if (first_nonstatic_field == null) {
first_nonstatic_field = field;
- return;
+ return true;
}
- if (Kind == Kind.Struct &&
- first_nonstatic_field.Parent != field.Parent &&
- RootContext.WarningLevel >= 3) {
+ if (Kind == Kind.Struct && first_nonstatic_field.Parent != field.Parent) {
Report.SymbolRelatedToPreviousError (first_nonstatic_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 ());
}
+ return true;
}
public void AddProperty (Property prop)
properties = new MemberCoreArrayList ();
if (prop.MemberName.Left != null)
- properties.Insert (0, prop);
- else
- properties.Add (prop);
+ AddMemberToList (prop, properties, true);
+ else
+ AddMemberToList (prop, properties, false);
}
public void AddEvent (Event e)
public void AddIndexer (Indexer i)
{
if (indexers == null)
- indexers = new IndexerArrayList (this);
+ indexers = new ArrayList ();
if (i.IsExplicitImpl)
- indexers.Insert (0, i);
- else
- indexers.Add (i);
+ AddMemberToList (i, indexers, true);
+ else
+ AddMemberToList (i, indexers, false);
}
public void AddOperator (Operator op)
}
}
- public MethodArrayList Methods {
+ public MemberCoreArrayList Methods {
get {
return methods;
}
}
}
- public ArrayList Interfaces {
- get {
- return interfaces;
- }
- }
-
public ArrayList CompilerGenerated {
get {
return compiler_generated;
public string IndexerName {
get {
- return indexers == null ? DefaultIndexerName : indexers.IndexerName;
+ return indexers == null ? DefaultIndexerName : indexer_name;
}
}
public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
if ((field.ModFlags & Modifiers.STATIC) != 0){
- if (initialized_static_fields == null)
+ if (initialized_static_fields == null) {
+ PartialContainer.HasStaticFieldInitializer = true;
initialized_static_fields = new ArrayList (4);
+ }
initialized_static_fields.Add (expression);
} else {
}
}
+ public void ResolveFieldInitializers (EmitContext ec)
+ {
+ // Field initializers are tricky for partial classes. They have to
+ // share same costructor (block) but they have they own resolve scope.
+ DeclSpace orig = ec.DeclContainer;
+
+ if (partial_parts != null) {
+ foreach (TypeContainer part in partial_parts) {
+ ec.DeclContainer = part;
+ part.DoResolveFieldInitializers (ec);
+ }
+ }
+ ec.DeclContainer = PartialContainer;
+ DoResolveFieldInitializers (ec);
+ ec.DeclContainer = orig;
+ }
+
+ void DoResolveFieldInitializers (EmitContext ec)
+ {
+ if (ec.IsStatic) {
+ if (initialized_static_fields == null)
+ return;
+
+ bool has_complex_initializer = false;
+ using (ec.Set (EmitContext.Flags.InFieldInitializer)) {
+ foreach (FieldInitializer fi in initialized_static_fields) {
+ fi.ResolveStatement (ec);
+ if (!fi.IsComplexInitializer)
+ continue;
+
+ has_complex_initializer = true;
+ }
+
+ // Need special check to not optimize code like this
+ // static int a = b = 5;
+ // static int b = 0;
+ if (!has_complex_initializer && RootContext.Optimize) {
+ for (int i = 0; i < initialized_static_fields.Count; ++i) {
+ FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
+ if (fi.IsDefaultInitializer) {
+ initialized_static_fields.RemoveAt (i);
+ --i;
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ if (initialized_fields == null)
+ return;
+
+ using (ec.Set (EmitContext.Flags.InFieldInitializer)) {
+ for (int i = 0; i < initialized_fields.Count; ++i) {
+ FieldInitializer fi = (FieldInitializer) initialized_fields [i];
+ fi.ResolveStatement (ec);
+ if (fi.IsDefaultInitializer && RootContext.Optimize) {
+ // Field is re-initialized to its default value => removed
+ initialized_fields.RemoveAt (i);
+ --i;
+ }
+ }
+ }
+ }
+
//
// Emits the instance field initializers
//
public bool EmitFieldInitializers (EmitContext ec)
{
+ if (partial_parts != null) {
+ foreach (TypeContainer part in partial_parts)
+ part.EmitFieldInitializers (ec);
+ }
+
ArrayList fields;
if (ec.IsStatic){
return base.GetClsCompliantAttributeValue ();
}
- public void AddBasesForPart (DeclSpace part, ArrayList bases)
+ public virtual void AddBasesForPart (DeclSpace part, ArrayList bases)
{
// FIXME: get rid of partial_parts and store lists of bases of each part here
// assumed, not verified: 'part' is in 'partial_parts'
if (!CheckRecursiveDefinition (this))
return false;
- if (base_type != null) {
+ if (base_type != null && base_type.Type != null) {
TypeBuilder.SetParent (base_type.Type);
ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
part.TypeBuilder = TypeBuilder;
}
- if (Interfaces != null) {
- foreach (TypeContainer iface in Interfaces) {
- if (iface.CreateType () == null) {
- error = true;
- return null;
- }
- }
- }
-
if (Types != null) {
foreach (TypeContainer tc in Types) {
if (tc.CreateType () == null) {
protected virtual bool DefineNestedTypes ()
{
- if (Interfaces != null) {
- foreach (TypeContainer iface in Interfaces)
- if (iface.DefineType () == null)
- return false;
- }
-
if (Types != null) {
foreach (TypeContainer tc in Types)
if (tc.DefineType () == null)
InTransit = tc;
- if (base_type != null) {
+ if (base_type != null && base_type.Type != null) {
Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
TypeContainer ptc = TypeManager.LookupTypeContainer (t);
if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
ConstructedType ct = base_type as ConstructedType;
if ((ct != null) && !ct.CheckConstraints (this))
return false;
+
+ member_cache = new MemberCache (base_type.Type, this);
+ } else if (Kind == Kind.Interface) {
+ member_cache = new MemberCache (null, this);
+ Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder);
+ for (int i = 0; i < ifaces.Length; ++i)
+ member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i]));
+ } else {
+ member_cache = new MemberCache (null, this);
+ }
+
+ if (types != null)
+ foreach (TypeContainer tc in types)
+ member_cache.AddNestedType (tc);
+
+ if (delegates != null)
+ foreach (Delegate d in delegates)
+ member_cache.AddNestedType (d);
+
+ if (partial_parts != null) {
+ foreach (TypeContainer part in partial_parts)
+ part.member_cache = member_cache;
}
if (!IsTopLevel) {
MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
if (conflict_symbol == null) {
- if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
+ 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) {
//
DefineContainerMembers (instance_constructors);
- DefineContainerMembers (properties);
DefineContainerMembers (events);
- DefineContainerMembers (indexers);
- DefineContainerMembers (methods);
+ DefineContainerMembers (ordered_explicit_member_list);
+ DefineContainerMembers (ordered_member_list);
+
DefineContainerMembers (operators);
DefineContainerMembers (delegates);
+ ComputeIndexerName();
+ CheckEqualsAndGetHashCode();
+
if (CurrentType != null) {
GenericType = CurrentType;
}
-#if CACHE
- member_cache = new MemberCache (this);
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts)
- part.member_cache = member_cache;
- }
-#endif
+#if GMCS_SOURCE
+ //
+ // FIXME: This hack is needed because member cache does not work
+ // with generic types, we rely on runtime to inflate dynamic types.
+ // TODO: This hack requires member cache refactoring to be removed
+ //
+ if (TypeBuilder.IsGenericType)
+ member_cache = new MemberCache (this);
+#endif
return true;
}
if (mcal != null)
mcal.DefineContainerMembers ();
}
+
+ protected virtual void ComputeIndexerName ()
+ {
+ 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.
+ //
+
+ // 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.");
+ continue;
+ }
+
+ seen_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;
+ }
+
+ protected virtual void EmitIndexerName ()
+ {
+ if (!seen_normal_indexers)
+ return;
+
+ CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
+ TypeBuilder.SetCustomAttribute (cb);
+ }
+
+ 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 ());
+ }
+ }
public override bool Define ()
{
if (PartialContainer != this)
throw new InternalErrorException ("should not happen");
- ArrayList [] lists = { types, delegates, interfaces };
+ ArrayList [] lists = { types, delegates };
for (int j = 0; j < lists.Length; ++j) {
ArrayList list = lists [j];
BindingFlags bf, MemberFilter filter, object criteria,
ref ArrayList members)
{
- ArrayList [] lists = { types, delegates, interfaces };
+ ArrayList [] lists = { types, delegates };
for (int j = 0; j < lists.Length; ++j) {
ArrayList list = lists [j];
//
// Since the whole process is a no-op, it is fine to check for null here.
//
+ // TODO: This approach will be one day completely removed, it's already
+ // used at few places only
+ //
+ //
public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
MemberFilter filter, object criteria)
{
if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
continue;
- if (!mc.IsUsed) {
+ 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 ());
}
}
//
// Check for internal or private fields that were never assigned
//
- if (RootContext.WarningLevel >= 3) {
+ if (Report.WarningLevel >= 3) {
CheckMemberUsage (properties, "property");
CheckMemberUsage (methods, "method");
CheckMemberUsage (constants, "constant");
//
// Only report 649 on level 4
//
- if (RootContext.WarningLevel < 4)
+ if (Report.WarningLevel < 4)
continue;
if ((f.caching_flags & Flags.IsAssigned) != 0)
if (IsGeneric) {
int offset = CountTypeParameters - CurrentTypeParameters.Length;
for (int i = offset; i < gen_params.Length; i++)
- CurrentTypeParameters [i - offset].EmitAttributes ();
+ CurrentTypeParameters [i - offset].Emit ();
}
#endif
default_static_constructor.Emit ();
if (methods != null){
- foreach (Method m in methods)
- m.Emit ();
+ for (int i = 0; i < methods.Count; ++i)
+ ((Method)methods[i]).Emit ();
}
if (operators != null)
foreach (Property p in properties)
p.Emit ();
- if (indexers != null){
- indexers.Emit ();
+ if (indexers != null) {
+ foreach (Indexer indx in indexers)
+ indx.Emit ();
+ EmitIndexerName ();
}
if (fields != null)
initialized_fields = null;
initialized_static_fields = null;
constants = null;
- interfaces = null;
+ ordered_explicit_member_list = null;
+ ordered_member_list = null;
methods = null;
events = null;
indexers = null;
public void Mark_HasEquals ()
{
- Methods.HasEquals = true;
+ cached_method |= CachedMethods.Equals;
}
public void Mark_HasGetHashCode ()
{
- Methods.HasGetHashCode = true;
+ cached_method |= CachedMethods.GetHashCode;
+ }
+
+ /// <summary>
+ /// Method container contains Equals method
+ /// </summary>
+ public bool HasEquals {
+ get {
+ return (cached_method & CachedMethods.Equals) != 0;
+ }
+ }
+
+ /// <summary>
+ /// Method container contains GetHashCode method
+ /// </summary>
+ public bool HasGetHashCode {
+ get {
+ return (cached_method & CachedMethods.GetHashCode) != 0;
+ }
+ }
+
+ public bool HasStaticFieldInitializer {
+ get {
+ return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
+ }
+ set {
+ if (value)
+ cached_method |= CachedMethods.HasStaticFieldInitializer;
+ else
+ cached_method &= ~CachedMethods.HasStaticFieldInitializer;
+ }
}
//
}
}
- MemberCache IMemberContainer.MemberCache {
- get {
- return member_cache;
- }
- }
-
bool IMemberContainer.IsInterface {
get {
return Kind == Kind.Interface;
get { return "T:"; }
}
- public virtual MemberCache BaseCache {
+ public MemberCache BaseCache {
get {
if (base_cache != null)
return base_cache;
{
base.VerifyMembers ();
- if ((events != null) && (RootContext.WarningLevel >= 3)) {
+ if ((events != null) && Report.WarningLevel >= 3) {
foreach (Event e in events){
- if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
- continue;
-
+ // 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 ());
}
c.Block = new ToplevelBlock (null, Location);
}
- void DefineFieldInitializers ()
- {
- if (initialized_fields != null) {
- for (int i = 0; i < initialized_fields.Count; ++i) {
- FieldInitializer fi = (FieldInitializer)initialized_fields[i];
-
- EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
- Location, null, null, ModFlags);
- ec.IsFieldInitializer = true;
-
- fi.ResolveStatement (ec);
- if (fi.IsDefaultInitializer && RootContext.Optimize) {
- // Field is re-initialized to its default value => removed
- initialized_fields.RemoveAt (i);
- --i;
- }
- }
- }
-
- if (initialized_static_fields != null) {
- bool has_complex_initializer = false;
-
- foreach (FieldInitializer fi in initialized_static_fields) {
- EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
- Location, null, null, ModFlags);
- ec.IsStatic = true;
- ec.IsFieldInitializer = true;
-
- fi.ResolveStatement (ec);
- if (!fi.IsComplexInitializer)
- continue;
-
- has_complex_initializer = true;
- }
-
- // Need special check to not optimize code like this
- // static int a = b = 5;
- // static int b = 0;
- if (!has_complex_initializer && RootContext.Optimize) {
- for (int i = 0; i < initialized_static_fields.Count; ++i) {
- FieldInitializer fi = (FieldInitializer)initialized_static_fields[i];
- if (fi.IsDefaultInitializer) {
- initialized_static_fields.RemoveAt (i);
- --i;
- }
- }
- }
-
- if (default_static_constructor == null && initialized_static_fields.Count > 0) {
- DefineDefaultConstructor (true);
- }
- }
-
- }
-
public override bool Define ()
{
- DefineFieldInitializers ();
+ if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer)
+ DefineDefaultConstructor (true);
if (default_static_constructor != null)
default_static_constructor.Define ();
public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name)
{
- return NamespaceEntry.LookupExtensionMethod (extensionType, true, name);
+ return NamespaceEntry.LookupExtensionMethod (extensionType, this, name);
}
protected override TypeAttributes TypeAttr {
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
- Report.FeatureIsNotISO1 (Location, "static classes");
+ Report.FeatureIsNotAvailable (Location, "static classes");
}
}
+ public override void AddBasesForPart (DeclSpace part, ArrayList bases)
+ {
+ if (part.Name == "System.Object")
+ Report.Error (537, part.Location,
+ "The class System.Object cannot have a base class or implement an interface.");
+ base.AddBasesForPart (part, bases);
+ }
+
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.attribute_usage_type) {
}
}
- if (IsStatic) {
- if (base_class != TypeManager.system_object_expr) {
+ if (PartialContainer.IsStaticClass) {
+ if (base_class.Type != TypeManager.object_type) {
Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
GetSignatureForError (), base_class.GetSignatureForError ());
return ifaces;
if (ifaces != null) {
foreach (TypeExpr t in ifaces)
Report.SymbolRelatedToPreviousError (t.Type);
- Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
+ Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
}
}
{
}
- protected override bool CheckForDuplications ()
- {
- throw new NotSupportedException ();
- }
-
protected override bool VerifyClsCompliance ()
{
if (!base.VerifyClsCompliance ())
if (!DefineParameters (Parameters))
return false;
- if (!base.CheckBase ())
- return false;
-
- return true;
- }
-
- // TODO: create a special method for operators only to make code better
- protected bool IsDuplicateImplementation (MethodCore method)
- {
- if (method == this)
- return false;
-
- Operator op2 = null;
- Operator op1 = null;
-
- if (!(method.MemberName.Equals (MemberName)))
- {
- op1 = this as Operator;
- if (op1 == null || !(op1.OperatorType == Operator.OpType.Explicit || op1.OperatorType == Operator.OpType.Implicit))
- return false;
-
- op2 = method as Operator;
- if (op2 == null || !(op2.OperatorType == Operator.OpType.Explicit || op2.OperatorType == Operator.OpType.Implicit))
+ if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
+ if (!Parent.MemberCache.CheckExistingMembersOverloads (this,
+ MemberName.IsGeneric ? MemberName.Basename : MemberName.MethodName, Parameters))
return false;
- } else {
- op1 = this as Operator;
- op2 = method as Operator;
- }
-
- Type[] param_types = method.ParameterTypes;
- // This never happen. Rewrite this as Equal
- if (param_types == null && ParameterTypes == null)
- return true;
- if (param_types == null || ParameterTypes == null)
- return false;
-
- if (param_types.Length != ParameterTypes.Length)
- return false;
-
- if (method.Parameters.HasArglist != Parameters.HasArglist)
- return false;
-
- bool equal = true;
-
- for (int i = 0; i < param_types.Length; i++) {
- if (param_types [i] != ParameterTypes [i])
- equal = false;
- }
- if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
- equal = false;
-
- // TODO: make operator compatible with MethodCore to avoid this
- if (op1 != null && op2 != null) {
- if (MemberType != method.MemberType)
- equal = false;
- }
-
- if (equal) {
- //
- // Try to report 663: method only differs on out/ref
- //
- Parameters info = ParameterInfo;
- Parameters other_info = method.ParameterInfo;
- for (int i = 0; i < info.Count; i++){
- if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
- Report.SymbolRelatedToPreviousError (method);
- Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
- GetSignatureForError ());
+ // TODO: Find a better way how to check reserved accessors collision
+ Method m = this as Method;
+ if (m != null) {
+ if (!m.CheckForDuplications ())
return false;
- }
}
-
- Report.SymbolRelatedToPreviousError (method);
- if (this is Operator && method is Operator)
- Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
- else
- Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
-
- return true;
}
- return false;
+ if (!base.CheckBase ())
+ return false;
+
+ return true;
}
//
get { return "M:"; }
}
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ if (overload is MethodCore || overload is AbstractPropertyEventMethod) {
+ caching_flags |= Flags.MethodOverloadsExist;
+ return true;
+ }
+
+ return false;
+ }
+
public virtual void SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;
if (!base.CheckBase ())
return false;
- if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
- return false;
-
if (IsExplicitImpl)
return true;
}
if (conflict_symbol == null) {
- if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+ 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 ());
}
return true;
// `name' is the user visible name for reporting errors (this is used to
// provide the right name regarding method names and properties)
//
- bool CheckMethodAgainstBase (Type baseMethodType)
+ bool CheckMethodAgainstBase (Type base_method_type)
{
bool ok = true;
ok = false;
}
- if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (baseMethodType))) {
+ if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
Report.SymbolRelatedToPreviousError (base_method);
if (this is PropertyBasedMember) {
Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
- GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
+ GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
}
else {
Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
- GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
+ GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
}
ok = false;
}
if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
//
// when overriding protected internal, the method can be declared
- // protected internal only within the same assembly
+ // protected internal only within the same assembly or assembly
+ // which has InternalsVisibleTo
//
-
if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
- //
- // assemblies differ - report an error
- //
-
- return false;
- } else if (thisp != base_classp) {
+ if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly)
+ return TypeManager.IsFriendAssembly (base_method.DeclaringType.Assembly);
+
+ if (thisp != base_classp) {
//
// same assembly, but other attributes differ - report an error
//
return false;
- };
+ }
} else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
//
// if it's not "protected internal", it must be "protected"
}
}
- public bool CheckAbstractAndExtern (bool has_block)
- {
- if (Parent.PartialContainer.Kind == Kind.Interface)
- return true;
-
- if (has_block) {
- if ((ModFlags & Modifiers.EXTERN) != 0) {
- Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
- GetSignatureForError ());
- return false;
- }
-
- if ((ModFlags & Modifiers.ABSTRACT) != 0) {
- Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
- GetSignatureForError ());
- return false;
- }
- } else {
- if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
- Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
- GetSignatureForError ());
- return false;
- }
- }
-
- return true;
- }
-
protected bool DefineParameters (Parameters parameters)
{
IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
if (iface_texpr == null)
return false;
+ if ((ModFlags & Modifiers.PARTIAL) != 0) {
+ Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
+ GetSignatureForError ());
+ return false;
+ }
+
InterfaceType = iface_texpr.Type;
if (!InterfaceType.IsInterface) {
}
}
- /// <summary>
- /// For custom member duplication search in a container
- /// </summary>
- protected abstract bool CheckForDuplications ();
-
/// <summary>
/// Gets base method and its return type
/// </summary>
return;
}
- MethodBuilder.SetCustomAttribute (cb);
+ if (MethodBuilder != null)
+ MethodBuilder.SetCustomAttribute (cb);
}
public override AttributeTargets AttributeTargets {
}
#if MS_COMPATIBLE
- MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags, ReturnType, null);
+ MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags); //, ReturnType, null);
#else
MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags);
#endif
if (!CheckAbstractAndExtern (block != null))
return false;
+ if ((ModFlags & Modifiers.PARTIAL) != 0) {
+ for (int i = 0; i < Parameters.Count; ++i ) {
+ if (Parameters.ParameterModifier (i) == Parameter.Modifier.OUT) {
+ Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
+ GetSignatureForError ());
+ return false;
+ }
+ }
+ }
+
if (!CheckBase ())
return false;
+
+ if (IsPartialDefinition) {
+ caching_flags &= ~Flags.Excluded_Undetected;
+ caching_flags |= Flags.Excluded;
+ // Add to member cache only when a partial method implementation is not there
+ if ((caching_flags & Flags.MethodOverloadsExist) == 0) {
+ MethodBase mb = new PartialMethodDefinitionInfo (this);
+ Parent.MemberCache.AddMember (mb, this);
+ TypeManager.AddMethod (mb, this);
+ }
+
+ return true;
+ }
MethodData = new MethodData (
this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
if (!MethodData.Define (Parent.PartialContainer))
return false;
-
+
MethodBuilder = MethodData.MethodBuilder;
+#if GMCS_SOURCE
+ if (MethodBuilder.IsGenericMethod)
+ Parent.MemberCache.AddGenericMember (MethodBuilder, this);
+#endif
+
+ Parent.MemberCache.AddMember (MethodBuilder, this);
+
if (!TypeManager.IsGenericParameter (MemberType)) {
if (MemberType.IsAbstract && MemberType.IsSealed) {
Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
public override void Emit ()
{
+#if GMCS_SOURCE
+ if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0)
+ MethodBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
+#endif
if (OptAttributes != null)
OptAttributes.Emit ();
GetSignatureForError ());
}
- public override bool MarkForDuplicationCheck ()
- {
- caching_flags |= Flags.TestMethodDuplication;
- return true;
+ public bool IsPartialDefinition {
+ get {
+ return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
+ }
+ }
+
+ public bool IsPartialImplementation {
+ get {
+ return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
+ }
}
public override string[] ValidAttributeTargets {
return true;
}
- IMethodData md = TypeManager.GetMethod (base_method);
+ IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
if (md == null) {
if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
caching_flags |= Flags.Excluded;
}
if (MethodData.implementing != null) {
+ Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
return;
base.ApplyAttributeBuilder (a, cb);
}
- protected override bool CheckForDuplications ()
+ public bool CheckForDuplications ()
{
- ArrayList ar = Parent.PartialContainer.Methods;
- if (ar != null) {
- int arLen = ar.Count;
-
- for (int i = 0; i < arLen; i++) {
- Method m = (Method) ar [i];
- if (IsDuplicateImplementation (m))
- return false;
- }
- }
-
- ar = Parent.PartialContainer.Properties;
+ ArrayList ar = Parent.PartialContainer.Properties;
if (ar != null) {
for (int i = 0; i < ar.Count; ++i) {
PropertyBase pb = (PropertyBase) ar [i];
}
}
- ar = Parent.PartialContainer.Events;
- if (ar != null) {
- for (int i = 0; i < ar.Count; ++i) {
- Event ev = (Event) ar [i];
- if (ev.AreAccessorsDuplicateImplementation (this))
- return false;
- }
- }
-
return true;
}
//
public override void Emit ()
{
- Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
- MethodData.Emit (Parent);
- base.Emit ();
+ try {
+ Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
+ if (IsPartialDefinition) {
+ //
+ // Do attribute checks only when partial implementation does not exist
+ //
+ if (MethodBuilder == null)
+ base.Emit ();
- if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
- MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
+ return;
+ }
- Block = null;
- MethodData = null;
+ if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0)
+ Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
+ GetSignatureForError ());
+
+ MethodData.Emit (Parent);
+ base.Emit ();
+
+ if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
+ MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
+
+ Block = null;
+ MethodData = null;
+ } catch {
+ Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
+ Location, MethodBuilder);
+ throw;
+ }
+ }
+
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ // TODO: It can be deleted when members will be defined in correct order
+ if (overload is Operator)
+ return overload.EnableOverloadChecks (this);
+
+ if (overload is Indexer)
+ return false;
+
+ return base.EnableOverloadChecks (overload);
}
public static void Error1599 (Location loc, Type t)
return mi;
}
+ public void SetPartialDefinition (Method methodDefinition)
+ {
+ caching_flags |= Flags.PartialDefinitionExists;
+ methodDefinition.MethodBuilder = MethodBuilder;
+ if (methodDefinition.attributes == null)
+ return;
+
+ if (attributes == null) {
+ attributes = methodDefinition.attributes;
+ } else {
+ attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
+ }
+ }
+
protected override bool VerifyClsCompliance ()
{
if (!base.VerifyClsCompliance ())
}
}
- public abstract class ConstructorInitializer {
- ArrayList argument_list;
- protected ConstructorInfo base_constructor;
- Location loc;
+ public abstract class ConstructorInitializer : Expression
+ {
+ readonly ArrayList argument_list;
+ MethodGroupExpr base_constructor_group;
public ConstructorInitializer (ArrayList argument_list, Location loc)
{
}
}
- public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
+ public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
{
- Expression base_constructor_group;
- Type t;
- bool error = false;
-
- ec.CurrentBlock = block;
-
if (argument_list != null){
foreach (Argument a in argument_list){
if (!a.Resolve (ec, loc))
return false;
}
}
- ec.CurrentBlock = null;
if (this is ConstructorBaseInitializer) {
if (ec.ContainerType.BaseType == null)
return true;
- t = ec.ContainerType.BaseType;
+ type = ec.ContainerType.BaseType;
if (ec.ContainerType.IsValueType) {
Report.Error (522, loc,
"`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
if (ec.ContainerType.IsValueType && argument_list == null)
return true;
- t = ec.ContainerType;
+ type = ec.ContainerType;
}
- base_constructor_group = Expression.MemberLookup (
- ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
+ base_constructor_group = MemberLookupFinal (
+ ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- loc);
-
- if (base_constructor_group == null){
- error = true;
- base_constructor_group = Expression.MemberLookup (
- t, null, t, ".ctor", MemberTypes.Constructor,
- BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- loc);
- }
-
- int errors = Report.Errors;
- if (base_constructor_group != null)
- base_constructor = (ConstructorInfo)
- ((MethodGroupExpr) base_constructor_group).OverloadResolve (
- ec, argument_list,
- false, loc);
+ loc) as MethodGroupExpr;
- if (base_constructor == null) {
- if (errors == Report.Errors)
- Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
- argument_list == null ? 0 : argument_list.Count);
+ if (base_constructor_group == null)
return false;
- }
-
- if (error) {
- Report.SymbolRelatedToPreviousError (base_constructor);
- Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
- base_constructor = null;
+
+ base_constructor_group = base_constructor_group.OverloadResolve (
+ ec, argument_list, false, loc);
+
+ if (base_constructor_group == null)
return false;
- }
- if (base_constructor == caller_builder){
+ ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
+
+ if (base_ctor == caller_builder){
Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
- return false;
}
-
+
return true;
}
- public virtual void Emit (EmitContext ec)
+ public override Expression DoResolve (EmitContext ec)
{
- if (base_constructor != null){
- ec.Mark (loc, false);
- if (ec.IsStatic)
- Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
- else
- Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
- }
+ throw new NotSupportedException ();
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ // It can be null for static initializers
+ if (base_constructor_group == null)
+ return;
+
+ ec.Mark (loc, false);
+ if (!ec.IsStatic)
+ base_constructor_group.InstanceExpression = ec.GetThis (loc);
+
+ base_constructor_group.EmitCall (ec, argument_list);
}
}
public ConstructorInitializer Initializer;
ListDictionary declarative_security;
ArrayList anonymous_methods;
+ bool has_compliant_args;
// <summary>
// Modifiers allowed for a constructor.
Modifiers.EXTERN |
Modifiers.PRIVATE;
- static string[] attribute_targets = new string [] { "method" };
+ static readonly string[] attribute_targets = new string [] { "method" };
- public Iterator Iterator {
- get { return null; }
- }
-
- bool has_compliant_args = false;
//
// The spec claims that static is not permitted, but
// my very own code has static constructors.
get { return AttributeTargets.Constructor; }
}
+ public Iterator Iterator {
+ get { return null; }
+ }
//
// Returns true if this is a default constructor
}
public bool ResolveMembers ()
- {
- if (anonymous_methods != null) {
- foreach (AnonymousMethodExpression ame in anonymous_methods) {
- if (!ame.CreateAnonymousHelpers ())
- return false;
- }
- }
-
- return true;
- }
-
- protected override bool CheckForDuplications ()
- {
- ArrayList ar = Parent.PartialContainer.InstanceConstructors;
- if (ar != null) {
- int arLen = ar.Count;
-
- for (int i = 0; i < arLen; i++) {
- Constructor m = (Constructor) ar [i];
- if (IsDuplicateImplementation (m))
+ {
+ if (anonymous_methods != null) {
+ foreach (AnonymousMethodExpression ame in anonymous_methods) {
+ if (!ame.CreateAnonymousHelpers ())
return false;
}
}
+
return true;
}
if (!DefineParameters (Parameters))
return false;
- if (!CheckForDuplications ())
- return false;
+ if ((caching_flags & Flags.MethodOverloadsExist) != 0)
+ Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorBuilder.ConstructorName,
+ Parameters);
if (Parent.PartialContainer.Kind == Kind.Struct) {
if (ParameterTypes.Length == 0) {
}
}
- if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
+ if ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0) {
Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
}
ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
}
+ Parent.MemberCache.AddMember (ConstructorBuilder, this);
TypeManager.AddMethod (ConstructorBuilder, this);
+
+ // It's here only to report an error
+ if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
+ member_type = TypeManager.void_type;
+ Iterator.CreateIterator (this, Parent, null, ModFlags);
+ }
return true;
}
if (OptAttributes != null)
OptAttributes.Emit ();
+ base.Emit ();
+
EmitContext ec = CreateEmitContext (null, null);
+ //
+ // If we use a "this (...)" constructor initializer, then
+ // do not emit field initializers, they are initialized in the other constructor
+ //
+ bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
+ !(Initializer is ConstructorThisInitializer);
+
+ if (emit_field_initializers)
+ Parent.PartialContainer.ResolveFieldInitializers (ec);
+
if (block != null) {
// If this is a non-static `struct' constructor and doesn't have any
// initializer, it must initialize all of the struct's fields.
if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
Initializer = new GeneratedBaseInitializer (Location);
-
//
// Spec mandates that Initializers will not have
// `this' access
//
ec.IsStatic = true;
if ((Initializer != null) &&
- !Initializer.Resolve (ConstructorBuilder, block, ec))
+ !Initializer.Resolve (ConstructorBuilder, ec))
return;
ec.IsStatic = false;
}
SourceMethod source = SourceMethod.Create (
Parent, ConstructorBuilder, block);
- //
- // Classes can have base initializers and instance field initializers.
- //
- if (Parent.PartialContainer.Kind == Kind.Class){
- if ((ModFlags & Modifiers.STATIC) == 0){
-
- //
- // If we use a "this (...)" constructor initializer, then
- // do not emit field initializers, they are initialized in the other constructor
- //
- if (!(Initializer != null && Initializer is ConstructorThisInitializer))
- Parent.PartialContainer.EmitFieldInitializers (ec);
- }
- }
-
bool unreachable = false;
if (block != null) {
if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
return;
+
ec.EmitMeta (block);
+ if (Report.Errors > 0)
+ return;
+
+ if (emit_field_initializers)
+ Parent.PartialContainer.EmitFieldInitializers (ec);
+
if (block.ScopeInfo != null) {
ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
init.EmitStatement (ec);
}
- }
- if (Initializer != null) {
- Initializer.Emit (ec);
- }
+ if (Initializer != null)
+ Initializer.Emit (ec);
- if ((ModFlags & Modifiers.STATIC) != 0)
- Parent.PartialContainer.EmitFieldInitializers (ec);
-
- if (block != null)
ec.EmitResolvedTopBlock (block, unreachable);
+ }
if (source != null)
source.CloseMethod ();
- base.Emit ();
-
if (declarative_security != null) {
foreach (DictionaryEntry de in declarative_security) {
ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
if (ParameterInfo.Count > 0) {
ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
- if (al.Count > 3)
+ if (al.Count > 2)
MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
{
ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
- return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
+ EmitContext ec = new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
+ ec.CurrentBlock = block;
+ return ec;
}
public bool IsExcluded()
if (implementing != null) {
AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
if (prop_method == null) {
- if (implementing.IsSpecialName) {
+ if (TypeManager.IsSpecialMethod (implementing)) {
Report.SymbolRelatedToPreviousError (implementing);
Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
implementing.Name.StartsWith ("get_") ? "get" : "set");
- return false;
}
} else if (implementing.DeclaringType.IsInterface) {
if (!implementing.IsSpecialName) {
flags |= MethodAttributes.Final;
}
- EmitContext ec = method.CreateEmitContext (container, null);
-
DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
if (builder == null)
if (implementing != null)
parent_method = implementing;
+ EmitContext ec = method.CreateEmitContext (container, null);
if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
return false;
}
return false;
}
- if ((RootContext.WarningLevel >= 4) &&
+ if (Report.WarningLevel >= 4 &&
((Parent.ModFlags & Modifiers.SEALED) != 0) &&
((ModFlags & Modifiers.PROTECTED) != 0) &&
((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
public override void Emit ()
{
+#if GMCS_SOURCE
+ if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0) {
+ FieldBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
+ }
+#endif
+
if (OptAttributes != null) {
OptAttributes.Emit ();
}
base.Emit ();
}
- public static void Error_VariableOfStaticClass (Location loc, string variableName, Type staticClass)
+ public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class)
{
- Report.SymbolRelatedToPreviousError (staticClass);
+ Report.SymbolRelatedToPreviousError (static_class);
Report.Error (723, loc, "`{0}': cannot declare variables of static types",
- variableName);
+ variable_name);
}
public Expression Initializer {
base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
{
if (RootContext.Version == LanguageVersion.ISO_1)
- Report.FeatureIsNotISO1 (loc, "fixed size buffers");
+ Report.FeatureIsNotAvailable (loc, "fixed size buffers");
this.size_expr = size_expr;
}
if (Parent.PartialContainer.Kind != Kind.Struct) {
Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
GetSignatureForError ());
- return false;
}
+ if (!Parent.IsInUnsafeScope)
+ Expression.UnsafeError (Location);
+
if (!base.Define ())
return false;
return false;
}
- EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
+ EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
Constant c = size_expr.ResolveAsConstant (ec, this);
if (c == null)
return false;
RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
+
+ Parent.MemberCache.AddMember (FieldBuilder, this);
TypeManager.RegisterFieldBase (FieldBuilder, this);
return true;
Modifiers.INTERNAL |
Modifiers.PRIVATE |
Modifiers.STATIC |
- Modifiers.VOLATILE |
- Modifiers.UNSAFE |
+ Modifiers.VOLATILE |
+ Modifiers.UNSAFE |
Modifiers.READONLY;
public Field (DeclSpace parent, Expression type, int mod, string name,
{
}
+ bool CanBeVolatile ()
+ {
+#if GMCS_SOURCE
+ if (TypeManager.IsGenericParameter (MemberType)) {
+ GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (MemberType);
+ if (constraints == null)
+ return false;
+
+ return constraints.IsReferenceType;
+ }
+#endif
+
+ if (!MemberType.IsValueType)
+ return true;
+
+ if (MemberType.IsEnum)
+ return true;
+
+ if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type ||
+ MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type ||
+ MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type ||
+ MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type ||
+ MemberType == TypeManager.float_type)
+ return true;
+
+ return false;
+ }
+
public override bool Define ()
{
if (!base.Define ())
return false;
- if (RootContext.WarningLevel > 1){
- Type ptype = Parent.TypeBuilder.BaseType;
-
- // ptype is only null for System.Object while compiling corlib.
- if (ptype != null){
- TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance,
- System.Type.FilterName, Name);
- }
- }
-
if ((ModFlags & Modifiers.VOLATILE) != 0){
- if (!MemberType.IsClass){
- Type vt = MemberType;
-
- if (TypeManager.IsEnumType (vt))
- vt = TypeManager.EnumToUnderlying (MemberType);
-
- if (!((vt == TypeManager.bool_type) ||
- (vt == TypeManager.sbyte_type) ||
- (vt == TypeManager.byte_type) ||
- (vt == TypeManager.short_type) ||
- (vt == TypeManager.ushort_type) ||
- (vt == TypeManager.int32_type) ||
- (vt == TypeManager.uint32_type) ||
- (vt == TypeManager.char_type) ||
- (vt == TypeManager.float_type) ||
- (!vt.IsValueType))){
- Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (vt));
- return false;
- }
+ if (!CanBeVolatile ()) {
+ Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
+ GetSignatureForError (), TypeManager.CSharpName (MemberType));
}
if ((ModFlags & Modifiers.READONLY) != 0){
Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
GetSignatureForError ());
- return false;
}
}
FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
- if (Parent.PartialContainer.Kind == Kind.Struct &&
- ((fa & FieldAttributes.Static) == 0) &&
- MemberType == Parent.TypeBuilder &&
- !TypeManager.IsBuiltinType (MemberType)){
- Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name +
- "' causes a cycle in the structure layout");
- return false;
- }
-
try {
FieldBuilder = Parent.TypeBuilder.DefineField (
Name, MemberType, Modifiers.FieldAttr (ModFlags));
+ Parent.MemberCache.AddMember (FieldBuilder, this);
TypeManager.RegisterFieldBase (FieldBuilder, this);
}
catch (ArgumentException) {
}
if (initializer != null)
- Parent.PartialContainer.RegisterFieldForInitialization (this,
- new FieldInitializer (FieldBuilder, initializer, Parent));
+ ((TypeContainer) Parent).RegisterFieldForInitialization (this,
+ new FieldInitializer (FieldBuilder, initializer));
+
+ if (Parent.PartialContainer.Kind == Kind.Struct && (fa & FieldAttributes.Static) == 0 &&
+ MemberType == Parent.TypeBuilder && !TypeManager.IsBuiltinType (MemberType) && initializer == null) {
+ Report.Error (523, Location, "Struct member `{0}' causes a cycle in the structure layout",
+ GetSignatureForError ());
+ return false;
+ }
return true;
}
virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
{
- System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
+ throw new NotSupportedException ("You forgot to define special attribute target handling");
}
// It is not supported for the accessors
{
EmitMethod (parent);
+#if GMCS_SOURCE
+ if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0)
+ method_data.MethodBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
+#endif
if (OptAttributes != null)
OptAttributes.Emit ();
method_data.Emit (parent);
}
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ // This can only happen with indexers and it will
+ // be catched as indexer difference
+ if (overload is AbstractPropertyEventMethod)
+ return true;
+
+ if (overload is MethodCore) {
+ caching_flags |= Flags.MethodOverloadsExist;
+ return true;
+ }
+ return false;
+ }
+
public override bool IsClsComplianceRequired()
{
return false;
Type[] param_types = method.ParameterTypes;
- if (param_types.Length != ParameterTypes.Length)
+ if (param_types == null || param_types.Length != ParameterTypes.Length)
return false;
for (int i = 0; i < param_types.Length; i++)
return false;
Report.SymbolRelatedToPreviousError (method);
- Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
+ Report.Error (82, Location, "A member `{0}' is already reserved",
+ method.GetSignatureForError ());
return true;
}
public override MethodBuilder Define (DeclSpace parent)
{
+ if (!CheckForDuplications ())
+ return null;
+
+ if (IsDummy)
+ return null;
+
base.Define (parent);
method_data = new MethodData (method, ModFlags, flags, this);
protected virtual void DefineParameters ()
{
- parameters = new Parameters (
- new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
- new Type[] { method.MemberType });
+ parameters = Parameters.CreateFullyResolved (
+ new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location));
}
public override MethodBuilder Define (DeclSpace parent)
{
+ if (!CheckForDuplications ())
+ return null;
+
if (IsDummy)
return null;
anonymous_methods = accessor.AnonymousMethods;
if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
- Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
+ Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
}
}
public virtual MethodBuilder Define (DeclSpace parent)
{
- if (!method.CheckAbstractAndExtern (block != null))
- return null;
-
TypeContainer container = parent.PartialContainer;
//
// Check for custom access modifier
//
- if (ModFlags == 0) {
- ModFlags = method.ModFlags;
+ if ((ModFlags & Modifiers.Accessibility) == 0) {
+ ModFlags |= method.ModFlags;
flags = method.flags;
} else {
if (container.Kind == Kind.Interface)
flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
}
+ CheckAbstractAndExtern (block != null);
return null;
}
void CheckModifiers (int modflags)
{
+ modflags &= Modifiers.Accessibility;
int flags = 0;
int mflags = method.ModFlags & Modifiers.Accessibility;
}
}
- public override bool MarkForDuplicationCheck ()
+ protected bool CheckForDuplications ()
{
- caching_flags |= Flags.TestMethodDuplication;
- return true;
+ if ((caching_flags & Flags.MethodOverloadsExist) == 0)
+ return true;
+
+ return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo);
}
}
//
// Accessors modifiers check
//
- if (Get.ModFlags != 0 && Set.ModFlags != 0) {
+ if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
+ (Set.ModFlags & Modifiers.Accessibility) != 0) {
Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
GetSignatureForError ());
return false;
return false;
}
- if (MemberType.IsAbstract && MemberType.IsSealed) {
+#if MS_COMPATIBLE
+ if (MemberType.IsGenericParameter)
+ return true;
+#endif
+
+ if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
return false;
}
bool DefineGet ()
{
- if (Get.IsDummy)
- return true;
-
GetBuilder = Get.Define (Parent);
- return GetBuilder != null;
+ return (Get.IsDummy) ? true : GetBuilder != null;
}
bool DefineSet (bool define)
{
- if (!define || Set.IsDummy)
+ if (!define)
return true;
SetBuilder = Set.Define (Parent);
- return SetBuilder != null;
+ return (Set.IsDummy) ? true : SetBuilder != null;
}
protected bool DefineAccessors ()
Modifiers.SEALED |
Modifiers.OVERRIDE |
Modifiers.ABSTRACT |
- Modifiers.UNSAFE |
+ Modifiers.UNSAFE |
Modifiers.EXTERN |
Modifiers.METHOD_YIELDS |
Modifiers.VIRTUAL;
const int AllowedInterfaceModifiers =
Modifiers.NEW;
+ void CreateAutomaticProperty (Block block, Accessor get_block, Accessor set_block)
+ {
+ // Make the field
+ Field field = new Field (
+ Parent, Type,
+ Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & Modifiers.STATIC),
+ "<" + Name + ">k__BackingField", null, Location);
+ ((TypeContainer)Parent).AddField (field);
+
+ // Make get block
+ get_block.Block = new ToplevelBlock (block, null, Location);
+ Return r = new Return (new SimpleName(field.Name, Location), Location);
+ get_block.Block.AddStatement (r);
+ get_block.ModFlags |= Modifiers.COMPILER_GENERATED;
+
+ // Make set block
+ Parameters parameters = new Parameters (new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location));
+ set_block.Block = new ToplevelBlock (block, parameters, Location);
+ Assign a = new Assign (new SimpleName(field.Name, Location), new SimpleName ("value", Location));
+ set_block.Block.AddStatement (new StatementExpression(a));
+ set_block.ModFlags |= Modifiers.COMPILER_GENERATED;
+ }
+
public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
MemberName name, Attributes attrs, Accessor get_block,
Accessor set_block, bool define_set_first)
+ : this (parent, type, mod, is_iface, name, attrs, get_block, set_block,
+ define_set_first, null)
+ {
+ }
+
+ public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
+ MemberName name, Attributes attrs, Accessor get_block,
+ Accessor set_block, bool define_set_first, Block current_block)
: base (parent, type, mod,
is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
is_iface, name, attrs, define_set_first)
{
+ if (!is_iface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
+ get_block != null && get_block.Block == null &&
+ set_block != null && set_block.Block == null) {
+ if (RootContext.Version <= LanguageVersion.ISO_2)
+ Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
+
+ CreateAutomaticProperty (current_block, get_block, set_block);
+ }
+
if (get_block == null)
Get = new GetMethod (this);
else
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
MemberName.ToString (), PropertyAttributes.None, MemberType, null);
- if (!Get.IsDummy)
+ if (!Get.IsDummy) {
PropertyBuilder.SetGetMethod (GetBuilder);
-
- if (!Set.IsDummy)
+ Parent.MemberCache.AddMember (GetBuilder, Get);
+ }
+
+ if (!Set.IsDummy) {
PropertyBuilder.SetSetMethod (SetBuilder);
+ Parent.MemberCache.AddMember (SetBuilder, Set);
+ }
TypeManager.RegisterProperty (PropertyBuilder, this);
+ Parent.MemberCache.AddMember (PropertyBuilder, this);
return true;
}
public override MethodBuilder Define (DeclSpace ds)
{
- method.CheckAbstractAndExtern (block != null);
+ CheckAbstractAndExtern (block != null);
return base.Define (ds);
}
+
+ public override string GetSignatureForError ()
+ {
+ return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
+ }
public override bool ResolveMembers ()
{
if (!base.Define ())
return false;
- if (IsExplicitImpl)
- SetMemberIsUsed ();
-
+ SetMemberIsUsed ();
return true;
}
// TODO: because we cannot use generics yet
FieldInfo field_info = ((EventField)method).FieldBuilder;
- mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
+ if (parent is Class) {
+ mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
+ }
+
if ((method.ModFlags & Modifiers.STATIC) != 0) {
ig.Emit (OpCodes.Ldsfld, field_info);
ig.Emit (OpCodes.Ldarg_0);
if (TypeManager.IsGenericType (MemberType))
SetMemberIsUsed();
+ if (Add.IsInterfaceImplementation)
+ SetMemberIsUsed ();
+
FieldBuilder = Parent.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
return false;
}
- Parent.PartialContainer.RegisterFieldForInitialization (this,
- new FieldInitializer (FieldBuilder, Initializer, Parent));
+ ((TypeContainer) Parent).RegisterFieldForInitialization (this,
+ new FieldInitializer (FieldBuilder, Initializer));
}
return true;
: base (method, prefix)
{
this.method = method;
+ this.ModFlags = method.ModFlags;
}
protected AEventAccessor (Event method, Accessor accessor, string prefix)
: base (method, accessor, prefix)
{
this.method = method;
+ this.ModFlags = method.ModFlags;
}
public override Iterator Iterator {
get { return null; }
}
+ public bool IsInterfaceImplementation {
+ get { return method_data.implementing != null; }
+ }
+
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.IsInternalMethodImplAttribute) {
return false;
}
- parameters = new Parameters (
- new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
- new Type[] { MemberType } );
+ parameters = Parameters.CreateFullyResolved (
+ new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location));
if (!CheckBase ())
return false;
EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);
EventBuilder.SetAddOnMethod (AddBuilder);
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
+
+ Parent.MemberCache.AddMember (EventBuilder, this);
+ Parent.MemberCache.AddMember (AddBuilder, Add);
+ Parent.MemberCache.AddMember (RemoveBuilder, Remove);
+
return true;
}
}
- public class Indexer : PropertyBase {
-
+ public class Indexer : PropertyBase
+ {
class GetIndexerMethod : GetMethod
{
public GetIndexerMethod (PropertyBase method):
base (method, accessor)
{
}
+
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ if (base.EnableOverloadChecks (overload)) {
+ overload.caching_flags |= Flags.MethodOverloadsExist;
+ return true;
+ }
+
+ return false;
+ }
public override Parameters ParameterInfo {
get {
parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
}
+
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ if (base.EnableOverloadChecks (overload)) {
+ overload.caching_flags |= Flags.MethodOverloadsExist;
+ return true;
+ }
+
+ return false;
+ }
}
const int AllowedModifiers =
is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
is_iface, name, attrs, define_set_first)
{
+ if (type == TypeManager.system_void_expr)
+ Report.Error (620, name.Location, "An indexer return type cannot be `void'");
+
this.parameters = parameters;
if (get_block == null)
Set = new SetIndexerMethod (this, set_block);
}
- protected override bool CheckForDuplications ()
- {
- ArrayList ar = Parent.PartialContainer.Indexers;
- if (ar != null) {
- int arLen = ar.Count;
-
- for (int i = 0; i < arLen; i++) {
- Indexer m = (Indexer) ar [i];
- if (IsDuplicateImplementation (m))
- return false;
- }
- }
-
- return true;
- }
-
- bool IsDuplicateImplementation (Indexer indexer)
- {
- if (this == indexer)
- return false;
-
- if (!MemberName.Equals (indexer.MemberName))
- return false;
-
- Type[] param_types = indexer.parameters.Types;
-
- // When it is not yet defined
- if (param_types == null)
- return false;
-
- if (param_types.Length != parameters.Count)
- return false;
-
- for (int i = 0; i < param_types.Length; i++)
- if (param_types [i] != parameters.Types [i])
- return false;
-
- Report.SymbolRelatedToPreviousError (indexer);
- Report.Error (111, Location, TypeContainer.Error111, indexer.GetSignatureForError ());
- return true;
- }
-
-
public override bool Define ()
{
if (!DoDefineBase ())
if (!DefineParameters (parameters))
return false;
- if (MemberType == TypeManager.void_type) {
- Report.Error (620, Location, "Indexers cannot have void type");
- return false;
- }
-
if (OptAttributes != null) {
Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
if (indexer_attr != null) {
if (!CheckBase ())
return false;
+
+ if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
+ if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, parameters))
+ return false;
+ }
+
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
if (!DefineAccessors ())
//
// Now name the parameters
//
- Parameter [] p = parameters.FixedParameters;
- if (p != null) {
- // TODO: should be done in parser and it needs to do cycle
- if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
- CSharpParser.Error_ParameterModifierNotValid (Location);
- return false;
- }
- }
-
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
Name, PropertyAttributes.None, MemberType, parameters.Types);
-
- if (!Get.IsDummy)
+
+ if (!Get.IsDummy) {
PropertyBuilder.SetGetMethod (GetBuilder);
+ Parent.MemberCache.AddMember (GetBuilder, Get);
+ }
- if (!Set.IsDummy)
+ if (!Set.IsDummy) {
PropertyBuilder.SetSetMethod (SetBuilder);
+ Parent.MemberCache.AddMember (SetBuilder, Set);
+ }
TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
-
+ Parent.MemberCache.AddMember (PropertyBuilder, this);
return true;
}
+ public override bool EnableOverloadChecks (MemberCore overload)
+ {
+ if (overload is Indexer) {
+ caching_flags |= Flags.MethodOverloadsExist;
+ return true;
+ }
+
+ return false;
+ }
+
public override string GetDocCommentName (DeclSpace ds)
{
return DocUtil.GetMethodDocCommentName (this, parameters, ds);
return sb.ToString ();
}
- public override bool MarkForDuplicationCheck ()
- {
- caching_flags |= Flags.TestMethodDuplication;
- return true;
- }
-
protected override PropertyInfo ResolveBaseProperty ()
{
return Parent.PartialContainer.BaseCache.FindMemberToOverride (
base.ApplyAttributeBuilder (a, cb);
}
- protected override bool CheckForDuplications ()
- {
- ArrayList ar = Parent.PartialContainer.Operators;
- if (ar != null) {
- int arLen = ar.Count;
-
- for (int i = 0; i < arLen; i++) {
- Operator o = (Operator) ar [i];
- if (IsDuplicateImplementation (o))
- return false;
- }
- }
-
- ar = Parent.PartialContainer.Methods;
- if (ar != null) {
- int arLen = ar.Count;
-
- for (int i = 0; i < arLen; i++) {
- Method m = (Method) ar [i];
- if (IsDuplicateImplementation (m))
- return false;
- }
- }
-
- return true;
- }
-
public override bool Define ()
{
const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
return false;
}
- // imlicit and explicit operator of same types are not allowed
- if (OperatorType == OpType.Explicit || OperatorType == OpType.Implicit)
- MarkForDuplicationCheck ();
-
if (!base.Define ())
return false;
+ // imlicit and explicit operator of same types are not allowed
+ if (OperatorType == OpType.Explicit)
+ Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Implicit", Parameters);
+ else if (OperatorType == OpType.Implicit)
+ Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Explicit", Parameters);
+
if (MemberType == TypeManager.void_type) {
Report.Error (590, Location, "User-defined operators cannot return void");
return false;
Type declaring_type = MethodData.DeclaringType;
Type return_type = MemberType;
Type first_arg_type = ParameterTypes [0];
+
+ Type first_arg_type_unwrap = first_arg_type;
+ if (TypeManager.IsNullableType (first_arg_type))
+ first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
+
+ Type return_type_unwrap = return_type;
+ if (TypeManager.IsNullableType (return_type))
+ return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];
+ //
// Rules for conversion operators
-
+ //
if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
- if (first_arg_type == return_type && first_arg_type == declaring_type){
+ if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
Report.Error (555, Location,
"User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
return false;
}
- if ((first_arg_type != declaring_type) && (return_type != declaring_type) &&
- !TypeManager.IsNullableTypeOf (first_arg_type, declaring_type) &&
- !TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
- Report.Error (
- 556, Location,
- "User-defined conversion must convert to or from the " +
- "enclosing type");
+ Type conv_type;
+ if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
+ conv_type = first_arg_type;
+ } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
+ conv_type = return_type;
+ } else {
+ Report.Error (556, Location,
+ "User-defined conversion must convert to or from the enclosing type");
return false;
}
- if (first_arg_type.IsInterface || return_type.IsInterface){
- Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
- GetSignatureForError ());
- return false;
- }
-
- if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
- if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
- Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
+ //
+ // Because IsInterface and IsClass are not supported
+ //
+ if (!TypeManager.IsGenericParameter (conv_type)) {
+ if (conv_type.IsInterface) {
+ Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
GetSignatureForError ());
return false;
}
- Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
- GetSignatureForError ());
- return false;
+
+ if (conv_type.IsClass) {
+ if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
+ Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
+ GetSignatureForError ());
+ return false;
+ }
+
+ if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
+ Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
+ GetSignatureForError ());
+ return false;
+ }
+ }
}
} else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
}
}
}
+