X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fclass.cs;h=b851ffec290552c2af646ae706bfc50f7fce1428;hb=5697a97b9870b44d6dab7bec66577fa3ec815ee0;hp=487bee231746c8d0f20efad6525f3f81fd7e61eb;hpb=7fde37f5eaf63949fbaeef8271064d2cf8e36a5a;p=mono.git
diff --git a/mcs/gmcs/class.cs b/mcs/gmcs/class.cs
index 487bee23174..b851ffec290 100755
--- a/mcs/gmcs/class.cs
+++ b/mcs/gmcs/class.cs
@@ -3,6 +3,7 @@
//
// Authors: Miguel de Icaza (miguel@gnu.org)
// Martin Baulig (martin@gnome.org)
+// Marek Safar (marek.safar@seznam.cz)
//
// Licensed under the terms of the GNU GPL
//
@@ -30,61 +31,392 @@
//
#define CACHE
using System;
+using System.Text;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using Mono.CompilerServices.SymbolWriter;
namespace Mono.CSharp {
+ public enum Kind {
+ Root,
+ Struct,
+ Class,
+ Interface
+ }
+
///
/// This is the base class for structs and classes.
///
- public class TypeContainer : DeclSpace, IMemberContainer {
+ public abstract class TypeContainer : DeclSpace, IMemberContainer {
+
+ public class MemberCoreArrayList: ArrayList
+ {
+ ///
+ /// Defines the MemberCore objects that are in this array
+ ///
+ public virtual void DefineContainerMembers ()
+ {
+ foreach (MemberCore mc in this) {
+ mc.Define ();
+ }
+ }
+
+ public virtual void Emit ()
+ {
+ foreach (MemberCore mc in this)
+ mc.Emit ();
+ }
+ }
+
+ public class MethodArrayList: MemberCoreArrayList
+ {
+ [Flags]
+ enum CachedMethods {
+ Equals = 1,
+ GetHashCode = 1 << 1
+ }
+
+ CachedMethods cached_method;
+ TypeContainer container;
+
+ public MethodArrayList (TypeContainer container)
+ {
+ this.container = container;
+ }
+
+ ///
+ /// Method container contains Equals method
+ ///
+ public bool HasEquals {
+ set {
+ cached_method |= CachedMethods.Equals;
+ }
+
+ get {
+ return (cached_method & CachedMethods.Equals) != 0;
+ }
+ }
+
+ ///
+ /// Method container contains GetHashCode method
+ ///
+ public bool HasGetHashCode {
+ set {
+ cached_method |= CachedMethods.GetHashCode;
+ }
+
+ get {
+ return (cached_method & CachedMethods.GetHashCode) != 0;
+ }
+ }
+
+ public override void DefineContainerMembers ()
+ {
+ base.DefineContainerMembers ();
+
+ if ((RootContext.WarningLevel >= 3) && HasEquals && !HasGetHashCode) {
+ Report.Warning (659, container.Location, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
+ }
+ }
+
+ }
+
+ public sealed class IndexerArrayList: MemberCoreArrayList
+ {
+ ///
+ /// The indexer name for this container
+ ///
+ public string IndexerName = DefaultIndexerName;
+
+ bool seen_normal_indexers = false;
+
+ TypeContainer container;
+
+ public IndexerArrayList (TypeContainer container)
+ {
+ this.container = container;
+ }
+
+ ///
+ /// 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.
+ ///
+ 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;
+
+ public OperatorArrayList (TypeContainer container)
+ {
+ this.container = container;
+ }
+
+ //
+ // Operator pair checking
+ //
+ class OperatorEntry
+ {
+ public int flags;
+ public Type ret_type;
+ public Type type1, type2;
+ public Operator op;
+ public Operator.OpType ot;
+
+ public OperatorEntry (int f, Operator o)
+ {
+ flags = f;
+
+ ret_type = o.OperatorMethod.ReturnType;
+ Type [] pt = o.OperatorMethod.ParameterTypes;
+ type1 = pt [0];
+ type2 = pt [1];
+ op = o;
+ ot = o.OperatorType;
+ }
+
+ public override int GetHashCode ()
+ {
+ return ret_type.GetHashCode ();
+ }
+
+ public override bool Equals (object o)
+ {
+ OperatorEntry other = (OperatorEntry) o;
+
+ if (other.ret_type != ret_type)
+ return false;
+ if (other.type1 != type1)
+ return false;
+ if (other.type2 != type2)
+ return false;
+ return true;
+ }
+ }
+
+ //
+ // Checks that some operators come in pairs:
+ // == and !=
+ // > and <
+ // >= and <=
+ // true and false
+ //
+ // They are matched based on the return type and the argument types
+ //
+ void CheckPairedOperators ()
+ {
+ Hashtable pairs = new Hashtable (null, null);
+ Operator true_op = null;
+ Operator false_op = null;
+ bool has_equality_or_inequality = false;
+
+ // Register all the operators we care about.
+ foreach (Operator op in this){
+ int reg = 0;
+
+ switch (op.OperatorType){
+ case Operator.OpType.Equality:
+ reg = 1;
+ has_equality_or_inequality = true;
+ break;
+ case Operator.OpType.Inequality:
+ reg = 2;
+ has_equality_or_inequality = true;
+ break;
+
+ case Operator.OpType.True:
+ true_op = op;
+ break;
+ case Operator.OpType.False:
+ false_op = op;
+ break;
+
+ case Operator.OpType.GreaterThan:
+ reg = 1; break;
+ case Operator.OpType.LessThan:
+ reg = 2; break;
+
+ case Operator.OpType.GreaterThanOrEqual:
+ reg = 1; break;
+ case Operator.OpType.LessThanOrEqual:
+ reg = 2; break;
+ }
+ if (reg == 0)
+ continue;
+
+ OperatorEntry oe = new OperatorEntry (reg, op);
+
+ object o = pairs [oe];
+ if (o == null)
+ pairs [oe] = oe;
+ else {
+ oe = (OperatorEntry) o;
+ oe.flags |= reg;
+ }
+ }
+
+ if (true_op != null){
+ if (false_op == null)
+ Report.Error (216, true_op.Location, "operator true requires a matching operator false");
+ } else if (false_op != null)
+ Report.Error (216, false_op.Location, "operator false requires a matching operator true");
+
+ //
+ // Look for the mistakes.
+ //
+ foreach (DictionaryEntry de in pairs){
+ OperatorEntry oe = (OperatorEntry) de.Key;
+
+ if (oe.flags == 3)
+ continue;
+
+ string s = "";
+ switch (oe.ot){
+ case Operator.OpType.Equality:
+ s = "!=";
+ break;
+ case Operator.OpType.Inequality:
+ s = "==";
+ break;
+ case Operator.OpType.GreaterThan:
+ s = "<";
+ break;
+ case Operator.OpType.LessThan:
+ s = ">";
+ break;
+ case Operator.OpType.GreaterThanOrEqual:
+ s = "<=";
+ break;
+ case Operator.OpType.LessThanOrEqual:
+ s = ">=";
+ break;
+ }
+ Report.Error (216, oe.op.Location,
+ "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
+ }
+
+ if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
+ if (container.Methods == null || !container.Methods.HasEquals)
+ Report.Warning (660, container.Location, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
+
+ if (container.Methods == null || !container.Methods.HasGetHashCode)
+ Report.Warning (661, container.Location, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
+ }
+ }
+
+ public override void DefineContainerMembers ()
+ {
+ base.DefineContainerMembers ();
+ CheckPairedOperators ();
+ }
+ }
+
+
+ // Whether this is a struct, class or interface
+ public readonly Kind Kind;
+
// Holds a list of classes and structures
ArrayList types;
// Holds the list of properties
- ArrayList properties;
+ MemberCoreArrayList properties;
// Holds the list of enumerations
- ArrayList enums;
+ MemberCoreArrayList enums;
// Holds the list of delegates
- ArrayList delegates;
+ MemberCoreArrayList delegates;
// Holds the list of constructors
- ArrayList instance_constructors;
+ protected MemberCoreArrayList instance_constructors;
// Holds the list of fields
- ArrayList fields;
+ MemberCoreArrayList fields;
// Holds a list of fields that have initializers
- ArrayList initialized_fields;
+ protected ArrayList initialized_fields;
// Holds a list of static fields that have initializers
- ArrayList initialized_static_fields;
+ protected ArrayList initialized_static_fields;
// Holds the list of constants
- ArrayList constants;
+ MemberCoreArrayList constants;
// Holds the list of
- ArrayList interfaces;
+ MemberCoreArrayList interfaces;
- // Holds order in which interfaces must be closed
- ArrayList interface_order;
-
// Holds the methods.
- ArrayList methods;
+ MethodArrayList methods;
// Holds the events
- ArrayList events;
+ MemberCoreArrayList events;
// Holds the indexers
- ArrayList indexers;
+ IndexerArrayList indexers;
// Holds the operators
- ArrayList operators;
+ MemberCoreArrayList operators;
+
+ // Holds the iterators
+ ArrayList iterators;
+
+ // Holds the parts of a partial class;
+ ArrayList parts;
// The emit context for toplevel objects.
EmitContext ec;
@@ -92,13 +424,8 @@ namespace Mono.CSharp {
//
// Pointers to the default constructor and the default static constructor
//
- Constructor default_constructor;
- Constructor default_static_constructor;
-
- //
- // Whether we have seen a static constructor for this class or not
- //
- bool have_static_constructor = false;
+ protected Constructor default_constructor;
+ protected Constructor default_static_constructor;
//
// Whether we have at least one non-static field
@@ -109,207 +436,156 @@ namespace Mono.CSharp {
// This one is computed after we can distinguish interfaces
// from classes from the arraylist `type_bases'
//
- string base_class_name;
+ string base_class_name;
+ TypeExpr parent_type;
ArrayList type_bases;
- // Information in the case we are an attribute type
-
- public AttributeTargets Targets = AttributeTargets.All;
- public bool AllowMultiple = false;
- public bool Inherited;
+ bool members_defined;
+ bool members_defined_ok;
// The interfaces we implement.
- TypeExpr [] ifaces;
+ protected Type[] ifaces;
+ protected Type ptype;
// The parent member container and our member cache
IMemberContainer parent_container;
MemberCache member_cache;
- //
- // The indexer name for this class
- //
- public string IndexerName;
+ public const string DefaultIndexerName = "Item";
Type GenericType;
- public TypeContainer ():
- this (null, null, "", null, new Location (-1)) {
- }
-
- public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
+ public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
+ Attributes attrs, Kind kind, Location l)
: base (ns, parent, name, attrs, l)
{
+ this.Kind = kind;
+
types = new ArrayList ();
base_class_name = null;
}
- public AdditionResult AddConstant (Const constant)
+ public bool AddToMemberContainer (MemberCore symbol, bool is_method)
{
- AdditionResult res;
- string basename = constant.Name;
- string fullname = Name + "." + basename;
+ return AddToContainer (symbol, is_method, String.Concat (Name, '.', symbol.Name), symbol.Name);
+ }
+
+ bool AddToTypeContainer (DeclSpace ds)
+ {
+ return AddToContainer (ds, false, ds.Name, ds.Basename);
+ }
+
+ public void AddConstant (Const constant)
+ {
+ if (!AddToMemberContainer (constant, false))
+ return;
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
- return res;
-
if (constants == null)
- constants = new ArrayList ();
+ constants = new MemberCoreArrayList ();
constants.Add (constant);
- DefineName (fullname, constant);
-
- return AdditionResult.Success;
}
- public AdditionResult AddEnum (Mono.CSharp.Enum e)
+ public void AddEnum (Mono.CSharp.Enum e)
{
- AdditionResult res;
-
- if ((res = IsValid (e.Basename, e.Name)) != AdditionResult.Success)
- return res;
+ if (!AddToTypeContainer (e))
+ return;
if (enums == null)
- enums = new ArrayList ();
+ enums = new MemberCoreArrayList ();
enums.Add (e);
- DefineName (e.Name, e);
-
- return AdditionResult.Success;
}
- public AdditionResult AddClass (Class c)
+ public void AddClassOrStruct (TypeContainer c)
{
- AdditionResult res;
- string name = c.Basename;
-
- if ((res = IsValid (name, c.Name)) != AdditionResult.Success)
- return res;
+ if (!AddToTypeContainer (c))
+ return;
- DefineName (c.Name, c);
types.Add (c);
-
- return AdditionResult.Success;
- }
-
- public AdditionResult AddStruct (Struct s)
- {
- AdditionResult res;
- string name = s.Basename;
-
- if ((res = IsValid (name, s.Name)) != AdditionResult.Success)
- return res;
-
- DefineName (s.Name, s);
- types.Add (s);
-
- return AdditionResult.Success;
}
- public AdditionResult AddDelegate (Delegate d)
+ public void AddDelegate (Delegate d)
{
- AdditionResult res;
- string name = d.Basename;
-
- if ((res = IsValid (name, d.Name)) != AdditionResult.Success)
- return res;
+ if (!AddToTypeContainer (d))
+ return;
if (delegates == null)
- delegates = new ArrayList ();
+ delegates = new MemberCoreArrayList ();
- DefineName (d.Name, d);
delegates.Add (d);
-
- return AdditionResult.Success;
}
- public AdditionResult AddMethod (Method method)
+ public void AddMethod (Method method)
{
- string basename = method.Name;
- string fullname = Name + "." + basename;
-
- Object value = defined_names [fullname];
-
- if (value != null && (!(value is Method)))
- return AdditionResult.NameExists;
-
- if (basename == Basename)
- return AdditionResult.EnclosingClash;
+ if (!AddToMemberContainer (method, true))
+ return;
if (methods == null)
- methods = new ArrayList ();
+ methods = new MethodArrayList (this);
if (method.Name.IndexOf ('.') != -1)
methods.Insert (0, method);
else
methods.Add (method);
-
- if (value == null)
- DefineName (fullname, method);
-
- return AdditionResult.Success;
}
- public AdditionResult AddConstructor (Constructor c)
+ public void AddConstructor (Constructor c)
{
- if (c.Name != Basename)
- return AdditionResult.NotAConstructor;
+ if (c.Name != Basename) {
+ Report.Error (1520, Location, "Class, struct, or interface method must have a return type");
+ }
bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
if (is_static){
- have_static_constructor = true;
- if (default_static_constructor != null){
- Console.WriteLine ("I have a static constructor already");
- Console.WriteLine (" " + default_static_constructor);
- return AdditionResult.MethodExists;
+ if (default_static_constructor != null) {
+ Report.SymbolRelatedToPreviousError (default_static_constructor);
+ Report.Error (111, c.Location, "Type '{0}' already defines a member " +
+ "called '{1}' with the same parameter types", Name, c.Name);
+ return;
}
default_static_constructor = c;
} else {
if (c.IsDefault ()){
- if (default_constructor != null)
- return AdditionResult.MethodExists;
+ if (default_constructor != null) {
+ Report.SymbolRelatedToPreviousError (default_constructor);
+ Report.Error (111, c.Location, "Type '{0}' already defines a member " +
+ "called '{1}' with the same parameter types", Name, c.Name);
+ return;
+ }
default_constructor = c;
}
if (instance_constructors == null)
- instance_constructors = new ArrayList ();
+ instance_constructors = new MemberCoreArrayList ();
instance_constructors.Add (c);
}
-
- return AdditionResult.Success;
}
- public AdditionResult AddInterface (Interface iface)
+ public void AddInterface (TypeContainer iface)
{
- AdditionResult res;
- string name = iface.Basename;
-
- if ((res = IsValid (name, iface.Name)) != AdditionResult.Success)
- return res;
-
- if (interfaces == null)
- interfaces = new ArrayList ();
+ if (!AddToTypeContainer (iface))
+ return;
+
+ if (interfaces == null) {
+ interfaces = new MemberCoreArrayList ();
+ }
+
interfaces.Add (iface);
- DefineName (iface.Name, iface);
-
- return AdditionResult.Success;
}
- public AdditionResult AddField (Field field)
+ public void AddField (Field field)
{
- AdditionResult res;
- string basename = field.Name;
- string fullname = Name + "." + basename;
+ if (!AddToMemberContainer (field, false))
+ return;
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
- return res;
-
if (fields == null)
- fields = new ArrayList ();
+ fields = new MemberCoreArrayList ();
fields.Add (field);
@@ -320,11 +596,6 @@ namespace Mono.CSharp {
initialized_static_fields.Add (field);
- //
- // We have not seen a static constructor,
- // but we will provide static initialization of fields
- //
- have_static_constructor = true;
} else {
if (initialized_fields == null)
initialized_fields = new ArrayList ();
@@ -335,112 +606,115 @@ namespace Mono.CSharp {
if ((field.ModFlags & Modifiers.STATIC) == 0)
have_nonstatic_fields = true;
-
- DefineName (fullname, field);
- return AdditionResult.Success;
}
- public AdditionResult AddProperty (Property prop)
+ public void AddProperty (Property prop)
{
- AdditionResult res;
-
- if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
- return res;
-
- if (prop.Get != null) {
- if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
- return res;
- }
-
- if (prop.Set != null) {
- if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
- return res;
- }
+ if (!AddToMemberContainer (prop, false) ||
+ !AddToMemberContainer (prop.Get, true) || !AddToMemberContainer (prop.Set, true))
+ return;
if (properties == null)
- properties = new ArrayList ();
+ properties = new MemberCoreArrayList ();
if (prop.Name.IndexOf ('.') != -1)
properties.Insert (0, prop);
else
properties.Add (prop);
-
- return AdditionResult.Success;
}
- AdditionResult AddProperty (Property prop, string basename)
+ public void AddEvent (Event e)
{
- AdditionResult res;
- string fullname = Name + "." + basename;
-
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
- return res;
-
- DefineName (fullname, prop);
-
- return AdditionResult.Success;
- }
+ if (!AddToMemberContainer (e, false))
+ return;
- public AdditionResult AddEvent (Event e)
- {
- AdditionResult res;
- string basename = e.Name;
- string fullname = Name + "." + basename;
+ if (e is EventProperty) {
+ if (!AddToMemberContainer (e.Add, true))
+ return;
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
- return res;
+ if (!AddToMemberContainer (e.Remove, true))
+ return;
+ }
if (events == null)
- events = new ArrayList ();
-
- events.Add (e);
- DefineName (fullname, e);
+ events = new MemberCoreArrayList ();
- return AdditionResult.Success;
+ events.Add (e);
}
+ ///
+ /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
+ ///
public void AddIndexer (Indexer i)
{
if (indexers == null)
- indexers = new ArrayList ();
+ indexers = new IndexerArrayList (this);
- if (i.InterfaceType != null)
+ if (i.IsExplicitImpl)
indexers.Insert (0, i);
else
indexers.Add (i);
}
- public AdditionResult AddOperator (Operator op)
+ public void AddOperator (Operator op)
{
+ if (!AddToMemberContainer (op, true))
+ return;
+
if (operators == null)
- operators = new ArrayList ();
+ operators = new OperatorArrayList (this);
operators.Add (op);
+ }
- string basename = op.Name;
- string fullname = Name + "." + basename;
- if (!defined_names.Contains (fullname))
- {
- DefineName (fullname, op);
- }
- return AdditionResult.Success;
+ public void AddIterator (Iterator i)
+ {
+ if (iterators == null)
+ iterators = new ArrayList ();
+
+ iterators.Add (i);
}
- public void RegisterOrder (Interface iface)
+ public void AddType (TypeContainer tc)
{
- if (interface_order == null)
- interface_order = new ArrayList ();
+ types.Add (tc);
+ }
+
+ public void AddPart (ClassPart part)
+ {
+ if (parts == null)
+ parts = new ArrayList ();
- interface_order.Add (iface);
+ parts.Add (part);
}
-
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.default_member_type) {
+ if (Indexers != null) {
+ Report.Error (646, a.Location,
+ "Cannot specify the DefaultMember attribute on" +
+ " a type containing an indexer");
+ return;
+ }
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
public ArrayList Types {
get {
return types;
}
}
- public ArrayList Methods {
+ public MethodArrayList Methods {
get {
return methods;
}
@@ -457,6 +731,12 @@ namespace Mono.CSharp {
return interfaces;
}
}
+
+ public ArrayList Iterators {
+ get {
+ return iterators;
+ }
+ }
public string Base {
get {
@@ -478,10 +758,6 @@ namespace Mono.CSharp {
get {
return fields;
}
-
- set {
- fields = value;
- }
}
public ArrayList InstanceConstructors {
@@ -526,18 +802,24 @@ namespace Mono.CSharp {
}
}
- public bool HaveStaticConstructor {
+ public ArrayList Parts {
get {
- return have_static_constructor;
+ return parts;
}
}
-
+
public virtual TypeAttributes TypeAttr {
get {
return Modifiers.TypeAttr (ModFlags, this);
}
}
+ public string IndexerName {
+ get {
+ return indexers == null ? DefaultIndexerName : indexers.IndexerName;
+ }
+ }
+
//
// Emits the instance field initializers
//
@@ -565,6 +847,8 @@ namespace Mono.CSharp {
Location l = f.Location;
FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
fe.InstanceExpression = instance_expr;
+ fe.IsFieldInitializer = true;
+
ExpressionStatement a = new Assign (fe, e, l);
a = a.ResolveStatement (ec);
@@ -580,7 +864,7 @@ namespace Mono.CSharp {
//
// Defines the default constructors
//
- void DefineDefaultConstructor (bool is_static)
+ protected void DefineDefaultConstructor (bool is_static)
{
Constructor c;
@@ -606,120 +890,182 @@ namespace Mono.CSharp {
}
- public void ReportStructInitializedInstanceError ()
- {
- string n = TypeBuilder.FullName;
-
- foreach (Field f in initialized_fields){
- Report.Error (
- 573, Location,
- "`" + n + "." + f.Name + "': can not have " +
- "instance field initializers in structs");
- }
- }
-
///
- /// The pending methods that need to be implemented (interfaces or abstract methods)
+ /// The pending methods that need to be implemented
+ // (interfaces or abstract methods)
///
public PendingImplementation Pending;
- ///
- /// This function computes the Base class and also the
- /// list of interfaces that the class or struct @c implements.
- ///
- /// The return value is an array (might be null) of
- /// interfaces implemented (as Types).
- ///
- /// The @parent argument is set to the parent object or null
- /// if this is `System.Object'.
- ///
- TypeExpr [] GetClassBases (bool is_class, out TypeExpr parent, out bool error)
+ public abstract void Register ();
+
+ public abstract PendingImplementation GetPendingImplementations ();
+
+ TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error)
{
- ArrayList bases = Bases;
- int count;
- int start, j, i;
+ ArrayList ifaces = new ArrayList ();
- error = false;
+ parent = null;
+ Location parent_loc = Location.Null;
- if (is_class)
- parent = null;
- else
- parent = TypeManager.system_valuetype_expr;
+ foreach (ClassPart part in parts) {
+ TypeExpr new_parent;
+ TypeExpr[] new_ifaces;
- if (bases == null){
- if (is_class){
- if (RootContext.StdLib)
- parent = TypeManager.system_object_expr;
- else if (Name != "System.Object")
- parent = TypeManager.system_object_expr;
- } else {
- //
- // If we are compiling our runtime,
- // and we are defining ValueType, then our
- // parent is `System.Object'.
- //
- if (!RootContext.StdLib && Name == "System.ValueType")
- parent = TypeManager.system_object_expr;
+ new_ifaces = part.GetClassBases (out new_parent, out error);
+ if (error)
+ return null;
+
+ if ((parent != null) && (new_parent != null) &&
+ !parent.Equals (new_parent)) {
+ Report.Error (263, part.Location,
+ "Partial declarations of `{0}' must " +
+ "not specify different base classes",
+ Name);
+
+ if (!Location.IsNull (parent_loc))
+ Report.LocationOfPreviousError (parent_loc);
+
+ error = true;
+ return null;
}
- return null;
+ if ((parent == null) && (new_parent != null)) {
+ parent = new_parent;
+ parent_loc = part.Location;
+ }
+
+ if (new_ifaces == null)
+ continue;
+
+ foreach (TypeExpr iface in new_ifaces) {
+ bool found = false;
+ foreach (TypeExpr old_iface in ifaces) {
+ if (old_iface.Equals (iface)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ ifaces.Add (iface);
+ }
}
- //
- // Bases should be null if there are no bases at all
- //
- count = bases.Count;
+ error = false;
+
+ TypeExpr[] retval = new TypeExpr [ifaces.Count];
+ ifaces.CopyTo (retval, 0);
+ return retval;
+ }
+
+ TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error)
+ {
+ parent = null;
+
+ int count = Bases.Count;
+ int start, i, j;
- if (is_class){
- TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
+ if (Kind == Kind.Class){
+ TypeExpr name = ResolveTypeExpr (
+ (Expression) Bases [0], false, Location);
if (name == null){
error = true;
return null;
}
- if (name is TypeParameterExpr){
+ if (name.IsClass){
+ parent = name;
+ start = 1;
+ } else {
+ start = 0;
+ }
+ } else {
+ start = 0;
+ }
+
+ TypeExpr [] ifaces = new TypeExpr [count-start];
+
+ for (i = start, j = 0; i < count; i++, j++){
+ Expression name = (Expression) Bases [i];
+ TypeExpr resolved = ResolveTypeExpr (name, false, Location);
+ if (resolved == null) {
+ error = true;
+ return null;
+ }
+
+ ifaces [j] = resolved;
+ }
+
+ error = false;
+ return ifaces;
+ }
+
+ ///
+ /// This function computes the Base class and also the
+ /// list of interfaces that the class or struct @c implements.
+ ///
+ /// The return value is an array (might be null) of
+ /// interfaces implemented (as Types).
+ ///
+ /// The @parent argument is set to the parent object or null
+ /// if this is `System.Object'.
+ ///
+ TypeExpr [] GetClassBases (out TypeExpr parent, out bool error)
+ {
+ ArrayList bases = Bases;
+ int start, j, i;
+
+ error = false;
+
+ TypeExpr[] ifaces;
+
+ if (parts != null)
+ ifaces = GetPartialBases (out parent, out error);
+ else if (Bases == null){
+ parent = null;
+ return null;
+ } else
+ ifaces = GetNormalBases (out parent, out error);
+
+ if (error)
+ return null;
+
+ if ((parent != null) && (Kind == Kind.Class)){
+ if (parent is TypeParameterExpr){
Report.Error (
- 689, name.Location,
+ 689, parent.Location,
"Type parameter `{0}' can not be used as a " +
- "base class or interface", name.Name);
+ "base class or interface", parent.Name);
error = true;
return null;
}
- if (IsGeneric && name.IsAttribute){
+ if (IsGeneric && parent.IsAttribute){
Report.Error (
- 698, name.Location,
+ 698, parent.Location,
"A generic type cannot derive from `{0}' " +
- "because it is an attribute class", name.Name);
+ "because it is an attribute class",
+ parent.Name);
error = true;
return null;
}
- if (name.IsClass){
- parent = name;
- start = 1;
- } else {
- parent = TypeManager.system_object_expr;
- start = 0;
- }
- if (name.IsSealed){
- string detail = "";
-
- if (name.IsValueType)
- detail = " (a class can not inherit from a struct/enum)";
-
- Report.Error (509, "class `"+ Name +
- "': Cannot inherit from sealed class `"+
- name.Name + "'" + detail);
+ if (parent.IsSealed){
error = true;
+ Report.SymbolRelatedToPreviousError (parent.Type);
+ if (parent.Type.IsAbstract) {
+ Report.Error (709, Location, "'{0}': Cannot derive from static class", GetSignatureForError ());
+ } else {
+ Report.Error (509, Location, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
+ }
return null;
}
if (!parent.CanInheritFrom ()){
Report.Error (644, Location,
"`{0}' cannot inherit from special class `{1}'",
- Name, parent.Name);
+ Name, parent_type.Name);
error = true;
return null;
}
@@ -727,55 +1073,62 @@ namespace Mono.CSharp {
if (!parent.AsAccessible (this, ModFlags))
Report.Error (60, Location,
"Inconsistent accessibility: base class `" +
- name.Name + "' is less accessible than class `" +
+ parent.Name + "' is less accessible than class `" +
Name + "'");
-
- } else {
- start = 0;
}
if (parent != null)
base_class_name = parent.Name;
- TypeExpr [] ifaces = new TypeExpr [count-start];
+ if (ifaces == null)
+ return null;
- for (i = start, j = 0; i < count; i++, j++){
- Expression name = (Expression) bases [i];
- TypeExpr resolved = ResolveTypeExpr (name, false, Location);
+ int count = ifaces != null ? ifaces.Length : 0;
- if (resolved == null)
- return null;
-
- bases [i] = resolved;
+ for (i = 0; i < count; i++) {
+ TypeExpr iface = (TypeExpr) ifaces [i];
- if (is_class == false && !resolved.IsInterface){
- Report.Error (527, "In Struct `" + Name + "', type `"+
- name +"' is not an interface");
+ if ((Kind != Kind.Class) && !iface.IsInterface){
+ string what = Kind == Kind.Struct ?
+ "Struct" : "Interface";
+
+ Report.Error (527, Location,
+ "In {0} `{1}', type `{2}' is not "+
+ "an interface", what, Name, iface.Name);
error = true;
return null;
}
-
- if (resolved.IsClass) {
+
+ if (iface.IsClass) {
if (parent != null){
- Report.Error (527, "In Class `" + Name + "', type `"+
- name+"' is not an interface");
+ Report.Error (527, Location,
+ "In Class `{0}', `{1}' is not " +
+ "an interface", Name, iface.Name);
error = true;
return null;
}
}
-
- for (int x = 0; x < j; x++) {
- if (resolved.Equals (ifaces [x])) {
- Report.Error (528, "`" + name + "' is already listed in interface list");
+
+ for (int x = 0; x < i; x++) {
+ if (iface.Equals (ifaces [x])) {
+ Report.Error (528, Location,
+ "`{0}' is already listed in " +
+ "interface list", iface.Name);
error = true;
return null;
}
}
- ifaces [j] = resolved;
+ if ((Kind == Kind.Interface) &&
+ !iface.AsAccessible (Parent, ModFlags))
+ Report.Error (61, Location,
+ "Inconsistent accessibility: base " +
+ "interface `{0}' is less accessible " +
+ "than interface `{1}'", iface.Name,
+ Name);
}
- return TypeManager.ExpandInterfaces (ifaces);
+ return ifaces;
}
bool CheckGenericInterfaces (Type[] ifaces)
@@ -815,96 +1168,130 @@ namespace Mono.CSharp {
public override TypeBuilder DefineType ()
{
TypeExpr parent;
- bool is_class;
-
- if (TypeBuilder != null)
- return TypeBuilder;
if (error)
return null;
-
- if (InTransit) {
- Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
- error = true;
- return null;
- }
-
- InTransit = true;
- if (this is Class)
- is_class = true;
- else
- is_class = false;
+ if (TypeBuilder != null)
+ return TypeBuilder;
ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
- ifaces = GetClassBases (is_class, out parent, out error);
+ TypeAttributes type_attributes = TypeAttr;
- if (error)
+ try {
+ if (IsTopLevel){
+ if (TypeManager.NamespaceClash (Name, Location)) {
+ error = true;
+ return null;
+ }
+
+ ModuleBuilder builder = CodeGen.Module.Builder;
+ TypeBuilder = builder.DefineType (
+ Name, type_attributes, null, null);
+ } else {
+ TypeBuilder builder;
+ if (Parent.TypeBuilder != null)
+ builder = Parent.TypeBuilder;
+ else
+ builder = Parent.DefineType ();
+
+ if (builder == null) {
+ error = true;
+ return null;
+ }
+
+ TypeBuilder = builder.DefineNestedType (
+ MemberName.Basename, type_attributes,
+ null, null);
+ }
+ }
+ catch (ArgumentException) {
+ Report.RuntimeMissingSupport ("static classes");
return null;
+ }
+
+ TypeManager.AddUserType (Name, TypeBuilder, this);
if (IsGeneric) {
- foreach (TypeParameter type_param in TypeParameters)
+ foreach (TypeParameter type_param in TypeParameters) {
if (!type_param.Resolve (this)) {
error = true;
return null;
}
- }
-
- if (!is_class && TypeManager.value_type == null)
- throw new Exception ();
-
- TypeAttributes type_attributes = TypeAttr;
+ }
- Type ptype;
- ConstructedType constructed = parent as ConstructedType;
- if ((constructed == null) && (parent != null))
- ptype = parent.ResolveType (ec);
- else
- ptype = null;
+ CurrentType = new ConstructedType (
+ Name, TypeParameters, Location);
- if (IsTopLevel){
- if (TypeManager.NamespaceClash (Name, Location)) {
- error = true;
- return null;
- }
+ string[] param_names = new string [TypeParameters.Length];
+ for (int i = 0; i < TypeParameters.Length; i++)
+ param_names [i] = TypeParameters [i].Name;
- ModuleBuilder builder = CodeGen.Module.Builder;
- TypeBuilder = builder.DefineType (
- Name, type_attributes, ptype, null);
-
- } else {
- TypeBuilder builder = Parent.DefineType ();
- if (builder == null)
- return null;
+ GenericTypeParameterBuilder[] gen_params;
- TypeBuilder = builder.DefineNestedType (
- Basename, type_attributes, ptype, null);
- }
+ gen_params = TypeBuilder.DefineGenericParameters (param_names);
- TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
+ for (int i = 0; i < gen_params.Length; i++)
+ TypeParameters [i].Define (gen_params [i]);
+ }
if (IsGeneric) {
- CurrentType = new ConstructedType (
- Name, TypeParameters, Location);
-
foreach (TypeParameter type_param in TypeParameters)
- type_param.Define (TypeBuilder);
+ if (!type_param.DefineType (ec)) {
+ error = true;
+ return null;
+ }
+ }
+
+ if ((Kind == Kind.Struct) && TypeManager.value_type == null)
+ throw new Exception ();
+
+ TypeExpr[] iface_exprs = GetClassBases (out parent_type, out error);
+ if (error)
+ return null;
+
+ if (parent_type == null) {
+ if (Kind == Kind.Class){
+ if (RootContext.StdLib)
+ parent_type = TypeManager.system_object_expr;
+ else if (Name != "System.Object")
+ parent_type = TypeManager.system_object_expr;
+ } else if (Kind == Kind.Struct){
+ //
+ // If we are compiling our runtime,
+ // and we are defining ValueType, then our
+ // parent is `System.Object'.
+ //
+ if (!RootContext.StdLib && Name == "System.ValueType")
+ parent_type = TypeManager.system_object_expr;
+ else if (Kind == Kind.Struct)
+ parent_type = TypeManager.system_valuetype_expr;
+ }
}
+ ConstructedType constructed = parent_type as ConstructedType;
+ if ((constructed == null) && (parent_type != null))
+ ptype = parent_type.ResolveType (ec);
+ else
+ ptype = null;
+
if (constructed != null) {
ptype = constructed.ResolveType (ec);
- if (ptype == null)
+ if (ptype == null) {
+ error = true;
return null;
-
- TypeBuilder.SetParent (ptype);
+ }
}
- if (IsGeneric) {
- foreach (TypeParameter type_param in TypeParameters)
- type_param.DefineType (ec, TypeBuilder);
+ if (!CheckRecursiveDefinition ()) {
+ error = true;
+ return null;
}
+ if (ptype != null)
+ TypeBuilder.SetParent (ptype);
+
//
// Structs with no fields need to have at least one byte.
// The right thing would be to set the PackingSize in a DefineType
@@ -912,30 +1299,36 @@ namespace Mono.CSharp {
// be specified.
//
- if (!is_class && !have_nonstatic_fields){
+ if ((Kind == Kind.Struct) && !have_nonstatic_fields){
TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
FieldAttributes.Private);
}
// add interfaces that were not added at type creation
- if (ifaces != null) {
- Type[] itypes = new Type [ifaces.Length];
- for (int i = 0; i < ifaces.Length; i++) {
- itypes [i] = ifaces [i].ResolveType (ec);
- if (itypes [i] == null)
- error = true;
+ if (iface_exprs != null) {
+ ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
+ if (ifaces == null) {
+ error = true;
+ return null;
}
- if (error)
- return null;
+ foreach (Type itype in ifaces)
+ TypeBuilder.AddInterfaceImplementation (itype);
- if (!CheckGenericInterfaces (itypes)) {
+ if (!CheckGenericInterfaces (ifaces)) {
error = true;
return null;
}
- for (int i = 0; i < ifaces.Length; i++)
- TypeBuilder.AddInterfaceImplementation (itypes [i]);
+ TypeManager.RegisterBuilder (TypeBuilder, ifaces);
+ }
+
+ if (IsGeneric) {
+ foreach (TypeParameter type_param in TypeParameters)
+ if (!type_param.CheckDependencies (ec)) {
+ error = true;
+ return null;
+ }
}
//
@@ -943,170 +1336,79 @@ namespace Mono.CSharp {
//
ec.ContainerType = TypeBuilder;
- if ((parent != null) && parent.IsAttribute) {
+ if ((parent_type != null) && parent_type.IsAttribute) {
RootContext.RegisterAttribute (this);
- TypeManager.RegisterAttrType (TypeBuilder, this);
- } else
+ } else if (!(this is Iterator))
RootContext.RegisterOrder (this);
-
+
+ if (!DefineNestedTypes ()) {
+ error = true;
+ return null;
+ }
+
+ return TypeBuilder;
+ }
+
+ protected virtual bool DefineNestedTypes ()
+ {
if (Interfaces != null) {
- foreach (Interface iface in Interfaces)
- if (iface.DefineType () == null) {
- error = true;
- return null;
- }
+ foreach (TypeContainer iface in Interfaces)
+ if (iface.DefineType () == null)
+ return false;
}
if (Types != null) {
foreach (TypeContainer tc in Types)
- if (tc.DefineType () == null) {
- error = true;
- return null;
- }
+ if (tc.DefineType () == null)
+ return false;
}
if (Delegates != null) {
foreach (Delegate d in Delegates)
- if (d.DefineType () == null) {
- error = true;
- return null;
- }
+ if (d.DefineType () == null)
+ return false;
}
if (Enums != null) {
foreach (Enum en in Enums)
- if (en.DefineType () == null) {
- error = true;
- return null;
- }
+ if (en.DefineType () == null)
+ return false;
}
- InTransit = false;
- return TypeBuilder;
- }
+ if (Parts != null) {
+ foreach (ClassPart part in Parts) {
+ part.TypeBuilder = TypeBuilder;
+ part.parent_type = parent_type;
+ }
+ }
+ return true;
+ }
- ///
- /// Defines the MemberCore objects that are in the `list' Arraylist
- ///
- /// The `defined_names' array contains a list of members defined in
- /// a base class
- ///
- static ArrayList remove_list = new ArrayList ();
- void DefineMembers (ArrayList list, MemberInfo [] defined_names)
+ protected bool CheckRecursiveDefinition ()
{
- int idx;
-
- remove_list.Clear ();
-
- foreach (MemberCore mc in list){
-
- if (defined_names != null)
- idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
- else
- idx = -1;
+ if (InTransit) {
+ Report.Error (146, Location,
+ "Class definition is circular: `{0}'",
+ GetSignatureForError ());
+ error = true;
+ return false;
+ }
- if (idx < 0){
- if (RootContext.WarningLevel >= 4){
- if ((mc.ModFlags & Modifiers.NEW) != 0)
- Warning_KeywordNewNotRequired (mc.Location, mc);
- }
- } else if (mc is MethodCore)
- ((MethodCore) mc).OverridesSomething = true;
+ InTransit = true;
- if (!mc.Define (this)){
- remove_list.Add (mc);
- continue;
- }
-
- if (idx < 0)
- continue;
+ Type parent = ptype;
+ if (parent != null) {
+ if (parent.IsGenericInstance)
+ parent = parent.GetGenericTypeDefinition ();
- MemberInfo match = defined_names [idx];
+ TypeContainer ptc = TypeManager.LookupTypeContainer (parent);
+ if ((ptc != null) && !ptc.CheckRecursiveDefinition ())
+ return false;
+ }
- if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
- continue;
-
- //
- // If we are both methods, let the method resolution emit warnings
- //
- if (match is MethodBase && mc is MethodCore)
- continue;
-
- if ((mc.ModFlags & Modifiers.NEW) == 0) {
- if (mc is Event) {
- if (!(match is EventInfo)) {
- Error_EventCanOnlyOverrideEvent (mc.Location, defined_names [idx]);
- return;
- }
-
- if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
- continue;
- }
-
- Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
- }
- }
-
- foreach (object o in remove_list)
- list.Remove (o);
-
- remove_list.Clear ();
- }
-
- //
- // Defines the indexers, and also verifies that the IndexerNameAttribute in the
- // class is consisten. 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 DefaultName attribute is attached
- // to the class.
- //
- void DefineIndexers ()
- {
- 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.
- //
- ArrayList list = new ArrayList ();
- foreach (Indexer i in Indexers){
- if (i.ExplicitInterfaceName != null)
- list.Add (i);
- }
- foreach (Indexer i in Indexers){
- if (i.ExplicitInterfaceName == null)
- list.Add (i);
- }
-
- foreach (Indexer i in list){
- string name;
-
- i.Define (this);
-
- name = i.IndexerName;
-
- if (i.InterfaceType != null)
- continue;
-
- if (class_indexer_name == null){
- class_indexer_name = name;
- continue;
- }
-
- if (name == class_indexer_name)
- continue;
-
- Report.Error (
- 668, "Two indexers have different names, " +
- " you should use the same name for all your indexers");
- }
- if (class_indexer_name == null)
- class_indexer_name = "Item";
- IndexerName = class_indexer_name;
+ InTransit = false;
+ return true;
}
static void Error_KeywordNotAllowed (Location loc)
@@ -1119,65 +1421,58 @@ namespace Mono.CSharp {
///
public override bool DefineMembers (TypeContainer container)
{
- MemberInfo [] defined_names = null;
+ if (members_defined)
+ return members_defined_ok;
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- if ((iface.ModFlags & Modifiers.NEW) == 0)
- iface.DefineMembers (this);
- else
- Error_KeywordNotAllowed (iface.Location);
- }
+ members_defined_ok = DoDefineMembers ();
+ members_defined = true;
- if (RootContext.WarningLevel > 1){
- Type ptype;
+ return members_defined_ok;
+ }
- //
- // This code throws an exception in the comparer
- // I guess the string is not an object?
- //
- ptype = TypeBuilder.BaseType;
- if (ptype != null){
- defined_names = (MemberInfo []) FindMembers (
- ptype, MemberTypes.All & ~MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.Static, null, null);
+ bool DoDefineMembers ()
+ {
+ //
+ // We need to be able to use the member cache while we are checking/defining
+ //
+ if (TypeBuilder.BaseType != null)
+ parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
- Array.Sort (defined_names, mif_compare);
+ // TODO:
+ //if (TypeBuilder.IsInterface) {
+ // parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types);
+ //}
+
+ if (IsTopLevel) {
+ if ((ModFlags & Modifiers.NEW) != 0)
+ Error_KeywordNotAllowed (Location);
+ } else {
+ // HACK: missing implemenation
+ // This is not fully functional. Better way how to handle this is to have recursive definition of containers
+ // instead of flat as we have now.
+ // Now we are not able to check inner attribute class because its parent had not been defined.
+
+ // TODO: remove this if
+ if (Parent.MemberCache != null) {
+ MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
+ if (conflict_symbol == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
+ }
+ }
}
}
- Class pclass = Parent as Class;
- if (pclass != null) {
- string pname = null;
- Type ptype = null;
- Type t = pclass.TypeBuilder.BaseType;
- while ((t != null) && (ptype == null)) {
- pname = t.FullName + "." + Basename;
- ptype = RootContext.LookupType (this, pname, true, Location.Null);
- t = t.BaseType;
- }
-
- if ((ModFlags & Modifiers.NEW) != 0) {
- if (ptype == null)
- Report.Warning (109, Location, "The member '" + Name + "' does not hide an " +
- "inherited member. The keyword new is not required.");
- } else if (ptype != null) {
- Report.Warning (108, Location, "The keyword new is required on `" +
- Name + "' because it hides inherited member '" +
- pname + "'.");
- }
- } else if ((ModFlags & Modifiers.NEW) != 0)
- Error_KeywordNotAllowed (Location);
-
- if (constants != null)
- DefineMembers (constants, defined_names);
-
- if (fields != null)
- DefineMembers (fields, defined_names);
+ DefineContainerMembers (constants);
+ DefineContainerMembers (fields);
- if (this is Class){
- if (instance_constructors == null){
+ if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
+ if ((instance_constructors == null) &&
+ !(this is StaticClass)) {
if (default_constructor == null)
DefineDefaultConstructor (false);
}
@@ -1187,7 +1482,7 @@ namespace Mono.CSharp {
DefineDefaultConstructor (true);
}
- if (this is Struct){
+ if (Kind == Kind.Struct){
//
// Structs can not have initialized instance
// fields
@@ -1200,42 +1495,30 @@ namespace Mono.CSharp {
ReportStructInitializedInstanceError ();
}
- Pending = PendingImplementation.GetPendingImplementations (this);
+ Pending = GetPendingImplementations ();
+
+ if (parts != null) {
+ foreach (ClassPart part in parts) {
+ if (!part.DefineMembers (this))
+ return false;
+ }
+ }
//
// Constructors are not in the defined_names array
//
- if (instance_constructors != null)
- DefineMembers (instance_constructors, null);
-
- if (default_static_constructor != null)
- default_static_constructor.Define (this);
-
- if (methods != null)
- DefineMembers (methods, defined_names);
-
- if (properties != null)
- DefineMembers (properties, defined_names);
-
- if (events != null)
- DefineMembers (events, defined_names);
-
- if (indexers != null) {
- DefineIndexers ();
- } else
- IndexerName = "Item";
+ DefineContainerMembers (instance_constructors);
- if (operators != null){
- DefineMembers (operators, null);
-
- CheckPairedOperators ();
- }
+ if (default_static_constructor != null)
+ default_static_constructor.Define ();
- if (enums != null)
- DefineMembers (enums, defined_names);
-
- if (delegates != null)
- DefineMembers (delegates, defined_names);
+ DefineContainerMembers (properties);
+ DefineContainerMembers (events);
+ DefineContainerMembers (indexers);
+ DefineContainerMembers (methods);
+ DefineContainerMembers (operators);
+ DefineContainerMembers (enums);
+ DefineContainerMembers (delegates);
if (CurrentType != null) {
GenericType = CurrentType.ResolveType (ec);
@@ -1245,27 +1528,65 @@ namespace Mono.CSharp {
#if CACHE
- if (TypeBuilder.BaseType != null)
- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
-
+ if (!(this is ClassPart))
member_cache = new MemberCache (this);
#endif
-
+ if (parts != null) {
+ foreach (ClassPart part in parts)
+ part.member_cache = member_cache;
+ }
+
+ if (iterators != null) {
+ foreach (Iterator iterator in iterators) {
+ if (iterator.DefineType () == null)
+ return false;
+ }
+
+ foreach (Iterator iterator in iterators) {
+ if (!iterator.DefineMembers (this))
+ return false;
+ }
+ }
+
return true;
}
- public override bool Define (TypeContainer container)
+ void ReportStructInitializedInstanceError ()
+ {
+ string n = TypeBuilder.FullName;
+
+ foreach (Field f in initialized_fields){
+ Report.Error (
+ 573, Location,
+ "`" + n + "." + f.Name + "': can not have " +
+ "instance field initializers in structs");
+ }
+ }
+
+ protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
+ {
+ if (mcal != null)
+ mcal.DefineContainerMembers ();
+ }
+
+ public override bool Define ()
{
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- if ((iface.ModFlags & Modifiers.NEW) == 0)
- iface.Define (this);
+ if (parts != null) {
+ foreach (ClassPart part in parts) {
+ if (!part.Define ())
+ return false;
+ }
}
return true;
}
+ public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
+ {
+ return ParentContainer.MemberCache.FindMemberWithSameName (name, ignore_methods, null);
+ }
+
///
/// This function is based by a delegate to the FindMembers routine
///
@@ -1281,15 +1602,74 @@ namespace Mono.CSharp {
static MemberFilter accepting_filter;
- ///
- /// A member comparission method based on name only
- ///
- static IComparer mif_compare;
-
static TypeContainer ()
{
accepting_filter = new MemberFilter (AlwaysAccept);
- mif_compare = new MemberInfoCompare ();
+ }
+
+ public MethodInfo[] GetMethods ()
+ {
+ ArrayList members = new ArrayList ();
+
+ DefineMembers (null);
+
+ if (methods != null) {
+ int len = methods.Count;
+ for (int i = 0; i < len; i++) {
+ Method m = (Method) methods [i];
+
+ members.Add (m.MethodBuilder);
+ }
+ }
+
+ if (operators != null) {
+ int len = operators.Count;
+ for (int i = 0; i < len; i++) {
+ Operator o = (Operator) operators [i];
+
+ members.Add (o.OperatorMethodBuilder);
+ }
+ }
+
+ if (properties != null) {
+ int len = properties.Count;
+ for (int i = 0; i < len; i++) {
+ Property p = (Property) properties [i];
+
+ if (p.GetBuilder != null)
+ members.Add (p.GetBuilder);
+ if (p.SetBuilder != null)
+ members.Add (p.SetBuilder);
+ }
+ }
+
+ if (indexers != null) {
+ int len = indexers.Count;
+ for (int i = 0; i < len; i++) {
+ Indexer ix = (Indexer) indexers [i];
+
+ if (ix.GetBuilder != null)
+ members.Add (ix.GetBuilder);
+ if (ix.SetBuilder != null)
+ members.Add (ix.SetBuilder);
+ }
+ }
+
+ if (events != null) {
+ int len = events.Count;
+ for (int i = 0; i < len; i++) {
+ Event e = (Event) events [i];
+
+ if (e.AddBuilder != null)
+ members.Add (e.AddBuilder);
+ if (e.RemoveBuilder != null)
+ members.Add (e.RemoveBuilder);
+ }
+ }
+
+ MethodInfo[] retMethods = new MethodInfo [members.Count];
+ members.CopyTo (retMethods, 0);
+ return retMethods;
}
///
@@ -1611,7 +1991,7 @@ namespace Mono.CSharp {
if (interfaces != null) {
int len = interfaces.Count;
for (int i = 0; i < len; i++) {
- Interface iface = (Interface) interfaces [i];
+ TypeContainer iface = (TypeContainer) interfaces [i];
if ((iface.ModFlags & modflags) == 0)
continue;
@@ -1659,7 +2039,8 @@ namespace Mono.CSharp {
//
// Lookup members in parent if requested.
//
- if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
+ if ((bf & BindingFlags.DeclaredOnly) == 0) {
+ if (TypeBuilder.BaseType != null) {
MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
if (list.Count > 0) {
if (members == null)
@@ -1668,6 +2049,8 @@ namespace Mono.CSharp {
members.AddRange (list);
}
}
+
+ }
Timer.StopTimer (TimerType.TcFindMembers);
@@ -1711,98 +2094,133 @@ namespace Mono.CSharp {
{
if (constants != null)
foreach (Const con in constants)
- con.Emit (this);
+ con.Emit ();
return;
}
+ protected virtual void VerifyMembers (EmitContext ec)
+ {
+ //
+ // Check for internal or private fields that were never assigned
+ //
+ if (RootContext.WarningLevel >= 3) {
+ if (fields != null){
+ foreach (Field f in fields) {
+ if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
+ continue;
+
+ if ((f.status & Field.Status.USED) == 0){
+ Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
+ continue;
+ }
+
+ //
+ // Only report 649 on level 4
+ //
+ if (RootContext.WarningLevel < 4)
+ continue;
+
+ if ((f.status & Field.Status.ASSIGNED) != 0)
+ continue;
+
+ Report.Warning (649, f.Location, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f.GetSignatureForError (), "");
+ }
+ }
+
+ if ((events != null) && (RootContext.WarningLevel >= 3)) {
+ foreach (Event e in events){
+ if (e.status == 0)
+ Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
+ }
+ }
+ }
+ }
+
///
/// Emits the code, this step is performed after all
/// the types, enumerations, constructors
///
- public void Emit ()
+ public void EmitType ()
{
- if (instance_constructors != null)
+ if (OptAttributes != null)
+ OptAttributes.Emit (ec, this);
+
+ Emit ();
+
+ if (instance_constructors != null) {
+ if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsCompliaceRequired (this)) {
+ bool has_compliant_args = false;
+
+ foreach (Constructor c in instance_constructors) {
+ c.Emit ();
+
+ if (has_compliant_args)
+ continue;
+
+ has_compliant_args = c.HasCompliantArgs;
+ }
+ if (!has_compliant_args)
+ Report.Error (3015, Location, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
+ } else {
foreach (Constructor c in instance_constructors)
- c.Emit (this);
+ c.Emit ();
+ }
+ }
if (default_static_constructor != null)
- default_static_constructor.Emit (this);
+ default_static_constructor.Emit ();
if (methods != null)
foreach (Method m in methods)
- m.Emit (this);
+ m.Emit ();
if (operators != null)
foreach (Operator o in operators)
- o.Emit (this);
+ o.Emit ();
if (properties != null)
foreach (Property p in properties)
- p.Emit (this);
+ p.Emit ();
if (indexers != null){
- foreach (Indexer ix in indexers)
- ix.Emit (this);
-
- CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
- this, IndexerName, ModFlags, Location);
- TypeBuilder.SetCustomAttribute (cb);
+ indexers.Emit ();
}
if (fields != null)
foreach (Field f in fields)
- f.Emit (this);
+ f.Emit ();
if (events != null){
foreach (Event e in Events)
- e.Emit (this);
+ e.Emit ();
}
- if (Pending != null)
- if (Pending.VerifyPendingMethods ())
- return;
-
- Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
-
- //
- // Check for internal or private fields that were never assigned
- //
- if (RootContext.WarningLevel >= 3) {
- if (fields != null){
- foreach (Field f in fields) {
- if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
- continue;
-
- if ((f.status & Field.Status.USED) == 0){
- Report.Warning (
- 169, f.Location, "Private field " +
- MakeName (f.Name) + " is never used");
- continue;
- }
-
- //
- // Only report 649 on level 4
- //
- if (RootContext.WarningLevel < 4)
- continue;
-
- if ((f.status & Field.Status.ASSIGNED) != 0)
- continue;
-
- Report.Warning (
- 649, f.Location,
- "Field " + MakeName (f.Name) + " is never assigned " +
- " to and will always have its default value");
- }
+ if (delegates != null) {
+ foreach (Delegate d in Delegates) {
+ d.Emit ();
}
+ }
- if (events != null){
- foreach (Event e in events){
- if (e.status == 0)
- Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
- }
+ if (enums != null) {
+ foreach (Enum e in enums) {
+ e.Emit ();
}
}
+
+ if (parts != null) {
+ foreach (ClassPart part in parts)
+ part.EmitType ();
+ }
+
+ if ((Pending != null) && !(this is ClassPart))
+ if (Pending.VerifyPendingMethods ())
+ return;
+
+ VerifyMembers (ec);
+
+ if (iterators != null)
+ foreach (Iterator iterator in iterators)
+ iterator.EmitType ();
// if (types != null)
// foreach (TypeContainer tc in types)
@@ -1811,11 +2229,11 @@ namespace Mono.CSharp {
public override void CloseType ()
{
- if (Created)
+ if ((caching_flags & Flags.CloseTypeCreated) != 0)
return;
-
+
try {
- Created = true;
+ caching_flags |= Flags.CloseTypeCreated;
TypeBuilder.CreateType ();
} catch (TypeLoadException){
//
@@ -1832,24 +2250,23 @@ namespace Mono.CSharp {
foreach (Enum en in Enums)
en.CloseType ();
- if (interface_order != null){
- foreach (Interface iface in interface_order)
- iface.CloseType ();
- }
-
if (Types != null){
foreach (TypeContainer tc in Types)
- if (tc is Struct)
+ if (tc.Kind == Kind.Struct)
tc.CloseType ();
foreach (TypeContainer tc in Types)
- if (!(tc is Struct))
+ if (tc.Kind != Kind.Struct)
tc.CloseType ();
}
if (Delegates != null)
foreach (Delegate d in Delegates)
d.CloseType ();
+
+ if (Iterators != null)
+ foreach (Iterator i in Iterators)
+ i.CloseType ();
types = null;
properties = null;
@@ -1860,11 +2277,11 @@ namespace Mono.CSharp {
initialized_static_fields = null;
constants = null;
interfaces = null;
- interface_order = null;
methods = null;
events = null;
indexers = null;
operators = null;
+ iterators = null;
ec = null;
default_constructor = null;
default_static_constructor = null;
@@ -1875,38 +2292,12 @@ namespace Mono.CSharp {
member_cache = null;
}
+ // TODO: make it obsolete and use GetSignatureForError
public string MakeName (string n)
{
return "`" + Name + "." + n + "'";
}
- public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
- {
- Report.Warning (
- 108, l, "The keyword new is required on " +
- MakeName (mi.Name) + " because it hides `" +
- mi.ReflectedType.Name + "." + mi.Name + "'");
- }
-
- public void Warning_KeywordNewNotRequired (Location l, MemberCore mc)
- {
- Report.Warning (
- 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
- "inherited member, the keyword new is not required");
- }
-
- public void Error_EventCanOnlyOverrideEvent (Location l, MemberInfo mi)
- {
- Report.Error (
- 72, l, MakeName (mi.Name) + " : cannot override; `" +
- mi.ReflectedType.Name + "." + mi.Name + "' is not an event");
- }
-
- public static int CheckMember (string name, MemberInfo mi, int ModFlags)
- {
- return 0;
- }
-
//
// Performs the validation on a Method's modifiers (properties have
// the same properties).
@@ -1930,7 +2321,7 @@ namespace Mono.CSharp {
}
}
- if (this is Struct){
+ if (Kind == Kind.Struct){
if ((flags & va) != 0){
Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
ok = false;
@@ -1991,28 +2382,84 @@ namespace Mono.CSharp {
return ok;
}
- Hashtable builder_and_args;
-
- public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
+ public bool UserDefinedStaticConstructor {
+ get {
+ return default_static_constructor != null;
+ }
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
{
- if (builder_and_args == null)
- builder_and_args = new Hashtable ();
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ VerifyClsName ();
+
+ // parent_container is null for System.Object
+ if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
+ Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (parent_container.Type));
+ }
return true;
}
+
///
- /// Performs checks for an explicit interface implementation. First it
- /// checks whether the `interface_type' is a base inteface implementation.
- /// Then it checks whether `name' exists in the interface type.
+ /// Checks whether container name is CLS Compliant
///
- public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
+ void VerifyClsName ()
{
- bool found = false;
+ Hashtable parent_members = parent_container == null ?
+ new Hashtable () :
+ parent_container.MemberCache.GetPublicMembers ();
+ Hashtable this_members = new Hashtable ();
- if (ifaces != null){
- foreach (TypeExpr t in ifaces){
- if (t.Type == interface_type){
- found = true;
+ foreach (DictionaryEntry entry in defined_names) {
+ MemberCore mc = (MemberCore)entry.Value;
+ if (!mc.IsClsCompliaceRequired (this))
+ continue;
+
+ string name = (string)entry.Key;
+ string basename = name.Substring (name.LastIndexOf ('.') + 1);
+
+ string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+ object found = parent_members [lcase];
+ if (found == null) {
+ found = this_members [lcase];
+ if (found == null) {
+ this_members.Add (lcase, mc);
+ continue;
+ }
+ }
+
+ if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
+ continue;
+
+ if (found is MemberInfo) {
+ if (basename == ((MemberInfo)found).Name)
+ continue;
+ Report.SymbolRelatedToPreviousError ((MemberInfo)found);
+ } else {
+ Report.SymbolRelatedToPreviousError ((MemberCore) found);
+ }
+ Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
+ }
+ }
+
+
+ ///
+ /// Performs checks for an explicit interface implementation. First it
+ /// checks whether the `interface_type' is a base inteface implementation.
+ /// Then it checks whether `name' exists in the interface type.
+ ///
+ public virtual bool VerifyImplements (Type interface_type, string full,
+ string name, Location loc)
+ {
+ bool found = false;
+
+ if (ifaces != null){
+ foreach (Type t in ifaces){
+ if (t == interface_type){
+ found = true;
break;
}
}
@@ -2026,6 +2473,18 @@ namespace Mono.CSharp {
return true;
}
+ protected override void VerifyObsoleteAttribute()
+ {
+ CheckUsageOfObsoleteAttribute (TypeBuilder.BaseType);
+
+ if (ifaces == null)
+ return;
+
+ foreach (Type iface in ifaces) {
+ CheckUsageOfObsoleteAttribute (iface);
+ }
+ }
+
//
// IMemberContainer
//
@@ -2042,12 +2501,6 @@ namespace Mono.CSharp {
}
}
- IMemberContainer IMemberContainer.Parent {
- get {
- return parent_container;
- }
- }
-
MemberCache IMemberContainer.MemberCache {
get {
return member_cache;
@@ -2056,7 +2509,7 @@ namespace Mono.CSharp {
bool IMemberContainer.IsInterface {
get {
- return false;
+ return Kind == Kind.Interface;
}
}
@@ -2071,181 +2524,329 @@ namespace Mono.CSharp {
return FindMembers (mt, new_bf, null, null);
}
- //
- // Operator pair checking
- //
+ public virtual IMemberContainer ParentContainer {
+ get {
+ return parent_container;
+ }
+ }
+
+ }
- class OperatorEntry {
- public int flags;
- public Type ret_type;
- public Type type1, type2;
- public Operator op;
- public Operator.OpType ot;
-
- public OperatorEntry (int f, Operator o)
- {
- flags = f;
+ public class PartialContainer : TypeContainer {
+
+ public readonly Namespace Namespace;
+ public readonly int OriginalModFlags;
+ public readonly int AllowedModifiers;
+ public readonly TypeAttributes DefaultTypeAttributes;
+
+ static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
+ MemberName name, int mod_flags, Kind kind,
+ Location loc)
+ {
+ PartialContainer pc;
+ string full_name = name.GetName (true);
+ DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
+ if (ds != null) {
+ pc = ds as PartialContainer;
+
+ if (pc == null) {
+ Report.Error (
+ 260, ds.Location, "Missing partial modifier " +
+ "on declaration of type `{0}'; another " +
+ "partial implementation of this type exists",
+ name);
+
+ Report.LocationOfPreviousError (loc);
+ return null;
+ }
+
+ if (pc.Kind != kind) {
+ Report.Error (
+ 261, loc, "Partial declarations of `{0}' " +
+ "must be all classes, all structs or " +
+ "all interfaces", name);
+ return null;
+ }
+
+ if (pc.OriginalModFlags != mod_flags) {
+ Report.Error (
+ 262, loc, "Partial declarations of `{0}' " +
+ "have conflicting accessibility modifiers",
+ name);
+ return null;
+ }
- ret_type = o.OperatorMethod.GetReturnType ();
- Type [] pt = o.OperatorMethod.ParameterTypes;
- type1 = pt [0];
- type2 = pt [1];
- op = o;
- ot = o.OperatorType;
+ return pc;
}
- public override int GetHashCode ()
- {
- return ret_type.GetHashCode ();
+ pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc);
+ RootContext.Tree.RecordDecl (full_name, pc);
+ parent.AddType (pc);
+ pc.Register ();
+ return pc;
+ }
+
+ public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
+ MemberName name, int mod, Attributes attrs,
+ Kind kind, Location loc)
+ {
+ PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
+ if (pc == null) {
+ // An error occured; create a dummy container, but don't
+ // register it.
+ pc = new PartialContainer (ns, parent, name, mod, kind, loc);
}
- public override bool Equals (object o)
- {
- OperatorEntry other = (OperatorEntry) o;
+ ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
+ pc.AddPart (part);
+ return part;
+ }
- if (other.ret_type != ret_type)
- return false;
- if (other.type1 != type1)
- return false;
- if (other.type2 != type2)
- return false;
- return true;
+ protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
+ MemberName name, int mod, Kind kind, Location l)
+ : base (ns, parent, name, null, kind, l)
+ {
+ this.Namespace = ns.NS;
+
+ switch (kind) {
+ case Kind.Class:
+ AllowedModifiers = Class.AllowedModifiers;
+ DefaultTypeAttributes = Class.DefaultTypeAttributes;
+ break;
+
+ case Kind.Struct:
+ AllowedModifiers = Struct.AllowedModifiers;
+ DefaultTypeAttributes = Struct.DefaultTypeAttributes;
+ break;
+
+ case Kind.Interface:
+ AllowedModifiers = Interface.AllowedModifiers;
+ DefaultTypeAttributes = Interface.DefaultTypeAttributes;
+ break;
+
+ default:
+ throw new InvalidOperationException ();
}
+
+ int accmods;
+ if (parent.Parent == null)
+ accmods = Modifiers.INTERNAL;
+ else
+ accmods = Modifiers.PRIVATE;
+
+ this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+ this.OriginalModFlags = mod;
}
-
- //
- // Checks that some operators come in pairs:
- // == and !=
- // > and <
- // >= and <=
- // true and false
- //
- // They are matched based on the return type and the argument types
- //
- void CheckPairedOperators ()
+
+ public override void Register ()
{
- Hashtable pairs = new Hashtable (null, null);
- Operator true_op = null;
- Operator false_op = null;
- bool has_equality_or_inequality = false;
-
- // Register all the operators we care about.
- foreach (Operator op in operators){
- int reg = 0;
-
- switch (op.OperatorType){
- case Operator.OpType.Equality:
- reg = 1;
- has_equality_or_inequality = true;
- break;
- case Operator.OpType.Inequality:
- reg = 2;
- has_equality_or_inequality = true;
- break;
+ if (Kind == Kind.Interface)
+ Parent.AddInterface (this);
+ else if (Kind == Kind.Class || Kind == Kind.Struct)
+ Parent.AddClassOrStruct (this);
+ else
+ throw new InvalidOperationException ();
+ }
- case Operator.OpType.True:
- true_op = op;
- break;
- case Operator.OpType.False:
- false_op = op;
- break;
-
- case Operator.OpType.GreaterThan:
- reg = 1; break;
- case Operator.OpType.LessThan:
- reg = 2; break;
-
- case Operator.OpType.GreaterThanOrEqual:
- reg = 1; break;
- case Operator.OpType.LessThanOrEqual:
- reg = 2; break;
- }
- if (reg == 0)
- continue;
+ public override PendingImplementation GetPendingImplementations ()
+ {
+ return PendingImplementation.GetPendingImplementations (this);
+ }
+
+ public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
+ Location l)
+ {
+ ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
+ AddPart (part);
+ return part;
+ }
+
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr | DefaultTypeAttributes;
+ }
+ }
+ }
+
+ public class ClassPart : TypeContainer, IMemberContainer {
+ public readonly PartialContainer PartialContainer;
+ public readonly bool IsPartial;
+
+ public ClassPart (NamespaceEntry ns, PartialContainer parent,
+ int mod, Attributes attrs, Kind kind, Location l)
+ : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
+ {
+ this.PartialContainer = parent;
+ this.IsPartial = true;
+
+ int accmods;
+ if (parent.Parent == null)
+ accmods = Modifiers.INTERNAL;
+ else
+ accmods = Modifiers.PRIVATE;
+
+ this.ModFlags = Modifiers.Check (
+ parent.AllowedModifiers, mod, accmods, l);
+ }
+
+ public override void Register ()
+ {
+ }
+
+ public override PendingImplementation GetPendingImplementations ()
+ {
+ return PartialContainer.Pending;
+ }
+
+ public override bool VerifyImplements (Type interface_type, string full,
+ string name, Location loc)
+ {
+ return PartialContainer.VerifyImplements (
+ interface_type, full, name, loc);
+ }
+
+ public override IMemberContainer ParentContainer {
+ get {
+ return PartialContainer.ParentContainer;
+ }
+ }
+ }
+
+ public abstract class ClassOrStruct : TypeContainer {
+ bool hasExplicitLayout = false;
- OperatorEntry oe = new OperatorEntry (reg, op);
+ public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
+ MemberName name, Attributes attrs, Kind kind,
+ Location l)
+ : base (ns, parent, name, attrs, kind, l)
+ {
+ }
+
+ public override PendingImplementation GetPendingImplementations ()
+ {
+ return PendingImplementation.GetPendingImplementations (this);
+ }
- object o = pairs [oe];
- if (o == null)
- pairs [oe] = oe;
- else {
- oe = (OperatorEntry) o;
- oe.flags |= reg;
+ protected override void VerifyMembers (EmitContext ec)
+ {
+ if (Fields != null) {
+ foreach (Field f in Fields) {
+ if ((f.ModFlags & Modifiers.STATIC) != 0)
+ continue;
+ if (hasExplicitLayout) {
+ if (f.OptAttributes == null
+ || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
+ Report.Error (625, f.Location,
+ "Instance field of type marked with"
+ + " StructLayout(LayoutKind.Explicit) must have a"
+ + " FieldOffset attribute.");
+ }
+ }
+ else {
+ if (f.OptAttributes != null
+ && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
+ Report.Error (636, f.Location,
+ "The FieldOffset attribute can only be placed on members of "
+ + "types marked with the StructLayout(LayoutKind.Explicit)");
+ }
+ }
}
}
+ base.VerifyMembers (ec);
+ }
- if (true_op != null){
- if (false_op == null)
- Report.Error (216, true_op.Location, "operator true requires a matching operator false");
- } else if (false_op != null)
- Report.Error (216, false_op.Location, "operator false requires a matching operator true");
-
- //
- // Look for the mistakes.
- //
- foreach (DictionaryEntry de in pairs){
- OperatorEntry oe = (OperatorEntry) de.Key;
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.struct_layout_attribute_type
+ && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
+ hasExplicitLayout = true;
- if (oe.flags == 3)
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override void Register ()
+ {
+ Parent.AddClassOrStruct (this);
+ }
+ }
+
+ ///
+ /// Class handles static classes declaration
+ ///
+ public sealed class StaticClass: Class {
+ public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
+ Attributes attrs, Location l)
+ : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l)
+ {
+ if (RootContext.Version == LanguageVersion.ISO_1) {
+ Report.FeatureIsNotStandardized (l, "static classes");
+ Environment.Exit (1);
+ }
+ }
+
+ protected override void DefineContainerMembers (MemberCoreArrayList list)
+ {
+ if (list == null)
+ 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 (this));
+ continue;
+ }
+
+ if ((m.ModFlags & Modifiers.STATIC) != 0)
continue;
- string s = "";
- switch (oe.ot){
- case Operator.OpType.Equality:
- s = "!=";
- break;
- case Operator.OpType.Inequality:
- s = "==";
- break;
- case Operator.OpType.GreaterThan:
- s = "<";
- break;
- case Operator.OpType.LessThan:
- s = ">";
- break;
- case Operator.OpType.GreaterThanOrEqual:
- s = "<=";
- break;
- case Operator.OpType.LessThanOrEqual:
- s = ">=";
- break;
+ if (m is Constructor) {
+ Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
+ continue;
+ }
+
+ if (m is Destructor) {
+ Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
+ continue;
}
- Report.Error (216, oe.op.Location,
- "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
+ Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
}
- if ((has_equality_or_inequality) && (RootContext.WarningLevel >= 2)) {
- MethodSignature equals_ms = new MethodSignature (
- "Equals", TypeManager.bool_type, new Type [] { TypeManager.object_type });
- MethodSignature hash_ms = new MethodSignature (
- "GetHashCode", TypeManager.int32_type, new Type [0]);
+ base.DefineContainerMembers (list);
+ }
+
+ public override TypeBuilder DefineType()
+ {
+ TypeBuilder tb = base.DefineType ();
+ if (tb == null)
+ return null;
- MemberList equals_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
- equals_ms);
- MemberList hash_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
- hash_ms);
+ if ((ptype != null) && (ptype != TypeManager.object_type)) {
+ Report.Error (
+ 713, Location,
+ "Static class '{0}' cannot derive from type '{1}'. " +
+ "Static classes must derive from object",
+ GetSignatureForError (), ptype);
+ return null;
+ }
- bool equals_ok = false;
- if ((equals_ml != null) && (equals_ml.Count == 1))
- equals_ok = equals_ml [0].DeclaringType == TypeBuilder;
- bool hash_ok = false;
- if ((hash_ml != null) && (hash_ml.Count == 1))
- hash_ok = hash_ml [0].DeclaringType == TypeBuilder;
+ if (ifaces != null) {
+ foreach (Type t in ifaces)
+ Report.SymbolRelatedToPreviousError (t);
+ Report.Error (
+ 714, Location,
+ "'{0}': static classes cannot implement interfaces",
+ GetSignatureForError ());
+ }
+ return tb;
+ }
- if (!equals_ok)
- Report.Warning (660, Location, "`" + Name + "' defines operator == or operator != but does " +
- "not override Object.Equals (object o)");
- if (!hash_ok)
- Report.Warning (661, Location, "`" + Name + "' defines operator == or operator != but does " +
- "not override Object.GetHashCode ()");
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
}
}
-
}
- public class Class : TypeContainer {
+ public class Class : ClassOrStruct {
//
// Modifiers allowed in a class declaration
//
@@ -2259,8 +2860,12 @@ namespace Mono.CSharp {
Modifiers.SEALED |
Modifiers.UNSAFE;
- public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (ns, parent, name, attrs, l)
+ // Information in the case we are an attribute type
+ AttributeUsageAttribute attribute_usage;
+
+ public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
+ Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, Kind.Class, l)
{
int accmods;
@@ -2270,20 +2875,54 @@ namespace Mono.CSharp {
accmods = Modifiers.PRIVATE;
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+ if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) {
+ Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
+ }
+
+ attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Class;
+ }
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.UsageAttribute != null) {
+ if (ptype != TypeManager.attribute_type &&
+ !ptype.IsSubclassOf (TypeManager.attribute_type) &&
+ TypeBuilder.FullName != "System.Attribute") {
+ Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
+ }
+ attribute_usage = a.UsageAttribute;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public AttributeUsageAttribute AttributeUsage {
+ get {
+ return attribute_usage;
+ }
}
+ public const TypeAttributes DefaultTypeAttributes =
+ TypeAttributes.AutoLayout | TypeAttributes.Class;
+
//
// FIXME: How do we deal with the user specifying a different
// layout?
//
public override TypeAttributes TypeAttr {
get {
- return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
+ return base.TypeAttr | DefaultTypeAttributes;
}
}
}
- public class Struct : TypeContainer {
+ public class Struct : ClassOrStruct {
//
// Modifiers allowed in a struct declaration
//
@@ -2295,8 +2934,9 @@ namespace Mono.CSharp {
Modifiers.UNSAFE |
Modifiers.PRIVATE;
- public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (ns, parent, name, attrs, l)
+ public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
+ int mod, Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, Kind.Struct, l)
{
int accmods;
@@ -2310,6 +2950,17 @@ namespace Mono.CSharp {
this.ModFlags |= Modifiers.SEALED;
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Struct;
+ }
+ }
+
+ public const TypeAttributes DefaultTypeAttributes =
+ TypeAttributes.SequentialLayout |
+ TypeAttributes.Sealed |
+ TypeAttributes.BeforeFieldInit;
+
//
// FIXME: Allow the user to specify a different set of attributes
// in some cases (Sealed for example is mandatory for a class,
@@ -2317,40 +2968,109 @@ namespace Mono.CSharp {
//
public override TypeAttributes TypeAttr {
get {
- return base.TypeAttr |
- TypeAttributes.SequentialLayout |
- TypeAttributes.Sealed |
- TypeAttributes.BeforeFieldInit;
+ return base.TypeAttr | DefaultTypeAttributes;
}
}
}
- public abstract class MethodCore : MemberBase {
- public readonly Parameters Parameters;
- protected Block block;
- protected DeclSpace ds;
-
- //
- // Parameters, cached for semantic analysis.
- //
- protected InternalParameters parameter_info;
- protected Type [] parameter_types;
-
- //
- // This is set from TypeContainer.DefineMembers if this method overrides something.
- //
- public bool OverridesSomething;
+ ///
+ /// Interfaces
+ ///
+ public class Interface : TypeContainer, IMemberContainer {
+ ///
+ /// Modifiers allowed in a class declaration
+ ///
+ public const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.UNSAFE |
+ Modifiers.PRIVATE;
- public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
- string name, Attributes attrs, Parameters parameters, Location loc)
- : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
+ public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name,
+ int mod, Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, Kind.Interface, l)
{
- Parameters = parameters;
- this.ds = ds;
- }
-
- //
- // Returns the System.Type array for the parameters of this method
+ int accmods;
+
+ if (parent.Parent == null)
+ accmods = Modifiers.INTERNAL;
+ else
+ accmods = Modifiers.PRIVATE;
+
+ this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+ }
+
+ public override void Register ()
+ {
+ Parent.AddInterface (this);
+ }
+
+ public override PendingImplementation GetPendingImplementations ()
+ {
+ return null;
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Interface;
+ }
+ }
+
+ public const TypeAttributes DefaultTypeAttributes =
+ TypeAttributes.AutoLayout |
+ TypeAttributes.Abstract |
+ TypeAttributes.Interface;
+
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr | DefaultTypeAttributes;
+ }
+ }
+ }
+
+ public abstract class MethodCore : MemberBase {
+ public readonly Parameters Parameters;
+ public readonly GenericMethod GenericMethod;
+ public readonly DeclSpace ds;
+ protected Block block;
+
+ //
+ // Parameters, cached for semantic analysis.
+ //
+ protected InternalParameters parameter_info;
+ protected Type [] parameter_types;
+
+ // Whether this is an operator method.
+ public bool IsOperator;
+
+ //
+ // The method we're overriding if this is an override method.
+ //
+ protected MethodInfo parent_method = null;
+
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public MethodCore (TypeContainer parent, GenericMethod generic,
+ Expression type, int mod, int allowed_mod, bool is_iface,
+ MemberName name, Attributes attrs, Parameters parameters,
+ Location loc)
+ : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
+ attrs, loc)
+ {
+ Parameters = parameters;
+ IsInterface = is_iface;
+ this.GenericMethod = generic;
+
+ if (generic != null)
+ ds = generic;
+ else
+ ds = parent;
+ }
+
+ //
+ // Returns the System.Type array for the parameters of this method
//
public Type [] ParameterTypes {
get {
@@ -2375,14 +3095,241 @@ namespace Mono.CSharp {
}
}
+ protected override bool CheckBase ()
+ {
+ if (!base.CheckBase ())
+ return false;
+
+ // Check whether arguments were correct.
+ if (!DoDefineParameters ())
+ return false;
+
+ if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
+ return false;
+
+ if (IsExplicitImpl)
+ return true;
+
+ // Is null for System.Object while compiling corlib and base interfaces
+ if (Parent.ParentContainer == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+ }
+ return true;
+ }
+
+ Type parent_ret_type = null;
+ parent_method = FindOutParentMethod (Parent, ref parent_ret_type);
+
+ // method is override
+ if (parent_method != null) {
+
+ if (!CheckMethodAgainstBase ())
+ return false;
+
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ if (!MemberType.Equals (TypeManager.TypeToCoreType (parent_ret_type))) {
+ Report.SymbolRelatedToPreviousError (parent_method);
+ Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
+ "change return type when overriding inherited member");
+ return false;
+ }
+ }
+
+ if (RootContext.WarningLevel > 2) {
+ if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
+ Parent.Methods.HasEquals = true;
+ else if (Name == "GetHashCode" && parameter_types.Length == 0)
+ Parent.Methods.HasGetHashCode = true;
+ }
+
+ ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
+ if (oa != null) {
+ EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
+ if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
+ Report.SymbolRelatedToPreviousError (parent_method);
+ Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
+ }
+ }
+ return true;
+ }
+
+ if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
+ return false;
+ }
+
+ MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
+ if (conflict_symbol == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+ }
+ return true;
+ }
+
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ if (this is Method && conflict_symbol is MethodBase)
+ return true;
+
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+ }
+
+ return true;
+ }
+
+
+ //
+ // Performs various checks on the MethodInfo `mb' regarding the modifier flags
+ // that have been defined.
+ //
+ // `name' is the user visible name for reporting errors (this is used to
+ // provide the right name regarding method names and properties)
+ //
+ bool CheckMethodAgainstBase ()
+ {
+ bool ok = true;
+
+ // TODO: replace with GetSignatureForError
+ string name = parent_method.DeclaringType.Name + "." + parent_method.Name;
+
+ if ((ModFlags & Modifiers.OVERRIDE) != 0){
+ if (!(parent_method.IsAbstract || parent_method.IsVirtual)){
+ Report.Error (
+ 506, Location, Parent.MakeName (Name) +
+ ": cannot override inherited member `" +
+ name + "' because it is not " +
+ "virtual, abstract or override");
+ ok = false;
+ }
+
+ // Now we check that the overriden method is not final
+
+ if (parent_method.IsFinal) {
+ // This happens when implementing interface methods.
+ if (parent_method.IsHideBySig && parent_method.IsVirtual) {
+ Report.Error (
+ 506, Location, Parent.MakeName (Name) +
+ ": cannot override inherited member `" +
+ name + "' because it is not " +
+ "virtual, abstract or override");
+ } else
+ Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
+ "override inherited member `" + name +
+ "' because it is sealed.");
+ ok = false;
+ }
+ //
+ // Check that the permissions are not being changed
+ //
+ MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
+ MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
+
+ //
+ // special case for "protected internal"
+ //
+
+ if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+ //
+ // when overriding protected internal, the method can be declared
+ // protected internal only within the same assembly
+ //
+
+ if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+ if (Parent.TypeBuilder.Assembly != parent_method.DeclaringType.Assembly){
+ //
+ // assemblies differ - report an error
+ //
+
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ } else if (thisp != parentp) {
+ //
+ // same assembly, but other attributes differ - report an error
+ //
+
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ };
+ } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
+ //
+ // if it's not "protected internal", it must be "protected"
+ //
+
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ } else if (Parent.TypeBuilder.Assembly == parent_method.DeclaringType.Assembly) {
+ //
+ // protected within the same assembly - an error
+ //
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
+ (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+ //
+ // protected ok, but other attributes differ - report an error
+ //
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ }
+ } else {
+ if (thisp != parentp){
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
+ }
+ }
+ }
+
+ if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
+ ModFlags |= Modifiers.NEW;
+ Report.SymbolRelatedToPreviousError (parent_method);
+ if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
+ if (RootContext.WarningLevel >= 2)
+ Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), parent_method);
+ } else
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+ }
+
+ return ok;
+ }
+
+ void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
+ {
+ //
+ // FIXME: report the old/new permissions?
+ //
+ Report.Error (
+ 507, Location, parent.MakeName (Name) +
+ ": can't change the access modifiers when overriding inherited " +
+ "member `" + name + "'");
+ }
+
+ protected static string Error722 {
+ get {
+ return "'{0}': static types cannot be used as return types";
+ }
+ }
+
+ ///
+ /// For custom member duplication search in a container
+ ///
+ protected abstract bool CheckForDuplications ();
+
+ ///
+ /// Gets parent method and its return type
+ ///
+ protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type);
+
protected virtual bool DoDefineParameters ()
{
// Check if arguments were correct
parameter_types = Parameters.GetParameterInfo (ds);
- if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
+ if ((parameter_types == null) ||
+ !CheckParameters (ds, parameter_types))
return false;
- parameter_info = new InternalParameters (ds, Parameters);
+ TypeParameter[] tparam = ds.IsGeneric ? ds.TypeParameters : null;
+ parameter_info = new InternalParameters (ds, Parameters, tparam);
Parameter array_param = Parameters.ArrayParameter;
if ((array_param != null) &&
@@ -2395,129 +3342,265 @@ namespace Mono.CSharp {
return true;
}
- public CallingConventions GetCallingConvention (bool is_class)
+ void error_425 (Type old, Type t, string name)
{
- CallingConventions cc = 0;
-
- cc = Parameters.GetCallingConvention ();
+ Report.Error (425, Location,
+ "The constraints of type parameter `{0}' " +
+ "of method `{1}' must match the constraints for " +
+ "type parameter `{2}' of method `{3}'",
+ TypeManager.CSharpName (old), Name,
+ TypeManager.CSharpName (t), name);
+ }
- if (is_class)
- if ((ModFlags & Modifiers.STATIC) == 0)
- cc |= CallingConventions.HasThis;
+ protected override bool CheckGenericOverride (MethodInfo method, string name)
+ {
+ ParameterData pd = Invocation.GetParameterData (method);
- // FIXME: How is `ExplicitThis' used in C#?
-
- return cc;
+ for (int i = 0; i < ParameterTypes.Length; i++) {
+ GenericConstraints ogc = pd.GenericConstraints (i);
+ GenericConstraints gc = ParameterInfo.GenericConstraints (i);
+
+ if ((gc == null) && (ogc == null))
+ continue;
+
+ Type ot = pd.ParameterType (i);
+ Type t = ParameterTypes [i];
+
+ if (!((gc != null) && (ogc != null))) {
+ error_425 (ot, t, name);
+ return false;
+ }
+
+ if (gc.HasConstructor != ogc.HasConstructor) {
+ error_425 (ot, t, name);
+ return false;
+ }
+
+ if (ogc.HasClassConstraint != gc.HasClassConstraint) {
+ error_425 (ot, t, name);
+ return false;
+ }
+
+ if (ogc.HasClassConstraint &&
+ !ogc.ClassConstraint.Equals (gc.ClassConstraint)) {
+ error_425 (ot, t, name);
+ return false;
+ }
+
+ Type[] oct = ogc.InterfaceConstraints;
+ Type[] ct = gc.InterfaceConstraints;
+
+ if (oct.Length != ct.Length) {
+ error_425 (ot, t, name);
+ return false;
+ }
+
+ for (int j = 0; j < oct.Length; j++)
+ if (!oct [j].Equals (ct [j])) {
+ error_425 (ot, t, name);
+ return false;
+ }
+ }
+
+ return true;
}
- //
- // The method's attributes are passed in because we need to extract
- // the "return:" attribute from there to apply on the return type
- //
- static public void LabelParameters (EmitContext ec,
- MethodBase builder,
- Parameters parameters,
- Attributes method_attrs,
- Location loc)
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
{
- //
- // Define each type attribute (in/out/ref) and
- // the argument names.
- //
- Parameter [] p = parameters.FixedParameters;
- int i = 0;
-
- MethodBuilder mb = null;
- ConstructorBuilder cb = null;
+ if (!base.VerifyClsCompliance (ds)) {
+ if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
+ Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
+ }
+ return false;
+ }
+
+ if (Parameters.HasArglist) {
+ Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
+ }
+
+ if (!AttributeTester.IsClsCompliant (MemberType)) {
+ Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
+ }
+
+ AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
- if (builder is MethodBuilder)
- mb = (MethodBuilder) builder;
+ return true;
+ }
+
+ protected bool IsDuplicateImplementation (MethodCore method)
+ {
+ if ((method == this) ||
+ (method.MemberName.GetTypeName () != MemberName.GetTypeName ()))
+ return false;
+
+ Type[] param_types = method.ParameterTypes;
+ if (param_types == null)
+ return false;
+
+ if (param_types.Length != ParameterTypes.Length)
+ return false;
+
+ int type_params = 0;
+ if (GenericMethod != null)
+ type_params = GenericMethod.CountTypeParameters;
+
+ int m_type_params = 0;
+ if (method.GenericMethod != null)
+ m_type_params = method.GenericMethod.CountTypeParameters;
+
+ if (type_params != m_type_params)
+ return false;
+
+ bool equal = true;
+ bool may_unify;
+
+ Type[] infered_types;
+ if (type_params > 0)
+ infered_types = new Type [type_params];
else
- cb = (ConstructorBuilder) builder;
+ infered_types = null;
- if (p != null){
- for (i = 0; i < p.Length; i++) {
- ParameterBuilder pb;
- ParameterAttributes par_attr = p [i].Attributes;
-
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, par_attr, p [i].Name);
- else
- pb = mb.DefineParameter (
- i + 1, par_attr, p [i].Name);
-
- Attributes attr = p [i].OptAttributes;
- if (attr != null){
- Attribute.ApplyAttributes (ec, pb, pb, attr);
-
- if (par_attr == ParameterAttributes.Out){
- if (attr.Contains (TypeManager.in_attribute_type))
- Report.Error (36, loc,
- "Can not use [In] attribute on out parameter");
- }
+ may_unify = Invocation.InferTypeArguments (
+ param_types, ParameterTypes, ref infered_types);
+
+ if (!may_unify) {
+ if (type_params > 0)
+ infered_types = new Type [type_params];
+ else
+ infered_types = null;
+
+ may_unify = Invocation.InferTypeArguments (
+ ParameterTypes, param_types, ref infered_types);
+ }
+
+ for (int i = 0; i < param_types.Length; i++) {
+ if (param_types [i] != ParameterTypes [i])
+ equal = false;
+ }
+
+ // TODO: make operator compatible with MethodCore to avoid this
+ if (this is Operator && method is Operator) {
+ if (MemberType != method.MemberType)
+ equal = false;
+ }
+
+ if (equal) {
+ //
+ // Try to report 663: method only differs on out/ref
+ //
+ ParameterData info = ParameterInfo;
+ ParameterData other_info = method.ParameterInfo;
+ for (int i = 0; i < info.Count; i++){
+ if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
+ Report.Error (663, Location,
+ "Overload method only differs " +
+ "in parameter modifier");
+ return false;
}
}
+
+ Report.SymbolRelatedToPreviousError (method);
+ Report.Error (111, Location, "Type '{0}' already defines a member called '{1}' with the same parameter types", Parent.Name, Name);
+ return true;
+ } else if (may_unify) {
+ Report.Error (408, Location,
+ "`{0}' cannot define overload members that " +
+ "may unify for some type parameter substitutions",
+ Parent.Name);
+ return true;
}
- if (parameters.ArrayParameter != null){
- ParameterBuilder pb;
- Parameter array_param = parameters.ArrayParameter;
+ return false;
+ }
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
- else
- pb = mb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
-
- CustomAttributeBuilder a = new CustomAttributeBuilder (
- TypeManager.cons_param_array_attribute, new object [0]);
-
- pb.SetCustomAttribute (a);
- }
+ protected override void VerifyObsoleteAttribute()
+ {
+ base.VerifyObsoleteAttribute ();
- //
- // And now for the return type attribute decoration
- //
- ParameterBuilder ret_pb;
- Attributes ret_attrs = null;
-
- if (mb == null || method_attrs == null)
+ if (parameter_types == null)
return;
- foreach (AttributeSection asec in method_attrs.AttributeSections) {
+ foreach (Type type in parameter_types) {
+ CheckUsageOfObsoleteAttribute (type);
+ }
+ }
+ }
- if (asec.Target != "return")
- continue;
+ public class SourceMethod : ISourceMethod
+ {
+ TypeContainer container;
+ MethodBase builder;
- if (ret_attrs == null)
- ret_attrs = new Attributes (asec);
+ protected SourceMethod (TypeContainer container, MethodBase builder,
+ ISourceFile file, Location start, Location end)
+ {
+ this.container = container;
+ this.builder = builder;
+
+ CodeGen.SymbolWriter.OpenMethod (
+ file, this, start.Row, 0, end.Row, 0);
+ }
+
+ public string Name {
+ get { return builder.Name; }
+ }
+
+ public int NamespaceID {
+ get { return container.NamespaceEntry.SymbolFileID; }
+ }
+
+ public int Token {
+ get {
+ if (builder is MethodBuilder)
+ return ((MethodBuilder) builder).GetToken ().Token;
+ else if (builder is ConstructorBuilder)
+ return ((ConstructorBuilder) builder).GetToken ().Token;
else
- ret_attrs.AddAttributeSection (asec);
+ throw new NotSupportedException ();
}
+ }
- if (ret_attrs != null) {
- try {
- ret_pb = mb.DefineParameter (0, ParameterAttributes.None, "");
- Attribute.ApplyAttributes (ec, ret_pb, ret_pb, ret_attrs);
+ public void CloseMethod ()
+ {
+ if (CodeGen.SymbolWriter != null)
+ CodeGen.SymbolWriter.CloseMethod ();
+ }
- } catch (ArgumentOutOfRangeException) {
- Report.Warning (
- -24, loc,
- ".NET SDK 1.0 does not permit setting custom attributes" +
- " on the return type of a method");
- }
- }
+ public static SourceMethod Create (TypeContainer parent,
+ MethodBase builder, Block block)
+ {
+ if (CodeGen.SymbolWriter == null)
+ return null;
+ if (block == null)
+ return null;
+
+ Location start_loc = block.StartLocation;
+ if (Location.IsNull (start_loc))
+ return null;
+
+ Location end_loc = block.EndLocation;
+ if (Location.IsNull (end_loc))
+ return null;
+
+ ISourceFile file = start_loc.SourceFile;
+ if (file == null)
+ return null;
+
+ return new SourceMethod (
+ parent, builder, file, start_loc, end_loc);
}
}
- public class Method : MethodCore, IIteratorContainer {
+ public class Method : MethodCore, IIteratorContainer, IMethodData {
public MethodBuilder MethodBuilder;
public MethodData MethodData;
- public readonly GenericMethod GenericMethod;
+ ReturnParameter return_attributes;
///
/// Modifiers allowed in a class declaration
@@ -2537,34 +3620,59 @@ namespace Mono.CSharp {
Modifiers.METHOD_YIELDS |
Modifiers.EXTERN;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW | Modifiers.UNSAFE;
+
//
// return_type can be "null" for VOID values.
//
- public Method (DeclSpace ds, Expression return_type, int mod, string name,
- Parameters parameters, Attributes attrs, Location l)
- : base (ds, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+ public Method (TypeContainer parent, GenericMethod generic,
+ Expression return_type, int mod, bool is_iface,
+ MemberName name, Parameters parameters, Attributes attrs,
+ Location l)
+ : base (parent, generic, return_type, mod,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, name, attrs, parameters, l)
{
}
- public Method (GenericMethod generic, Expression return_type, int mod, string name,
- Parameters parameters, Attributes attrs, Location l)
- : base (generic, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
+
+ public override string GetSignatureForError()
{
- GenericMethod = generic;
+ if (MethodBuilder == null) {
+ return GetSignatureForError (Parent);
+ }
+ return TypeManager.CSharpSignature (MethodBuilder);
}
- //
- // Returns the `System.Type' for the ReturnType of this
- // function. Provides a nice cache. (used between semantic analysis
- // and actual code generation
- //
- public Type GetReturnType ()
+ ///
+ /// Use this method when MethodBuilder is null
+ ///
+ public override string GetSignatureForError (TypeContainer tc)
{
- return MemberType;
- }
+ // TODO: get params from somewhere
+ if (parameter_info == null)
+ return base.GetSignatureForError (tc);
- // Whether this is an operator method.
- public bool IsOperator;
+ // TODO: move to parameters
+ System.Text.StringBuilder args = new System.Text.StringBuilder ();
+ if (parameter_info.Parameters.FixedParameters != null) {
+ for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
+ Parameter p = parameter_info.Parameters.FixedParameters [i];
+ args.Append (p.GetSignatureForError ());
+
+ if (i < parameter_info.Parameters.FixedParameters.Length - 1)
+ args.Append (',');
+ }
+ }
+
+ return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
+ }
void DuplicateEntryPoint (MethodInfo b, Location location)
{
@@ -2575,14 +3683,6 @@ namespace Mono.CSharp {
TypeManager.CSharpSignature(b) + "'");
}
- void Report28 (MethodInfo b)
- {
- Report.Warning (
- 28, Location,
- "`" + TypeManager.CSharpSignature(b) +
- "' has the wrong signature to be an entry point");
- }
-
public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
{
if (b.ReturnType != TypeManager.void_type &&
@@ -2605,100 +3705,105 @@ namespace Mono.CSharp {
return false;
}
- //
- // Checks our base implementation if any
- //
- protected override bool CheckBase (TypeContainer container)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- base.CheckBase (container);
-
- // Check whether arguments were correct.
- if (!DoDefineParameters ())
- return false;
+ if (a.Target == AttributeTargets.ReturnValue) {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (MethodBuilder, Location);
- MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
- if (IsOperator) {
- flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
- } else {
- MemberList mi_this;
-
- mi_this = TypeContainer.FindMembers (
- container.TypeBuilder, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly,
- MethodSignature.method_signature_filter, ms);
-
- if (mi_this.Count > 0) {
- Report.Error (111, Location, "Class `" + container.Name + "' " +
- "already defines a member called `" + Name + "' " +
- "with the same parameter types");
- return false;
- }
- }
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
- //
- // Verify if the parent has a type with the same name, and then
- // check whether we have to create a new slot for it or not.
- //
- Type ptype = container.TypeBuilder.BaseType;
+ if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+ MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
+ }
- // ptype is only null for System.Object while compiling corlib.
- if (ptype != null){
- MemberList mi, mi_static, mi_instance;
+ if (a.Type == TypeManager.dllimport_type) {
+ const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
+ if ((ModFlags & extern_static) != extern_static) {
+ Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
+ }
- mi_instance = TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
- MethodSignature.inheritable_method_signature_filter,
- ms);
+ return;
+ }
- if (mi_instance.Count > 0){
- mi = mi_instance;
- } else {
- mi_static = TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
- MethodSignature.inheritable_method_signature_filter, ms);
+ if (a.Type == TypeManager.conditional_attribute_type) {
+ if (IsOperator || IsExplicitImpl) {
+ Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
+ return;
+ }
- if (mi_static.Count > 0)
- mi = mi_static;
- else
- mi = null;
+ if (ReturnType != TypeManager.void_type) {
+ Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
+ return;
}
- if (mi != null && mi.Count > 0){
- parent_method = (MethodInfo) mi [0];
- string name = parent_method.DeclaringType.Name + "." +
- parent_method.Name;
+ if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
+ return;
+ }
- if (!CheckMethodAgainstBase (container, flags, parent_method, name))
- return false;
+ if (IsInterface) {
+ Report.Error (582, Location, "Conditional not valid on interface members");
+ return;
+ }
- if ((ModFlags & Modifiers.NEW) == 0) {
- Type parent_ret = TypeManager.TypeToCoreType (
- parent_method.ReturnType);
+ if (MethodData.IsImplementing) {
+ Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
+ return;
+ }
- if (parent_ret != MemberType) {
- Report.Error (
- 508, Location, container.MakeName (Name) + ": cannot " +
- "change return type when overriding " +
- "inherited member " + name);
- return false;
- }
+ for (int i = 0; i < parameter_info.Count; ++i) {
+ if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
+ Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
+ return;
}
- } else {
- if (!OverridesSomething && ((ModFlags & Modifiers.NEW) != 0))
- WarningNotHiding (container);
+ }
+ }
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- Report.Error (115, Location,
- container.MakeName (Name) +
- " no suitable methods found to override");
- }
+ MethodBuilder.SetCustomAttribute (cb);
+ }
+
+ protected override bool CheckForDuplications ()
+ {
+ ArrayList ar = Parent.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.Properties;
+ if (ar != null) {
+ for (int i = 0; i < ar.Count; ++i) {
+ PropertyBase pb = (PropertyBase) ar [i];
+ if (pb.AreAccessorsDuplicateImplementation (this))
+ return false;
}
- } else if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (container);
+ }
+
+ ar = Parent.Indexers;
+ if (ar != null) {
+ for (int i = 0; i < ar.Count; ++i) {
+ PropertyBase pb = (PropertyBase) ar [i];
+ if (pb.AreAccessorsDuplicateImplementation (this))
+ return false;
+ }
+ }
+
+ ar = Parent.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;
}
@@ -2706,47 +3811,46 @@ namespace Mono.CSharp {
//
// Creates the type
//
- public override bool Define (TypeContainer container)
+ public override bool Define ()
{
- DeclSpace decl;
+ if (!DoDefineBase ())
+ return false;
+
MethodBuilder mb = null;
if (GenericMethod != null) {
- mb = container.TypeBuilder.DefineGenericMethod (Name, flags);
+ string mname = MemberName.GetMethodName ();
+ mb = Parent.TypeBuilder.DefineGenericMethod (mname, flags);
if (!GenericMethod.Define (mb))
return false;
- decl = GenericMethod;
- } else
- decl = container;
+ }
- if (!DoDefine (decl, container))
+ if (!DoDefine (ds))
return false;
- if (!CheckBase (container))
+ if (!CheckBase ())
return false;
- CallingConventions cc = GetCallingConvention (container is Class);
+ if (IsOperator)
+ flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
- MethodData = new MethodData (ds, this, null, MemberType,
- ParameterTypes, ParameterInfo, cc,
- OptAttributes, ModFlags, flags, true,
- mb, GenericMethod);
+ MethodData = new MethodData (this, ParameterInfo, ModFlags, flags,
+ this, mb, GenericMethod);
- if (!MethodData.Define (container))
+ if (!MethodData.Define (Parent))
return false;
//
// Setup iterator if we are one
//
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
- IteratorHandler ih = new IteratorHandler (
- Name, container, MemberType,
- ParameterTypes, ParameterInfo,
- ModFlags, Location);
+ Iterator iterator = new Iterator (
+ Parent, Name, MemberType, ParameterTypes,
+ ParameterInfo, ModFlags, block, Location);
- Block new_block = ih.Setup (block);
- if (new_block == null)
+ if (!iterator.DefineIterator ())
return false;
- block = new_block;
+
+ block = iterator.Block;
}
MethodBuilder = MethodData.MethodBuilder;
@@ -2757,10 +3861,10 @@ namespace Mono.CSharp {
if (Name == "Main" &&
((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
(RootContext.MainClass == null ||
- RootContext.MainClass == container.TypeBuilder.FullName)){
+ RootContext.MainClass == Parent.TypeBuilder.FullName)){
if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
if (RootContext.EntryPoint == null) {
- if (container.IsGeneric){
+ if (Parent.IsGeneric){
Report.Error (-201, Location,
"Entry point can not be defined in a generic class");
}
@@ -2771,8 +3875,15 @@ namespace Mono.CSharp {
DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
DuplicateEntryPoint (MethodBuilder, Location);
}
- } else
- Report28(MethodBuilder);
+ } else {
+ if (RootContext.WarningLevel >= 4)
+ Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder) );
+ }
+ }
+
+ if (MemberType.IsAbstract && MemberType.IsSealed) {
+ Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
+ return false;
}
return true;
@@ -2781,22 +3892,150 @@ namespace Mono.CSharp {
//
// Emits the code
//
- public void Emit (TypeContainer container)
+ public override void Emit ()
{
- MethodData.Emit (container, Block, this);
+ MethodData.Emit (Parent, this);
+ base.Emit ();
Block = null;
MethodData = null;
}
+ protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+ {
+ MethodInfo mi = (MethodInfo) container.ParentContainer.MemberCache.FindMemberToOverride (
+ container.TypeBuilder, Name, ParameterTypes, false);
+
+ if (mi == null)
+ return null;
+
+ parent_ret_type = mi.ReturnType;
+ return mi;
+ }
+
+ protected override bool VerifyClsCompliance(DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ if (parameter_types.Length > 0) {
+ ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
+ if (al.Count > 1)
+ ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
+ }
+
+ return true;
+ }
+
+
void IIteratorContainer.SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;
}
+
+ #region IMethodData Members
+
+ public CallingConventions CallingConventions {
+ get {
+ CallingConventions cc = Parameters.GetCallingConvention ();
+ if (Parameters.HasArglist)
+ block.HasVarargs = true;
+
+ if (!IsInterface)
+ if ((ModFlags & Modifiers.STATIC) == 0)
+ cc |= CallingConventions.HasThis;
+
+ // FIXME: How is `ExplicitThis' used in C#?
+
+ return cc;
+ }
+ }
+
+ public Type ReturnType {
+ get {
+ return MemberType;
+ }
+ }
+
+ public MemberName MethodName {
+ get {
+ return MemberName;
+ }
+ }
+
+ public new Location Location {
+ get {
+ return base.Location;
+ }
+ }
+
+ public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+ {
+ return new EmitContext (
+ tc, ds, Location, ig, ReturnType, ModFlags, false);
+ }
+
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return GetObsoleteAttribute (ds);
+ }
+
+ ///
+ /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
+ ///
+ public bool IsExcluded (EmitContext ec)
+ {
+ if ((caching_flags & Flags.Excluded_Undetected) == 0)
+ return (caching_flags & Flags.Excluded) != 0;
+
+ caching_flags &= ~Flags.Excluded_Undetected;
+
+ if (parent_method == null) {
+ if (OptAttributes == null)
+ return false;
+
+ Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
+
+ if (attrs == null)
+ return false;
+
+ foreach (Attribute a in attrs) {
+ string condition = a.GetConditionalAttributeValue (ds);
+ if (RootContext.AllDefines.Contains (condition))
+ return false;
+ }
+
+ caching_flags |= Flags.Excluded;
+ return true;
+ }
+
+ IMethodData md = TypeManager.GetMethod (parent_method);
+ if (md == null) {
+ if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
+ caching_flags |= Flags.Excluded;
+ return true;
+ }
+ return false;
+ }
+
+ if (md.IsExcluded (ec)) {
+ caching_flags |= Flags.Excluded;
+ return true;
+ }
+ return false;
+ }
+
+ GenericMethod IMethodData.GenericMethod {
+ get {
+ return GenericMethod;
+ }
+ }
+
+ #endregion
}
public abstract class ConstructorInitializer {
ArrayList argument_list;
- ConstructorInfo parent_constructor;
+ protected ConstructorInfo parent_constructor;
Parameters parameters;
Location loc;
@@ -2814,7 +4053,7 @@ namespace Mono.CSharp {
}
}
- public bool Resolve (EmitContext ec)
+ public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
{
Expression parent_constructor_group;
Type t;
@@ -2843,19 +4082,30 @@ namespace Mono.CSharp {
t = ec.ContainerType;
parent_constructor_group = Expression.MemberLookup (
- ec, t, null, t, ".ctor", 0,
- MemberTypes.Constructor,
+ ec, t, ".ctor", MemberTypes.Constructor,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
loc);
if (parent_constructor_group == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
+ parent_constructor_group = Expression.MemberLookup (
+ ec, t, ".ctor", MemberTypes.Constructor,
+ BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ loc);
+
+ if (parent_constructor_group != null)
+ Report.Error (
+ 112, loc, "`{0}.{1}' is inaccessible due to " +
+ "its protection level", t.FullName, t.Name);
+ else
+ Report.Error (
+ 1501, loc, "Can not find a constructor for " +
+ "this argument list");
return false;
}
- parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
- (MethodGroupExpr) parent_constructor_group, argument_list, loc);
+ parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
+ ec, (MethodGroupExpr) parent_constructor_group, argument_list,
+ false, loc);
if (parent_constructor == null){
Report.Error (1501, loc,
@@ -2863,6 +4113,11 @@ namespace Mono.CSharp {
return false;
}
+ if (parent_constructor == caller_builder){
+ Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
+ return false;
+ }
+
return true;
}
@@ -2876,6 +4131,66 @@ namespace Mono.CSharp {
Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
}
}
+
+ ///
+ /// Method search for base ctor. (We do not cache it).
+ ///
+ Constructor GetOverloadedConstructor (TypeContainer tc)
+ {
+ if (tc.InstanceConstructors == null)
+ return null;
+
+ foreach (Constructor c in tc.InstanceConstructors) {
+ if (Arguments == null) {
+ if (c.ParameterTypes.Length == 0)
+ return c;
+
+ continue;
+ }
+
+ bool ok = true;
+
+ int count = c.ParameterInfo.Count;
+ if ((count > 0) &&
+ c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
+ for (int i = 0; i < count-1; i++)
+ if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
+ ok = false;
+ break;
+ }
+ } else {
+ if (c.ParameterTypes.Length != Arguments.Count)
+ continue;
+
+ for (int i = 0; i < Arguments.Count; ++i)
+ if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
+ ok = false;
+ break;
+ }
+ }
+
+ if (!ok)
+ continue;
+
+ return c;
+ }
+
+ return null;
+ }
+
+ //TODO: implement caching when it will be necessary
+ public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
+ {
+ Constructor ctor = GetOverloadedConstructor (tc);
+ if (ctor == null)
+ return;
+
+ ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
+ if (oa == null)
+ return;
+
+ AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
+ }
}
public class ConstructorBaseInitializer : ConstructorInitializer {
@@ -2883,6 +4198,24 @@ namespace Mono.CSharp {
base (argument_list, pars, l)
{
}
+
+ public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
+ if (parent_constructor == null)
+ return;
+
+ TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType);
+ if (type_ds == null) {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
+
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
+
+ return;
+ }
+
+ base.CheckObsoleteAttribute (type_ds, loc);
+ }
+
}
public class ConstructorThisInitializer : ConstructorInitializer {
@@ -2892,7 +4225,7 @@ namespace Mono.CSharp {
}
}
- public class Constructor : MethodCore {
+ public class Constructor : MethodCore, IMethodData {
public ConstructorBuilder ConstructorBuilder;
public ConstructorInitializer Initializer;
@@ -2908,17 +4241,40 @@ namespace Mono.CSharp {
Modifiers.EXTERN |
Modifiers.PRIVATE;
+ bool has_compliant_args = false;
//
// The spec claims that static is not permitted, but
// my very own code has static constructors.
//
- public Constructor (DeclSpace ds, string name, int mod, Parameters args,
+ public Constructor (TypeContainer ds, string name, int mod, Parameters args,
ConstructorInitializer init, Location l)
- : base (ds, null, mod, AllowedModifiers, name, null, args, l)
+ : base (ds, null, null, mod, AllowedModifiers, false,
+ new MemberName (name), null, args, l)
{
Initializer = init;
}
+ public override string GetSignatureForError()
+ {
+ if (ConstructorBuilder == null)
+ return GetSignatureForError (Parent);
+
+ return TypeManager.CSharpSignature (ConstructorBuilder);
+ }
+
+ public bool HasCompliantArgs {
+ get {
+ return has_compliant_args;
+ }
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Constructor;
+ }
+ }
+
+
//
// Returns true if this is a default constructor
//
@@ -2935,28 +4291,71 @@ namespace Mono.CSharp {
(Initializer.Arguments == null);
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ ConstructorBuilder.SetCustomAttribute (cb);
+ }
+
+ protected override bool CheckForDuplications ()
+ {
+ ArrayList ar = Parent.InstanceConstructors;
+ if (ar != null) {
+ int arLen = ar.Count;
+
+ for (int i = 0; i < arLen; i++) {
+ Constructor m = (Constructor) ar [i];
+ if (IsDuplicateImplementation (m))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected override bool CheckBase ()
+ {
+ // Check whether arguments were correct.
+ if (!DoDefineParameters ())
+ return false;
+
+ // TODO: skip the rest for generated ctor
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ return true;
+
+ if (!CheckForDuplications ())
+ return false;
+
+ if (Parent.Kind == Kind.Struct) {
+ if (ParameterTypes.Length == 0) {
+ Report.Error (568, Location,
+ "Structs can not contain explicit parameterless " +
+ "constructors");
+ return false;
+ }
+
+ if ((ModFlags & Modifiers.PROTECTED) != 0) {
+ Report.Error (666, Location, "Protected member in struct declaration");
+ return false;
+ }
+ }
+
+ if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
+ Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
+ }
+
+ return true;
+ }
+
//
// Creates the ConstructorBuilder
//
- public override bool Define (TypeContainer container)
+ public override bool Define ()
{
MethodAttributes ca = (MethodAttributes.RTSpecialName |
MethodAttributes.SpecialName);
- // Check if arguments were correct.
- if (!DoDefineParameters ())
- return false;
-
if ((ModFlags & Modifiers.STATIC) != 0){
ca |= MethodAttributes.Static | MethodAttributes.Private;
} else {
- if (container is Struct && ParameterTypes.Length == 0){
- Report.Error (
- 568, Location,
- "Structs can not contain explicit parameterless " +
- "constructors");
- return false;
- }
ca |= MethodAttributes.HideBySig;
if ((ModFlags & Modifiers.PUBLIC) != 0)
@@ -2974,23 +4373,23 @@ namespace Mono.CSharp {
ca |= MethodAttributes.Private;
}
- ConstructorBuilder = container.TypeBuilder.DefineConstructor (
- ca, GetCallingConvention (container is Class), ParameterTypes);
+ // Check if arguments were correct.
+ if (!CheckBase ())
+ return false;
+
+ ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
+ ca, CallingConventions,
+ ParameterTypes);
if ((ModFlags & Modifiers.UNSAFE) != 0)
ConstructorBuilder.InitLocals = false;
+ TypeManager.AddMethod (ConstructorBuilder, this);
+
//
// HACK because System.Reflection.Emit is lame
//
- if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
- Report.Error (
- 111, Location,
- "Class `" +container.Name+ "' already contains a definition with the " +
- "same return value and parameter types for constructor `" + Name
- + "'");
- return false;
- }
+ TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
return true;
}
@@ -2998,10 +4397,9 @@ namespace Mono.CSharp {
//
// Emits the code
//
- public void Emit (TypeContainer container)
+ public override void Emit ()
{
- ILGenerator ig = ConstructorBuilder.GetILGenerator ();
- EmitContext ec = new EmitContext (container, Location, ig, null, ModFlags, true);
+ EmitContext ec = CreateEmitContext (null, null);
//
// extern methods have no bodies
@@ -3023,7 +4421,7 @@ namespace Mono.CSharp {
}
if ((ModFlags & Modifiers.STATIC) == 0){
- if (container is Class && Initializer == null)
+ if (Parent.Kind == Kind.Class && Initializer == null)
Initializer = new ConstructorBaseInitializer (
null, Parameters.EmptyReadOnlyParameters, Location);
@@ -3033,30 +4431,20 @@ namespace Mono.CSharp {
// `this' access
//
ec.IsStatic = true;
- if (Initializer != null && !Initializer.Resolve (ec))
+ if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
return;
ec.IsStatic = false;
}
- MethodCore.LabelParameters (ec, ConstructorBuilder,
- Parameters, OptAttributes, Location);
+ Parameters.LabelParameters (ec, ConstructorBuilder, Location);
- SymbolWriter sw = CodeGen.SymbolWriter;
- bool generate_debugging = false;
-
- if ((sw != null) && (block != null) &&
- !Location.IsNull (Location) &&
- !Location.IsNull (block.EndLocation)) {
-
- sw.OpenMethod (container, ConstructorBuilder, Location, block.EndLocation);
-
- generate_debugging = true;
- }
+ SourceMethod source = SourceMethod.Create (
+ Parent, ConstructorBuilder, block);
//
// Classes can have base initializers and instance field initializers.
//
- if (container is Class){
+ if (Parent.Kind == Kind.Class){
if ((ModFlags & Modifiers.STATIC) == 0){
//
@@ -3064,45 +4452,158 @@ namespace Mono.CSharp {
// do not emit field initializers, they are initialized in the other constructor
//
if (!(Initializer != null && Initializer is ConstructorThisInitializer))
- container.EmitFieldInitializers (ec);
+ Parent.EmitFieldInitializers (ec);
}
}
- if (Initializer != null)
+ if (Initializer != null) {
+ Initializer.CheckObsoleteAttribute (Parent, Location);
Initializer.Emit (ec);
+ }
if ((ModFlags & Modifiers.STATIC) != 0)
- container.EmitFieldInitializers (ec);
+ Parent.EmitFieldInitializers (ec);
- Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes);
+ if (OptAttributes != null)
+ OptAttributes.Emit (ec, this);
// If this is a non-static `struct' constructor and doesn't have any
// initializer, it must initialize all of the struct's fields.
- if ((container is Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
- Block.AddThisVariable (container, Location);
+ if ((Parent.Kind == Kind.Struct) &&
+ ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
+ Block.AddThisVariable (Parent, Location);
ec.EmitTopBlock (block, ParameterInfo, Location);
- if (generate_debugging)
- sw.CloseMethod ();
+ if (source != null)
+ source.CloseMethod ();
+
+ base.Emit ();
block = null;
}
+
+ // Is never override
+ protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+ {
+ return null;
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
+ return false;
+ }
+
+ if (parameter_types.Length > 0) {
+ ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
+ if (al.Count > 3)
+ ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
+
+ if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
+ foreach (Type param in parameter_types) {
+ if (param.IsArray) {
+ return true;
+ }
+ }
+ }
+ }
+ has_compliant_args = true;
+ return true;
+ }
+
+ #region IMethodData Members
+
+ public System.Reflection.CallingConventions CallingConventions {
+ get {
+ CallingConventions cc = Parameters.GetCallingConvention ();
+
+ if (Parent.Kind == Kind.Class)
+ if ((ModFlags & Modifiers.STATIC) == 0)
+ cc |= CallingConventions.HasThis;
+
+ // FIXME: How is `ExplicitThis' used in C#?
+
+ return cc;
+ }
+ }
+
+ public new Location Location {
+ get {
+ return base.Location;
+ }
+ }
+
+ public MemberName MethodName {
+ get {
+ return MemberName;
+ }
+ }
+
+ public Type ReturnType {
+ get {
+ return MemberType;
+ }
+ }
+
+ public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+ {
+ ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
+ return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
+ }
+
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return null;
+ }
+
+ public bool IsExcluded(EmitContext ec)
+ {
+ return false;
+ }
+
+ GenericMethod IMethodData.GenericMethod {
+ get {
+ return null;
+ }
+ }
+
+ #endregion
+ }
+
+ ///
+ /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
+ ///
+ public interface IMethodData
+ {
+ CallingConventions CallingConventions { get; }
+ Location Location { get; }
+ MemberName MethodName { get; }
+ Type[] ParameterTypes { get; }
+ Type ReturnType { get; }
+ GenericMethod GenericMethod { get; }
+
+ Attributes OptAttributes { get; }
+ Block Block { get; }
+
+ EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
+ ObsoleteAttribute GetObsoleteAttribute ();
+ string GetSignatureForError (TypeContainer tc);
+ bool IsExcluded (EmitContext ec);
+ bool IsClsCompliaceRequired (DeclSpace ds);
}
//
// Encapsulates most of the Method's state
//
public class MethodData {
+
+ readonly IMethodData method;
+
//
// The return type of this method
//
- public readonly Type ReturnType;
- public readonly Type[] ParameterTypes;
public readonly GenericMethod GenericMethod;
public readonly InternalParameters ParameterInfo;
- public readonly CallingConventions CallingConventions;
- public readonly Attributes OptAttributes;
- public readonly Location Location;
//
// Are we implementing an interface ?
@@ -3112,16 +4613,11 @@ namespace Mono.CSharp {
//
// Protected data.
//
- protected DeclSpace ds;
protected MemberBase member;
protected int modifiers;
protected MethodAttributes flags;
- protected bool is_method;
- protected string accessor_name;
+ protected Type declaring_type;
- //
- // It can either hold a string with the condition, or an arraylist of conditions.
- object conditionals;
EmitContext ec;
MethodBuilder builder = null;
@@ -3131,252 +4627,81 @@ namespace Mono.CSharp {
}
}
- public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
- Type [] parameter_types, InternalParameters parameters,
- CallingConventions cc, Attributes opt_attrs,
- int modifiers, MethodAttributes flags, bool is_method)
+ public Type DeclaringType {
+ get {
+ return declaring_type;
+ }
+ }
+
+ public MethodData (MemberBase member, InternalParameters parameters,
+ int modifiers, MethodAttributes flags, IMethodData method)
{
- this.ds = ds;
this.member = member;
- this.accessor_name = name;
- this.ReturnType = return_type;
- this.ParameterTypes = parameter_types;
this.ParameterInfo = parameters;
- this.CallingConventions = cc;
- this.OptAttributes = opt_attrs;
this.modifiers = modifiers;
this.flags = flags;
- this.is_method = is_method;
- this.Location = member.Location;
- this.conditionals = null;
- }
-
- public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
- Type [] parameter_types, InternalParameters parameters,
- CallingConventions cc, Attributes opt_attrs,
- int modifiers, MethodAttributes flags, bool is_method,
- MethodBuilder builder, GenericMethod generic)
- : this (ds, member, name, return_type, parameter_types, parameters,
- cc, opt_attrs, modifiers, flags, is_method)
- {
- this.builder = builder;
- this.GenericMethod = generic;
- }
-
- //
- // Attributes.
- //
- Attribute dllimport_attribute = null;
- string obsolete = null;
- bool obsolete_error = false;
-
- public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
- {
- if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
- return true;
-
- foreach (AttributeSection asec in opt_attrs.AttributeSections) {
- if (asec.Attributes == null)
- continue;
-
- foreach (Attribute a in asec.Attributes) {
- if (a.Name == "Conditional") {
- if (!ApplyConditionalAttribute (a))
- return false;
- } else if (a.Name == "Obsolete") {
- if (!ApplyObsoleteAttribute (a))
- return false;
- } else if (a.Name.IndexOf ("DllImport") != -1) {
- if (!is_method) {
- a.Type = TypeManager.dllimport_type;
- Attribute.Error_AttributeNotValidForElement (a, Location);
- return false;
- }
- if (!ApplyDllImportAttribute (a))
- return false;
- }
- }
- }
-
- return true;
- }
-
- //
- // Applies the `DllImport' attribute to the method.
- //
- protected virtual bool ApplyDllImportAttribute (Attribute a)
- {
- const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
- if ((modifiers & extern_static) != extern_static) {
- Report.Error (601, Location,
- "The DllImport attribute must be specified on a method " +
- "marked `static' and `extern'.");
- return false;
- }
-
- flags |= MethodAttributes.PinvokeImpl;
- dllimport_attribute = a;
- return true;
- }
-
- //
- // Applies the `Obsolete' attribute to the method.
- //
- protected virtual bool ApplyObsoleteAttribute (Attribute a)
- {
- if (obsolete != null) {
- Report.Error (579, Location, "Duplicate `Obsolete' attribute");
- return false;
- }
-
- obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
- return obsolete != null;
- }
-
- //
- // Applies the `Conditional' attribute to the method.
- //
- protected virtual bool ApplyConditionalAttribute (Attribute a)
- {
- // The Conditional attribute is only valid on methods.
- if (!is_method) {
- Attribute.Error_AttributeNotValidForElement (a, Location);
- return false;
- }
-
- string condition = a.Conditional_GetConditionName ();
-
- if (condition == null)
- return false;
-
- if (ReturnType != TypeManager.void_type) {
- Report.Error (578, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because its return type is not void");
- return false;
- }
-
- if ((modifiers & Modifiers.OVERRIDE) != 0) {
- Report.Error (243, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an override method");
- return false;
- }
-
- if (member.IsExplicitImpl) {
- Report.Error (577, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an explicit interface implementation");
- return false;
- }
-
- if (IsImplementing) {
- Report.Error (623, Location,
- "Conditional not valid on `" + member.Name + "' " +
- "because it is an interface method");
- return false;
- }
- //
- // The likelyhood that the conditional will be more than 1 is very slim
- //
- if (conditionals == null)
- conditionals = condition;
- else if (conditionals is string){
- string s = (string) conditionals;
- conditionals = new ArrayList ();
- ((ArrayList)conditionals).Add (s);
- } else
- ((ArrayList)conditionals).Add (condition);
-
- return true;
+ this.method = method;
}
- //
- // Checks whether this method should be ignored due to its Conditional attributes.
- //
- bool ShouldIgnore (Location loc)
- {
- // When we're overriding a virtual method, we implicitly inherit the
- // Conditional attributes from our parent.
- if (member.ParentMethod != null) {
- TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
- member.ParentMethod, loc);
-
- if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
- return true;
- }
-
- if (conditionals != null){
- if (conditionals is string){
- if (RootContext.AllDefines [conditionals] == null)
- return true;
- } else {
- foreach (string condition in (ArrayList) conditionals)
- if (RootContext.AllDefines [condition] == null)
- return true;
- }
- }
- return false;
+ public MethodData (MemberBase member, InternalParameters parameters,
+ int modifiers, MethodAttributes flags,
+ IMethodData method, MethodBuilder builder,
+ GenericMethod generic)
+ : this (member, parameters, modifiers, flags, method)
+ {
+ this.builder = builder;
+ this.GenericMethod = generic;
}
- //
- // Returns the TypeManager.MethodFlags for this method.
- // This emits an error 619 / warning 618 if the method is obsolete.
- // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
- //
- public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
+ static string RemoveArity (string name)
{
- TypeManager.MethodFlags flags = 0;
+ int start = 0;
+ StringBuilder sb = new StringBuilder ();
+ while (start < name.Length) {
+ int pos = name.IndexOf ('`', start);
+ if (pos < 0) {
+ sb.Append (name.Substring (start));
+ break;
+ }
- if (obsolete != null) {
- if (obsolete_error) {
- Report.Error (619, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
- return TypeManager.MethodFlags.IsObsoleteError;
- } else
- Report.Warning (618, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
+ sb.Append (name.Substring (start, pos-start));
- flags |= TypeManager.MethodFlags.IsObsolete;
- }
+ pos++;
+ while ((pos < name.Length) && Char.IsNumber (name [pos]))
+ pos++;
- if (ShouldIgnore (loc))
- flags |= TypeManager.MethodFlags.ShouldIgnore;
+ start = pos;
+ }
- return flags;
+ return sb.ToString ();
}
- public virtual bool Define (TypeContainer container)
+ public bool Define (TypeContainer container)
{
MethodInfo implementing = null;
- string method_name, name, prefix;
-
- if (OptAttributes != null)
- if (!ApplyAttributes (OptAttributes, is_method))
- return false;
+ string prefix;
if (member.IsExplicitImpl)
- prefix = member.InterfaceType.FullName + ".";
+ prefix = RemoveArity (member.InterfaceType.FullName) + ".";
else
prefix = "";
- if (accessor_name != null)
- name = accessor_name + "_" + member.ShortName;
- else
- name = member.ShortName;
- method_name = prefix + name;
+ string name = method.MethodName.Name;
+ string method_name = prefix + name;
+
+ Type[] ParameterTypes = method.ParameterTypes;
if (container.Pending != null){
if (member is Indexer)
implementing = container.Pending.IsInterfaceIndexer (
- member.InterfaceType, ReturnType, ParameterTypes);
+ member.InterfaceType, method.ReturnType, ParameterTypes);
else
implementing = container.Pending.IsInterfaceMethod (
- member.InterfaceType, name, ReturnType, ParameterTypes);
+ member.InterfaceType, name, method.ReturnType, ParameterTypes);
if (member.InterfaceType != null && implementing == null){
- Report.Error (539, Location, "'{0}' in explicit interface declaration is not an interface", method_name);
+ Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
return false;
}
}
@@ -3395,7 +4720,7 @@ namespace Mono.CSharp {
//
if (member.IsExplicitImpl){
if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
- Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
+ Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
implementing = null;
}
} else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
@@ -3421,7 +4746,7 @@ namespace Mono.CSharp {
//
if ((modifiers & Modifiers.STATIC) != 0){
implementing = null;
- Modifiers.Error_InvalidModifier (Location, "static");
+ Modifiers.Error_InvalidModifier (method.Location, "static");
}
}
@@ -3445,47 +4770,20 @@ namespace Mono.CSharp {
if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
flags |= MethodAttributes.Final;
- // Get the method name from the explicit interface.
- if (member.InterfaceType != null) {
- name = implementing.Name;
- method_name = prefix + name;
- }
-
IsImplementing = true;
}
- ec = new EmitContext (
- container, ds, Location, null, ReturnType, modifiers, false);
+ EmitContext ec = method.CreateEmitContext (container, null);
- //
- // Create the MethodBuilder for the method
- //
- if ((flags & MethodAttributes.PinvokeImpl) != 0) {
- if ((modifiers & Modifiers.STATIC) == 0) {
- Report.Error (601, Location,
- "The DllImport attribute must be specified on " +
- "a method marked 'static' and 'extern'.");
- return false;
- }
- builder = dllimport_attribute.DefinePInvokeMethod (
- ec, container.TypeBuilder, method_name, flags,
- ReturnType, ParameterTypes);
- } else if (builder == null)
- builder = container.TypeBuilder.DefineMethod (
- method_name, flags, CallingConventions,
- ReturnType, ParameterTypes);
- else
- builder.SetGenericMethodSignature (
- flags, CallingConventions,
- ReturnType, ParameterTypes);
+ DefineMethodBuilder (ec, container, method_name, ParameterTypes);
if (builder == null)
return false;
- if (GenericMethod != null) {
- if (!GenericMethod.DefineType (ec, builder))
- return false;
- }
+ if (container.CurrentType != null)
+ declaring_type = container.CurrentType.ResolveType (ec);
+ else
+ declaring_type = container.TypeBuilder;
if ((modifiers & Modifiers.UNSAFE) != 0)
builder.InitLocals = false;
@@ -3496,11 +4794,11 @@ namespace Mono.CSharp {
//
if (member is Indexer) {
container.Pending.ImplementIndexer (
- member.InterfaceType, builder, ReturnType,
- ParameterTypes, true);
+ member.InterfaceType, builder, method.ReturnType,
+ ParameterTypes, member.IsExplicitImpl);
} else
container.Pending.ImplementMethod (
- member.InterfaceType, name, ReturnType,
+ member.InterfaceType, name, method.ReturnType,
ParameterTypes, member.IsExplicitImpl);
if (member.IsExplicitImpl)
@@ -3509,71 +4807,104 @@ namespace Mono.CSharp {
}
- if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
- Report.Error (111, Location,
- "Class `" + container.Name +
- "' already contains a definition with the " +
- "same return value and parameter types as the " +
- "'get' method of property `" + member.Name + "'");
- return false;
- }
+ TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
+ TypeManager.AddMethod (builder, method);
+
+ if (GenericMethod != null) {
+ bool is_override = member.IsExplicitImpl |
+ ((modifiers & Modifiers.OVERRIDE) != 0);
- TypeManager.AddMethod (builder, this);
+ is_override &= IsImplementing;
+
+ if (!GenericMethod.DefineType (
+ ec, builder, implementing, is_override))
+ return false;
+ }
return true;
}
+ ///
+ /// Create the MethodBuilder for the method
+ ///
+ void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
+ {
+ const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
+
+ if ((modifiers & extern_static) == extern_static) {
+
+ if (method.OptAttributes != null) {
+ Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
+ if (dllimport_attribute != null) {
+ flags |= MethodAttributes.PinvokeImpl;
+ builder = dllimport_attribute.DefinePInvokeMethod (
+ ec, container.TypeBuilder, method_name, flags,
+ method.ReturnType, ParameterTypes);
+
+ return;
+ }
+ }
+
+ // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
+ // We are more strict than Microsoft and report CS0626 like error
+ if (method.OptAttributes == null ||
+ !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
+ Report.Error (626, method.Location, "Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation", method.GetSignatureForError (container));
+ return;
+ }
+ }
+
+ if (builder == null)
+ builder = container.TypeBuilder.DefineMethod (
+ method_name, flags, method.CallingConventions,
+ method.ReturnType, ParameterTypes);
+ else
+ builder.SetGenericMethodSignature (
+ flags, method.CallingConventions,
+ method.ReturnType, ParameterTypes);
+ }
+
//
// Emits the code
//
- public virtual void Emit (TypeContainer container, Block block, object kind)
+ public void Emit (TypeContainer container, Attributable kind)
{
- ILGenerator ig;
EmitContext ec;
-
if ((flags & MethodAttributes.PinvokeImpl) == 0)
- ig = builder.GetILGenerator ();
+ ec = method.CreateEmitContext (container, builder.GetILGenerator ());
else
- ig = null;
+ ec = method.CreateEmitContext (container, null);
- ec = new EmitContext (container, ds, Location, ig, ReturnType, modifiers, false);
+ Location loc = method.Location;
+ Attributes OptAttributes = method.OptAttributes;
if (OptAttributes != null)
- Attribute.ApplyAttributes (ec, builder, kind, OptAttributes);
+ OptAttributes.Emit (ec, kind);
if (member is MethodCore)
- MethodCore.LabelParameters (ec, MethodBuilder,
- ((MethodCore) member).Parameters,
- OptAttributes,
- Location);
+ ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
+ Block block = method.Block;
+
//
// abstract or extern methods have no bodies
//
if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
- if (block == null) {
- SymbolWriter sw = CodeGen.SymbolWriter;
-
- if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0)) {
- sw.OpenMethod (container, MethodBuilder, Location, Location);
- sw.CloseMethod ();
- }
-
+ if (block == null)
return;
- }
//
// abstract or extern methods have no bodies.
//
if ((modifiers & Modifiers.ABSTRACT) != 0)
Report.Error (
- 500, Location, "Abstract method `" +
+ 500, method.Location, "Abstract method `" +
TypeManager.CSharpSignature (builder) +
"' can not have a body");
if ((modifiers & Modifiers.EXTERN) != 0)
Report.Error (
- 179, Location, "External method `" +
+ 179, method.Location, "External method `" +
TypeManager.CSharpSignature (builder) +
"' can not have a body");
@@ -3585,13 +4916,16 @@ namespace Mono.CSharp {
//
if (block == null) {
Report.Error (
- 501, Location, "Method `" +
+ 501, method.Location, "Method `" +
TypeManager.CSharpSignature (builder) +
"' must declare a body since it is not marked " +
"abstract or extern");
return;
}
+ SourceMethod source = SourceMethod.Create (
+ container, MethodBuilder, method.Block);
+
//
// Handle destructors specially
//
@@ -3599,19 +4933,11 @@ namespace Mono.CSharp {
//
if (member is Destructor)
EmitDestructor (ec, block);
- else {
- SymbolWriter sw = CodeGen.SymbolWriter;
-
- if ((sw != null) && !Location.IsNull (Location) &&
- !Location.IsNull (block.EndLocation)) {
- sw.OpenMethod (container, MethodBuilder, Location, block.EndLocation);
-
- ec.EmitTopBlock (block, ParameterInfo, Location);
+ else
+ ec.EmitTopBlock (block, ParameterInfo, loc);
- sw.CloseMethod ();
- } else
- ec.EmitTopBlock (block, ParameterInfo, Location);
- }
+ if (source != null)
+ source.CloseMethod ();
}
void EmitDestructor (EmitContext ec, Block block)
@@ -3625,7 +4951,7 @@ namespace Mono.CSharp {
ig.BeginExceptionBlock ();
ec.ReturnLabel = finish;
ec.HasReturnLabel = true;
- ec.EmitTopBlock (block, null, Location);
+ ec.EmitTopBlock (block, null, method.Location);
// ig.MarkLabel (finish);
ig.BeginFinallyBlock ();
@@ -3633,7 +4959,7 @@ namespace Mono.CSharp {
if (ec.ContainerType.BaseType != null) {
Expression member_lookup = Expression.MemberLookup (
ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
- "Finalize", 0, MemberTypes.Method, Expression.AllBindingFlags, Location);
+ "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
if (member_lookup != null){
MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
@@ -3651,17 +4977,27 @@ namespace Mono.CSharp {
public class Destructor : Method {
- public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
+ public Destructor (TypeContainer ds, Expression return_type, int mod, string name,
Parameters parameters, Attributes attrs, Location l)
- : base (ds, return_type, mod, name, parameters, attrs, l)
+ : base (ds, null, return_type, mod, false, new MemberName (name),
+ parameters, attrs, l)
{ }
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.conditional_attribute_type) {
+ Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
}
abstract public class MemberBase : MemberCore {
public Expression Type;
- protected MethodAttributes flags;
+ public MethodAttributes flags;
protected readonly int explicit_mod_flags;
@@ -3684,201 +5020,70 @@ namespace Mono.CSharp {
//
// The name of the interface we are explicitly implementing
//
- public string ExplicitInterfaceName = null;
+ public MemberName ExplicitInterfaceName = null;
//
- // If true, the interface type we are explicitly implementing
+ // Whether this is an interface member.
//
- public Type InterfaceType = null;
+ public bool IsInterface;
//
- // The method we're overriding if this is an override method.
+ // If true, the interface type we are explicitly implementing
//
- protected MethodInfo parent_method = null;
- public MethodInfo ParentMethod {
- get {
- return parent_method;
- }
- }
+ public Type InterfaceType = null;
//
// The constructor is only exposed to our children
//
- protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
+ protected MemberBase (TypeContainer parent, Expression type, int mod,
+ int allowed_mod, int def_mod, MemberName name,
Attributes attrs, Location loc)
- : base (name, attrs, loc)
+ : base (parent, name, attrs, loc)
{
explicit_mod_flags = mod;
Type = type;
ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
- }
-
- protected virtual bool CheckBase (TypeContainer container)
- {
- if ((container is Struct) || (RootContext.WarningLevel > 3)){
- if ((ModFlags & Modifiers.PROTECTED) != 0 && (container.ModFlags & Modifiers.SEALED) != 0){
- if (container is Struct){
- Report.Error (666, Location, "Protected member in struct declaration");
- return false;
- } else
- Report.Warning (628, Location, "Member " + container.MakeName (Name) + " protected in sealed class");
- }
- }
- return true;
- }
- protected void WarningNotHiding (TypeContainer parent)
- {
- Report.Warning (
- 109, Location,
- "The member " + parent.MakeName (Name) + " does not hide an " +
- "inherited member. The keyword new is not required");
-
+ // Check for explicit interface implementation
+ if (MemberName.Left != null) {
+ ExplicitInterfaceName = MemberName.Left;
+ ShortName = MemberName.Name;
+ IsExplicitImpl = true;
+ } else
+ ShortName = Name;
}
- void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
- string name)
+ protected virtual bool CheckBase ()
{
- //
- // FIXME: report the old/new permissions?
- //
- Report.Error (
- 507, Location, parent.MakeName (Name) +
- ": can't change the access modifiers when overriding inherited " +
- "member `" + name + "'");
- }
-
- //
- // Performs various checks on the MethodInfo `mb' regarding the modifier flags
- // that have been defined.
- //
- // `name' is the user visible name for reporting errors (this is used to
- // provide the right name regarding method names and properties)
- //
- protected bool CheckMethodAgainstBase (TypeContainer parent, MethodAttributes my_attrs,
- MethodInfo mb, string name)
- {
- bool ok = true;
-
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- if (!(mb.IsAbstract || mb.IsVirtual)){
- Report.Error (
- 506, Location, parent.MakeName (Name) +
- ": cannot override inherited member `" +
- name + "' because it is not " +
- "virtual, abstract or override");
- ok = false;
- }
-
- // Now we check that the overriden method is not final
-
- if (mb.IsFinal) {
- // This happens when implementing interface methods.
- if (mb.IsHideBySig && mb.IsVirtual) {
- Report.Error (
- 506, Location, parent.MakeName (Name) +
- ": cannot override inherited member `" +
- name + "' because it is not " +
- "virtual, abstract or override");
- } else
- Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
- "override inherited member `" + name +
- "' because it is sealed.");
- ok = false;
- }
- //
- // Check that the permissions are not being changed
- //
- MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
- MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
-
- //
- // special case for "protected internal"
- //
-
- if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- //
- // when overriding protected internal, the method can be declared
- // protected internal only within the same assembly
- //
-
- if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly){
- //
- // assemblies differ - report an error
- //
-
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- } else if (thisp != parentp) {
- //
- // same assembly, but other attributes differ - report an error
- //
-
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- };
- } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
- //
- // if it's not "protected internal", it must be "protected"
- //
-
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- } else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly) {
- //
- // protected within the same assembly - an error
- //
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
- (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
- //
- // protected ok, but other attributes differ - report an error
- //
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- }
- } else {
- if (thisp != parentp){
- Error_CannotChangeAccessModifiers (parent, mb, name);
- ok = false;
- }
- }
+ if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
+ Report.Error (666, Location, "Protected member in struct declaration");
+ return false;
}
- if (mb.IsVirtual || mb.IsAbstract){
- if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
- if (Name != "Finalize"){
- Report.Warning (
- 114, 2, Location, parent.MakeName (Name) +
- " hides inherited member `" + name +
- "'. To make the current member override that " +
- "implementation, add the override keyword, " +
- "otherwise use the new keyword");
- ModFlags |= Modifiers.NEW;
- }
- }
- } else {
- if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
- if (Name != "Finalize"){
- Report.Warning (
- 108, 1, Location, "The keyword new is required on " +
- parent.MakeName (Name) + " because it hides " +
- "inherited member `" + name + "'");
- ModFlags |= Modifiers.NEW;
- }
- }
+ if ((RootContext.WarningLevel >= 4) &&
+ ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
+ ((ModFlags & Modifiers.PROTECTED) != 0) &&
+ ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
+ Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
}
- return ok;
+ return true;
}
+ protected abstract bool CheckGenericOverride (MethodInfo method, string name);
+
protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
{
bool error = false;
foreach (Type partype in parameters){
+ if (partype == TypeManager.void_type) {
+ Report.Error (
+ 1547, Location, "Keyword 'void' cannot " +
+ "be used in this context");
+ return false;
+ }
+
if (partype.IsPointer){
if (!UnsafeOK (ds))
error = true;
@@ -3910,22 +5115,39 @@ namespace Mono.CSharp {
return !error;
}
- protected virtual bool DoDefine (DeclSpace decl, TypeContainer container)
+ protected virtual bool DoDefineBase ()
{
if (Name == null)
- Name = "this";
+ throw new InternalErrorException ();
+
+ if (IsInterface) {
+ ModFlags = Modifiers.PUBLIC |
+ Modifiers.ABSTRACT |
+ Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
+
+ flags = MethodAttributes.Public |
+ MethodAttributes.Abstract |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.Virtual;
+ } else {
+ if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
+ return false;
- if (!container.MethodModifiersValid (ModFlags, Name, Location))
- return false;
+ flags = Modifiers.MethodAttr (ModFlags);
+ }
- flags = Modifiers.MethodAttr (ModFlags);
+ return true;
+ }
+ protected virtual bool DoDefine (DeclSpace decl)
+ {
// Lookup Type, verify validity
MemberType = decl.ResolveType (Type, false, Location);
if (MemberType == null)
return false;
- if ((container.ModFlags & Modifiers.SEALED) != 0){
+ if ((Parent.ModFlags & Modifiers.SEALED) != 0){
if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
Report.Error (549, Location, "Virtual method can not be contained in sealed class");
return false;
@@ -3933,7 +5155,7 @@ namespace Mono.CSharp {
}
// verify accessibility
- if (!container.AsAccessible (MemberType, ModFlags)) {
+ if (!Parent.AsAccessible (MemberType, ModFlags)) {
if (this is Property)
Report.Error (53, Location,
"Inconsistent accessibility: property type `" +
@@ -3963,23 +5185,12 @@ namespace Mono.CSharp {
return false;
}
- if (MemberType.IsPointer && !UnsafeOK (container))
+ if (MemberType.IsPointer && !UnsafeOK (Parent))
return false;
-
- //
- // Check for explicit interface implementation
- //
- if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
- int pos = Name.LastIndexOf ('.');
- ExplicitInterfaceName = Name.Substring (0, pos);
- ShortName = Name.Substring (pos + 1);
- } else
- ShortName = Name;
-
- if (ExplicitInterfaceName != null) {
- InterfaceType = RootContext.LookupType (
- container, ExplicitInterfaceName, false, Location);
+ if (IsExplicitImpl) {
+ InterfaceType = Parent.ResolveType (
+ ExplicitInterfaceName.GetTypeExpression (Location), false, Location);
if (InterfaceType == null)
return false;
@@ -3988,20 +5199,44 @@ namespace Mono.CSharp {
return false;
}
- // Compute the full name that we need to export.
- Name = InterfaceType.FullName + "." + ShortName;
-
- if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
+ if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
return false;
Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
-
- IsExplicitImpl = true;
- } else
- IsExplicitImpl = false;
+ }
return true;
}
+
+ ///
+ /// The name of the member can be changed during definition (see IndexerName attribute)
+ ///
+ protected virtual void UpdateMemberName ()
+ {
+ MemberName.Name = ShortName;
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
+ }
+
+ protected override bool VerifyClsCompliance(DeclSpace ds)
+ {
+ if (base.VerifyClsCompliance (ds)) {
+ return true;
+ }
+
+ if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
+ Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
+ }
+ return false;
+ }
+
+ protected override void VerifyObsoleteAttribute()
+ {
+ CheckUsageOfObsoleteAttribute (MemberType);
+ }
}
//
@@ -4015,16 +5250,47 @@ namespace Mono.CSharp {
[Flags]
public enum Status : byte { ASSIGNED = 1, USED = 2 }
+ static string[] attribute_targets = new string [] { "field" };
+
+ ///
+ /// Symbol with same name in parent class/struct
+ ///
+ public MemberInfo conflict_symbol;
+
//
// The constructor is only exposed to our children
//
- protected FieldBase (Expression type, int mod, int allowed_mod, string name,
- object init, Attributes attrs, Location loc)
- : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
+ protected FieldBase (TypeContainer parent, Expression type, int mod,
+ int allowed_mod, MemberName name, object init,
+ Attributes attrs, Location loc)
+ : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
+ name, attrs, loc)
{
this.init = init;
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Field;
+ }
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.marshal_as_attr_type) {
+ UnmanagedMarshal marshal = a.GetMarshal ();
+ if (marshal != null) {
+ FieldBuilder.SetMarshal (marshal);
+ return;
+ }
+ Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
+ return;
+ }
+
+
+ FieldBuilder.SetCustomAttribute (cb);
+ }
+
//
// Whether this field has an initializer.
//
@@ -4039,6 +5305,11 @@ namespace Mono.CSharp {
Expression init_expr;
bool init_expr_initialized = false;
+ protected override bool CheckGenericOverride (MethodInfo method, string name)
+ {
+ return true;
+ }
+
//
// Resolves and returns the field initializer.
//
@@ -4063,6 +5334,80 @@ namespace Mono.CSharp {
return init_expr;
}
+ protected override bool CheckBase ()
+ {
+ if (!base.CheckBase ())
+ return false;
+
+ // TODO: Implement
+ if (IsInterface)
+ return true;
+
+ conflict_symbol = Parent.FindMemberWithSameName (Name, false);
+ if (conflict_symbol == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+ }
+ return true;
+ }
+
+ if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+ }
+
+ return true;
+ }
+
+ protected override bool DoDefine (DeclSpace ds)
+ {
+ if (!base.DoDefine (ds))
+ return false;
+
+ if (MemberType == TypeManager.void_type) {
+ Report.Error (1547, Location,
+ "Keyword 'void' cannot be used in this context");
+ return false;
+ }
+
+ if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
+ Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
+ return false;
+ }
+
+ return true;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ if (FieldBuilder == null) {
+ return base.GetSignatureForError (Parent);
+ }
+ return TypeManager.GetFullNameSignature (FieldBuilder);
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ if (FieldBuilder == null) {
+ return true;
+ }
+
+ if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
+ Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
+ }
+ return true;
+ }
+
+
public void SetAssigned ()
{
status |= Status.ASSIGNED;
@@ -4087,34 +5432,35 @@ namespace Mono.CSharp {
Modifiers.UNSAFE |
Modifiers.READONLY;
- public Field (Expression type, int mod, string name, Object expr_or_array_init,
- Attributes attrs, Location loc)
- : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
+ public Field (TypeContainer parent, Expression type, int mod, string name,
+ Object expr_or_array_init, Attributes attrs, Location loc)
+ : base (parent, type, mod, AllowedModifiers, new MemberName (name),
+ expr_or_array_init, attrs, loc)
{
}
- public override bool Define (TypeContainer container)
+ public override bool Define ()
{
- Type t = container.ResolveType (Type, false, Location);
-
- if (t == null)
+ MemberType = Parent.ResolveType (Type, false, Location);
+
+ if (MemberType == null)
return false;
- CheckBase (container);
+ CheckBase ();
- if (!container.AsAccessible (t, ModFlags)) {
+ if (!Parent.AsAccessible (MemberType, ModFlags)) {
Report.Error (52, Location,
"Inconsistent accessibility: field type `" +
- TypeManager.CSharpName (t) + "' is less " +
+ TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than field `" + Name + "'");
return false;
}
- if (t.IsPointer && !UnsafeOK (container))
+ if (MemberType.IsPointer && !UnsafeOK (Parent))
return false;
if (RootContext.WarningLevel > 1){
- Type ptype = container.TypeBuilder.BaseType;
+ Type ptype = Parent.TypeBuilder.BaseType;
// ptype is only null for System.Object while compiling corlib.
if (ptype != null){
@@ -4127,23 +5473,24 @@ namespace Mono.CSharp {
}
if ((ModFlags & Modifiers.VOLATILE) != 0){
- if (!t.IsClass){
- Type vt = t;
+ if (!MemberType.IsClass){
+ Type vt = MemberType;
if (TypeManager.IsEnumType (vt))
- vt = TypeManager.EnumToUnderlying (t);
+ vt = TypeManager.EnumToUnderlying (MemberType);
if (!((vt == TypeManager.bool_type) ||
(vt == TypeManager.sbyte_type) ||
(vt == TypeManager.byte_type) ||
- (vt == TypeManager.short_type) ||
+ (vt == TypeManager.short_type) ||
(vt == TypeManager.ushort_type) ||
- (vt == TypeManager.int32_type) ||
+ (vt == TypeManager.int32_type) ||
(vt == TypeManager.uint32_type) ||
- (vt == TypeManager.char_type) ||
- (vt == TypeManager.float_type))){
+ (vt == TypeManager.char_type) ||
+ (vt == TypeManager.float_type) ||
+ (!vt.IsValueType))){
Report.Error (
- 677, Location, container.MakeName (Name) +
+ 677, Location, Parent.MakeName (Name) +
" A volatile field can not be of type `" +
TypeManager.CSharpName (vt) + "'");
return false;
@@ -4158,224 +5505,545 @@ namespace Mono.CSharp {
}
}
- FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
+ FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
+
+ if (Parent.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));
+
+ TypeManager.RegisterFieldBase (FieldBuilder, this);
+ }
+ catch (ArgumentException) {
+ Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
+ return false;
+ }
+
+ return true;
+ }
+
+ public override void Emit ()
+ {
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (
+ Parent, Location, null, FieldBuilder.FieldType,
+ ModFlags);
+ OptAttributes.Emit (ec, this);
+ }
+
+ base.Emit ();
+ }
+ }
+
+ //
+ // `set' and `get' accessors are represented with an Accessor.
+ //
+ public class Accessor {
+ //
+ // Null if the accessor is empty, or a Block if not
+ //
+ public Block Block;
+ public Attributes Attributes;
+ public Location Location;
+
+ public Accessor (Block b, Attributes attrs, Location loc)
+ {
+ Block = b;
+ Attributes = attrs;
+ Location = loc;
+ }
+ }
+
+
+ // Ooouh Martin, templates are missing here.
+ // When it will be possible move here a lot of child code and template method type.
+ public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
+ protected MethodData method_data;
+ protected Block block;
+
+ // The accessor are created event if they are not wanted.
+ // But we need them because their names are reserved.
+ // Field says whether accessor will be emited or not
+ public readonly bool IsDummy;
+
+ protected readonly string prefix;
+
+ ReturnParameter return_attributes;
+
+ public AbstractPropertyEventMethod (MemberBase member, string prefix)
+ : base (null, SetupName (prefix, member), null, member.Location)
+ {
+ this.prefix = prefix;
+ IsDummy = true;
+ }
+
+ public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
+ string prefix)
+ : base (null, SetupName (prefix, member),
+ accessor.Attributes, accessor.Location)
+ {
+ this.prefix = prefix;
+ this.block = accessor.Block;
+ }
+
+ static MemberName SetupName (string prefix, MemberBase member)
+ {
+ MemberName name = member.MemberName.Clone ();
+ name.Name = prefix + member.ShortName;
+ return name;
+ }
+
+ public void UpdateName (MemberBase member)
+ {
+ MemberName.Name = prefix + member.ShortName;
+ }
+
+ #region IMethodData Members
+
+ public Block Block {
+ get {
+ return block;
+ }
+
+ set {
+ block = value;
+ }
+ }
+
+ public CallingConventions CallingConventions {
+ get {
+ return CallingConventions.Standard;
+ }
+ }
+
+ public bool IsExcluded (EmitContext ec)
+ {
+ return false;
+ }
+
+ GenericMethod IMethodData.GenericMethod {
+ get {
+ return null;
+ }
+ }
+
+ public MemberName MethodName {
+ get {
+ return MemberName;
+ }
+ }
+
+ public abstract ObsoleteAttribute GetObsoleteAttribute ();
+ public abstract Type[] ParameterTypes { get; }
+ public abstract Type ReturnType { get; }
+ public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
+
+ #endregion
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
+ a.Type == TypeManager.conditional_attribute_type) {
+ Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+ return;
+ }
+
+ if (a.Target == AttributeTargets.Method) {
+ method_data.MethodBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ if (a.Target == AttributeTargets.ReturnValue) {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ ApplyToExtraTarget (a, cb);
+ }
+
+ virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
+ {
+ System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
+ }
+
+ public override bool Define()
+ {
+ return false;
+ }
+
+ public virtual void Emit (TypeContainer container)
+ {
+ method_data.Emit (container, this);
+ block = null;
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return false;
+ }
+
+ public bool IsDuplicateImplementation (MethodCore method)
+ {
+ if (Name != method.Name)
+ return false;
+
+ Type[] param_types = method.ParameterTypes;
+
+ if (param_types.Length != ParameterTypes.Length)
+ return false;
+
+ for (int i = 0; i < param_types.Length; i++)
+ if (param_types [i] != ParameterTypes [i])
+ return false;
+
+ Report.SymbolRelatedToPreviousError (method);
+ Report.Error (111, Location, "Type '{0}' already defines a member called '{1}' with " +
+ "the same parameter types", Parent.Name, Name);
+ return true;
+ }
+
+ public new Location Location {
+ get {
+ return base.Location;
+ }
+ }
+
+ protected override void VerifyObsoleteAttribute()
+ {
+ }
+
+ }
+
+ //
+ // Properties and Indexers both generate PropertyBuilders, we use this to share
+ // their common bits.
+ //
+ abstract public class PropertyBase : MethodCore {
+
+ public class GetMethod: PropertyMethod
+ {
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public GetMethod (MethodCore method):
+ base (method, "get_")
+ {
+ }
+
+ public GetMethod (MethodCore method, Accessor accessor):
+ base (method, accessor, "get_")
+ {
+ }
+
+ public override MethodBuilder Define(TypeContainer container)
+ {
+ method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (base.GetSignatureForError (tc), ".get");
+ }
+
+ public override Type ReturnType {
+ get {
+ return method.MemberType;
+ }
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public class SetMethod: PropertyMethod {
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+ ImplicitParameter param_attr;
+
+ public SetMethod (MethodCore method):
+ base (method, "set_")
+ {
+ }
+
+ public SetMethod (MethodCore method, Accessor accessor):
+ base (method, accessor, "set_")
+ {
+ }
+
+ protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == AttributeTargets.Parameter) {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ protected virtual InternalParameters GetParameterInfo (TypeContainer container)
+ {
+ Parameter [] parms = new Parameter [1];
+ parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
+ return new InternalParameters (
+ container, new Parameters (parms, null, method.Location));
+ }
+
+ public override MethodBuilder Define(TypeContainer container)
+ {
+ method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (base.GetSignatureForError (tc), ".set");
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ return new Type[] { method.MemberType };
+ }
+ }
+
+ public override Type ReturnType {
+ get {
+ return TypeManager.void_type;
+ }
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ static string[] attribute_targets = new string [] { "property" };
+
+ public abstract class PropertyMethod: AbstractPropertyEventMethod {
+ protected readonly MethodCore method;
+
+ public PropertyMethod (MethodCore method, string prefix)
+ : base (method, prefix)
+ {
+ this.method = method;
+ }
+
+ public PropertyMethod (MethodCore method, Accessor accessor, string prefix)
+ : base (method, accessor, prefix)
+ {
+ this.method = method;
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
+ }
- if (container is Struct &&
- ((fa & FieldAttributes.Static) == 0) &&
- t == container.TypeBuilder &&
- !TypeManager.IsBuiltinType (t)){
- Report.Error (523, Location, "Struct member `" + container.Name + "." + Name +
- "' causes a cycle in the structure layout");
- return false;
+ public InternalParameters ParameterInfo
+ {
+ get {
+ return method_data.ParameterInfo;
+ }
}
- try {
- FieldBuilder = container.TypeBuilder.DefineField (
- Name, t, Modifiers.FieldAttr (ModFlags));
+ public abstract MethodBuilder Define (TypeContainer container);
- TypeManager.RegisterFieldBase (FieldBuilder, this);
- }
- catch (ArgumentException) {
- Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
- return false;
+ public override Type[] ParameterTypes {
+ get {
+ return TypeManager.NoTypes;
+ }
}
- return true;
- }
-
- public void Emit (TypeContainer tc)
- {
- EmitContext ec = new EmitContext (tc, Location, null,
- FieldBuilder.FieldType, ModFlags);
+ public override EmitContext CreateEmitContext (TypeContainer tc,
+ ILGenerator ig)
+ {
+ return new EmitContext (
+ tc, method.ds, method.Location, ig, ReturnType,
+ method.ModFlags, false);
+ }
- Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes);
- }
- }
+ public override ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.ds);
+ }
- //
- // `set' and `get' accessors are represented with an Accessor.
- //
- public class Accessor {
- //
- // Null if the accessor is empty, or a Block if not
- //
- public Block Block;
- public Attributes OptAttributes;
-
- public Accessor (Block b, Attributes attrs)
- {
- Block = b;
- OptAttributes = attrs;
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (tc.Name, '.', method.Name);
+ }
}
- }
- //
- // Properties and Indexers both generate PropertyBuilders, we use this to share
- // their common bits.
- //
- abstract public class PropertyBase : MethodCore {
- public Accessor Get, Set;
+ public PropertyMethod Get, Set;
public PropertyBuilder PropertyBuilder;
public MethodBuilder GetBuilder, SetBuilder;
- public MethodData GetData, SetData;
protected EmitContext ec;
- public PropertyBase (DeclSpace ds, Expression type, string name, int mod_flags,
- int allowed_mod, Parameters parameters,
- Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (ds, type, mod_flags, allowed_mod, name, attrs, parameters, loc)
+ public PropertyBase (TypeContainer parent, Expression type, int mod_flags,
+ int allowed_mod, bool is_iface, MemberName name,
+ Parameters parameters, Attributes attrs,
+ Location loc)
+ : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
+ attrs, parameters, loc)
{
- Get = get_block;
- Set = set_block;
}
- protected override bool DoDefine (DeclSpace decl, TypeContainer container)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- if (!base.DoDefine (decl, container))
- return false;
-
- ec = new EmitContext (container, Location, null, MemberType, ModFlags);
+ PropertyBuilder.SetCustomAttribute (cb);
+ }
- return true;
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Property;
+ }
}
- //
- // Checks our base implementation if any
- //
- protected override bool CheckBase (TypeContainer container)
+ protected override bool DoDefine (DeclSpace decl)
{
- base.CheckBase (container);
-
- // Check whether arguments were correct.
- if (!DoDefineParameters ())
+ if (!base.DoDefine (decl))
return false;
- if (IsExplicitImpl)
- return true;
-
- string report_name;
- MethodSignature ms, base_ms;
- if (this is Indexer) {
- string name, base_name;
-
- report_name = "this";
- name = TypeManager.IndexerPropertyName (container.TypeBuilder);
- ms = new MethodSignature (name, null, ParameterTypes);
- base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
- base_ms = new MethodSignature (base_name, null, ParameterTypes);
- } else {
- report_name = Name;
- ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
+ if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
+ Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
+ return false;
}
- //
- // Verify if the parent has a type with the same name, and then
- // check whether we have to create a new slot for it or not.
- //
- Type ptype = container.TypeBuilder.BaseType;
+ if (MemberType.IsAbstract && MemberType.IsSealed) {
+ Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
+ return false;
+ }
- // ptype is only null for System.Object while compiling corlib.
- if (ptype == null) {
- if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (container);
+ ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
+ return true;
+ }
- return true;
- }
+ public override string GetSignatureForError()
+ {
+ if (PropertyBuilder == null)
+ return GetSignatureForError (Parent);
- MemberList props_this;
+ return TypeManager.CSharpSignature (PropertyBuilder, false);
+ }
- props_this = TypeContainer.FindMembers (
- container.TypeBuilder, MemberTypes.Property,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly,
- MethodSignature.method_signature_filter, ms);
- if (props_this.Count > 0) {
- Report.Error (111, Location, "Class `" + container.Name + "' " +
- "already defines a member called `" + report_name + "' " +
- "with the same parameter types");
- return false;
+ protected override bool CheckForDuplications ()
+ {
+ ArrayList ar = Parent.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;
+ }
}
- MemberList mi_props;
-
- mi_props = TypeContainer.FindMembers (
- ptype, MemberTypes.Property,
- BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Instance | BindingFlags.Static,
- MethodSignature.inheritable_method_signature_filter, base_ms);
+ ar = Parent.Properties;
+ if (ar != null) {
+ int arLen = ar.Count;
+
+ for (int i = 0; i < arLen; i++) {
+ Property m = (Property) ar [i];
+ if (IsDuplicateImplementation (m))
+ return false;
+ }
+ }
- if (mi_props.Count > 0){
- PropertyInfo parent_property = (PropertyInfo) mi_props [0];
- string name = parent_property.DeclaringType.Name + "." +
- parent_property.Name;
+ return true;
+ }
- MethodInfo get, set, parent_method;
- get = parent_property.GetGetMethod (true);
- set = parent_property.GetSetMethod (true);
+ protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+ {
+ PropertyInfo parent_property = container.ParentContainer.MemberCache.FindMemberToOverride (
+ container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
- if (get != null)
- parent_method = get;
- else if (set != null)
- parent_method = set;
- else
- throw new Exception ("Internal error!");
+ if (parent_property == null)
+ return null;
- if (!CheckMethodAgainstBase (container, flags, parent_method, name))
- return false;
+ parent_ret_type = parent_property.PropertyType;
- if ((ModFlags & Modifiers.NEW) == 0) {
- Type parent_type = TypeManager.TypeToCoreType (
- parent_property.PropertyType);
+ MethodInfo temp_m;
+ temp_m = parent_property.GetGetMethod (true);
+ if (temp_m != null)
+ return temp_m;
- if (parent_type != MemberType) {
- Report.Error (
- 508, Location, container.MakeName (Name) + ": cannot " +
- "change return type when overriding " +
- "inherited member " + name);
- return false;
- }
- }
- } else {
- if ((ModFlags & Modifiers.NEW) != 0)
- WarningNotHiding (container);
-
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- if (this is Indexer)
- Report.Error (115, Location,
- container.MakeName (Name) +
- " no suitable indexers found to override");
- else
- Report.Error (115, Location,
- container.MakeName (Name) +
- " no suitable properties found to override");
- return false;
- }
- }
- return true;
+ System.Diagnostics.Debug.Assert (parent_property.GetSetMethod (true) != null, "Internal error property without get/set");
+ return parent_property.GetSetMethod (true);
}
- public void Emit (TypeContainer tc)
+ public override void Emit ()
{
//
// The PropertyBuilder can be null for explicit implementations, in that
// case, we do not actually emit the ".property", so there is nowhere to
// put the attribute
//
- if (PropertyBuilder != null)
- Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes);
+ if (PropertyBuilder != null && OptAttributes != null)
+ OptAttributes.Emit (ec, this);
+
+ if (!Get.IsDummy)
+ Get.Emit (Parent);
+
+ if (!Set.IsDummy)
+ Set.Emit (Parent);
+
+ base.Emit ();
+ }
+
+ ///
+ /// Tests whether accessors are not in collision with some method (CS0111)
+ ///
+ public bool AreAccessorsDuplicateImplementation (MethodCore mc)
+ {
+ return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
+ }
+
+ protected override void UpdateMemberName ()
+ {
+ base.UpdateMemberName ();
+
+ Get.UpdateName (this);
+ Set.UpdateName (this);
+ }
- if (GetData != null) {
- GetData.Emit (tc, Get.Block, Get);
- Get.Block = null;
- }
- if (SetData != null) {
- SetData.Emit (tc, Set.Block, Set);
- Set.Block = null;
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
}
}
}
@@ -4396,102 +6064,88 @@ namespace Mono.CSharp {
Modifiers.METHOD_YIELDS |
Modifiers.VIRTUAL;
- public Property (DeclSpace ds, Expression type, string name, int mod_flags,
- Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (ds, type, name, mod_flags, AllowedModifiers,
- Parameters.EmptyReadOnlyParameters,
- get_block, set_block, attrs, loc)
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
+
+ public Property (TypeContainer parent, Expression type, int mod_flags,
+ bool is_iface, MemberName name, Attributes attrs,
+ Accessor get_block, Accessor set_block, Location loc)
+ : base (parent, type, mod_flags,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
+ loc)
{
+ if (get_block == null)
+ Get = new GetMethod (this);
+ else
+ Get = new GetMethod (this, get_block);
+
+ if (set_block == null)
+ Set = new SetMethod (this);
+ else
+ Set = new SetMethod (this, set_block);
}
- public override bool Define (TypeContainer container)
+ public override bool Define ()
{
- if (!DoDefine (container, container))
+ if (!DoDefineBase ())
return false;
- if (!CheckBase (container))
+ if (!DoDefine (Parent))
return false;
- flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
+ if (!CheckBase ())
+ return false;
- if (Get != null) {
- Type [] parameters = TypeManager.NoTypes;
+ flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
- InternalParameters ip = new InternalParameters (
- container, Parameters.EmptyReadOnlyParameters);
+ if (!Get.IsDummy) {
- GetData = new MethodData (container, this, "get", MemberType,
- parameters, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
+ GetBuilder = Get.Define (Parent);
+ if (GetBuilder == null)
+ return false;
//
// Setup iterator if we are one
//
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
- IteratorHandler ih = new IteratorHandler (
- "get", container, MemberType,
- parameters, ip, ModFlags, Location);
+ Iterator iterator = new Iterator (
+ Parent, "get", MemberType,
+ TypeManager.NoTypes, Get.ParameterInfo,
+ ModFlags, Get.Block, Location);
- Block new_block = ih.Setup (block);
- if (new_block == null)
+ if (!iterator.DefineIterator ())
return false;
- block = new_block;
+ Get.Block = iterator.Block;
}
-
- if (!GetData.Define (container))
- return false;
-
- GetBuilder = GetData.MethodBuilder;
}
- if (Set != null) {
- Type [] parameters = new Type [1];
- parameters [0] = MemberType;
-
- Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
- InternalParameters ip = new InternalParameters (
- container, new Parameters (parms, null, Location));
-
- SetData = new MethodData (container, this, "set", TypeManager.void_type,
- parameters, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (container))
+ if (!Set.IsDummy) {
+ SetBuilder = Set.Define (Parent);
+ if (SetBuilder == null)
return false;
- SetBuilder = SetData.MethodBuilder;
SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
}
// FIXME - PropertyAttributes.HasDefault ?
- PropertyAttributes prop_attr =
- PropertyAttributes.RTSpecialName |
+ PropertyAttributes prop_attr = PropertyAttributes.None;
+ if (!IsInterface)
+ prop_attr |= PropertyAttributes.RTSpecialName |
PropertyAttributes.SpecialName;
if (!IsExplicitImpl){
- PropertyBuilder = container.TypeBuilder.DefineProperty (
+ PropertyBuilder = Parent.TypeBuilder.DefineProperty (
Name, prop_attr, MemberType, null);
- if (Get != null)
+ if (!Get.IsDummy)
PropertyBuilder.SetGetMethod (GetBuilder);
- if (Set != null)
+ if (!Set.IsDummy)
PropertyBuilder.SetSetMethod (SetBuilder);
- //
- // HACK for the reasons exposed above
- //
- if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
- Report.Error (
- 111, Location,
- "Class `" + container.Name +
- "' already contains a definition for the property `" +
- Name + "'");
- return false;
- }
+ TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
}
return true;
}
@@ -4638,15 +6292,247 @@ namespace Mono.CSharp {
return event_type;
}
}
-
- public void SetUsed ()
- {
- if (my_event != null)
- my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
- }
- }
-
- public class Event : FieldBase {
+
+ public void SetUsed ()
+ {
+ if (my_event != null)
+ my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
+ }
+ }
+
+ ///
+ /// For case when event is declared like property (with add and remove accessors).
+ ///
+ public class EventProperty: Event {
+
+ static string[] attribute_targets = new string [] { "event", "property" };
+
+ public EventProperty (TypeContainer parent, Expression type, int mod_flags,
+ bool is_iface, MemberName name, Object init,
+ Attributes attrs, Accessor add, Accessor remove,
+ Location loc)
+ : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this, add);
+ Remove = new RemoveDelegateMethod (this, remove);
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ ///
+ /// Event is declared like field.
+ ///
+ public class EventField: Event {
+
+ static string[] attribute_targets = new string [] { "event", "field", "method" };
+
+ public EventField (TypeContainer parent, Expression type, int mod_flags,
+ bool is_iface, MemberName name, Object init,
+ Attributes attrs, Location loc)
+ : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this);
+ Remove = new RemoveDelegateMethod (this);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == AttributeTargets.Field) {
+ FieldBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ if (a.Target == AttributeTargets.Method) {
+ AddBuilder.SetCustomAttribute (cb);
+ RemoveBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public abstract class Event : FieldBase {
+
+ protected sealed class AddDelegateMethod: DelegateMethod
+ {
+
+ public AddDelegateMethod (Event method):
+ base (method, "add_")
+ {
+ }
+
+ public AddDelegateMethod (Event method, Accessor accessor):
+ base (method, accessor, "add_")
+ {
+ }
+
+ protected override MethodInfo DelegateMethodInfo {
+ get {
+ return TypeManager.delegate_combine_delegate_delegate;
+ }
+ }
+
+ }
+
+ protected sealed class RemoveDelegateMethod: DelegateMethod
+ {
+ public RemoveDelegateMethod (Event method):
+ base (method, "remove_")
+ {
+ }
+
+ public RemoveDelegateMethod (Event method, Accessor accessor):
+ base (method, accessor, "remove_")
+ {
+ }
+
+ protected override MethodInfo DelegateMethodInfo {
+ get {
+ return TypeManager.delegate_remove_delegate_delegate;
+ }
+ }
+
+ }
+
+ public abstract class DelegateMethod: AbstractPropertyEventMethod
+ {
+ protected readonly Event method;
+ ImplicitParameter param_attr;
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+
+ public DelegateMethod (Event method, string prefix)
+ : base (method, prefix)
+ {
+ this.method = method;
+ }
+
+ public DelegateMethod (Event method, Accessor accessor, string prefix)
+ : base (method, accessor, prefix)
+ {
+ this.method = method;
+ }
+
+ protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == AttributeTargets.Parameter) {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
+ }
+
+ public MethodBuilder Define (TypeContainer container, InternalParameters ip)
+ {
+ method_data = new MethodData (method, ip, method.ModFlags,
+ method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ MethodBuilder mb = method_data.MethodBuilder;
+ mb.DefineParameter (1, ParameterAttributes.None, "value");
+ return mb;
+ }
+
+
+ public override void Emit (TypeContainer tc)
+ {
+ if (block != null) {
+ base.Emit (tc);
+ return;
+ }
+
+ ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
+ EmitContext ec = CreateEmitContext (tc, ig);
+ FieldInfo field_info = (FieldInfo)method.FieldBuilder;
+
+ method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
+ if ((method.ModFlags & Modifiers.STATIC) != 0) {
+ ig.Emit (OpCodes.Ldsfld, field_info);
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Call, DelegateMethodInfo);
+ ig.Emit (OpCodes.Castclass, method.MemberType);
+ ig.Emit (OpCodes.Stsfld, field_info);
+ } else {
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldfld, field_info);
+ ig.Emit (OpCodes.Ldarg_1);
+ ig.Emit (OpCodes.Call, DelegateMethodInfo);
+ ig.Emit (OpCodes.Castclass, method.MemberType);
+ ig.Emit (OpCodes.Stfld, field_info);
+ }
+ ig.Emit (OpCodes.Ret);
+ }
+
+ protected abstract MethodInfo DelegateMethodInfo { get; }
+
+ public override Type[] ParameterTypes {
+ get {
+ return new Type[] { method.MemberType };
+ }
+ }
+
+ public override Type ReturnType {
+ get {
+ return TypeManager.void_type;
+ }
+ }
+
+ public override EmitContext CreateEmitContext (TypeContainer tc,
+ ILGenerator ig)
+ {
+ return new EmitContext (
+ tc, method.Parent, Location, ig, ReturnType,
+ method.ModFlags, false);
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (tc.Name, '.', method.Name);
+ }
+
+ public override ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.Parent);
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
@@ -4660,83 +6546,91 @@ namespace Mono.CSharp {
Modifiers.UNSAFE |
Modifiers.ABSTRACT;
- public readonly Accessor Add;
- public readonly Accessor Remove;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
+
+ public DelegateMethod Add, Remove;
public MyEventBuilder EventBuilder;
+ public MethodBuilder AddBuilder, RemoveBuilder;
- MethodBuilder AddBuilder, RemoveBuilder;
MethodData AddData, RemoveData;
- public Event (Expression type, string name, Object init, int mod, Accessor add,
- Accessor remove, Attributes attrs, Location loc)
- : base (type, mod, AllowedModifiers, name, init, attrs, loc)
+ public Event (TypeContainer parent, Expression type, int mod_flags,
+ bool is_iface, MemberName name, Object init, Attributes attrs,
+ Location loc)
+ : base (parent, type, mod_flags,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ name, init, attrs, loc)
+ {
+ IsInterface = is_iface;
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ EventBuilder.SetCustomAttribute (cb);
+ }
+
+ public bool AreAccessorsDuplicateImplementation (MethodCore mc)
{
- Add = add;
- Remove = remove;
+ return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
}
- public override bool Define (TypeContainer container)
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Event;
+ }
+ }
+
+ public override bool Define ()
{
- EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
- MethodAttributes m_attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName
+ EventAttributes e_attr;
+ e_attr = EventAttributes.None;
;
- if (!DoDefine (container, container))
+ if (!DoDefineBase ())
+ return false;
+
+ if (!DoDefine (Parent))
return false;
if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
- Report.Error (74, Location, "'" + container.Name + "." + Name +
+ Report.Error (74, Location, "'" + Parent.Name + "." + Name +
"': abstract event can not have an initializer");
return false;
}
-
- if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
- Report.Error (66, Location, "'" + container.Name + "." + Name +
+
+ if (!TypeManager.IsDelegateType (MemberType)) {
+ Report.Error (66, Location, "'" + Parent.Name + "." + Name +
"' : event must be of a delegate type");
return false;
}
- Type [] parameter_types = new Type [1];
- parameter_types [0] = MemberType;
-
Parameter [] parms = new Parameter [1];
parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
InternalParameters ip = new InternalParameters (
- container, new Parameters (parms, null, Location));
+ Parent, new Parameters (parms, null, Location));
- if (!CheckBase (container))
+ if (!CheckBase ())
return false;
//
// Now define the accessors
//
- AddData = new MethodData (container, this, "add", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Add != null) ? Add.OptAttributes : null,
- ModFlags, flags | m_attr, false);
- if (!AddData.Define (container))
+ AddBuilder = Add.Define (Parent, ip);
+ if (AddBuilder == null)
return false;
- AddBuilder = AddData.MethodBuilder;
- AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
-
- RemoveData = new MethodData (container, this, "remove", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Remove != null) ? Remove.OptAttributes : null,
- ModFlags, flags | m_attr, false);
-
- if (!RemoveData.Define (container))
+ RemoveBuilder = Remove.Define (Parent, ip);
+ if (RemoveBuilder == null)
return false;
- RemoveBuilder = RemoveData.MethodBuilder;
- RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
-
if (!IsExplicitImpl){
EventBuilder = new MyEventBuilder (this,
- container.TypeBuilder, Name, e_attr, MemberType);
+ Parent.TypeBuilder, Name, e_attr, MemberType);
- if (Add == null && Remove == null) {
- FieldBuilder = container.TypeBuilder.DefineField (
+ if (Add.Block == null && Remove.Block == null &&
+ !IsInterface) {
+ FieldBuilder = Parent.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
TypeManager.RegisterPrivateFieldOfEvent (
@@ -4747,85 +6641,133 @@ namespace Mono.CSharp {
EventBuilder.SetAddOnMethod (AddBuilder);
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
- if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
- Report.Error (111, Location,
- "Class `" + container.Name +
- "' already contains a definition for the event `" +
- Name + "'");
- return false;
- }
+ TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
}
return true;
}
- void EmitDefaultMethod (EmitContext ec, bool is_add)
+ protected override bool CheckBase ()
+ {
+ if (!base.CheckBase ())
+ return false;
+
+ if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
+ if (!(conflict_symbol is EventInfo)) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public override void Emit ()
{
- ILGenerator ig = ec.ig;
- MethodInfo method = null;
-
- if (is_add)
- method = TypeManager.delegate_combine_delegate_delegate;
- else
- method = TypeManager.delegate_remove_delegate_delegate;
-
- if ((ModFlags & Modifiers.STATIC) != 0) {
- ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Call, method);
- ig.Emit (OpCodes.Castclass, MemberType);
- ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
- } else {
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
- ig.Emit (OpCodes.Ldarg_1);
- ig.Emit (OpCodes.Call, method);
- ig.Emit (OpCodes.Castclass, MemberType);
- ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (
+ Parent, Location, null, MemberType, ModFlags);
+ OptAttributes.Emit (ec, this);
}
- ig.Emit (OpCodes.Ret);
+
+ if (!IsInterface) {
+ Add.Emit (Parent);
+ Remove.Emit (Parent);
+ }
+
+ base.Emit ();
}
- public void Emit (TypeContainer tc)
+ public override string GetSignatureForError ()
{
- EmitContext ec;
+ if (EventBuilder == null)
+ return base.GetSignatureForError (Parent);
+
+ return TypeManager.GetFullNameSignature (EventBuilder);
+ }
+ }
- ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
- Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes);
+
+ public class Indexer : PropertyBase {
- if (Add != null) {
- AddData.Emit (tc, Add.Block, Add);
- Add.Block = null;
- } else {
- ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
- ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
- EmitDefaultMethod (ec, true);
+ class GetIndexerMethod: GetMethod
+ {
+ public GetIndexerMethod (MethodCore method):
+ base (method)
+ {
}
- if (Remove != null) {
- RemoveData.Emit (tc, Remove.Block, Remove);
- Remove.Block = null;
- } else {
- ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
- ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
- EmitDefaultMethod (ec, false);
+ public GetIndexerMethod (MethodCore method, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ return method.ParameterTypes;
+ }
}
}
-
- }
- //
- // FIXME: This does not handle:
- //
- // int INTERFACENAME [ args ]
- // Does not
- //
- // Only:
- //
- // int this [ args ]
-
- public class Indexer : PropertyBase {
+ class SetIndexerMethod: SetMethod
+ {
+ readonly Parameters parameters;
+
+ public SetIndexerMethod (MethodCore method):
+ base (method)
+ {
+ }
+
+ public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
+ base (method, accessor)
+ {
+ this.parameters = parameters;
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ int top = method.ParameterTypes.Length;
+ Type [] set_pars = new Type [top + 1];
+ method.ParameterTypes.CopyTo (set_pars, 0);
+ set_pars [top] = method.MemberType;
+ return set_pars;
+ }
+ }
+
+ protected override InternalParameters GetParameterInfo (TypeContainer container)
+ {
+ Parameter [] fixed_parms = parameters.FixedParameters;
+
+ if (fixed_parms == null){
+ throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
+ // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+ // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+ //
+ // Here is the problem: the `value' parameter has
+ // to come *after* the array parameter in the declaration
+ // like this:
+ // X (object [] x, Type value)
+ // .param [0]
+ //
+ // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+ // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+
+ }
+
+ Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
+
+ fixed_parms.CopyTo (tmp, 0);
+ tmp [fixed_parms.Length] = new Parameter (
+ method.Type, "value", Parameter.Modifier.NONE, null);
+
+ Parameters set_formal_params = new Parameters (tmp, null, method.Location);
+
+ return new InternalParameters (container, set_formal_params);
+ }
+
+ }
+
const int AllowedModifiers =
Modifiers.NEW |
@@ -4840,110 +6782,91 @@ namespace Mono.CSharp {
Modifiers.EXTERN |
Modifiers.ABSTRACT;
- public string IndexerName;
- public string InterfaceIndexerName;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
//
// Are we implementing an interface ?
//
- public Indexer (DeclSpace ds, Expression type, string int_type, int flags,
- Parameters parameters, Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (ds, type, "", flags, AllowedModifiers, parameters, get_block, set_block,
- attrs, loc)
- {
- ExplicitInterfaceName = int_type;
+ public Indexer (TypeContainer parent, Expression type, MemberName name, int mod,
+ bool is_iface, Parameters parameters, Attributes attrs,
+ Accessor get_block, Accessor set_block, Location loc)
+ : base (parent, type, mod,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, name, parameters, attrs, loc)
+ {
+ if (get_block == null)
+ Get = new GetIndexerMethod (this);
+ else
+ Get = new GetIndexerMethod (this, get_block);
+
+ if (set_block == null)
+ Set = new SetIndexerMethod (this);
+ else
+ Set = new SetIndexerMethod (this, parameters, set_block);
}
- public override bool Define (TypeContainer container)
+ public override bool Define ()
{
PropertyAttributes prop_attr =
PropertyAttributes.RTSpecialName |
PropertyAttributes.SpecialName;
- if (!DoDefine (container, container))
+ if (!DoDefineBase ())
return false;
- IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
- if (IndexerName == null)
- IndexerName = "Item";
- else if (IsExplicitImpl)
- Report.Error (592, Location,
- "Attribute 'IndexerName' is not valid on this declaration " +
- "type. It is valid on `property' declarations only.");
+ if (!DoDefine (Parent))
+ return false;
- ShortName = IndexerName;
- if (IsExplicitImpl) {
- InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
- Name = InterfaceType.FullName + "." + IndexerName;
- } else {
- InterfaceIndexerName = IndexerName;
- Name = ShortName;
+ if (OptAttributes != null) {
+ Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
+ if (indexer_attr != null) {
+ ShortName = indexer_attr.GetIndexerAttributeValue (ec);
+
+ if (IsExplicitImpl) {
+ Report.Error (415, indexer_attr.Location, "The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration");
+ return false;
+ }
+
+ if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ Report.Error (609, indexer_attr.Location, "Cannot set the 'IndexerName' attribute on an indexer marked override");
+ return false;
+ }
+
+ if (!Tokenizer.IsValidIdentifier (ShortName)) {
+ Report.Error (633, indexer_attr.Location, "The argument to the 'IndexerName' attribute must be a valid identifier");
+ return false;
+ }
+
+ UpdateMemberName ();
+ }
}
- if (!CheckNameCollision (container))
+ if (InterfaceType != null) {
+ string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
+ if (parent_IndexerName != Name)
+ ShortName = parent_IndexerName;
+ UpdateMemberName ();
+ }
+
+ if (!Parent.AddToMemberContainer (this, true) ||
+ !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true))
return false;
- if (!CheckBase (container))
+ if (!CheckBase ())
return false;
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
- if (Get != null){
- InternalParameters ip = new InternalParameters (container, Parameters);
-
- GetData = new MethodData (container, this, "get", MemberType,
- ParameterTypes, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
-
- if (!GetData.Define (container))
+ if (!Get.IsDummy){
+ GetBuilder = Get.Define (Parent);
+ if (GetBuilder == null)
return false;
-
- GetBuilder = GetData.MethodBuilder;
}
- if (Set != null){
- int top = ParameterTypes.Length;
- Type [] set_pars = new Type [top + 1];
- ParameterTypes.CopyTo (set_pars, 0);
- set_pars [top] = MemberType;
-
- Parameter [] fixed_parms = Parameters.FixedParameters;
-
- if (fixed_parms == null){
- throw new Exception ("We currently do not support only array arguments in an indexer at: " + Location);
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- //
- // Here is the problem: the `value' parameter has
- // to come *after* the array parameter in the declaration
- // like this:
- // X (object [] x, Type value)
- // .param [0]
- //
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
- // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
-
- }
-
- Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
-
-
- fixed_parms.CopyTo (tmp, 0);
- tmp [fixed_parms.Length] = new Parameter (
- Type, "value", Parameter.Modifier.NONE, null);
-
- Parameters set_formal_params = new Parameters (tmp, null, Location);
-
- InternalParameters ip = new InternalParameters (container, set_formal_params);
-
- SetData = new MethodData (container, this, "set", TypeManager.void_type,
- set_pars, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (container))
+ if (!Set.IsDummy){
+ SetBuilder = Set.Define (Parent);
+ if (SetBuilder == null)
return false;
-
- SetBuilder = SetData.MethodBuilder;
}
//
@@ -4951,19 +6874,24 @@ namespace Mono.CSharp {
//
Parameter [] p = Parameters.FixedParameters;
if (p != null) {
+ if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
+ Report.Error (631, Location, "ref and out are not valid in this context");
+ return false;
+ }
+
int i;
for (i = 0; i < p.Length; ++i) {
- if (Get != null)
+ if (!Get.IsDummy)
GetBuilder.DefineParameter (
i + 1, p [i].Attributes, p [i].Name);
- if (Set != null)
+ if (!Set.IsDummy)
SetBuilder.DefineParameter (
i + 1, p [i].Attributes, p [i].Name);
}
- if (Set != null)
+ if (!Set.IsDummy)
SetBuilder.DefineParameter (
i + 1, ParameterAttributes.None, "value");
@@ -4982,13 +6910,13 @@ namespace Mono.CSharp {
// explicit interface implementation.
//
if (!IsExplicitImpl) {
- PropertyBuilder = container.TypeBuilder.DefineProperty (
- IndexerName, prop_attr, MemberType, ParameterTypes);
+ PropertyBuilder = Parent.TypeBuilder.DefineProperty (
+ ShortName, prop_attr, MemberType, ParameterTypes);
- if (GetData != null)
+ if (!Get.IsDummy)
PropertyBuilder.SetGetMethod (GetBuilder);
- if (SetData != null)
+ if (!Set.IsDummy)
PropertyBuilder.SetSetMethod (SetBuilder);
TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
@@ -4998,52 +6926,21 @@ namespace Mono.CSharp {
return true;
}
- bool CheckNameCollision (TypeContainer container) {
- switch (VerifyName (container)){
- case DeclSpace.AdditionResult.NameExists:
- Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
- return false;
-
- case DeclSpace.AdditionResult.Success:
- return true;
- }
- throw new NotImplementedException ();
- }
-
- DeclSpace.AdditionResult VerifyName (TypeContainer container) {
- if (!AddIndexer (container, container.Name + "." + Name))
- return DeclSpace.AdditionResult.NameExists;
-
- if (Get != null) {
- if (!AddIndexer (container, container.Name + ".get_" + Name))
- return DeclSpace.AdditionResult.NameExists;
- }
-
- if (Set != null) {
- if (!AddIndexer (container, container.Name + ".set_" + Name))
- return DeclSpace.AdditionResult.NameExists;
- }
- return DeclSpace.AdditionResult.Success;
- }
-
- bool AddIndexer (TypeContainer container, string fullname)
+ public override string GetSignatureForError ()
{
- object value = container.GetDefinition (fullname);
-
- if (value != null) {
- return value.GetType () != GetType () ? false : true;
- }
+ if (PropertyBuilder == null)
+ return GetSignatureForError (Parent);
- container.DefineName (fullname, this);
- return true;
+ return TypeManager.CSharpSignature (PropertyBuilder, true);
}
- public override string GetSignatureForError () {
- return TypeManager.CSharpSignature (PropertyBuilder, true);
+ public override string GetSignatureForError(TypeContainer tc)
+ {
+ return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
}
}
- public class Operator : MemberBase, IIteratorContainer {
+ public class Operator : MethodCore, IIteratorContainer {
const int AllowedModifiers =
Modifiers.PUBLIC |
@@ -5094,79 +6991,100 @@ namespace Mono.CSharp {
};
public readonly OpType OperatorType;
- public readonly Expression ReturnType;
- public readonly Expression FirstArgType, SecondArgType;
- public readonly string FirstArgName, SecondArgName;
- public Block Block;
public MethodBuilder OperatorMethodBuilder;
- public string MethodName;
public Method OperatorMethod;
- public Operator (OpType type, Expression ret_type, int mod_flags,
- Expression arg1type, string arg1name,
- Expression arg2type, string arg2name,
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public Operator (TypeContainer parent, OpType type, Expression ret_type,
+ int mod_flags, Parameters parameters,
Block block, Attributes attrs, Location loc)
- : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
+ : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
+ new MemberName ("op_" + type), attrs, parameters, loc)
{
OperatorType = type;
- Name = "op_" + OperatorType;
- ReturnType = ret_type;
- FirstArgType = arg1type;
- FirstArgName = arg1name;
- SecondArgType = arg2type;
- SecondArgName = arg2name;
Block = block;
}
- string Prototype (TypeContainer container)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
- SecondArgType + ")";
+ OperatorMethod.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
}
- public override bool Define (TypeContainer container)
+ protected override bool CheckGenericOverride (MethodInfo method, string name)
{
- int length = 1;
- MethodName = "op_" + OperatorType;
-
- if (SecondArgType != null)
- length = 2;
-
- Parameter [] param_list = new Parameter [length];
+ return true;
+ }
+
+ protected override bool CheckForDuplications()
+ {
+ ArrayList ar = Parent.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.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 ()
+ {
if ((ModFlags & RequiredModifiers) != RequiredModifiers){
Report.Error (
558, Location,
"User defined operators `" +
- Prototype (container) +
+ GetSignatureForError (Parent) +
"' must be declared static and public");
return false;
}
- param_list[0] = new Parameter (FirstArgType, FirstArgName,
- Parameter.Modifier.NONE, null);
- if (SecondArgType != null)
- param_list[1] = new Parameter (SecondArgType, SecondArgName,
- Parameter.Modifier.NONE, null);
-
- OperatorMethod = new Method (container, ReturnType, ModFlags, MethodName,
- new Parameters (param_list, null, Location),
- OptAttributes, Location);
+ if (!DoDefine (ds))
+ return false;
+
+ OperatorMethod = new Method (
+ Parent, null, Type, ModFlags, false, MemberName,
+ Parameters, OptAttributes, Location);
OperatorMethod.Block = Block;
OperatorMethod.IsOperator = true;
- OperatorMethod.Define (container);
+ OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
+ OperatorMethod.Define ();
if (OperatorMethod.MethodBuilder == null)
return false;
OperatorMethodBuilder = OperatorMethod.MethodBuilder;
- Type [] param_types = OperatorMethod.ParameterTypes;
- Type declaring_type = OperatorMethodBuilder.DeclaringType;
- Type return_type = OperatorMethod.GetReturnType ();
- Type first_arg_type = param_types [0];
+ parameter_types = OperatorMethod.ParameterTypes;
+ Type declaring_type = OperatorMethod.MethodData.DeclaringType;
+ Type return_type = OperatorMethod.ReturnType;
+ Type first_arg_type = parameter_types [0];
+
+ if (!CheckBase ())
+ return false;
// Rules for conversion operators
@@ -5205,15 +7123,21 @@ namespace Mono.CSharp {
return false;
}
- if (first_arg_type.IsSubclassOf (return_type) ||
- return_type.IsSubclassOf (first_arg_type)){
- Report.Error (
- -10, Location,
- "User-defined conversion cannot convert between types " +
- "that derive from each other");
+ if (first_arg_type.IsSubclassOf (return_type)
+ || return_type.IsSubclassOf (first_arg_type)){
+ if (declaring_type.IsSubclassOf (return_type)) {
+ Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
+ return false;
+ }
+ Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
+ return false;
+ }
+ } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
+ if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
+ Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
return false;
}
- } else if (SecondArgType == null) {
+ } else if (Parameters.FixedParameters.Length == 1) {
// Checks for Unary operators
if (first_arg_type != declaring_type){
@@ -5249,7 +7173,7 @@ namespace Mono.CSharp {
// Checks for Binary operators
if (first_arg_type != declaring_type &&
- param_types [1] != declaring_type){
+ parameter_types [1] != declaring_type){
Report.Error (
563, Location,
"One of the parameters of a binary operator must " +
@@ -5261,7 +7185,7 @@ namespace Mono.CSharp {
return true;
}
- public void Emit (TypeContainer container)
+ public override void Emit ()
{
//
// abstract or extern methods have no bodies
@@ -5269,10 +7193,16 @@ namespace Mono.CSharp {
if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
return;
- OperatorMethod.Emit (container);
+ OperatorMethod.Emit ();
Block = null;
}
+ // Operator cannot be override
+ protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+ {
+ return null;
+ }
+
public static string GetName (OpType ot)
{
switch (ot){
@@ -5331,13 +7261,34 @@ namespace Mono.CSharp {
default: return "";
}
}
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ StringBuilder sb = new StringBuilder ();
+ sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.ToString (), Parameters.FixedParameters [0].GetSignatureForError ());
+
+ if (Parameters.FixedParameters.Length > 1) {
+ sb.Append (",");
+ sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
+ }
+ sb.Append (")");
+ return sb.ToString ();
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return ToString ();
+ }
public override string ToString ()
{
- Type return_type = OperatorMethod.GetReturnType();
+ if (OperatorMethod == null)
+ return Name;
+
+ Type return_type = OperatorMethod.ReturnType;
Type [] param_types = OperatorMethod.ParameterTypes;
- if (SecondArgType == null)
+ if (Parameters.FixedParameters.Length == 1)
return String.Format (
"{0} operator {1}({2})",
TypeManager.CSharpName (return_type),
@@ -5351,6 +7302,12 @@ namespace Mono.CSharp {
param_types [0], param_types [1]);
}
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
public void SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;
@@ -5369,22 +7326,7 @@ namespace Mono.CSharp {
/// This delegate is used to extract methods which have the
/// same signature as the argument
///
- public static MemberFilter method_signature_filter;
-
- ///
- /// This delegate is used to extract inheritable methods which
- /// have the same signature as the argument. By inheritable,
- /// this means that we have permissions to override the method
- /// from the current assembly and class
- ///
- public static MemberFilter inheritable_method_signature_filter;
-
- static MethodSignature ()
- {
- method_signature_filter = new MemberFilter (MemberSignatureCompare);
- inheritable_method_signature_filter = new MemberFilter (
- InheritableMemberSignatureCompare);
- }
+ public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
public MethodSignature (string name, Type ret_type, Type [] parameters)
{
@@ -5491,50 +7433,5 @@ namespace Mono.CSharp {
}
return true;
}
-
- //
- // This filter should be used when we are requesting methods that
- // we want to override.
- //
- // This makes a number of assumptions, for example
- // that the methods being extracted are of a parent
- // class (this means we know implicitly that we are
- // being called to find out about members by a derived
- // class).
- //
- static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
- {
- MethodInfo mi;
- PropertyInfo pi = m as PropertyInfo;
-
- if (pi != null) {
- mi = pi.GetGetMethod (true);
- if (mi == null)
- mi = pi.GetSetMethod (true);
- } else
- mi = m as MethodInfo;
-
- if (mi == null){
- Console.WriteLine ("Nothing found");
- }
-
- MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
-
- // If only accessible to the current class.
- if (prot == MethodAttributes.Private)
- return false;
-
- if (!MemberSignatureCompare (m, filter_criteria))
- return false;
-
- // If only accessible to the defining assembly or
- if (prot == MethodAttributes.FamANDAssem ||
- prot == MethodAttributes.Assembly){
- return m.DeclaringType.Assembly == CodeGen.Assembly.Builder;
- }
-
- // Anything else (FamOrAssembly and Public) is fine
- return true;
- }
}
}