using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Mono.CSharp {
//
// Whether we have seen a static constructor for this class or not
//
- bool have_static_constructor = false;
+ public bool UserDefinedStaticConstructor = false;
//
// Whether we have at least one non-static field
// from classes from the arraylist `type_bases'
//
string base_class_name;
+ public Type base_classs_type;
ArrayList type_bases;
- // Attributes for this type
- protected Attributes attributes;
-
- // 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.
- Type [] ifaces;
+ TypeExpr [] ifaces;
+ Type[] base_inteface_types;
// The parent member container and our member cache
IMemberContainer parent_container;
//
public string IndexerName;
- public TypeContainer (TypeContainer parent, string name, Location l)
- : base (parent, name, l)
+ public TypeContainer ():
+ this (null, null, "", null, new Location (-1)) {
+ }
+
+ public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
{
- string n;
types = new ArrayList ();
- if (parent == null)
- n = "";
- else
- n = parent.Name;
-
base_class_name = null;
-
- //Console.WriteLine ("New class " + name + " inside " + n);
}
public AdditionResult AddConstant (Const constant)
if (methods == null)
methods = new ArrayList ();
- if (method.Name.IndexOf (".") != -1)
+ if (method.Name.IndexOf ('.') != -1)
methods.Insert (0, method);
else
methods.Add (method);
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);
+ UserDefinedStaticConstructor = true;
+ if (default_static_constructor != null)
return AdditionResult.MethodExists;
- }
default_static_constructor = c;
} else {
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 ();
public AdditionResult AddProperty (Property prop)
{
AdditionResult res;
- string basename = prop.Name;
- string fullname = Name + "." + basename;
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+ 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 (properties == null)
properties = new ArrayList ();
- if (prop.Name.IndexOf (".") != -1)
+ if (prop.Name.IndexOf ('.') != -1)
properties.Insert (0, prop);
else
properties.Add (prop);
+
+ return AdditionResult.Success;
+ }
+
+ AdditionResult AddProperty (Property prop, string basename)
+ {
+ AdditionResult res;
+ string fullname = Name + "." + basename;
+
+ if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+ return res;
+
DefineName (fullname, prop);
return AdditionResult.Success;
return AdditionResult.Success;
}
- public AdditionResult AddIndexer (Indexer i)
+ public void AddIndexer (Indexer i)
{
if (indexers == null)
indexers = new ArrayList ();
- if (i.InterfaceType != null)
+ if (i.ExplicitInterfaceName != null)
indexers.Insert (0, i);
else
indexers.Add (i);
-
- return AdditionResult.Success;
}
public AdditionResult AddOperator (Operator op)
operators.Add (op);
+ string basename = op.Name;
+ string fullname = Name + "." + basename;
+ if (!defined_names.Contains (fullname))
+ {
+ DefineName (fullname, op);
+ }
return AdditionResult.Success;
}
+ 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 void RegisterOrder (Interface iface)
{
if (interface_order == null)
return delegates;
}
}
-
- public Attributes OptAttributes {
- get {
- return attributes;
- }
- }
-
- public bool HaveStaticConstructor {
- get {
- return have_static_constructor;
- }
- }
-
+
public virtual TypeAttributes TypeAttr {
get {
return Modifiers.TypeAttr (ModFlags, this);
public bool EmitFieldInitializers (EmitContext ec)
{
ArrayList fields;
- ILGenerator ig = ec.ig;
Expression instance_expr;
if (ec.IsStatic){
Location l = f.Location;
FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
fe.InstanceExpression = instance_expr;
- Expression a = new Assign (fe, e, l);
+ ExpressionStatement a = new Assign (fe, e, l);
- a = a.Resolve (ec);
+ a = a.ResolveStatement (ec);
if (a == null)
return false;
- if (a is ExpressionStatement)
- ((ExpressionStatement) a).EmitStatement (ec);
- else {
- throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
- }
+ a.EmitStatement (ec);
}
return true;
void DefineDefaultConstructor (bool is_static)
{
Constructor c;
- int mods = 0;
- c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
+ // The default constructor is public
+ // If the class is abstract, the default constructor is protected
+ // The default static constructor is private
+
+ int mods = Modifiers.PUBLIC;
+ if (is_static)
+ mods = Modifiers.STATIC | Modifiers.PRIVATE;
+ else if ((ModFlags & Modifiers.ABSTRACT) != 0)
+ mods = Modifiers.PROTECTED;
+
+ c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
new ConstructorBaseInitializer (
null, Parameters.EmptyReadOnlyParameters,
Location),
Location);
- if (is_static)
- mods = Modifiers.STATIC;
-
- c.ModFlags = mods;
-
AddConstructor (c);
- c.Block = new Block (null);
+ c.Block = new ToplevelBlock (null, Location);
}
/// The @parent argument is set to the parent object or null
/// if this is `System.Object'.
/// </summary>
- Type [] GetClassBases (bool is_class, out Type parent, out bool error)
+ TypeExpr [] GetClassBases (bool is_class, bool is_iface,
+ out TypeExpr parent, out bool error)
{
ArrayList bases = Bases;
int count;
error = false;
- if (is_class)
+ if (is_class || is_iface)
parent = null;
else
- parent = TypeManager.value_type;
+ parent = TypeManager.system_valuetype_expr;
if (bases == null){
if (is_class){
if (RootContext.StdLib)
- parent = TypeManager.object_type;
+ parent = TypeManager.system_object_expr;
else if (Name != "System.Object")
- parent = TypeManager.object_type;
+ parent = TypeManager.system_object_expr;
} else {
//
// If we are compiling our runtime,
// parent is `System.Object'.
//
if (!RootContext.StdLib && Name == "System.ValueType")
- parent = TypeManager.object_type;
+ parent = TypeManager.system_object_expr;
}
return null;
count = bases.Count;
if (is_class){
- Expression name = (Expression) bases [0];
- name = ResolveTypeExpr (name, false, Location);
+ TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
if (name == null){
error = true;
return null;
}
- Type first = name.Type;
-
- if (first.IsClass){
- parent = first;
+ if (name.IsClass){
+ parent = name;
start = 1;
- } else if (first.IsSealed){
+ } else {
+ parent = TypeManager.system_object_expr;
+ start = 0;
+ }
+ if (name.IsSealed){
string detail = "";
- if (first.IsValueType)
+ if (name.IsValueType)
detail = " (a class can not inherit from a struct/enum)";
Report.Error (509, "class `"+ Name +
"': Cannot inherit from sealed class `"+
- first + "'" + detail);
+ name.Name + "'" + detail);
+ error = true;
+ return null;
+ }
+
+ if (!parent.CanInheritFrom ()){
+ Report.Error (644, Location,
+ "`{0}' cannot inherit from special class `{1}'",
+ Name, parent.Name);
error = true;
return null;
- } else {
- parent = TypeManager.object_type;
- start = 0;
}
- if (!AsAccessible (parent, ModFlags))
+ if (!parent.AsAccessible (this, ModFlags))
Report.Error (60, Location,
"Inconsistent accessibility: base class `" +
- TypeManager.CSharpName (parent) + "' is less " +
- "accessible than class `" +
+ name.Name + "' is less accessible than class `" +
Name + "'");
} else {
start = 0;
}
- Type [] ifaces = new Type [count-start];
+ if (parent != null)
+ base_class_name = parent.Name;
+
+ TypeExpr [] ifaces = new TypeExpr [count-start];
for (i = start, j = 0; i < count; i++, j++){
Expression name = (Expression) bases [i];
- Expression resolved = ResolveTypeExpr (name, false, Location);
+ TypeExpr resolved = ResolveTypeExpr (name, false, Location);
if (resolved == null)
return null;
bases [i] = resolved;
- Type t = resolved.Type;
-
- if (t == null){
- error = true;
- return null;
- }
- if (is_class == false && !t.IsInterface){
+ if (is_class == false && !resolved.IsInterface){
Report.Error (527, "In Struct `" + Name + "', type `"+
name +"' is not an interface");
error = true;
return null;
}
- if (t.IsClass) {
+ if (resolved.IsClass) {
if (parent != null){
Report.Error (527, "In Class `" + Name + "', type `"+
name+"' is not an interface");
}
for (int x = 0; x < j; x++) {
- if (t == ifaces [x]) {
+ if (resolved.Equals (ifaces [x])) {
Report.Error (528, "`" + name + "' is already listed in interface list");
error = true;
return null;
}
}
- ifaces [j] = t;
+ if (is_iface &&
+ !resolved.AsAccessible (Parent, ModFlags))
+ Report.Error (61, Location,
+ "Inconsistent accessibility: base interface `" +
+ name + "' is less accessible than interface `" +
+ Name + "'");
+
+ ifaces [j] = resolved;
}
return TypeManager.ExpandInterfaces (ifaces);
}
+
+ bool error = false;
//
// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
//
public override TypeBuilder DefineType ()
{
- Type parent;
- bool error;
- bool is_class;
+ TypeExpr parent;
+ bool is_class, is_iface;
if (TypeBuilder != null)
return TypeBuilder;
+
+ if (error)
+ return null;
- if (InTransit)
+ 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
+ if (this is Interface) {
+ is_iface = true;
is_class = false;
+ } else {
+ is_iface = false;
+ if (this is Class)
+ is_class = true;
+ else
+ is_class = false;
+ }
ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
- ifaces = GetClassBases (is_class, out parent, out error);
-
+ ifaces = GetClassBases (is_class, is_iface, out parent, out error);
+
if (error)
return null;
- if (is_class && parent != null){
- if (parent == TypeManager.enum_type ||
- (parent == TypeManager.value_type && RootContext.StdLib) ||
- parent == TypeManager.delegate_type ||
- parent == TypeManager.array_type){
- Report.Error (
- 644, Location, "`" + Name + "' cannot inherit from " +
- "special class `" + TypeManager.CSharpName (parent) + "'");
- return null;
- }
- }
-
if (!is_class && TypeManager.value_type == null)
throw new Exception ();
TypeAttributes type_attributes = TypeAttr;
- // if (parent_builder is ModuleBuilder) {
+ if (parent != null)
+ base_classs_type = parent.ResolveType (ec);
+
if (IsTopLevel){
- if (TypeManager.NamespaceClash (Name))
+ if (TypeManager.NamespaceClash (Name, Location)) {
+ error = true;
return null;
+ }
- ModuleBuilder builder = CodeGen.ModuleBuilder;
+ ModuleBuilder builder = CodeGen.Module.Builder;
TypeBuilder = builder.DefineType (
- Name, type_attributes, parent, ifaces);
+ Name, type_attributes, base_classs_type, null);
} else {
- TypeBuilder builder = Parent.TypeBuilder;
+ TypeBuilder builder = Parent.DefineType ();
+ if (builder == null)
+ return null;
+
TypeBuilder = builder.DefineNestedType (
- Basename, type_attributes, parent, ifaces);
+ Basename, type_attributes, base_classs_type, null);
}
//
// be specified.
//
- if (!is_class && !have_nonstatic_fields){
+ if (!is_class && !is_iface && !have_nonstatic_fields){
TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
FieldAttributes.Private);
- // add interfaces that were not added at type creation
- if (ifaces != null) {
- foreach (Type i in ifaces)
- TypeBuilder.AddInterfaceImplementation (i);
+ }
+
+ // add interfaces that were not added at type creation
+ if (ifaces != null) {
+ base_inteface_types = new Type[ifaces.Length];
+ for (int i = 0; i < ifaces.Length; ++i) {
+ Type itype = ifaces [i].ResolveType (ec);
+ TypeBuilder.AddInterfaceImplementation (itype);
+ base_inteface_types [i] = itype;
}
}
TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
- if ((parent != null) &&
- (parent == TypeManager.attribute_type ||
- parent.IsSubclassOf (TypeManager.attribute_type))) {
+ if ((parent != null) && parent.IsAttribute) {
RootContext.RegisterAttribute (this);
- TypeManager.RegisterAttrType (TypeBuilder, this);
} else
RootContext.RegisterOrder (this);
if (Interfaces != null) {
foreach (Interface iface in Interfaces)
- iface.DefineType ();
+ if (iface.DefineType () == null) {
+ error = true;
+ return null;
+ }
}
if (Types != null) {
foreach (TypeContainer tc in Types)
- tc.DefineType ();
+ if (tc.DefineType () == null) {
+ error = true;
+ return null;
+ }
}
if (Delegates != null) {
foreach (Delegate d in Delegates)
- d.DefineType ();
+ if (d.DefineType () == null) {
+ error = true;
+ return null;
+ }
}
if (Enums != null) {
foreach (Enum en in Enums)
- en.DefineType ();
+ if (en.DefineType () == null) {
+ error = true;
+ return null;
+ }
}
InTransit = false;
remove_list.Clear ();
foreach (MemberCore mc in list){
- if (!mc.Define (this)){
- remove_list.Add (mc);
- continue;
- }
-
- if (defined_names == null)
- continue;
- idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
+ if (defined_names != null)
+ idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
+ else
+ idx = -1;
+
if (idx < 0){
if (RootContext.WarningLevel >= 4){
if ((mc.ModFlags & Modifiers.NEW) != 0)
- Warning_KewywordNewNotRequired (mc.Location, mc);
+ Warning_KeywordNewNotRequired (mc.Location, mc);
}
+ } else if (mc is MethodCore)
+ ((MethodCore) mc).OverridesSomething = true;
+
+ if (!mc.Define (this)){
+ remove_list.Add (mc);
continue;
}
+
+ if (idx < 0)
+ continue;
MemberInfo match = defined_names [idx];
//
if (match is MethodBase && mc is MethodCore)
continue;
-
- if ((mc.ModFlags & Modifiers.NEW) == 0)
+
+ 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)
//
// 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
+ // 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 DefaultName attribute is attached
+ // but it is never emitted, instead a DefaultMember attribute is attached
// to the class.
//
void DefineIndexers ()
{
string class_indexer_name = null;
-
- foreach (Indexer i in Indexers){
+
+ //
+ // 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
+ bool seen_normal_indexers = false;
+
+ foreach (Indexer i in Indexers) {
string name;
-
+
i.Define (this);
name = i.IndexerName;
- if (i.InterfaceType != null)
+ if (i.InterfaceType != null) {
+ if (seen_normal_indexers)
+ throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
continue;
+ }
- if (class_indexer_name == null){
+ seen_normal_indexers = true;
+
+ 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");
+ else if (name != class_indexer_name)
+ Report.Error (668, "Two indexers have different names, " +
+ " you should use the same name for all your indexers");
}
- if (class_indexer_name == null)
+
+ if (seen_normal_indexers && class_indexer_name == null)
class_indexer_name = "Item";
IndexerName = class_indexer_name;
}
/// Populates our TypeBuilder with fields and methods
/// </summary>
public override bool DefineMembers (TypeContainer container)
+ {
+ if (members_defined)
+ return members_defined_ok;
+
+ members_defined_ok = DoDefineMembers ();
+ members_defined = true;
+
+ return members_defined_ok;
+ }
+
+ bool DoDefineMembers ()
{
MemberInfo [] defined_names = null;
+ //
+ // We need to be able to use the member cache while we are checking/defining
+ //
+#if CACHE
+ if (TypeBuilder.BaseType != null)
+ parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
+#endif
+
if (interface_order != null){
foreach (Interface iface in interface_order)
if ((iface.ModFlags & Modifiers.NEW) == 0)
Array.Sort (defined_names, mif_compare);
}
}
-
+
+ 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);
ReportStructInitializedInstanceError ();
}
- Pending = PendingImplementation.GetPendingImplementations (this);
+ if (!(this is Interface))
+ Pending = PendingImplementation.GetPendingImplementations (this);
//
// Constructors are not in the defined_names array
if (events != null)
DefineMembers (events, defined_names);
- if (indexers != null) {
+ if (indexers != null)
DefineIndexers ();
- } else
- IndexerName = "Item";
if (operators != null){
DefineMembers (operators, null);
DefineMembers (delegates, defined_names);
#if CACHE
- if (TypeBuilder.BaseType != null)
- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
-
member_cache = new MemberCache (this);
#endif
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;
+ }
/// <summary>
/// This method returns the members of this type just like Type.FindMembers would
public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
MemberFilter filter, object criteria)
{
- ArrayList members = new ArrayList ();
+ ArrayList members = null;
int modflags = 0;
if ((bf & BindingFlags.Public) != 0)
if ((mt & MemberTypes.Field) != 0) {
if (fields != null) {
- foreach (Field f in fields) {
+ int len = fields.Count;
+ for (int i = 0; i < len; i++) {
+ Field f = (Field) fields [i];
+
if ((f.ModFlags & modflags) == 0)
continue;
if ((f.ModFlags & static_mask) != static_flags)
continue;
FieldBuilder fb = f.FieldBuilder;
- if (fb != null && filter (fb, criteria) == true)
+ if (fb != null && filter (fb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (fb);
+ }
}
}
if (constants != null) {
- foreach (Const con in constants) {
+ int len = constants.Count;
+ for (int i = 0; i < len; i++) {
+ Const con = (Const) constants [i];
+
if ((con.ModFlags & modflags) == 0)
continue;
if ((con.ModFlags & static_mask) != static_flags)
continue;
FieldBuilder fb = con.FieldBuilder;
- if (fb != null && filter (fb, criteria) == true)
+ if (fb != null && filter (fb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (fb);
+ }
}
}
}
if ((mt & MemberTypes.Method) != 0) {
if (methods != null) {
- foreach (Method m in methods) {
+ int len = methods.Count;
+ for (int i = 0; i < len; i++) {
+ Method m = (Method) methods [i];
+
if ((m.ModFlags & modflags) == 0)
continue;
if ((m.ModFlags & static_mask) != static_flags)
MethodBuilder mb = m.MethodBuilder;
- if (mb != null && filter (mb, criteria) == true)
- members.Add (mb);
+ if (mb != null && filter (mb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
+ members.Add (mb);
+ }
}
}
- if (operators != null){
- foreach (Operator o in operators) {
+ if (operators != null) {
+ int len = operators.Count;
+ for (int i = 0; i < len; i++) {
+ Operator o = (Operator) operators [i];
+
if ((o.ModFlags & modflags) == 0)
continue;
if ((o.ModFlags & static_mask) != static_flags)
continue;
MethodBuilder ob = o.OperatorMethodBuilder;
- if (ob != null && filter (ob, criteria) == true)
+ if (ob != null && filter (ob, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (ob);
+ }
}
}
- if (properties != null){
- foreach (Property p in properties){
+ if (properties != null) {
+ int len = properties.Count;
+ for (int i = 0; i < len; i++) {
+ Property p = (Property) properties [i];
+
if ((p.ModFlags & modflags) == 0)
continue;
if ((p.ModFlags & static_mask) != static_flags)
MethodBuilder b;
b = p.GetBuilder;
- if (b != null && filter (b, criteria) == true)
+ if (b != null && filter (b, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (b);
+ }
b = p.SetBuilder;
- if (b != null && filter (b, criteria) == true)
+ if (b != null && filter (b, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (b);
+ }
}
}
- if (indexers != null){
- foreach (Indexer ix in indexers){
+ if (indexers != null) {
+ int len = indexers.Count;
+ for (int i = 0; i < len; i++) {
+ Indexer ix = (Indexer) indexers [i];
+
if ((ix.ModFlags & modflags) == 0)
continue;
if ((ix.ModFlags & static_mask) != static_flags)
MethodBuilder b;
b = ix.GetBuilder;
- if (b != null && filter (b, criteria) == true)
+ if (b != null && filter (b, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (b);
+ }
b = ix.SetBuilder;
- if (b != null && filter (b, criteria) == true)
+ if (b != null && filter (b, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (b);
+ }
}
}
}
if ((mt & MemberTypes.Event) != 0) {
- if (events != null)
- foreach (Event e in events) {
+ if (events != null) {
+ int len = events.Count;
+ for (int i = 0; i < len; i++) {
+ Event e = (Event) events [i];
+
if ((e.ModFlags & modflags) == 0)
continue;
if ((e.ModFlags & static_mask) != static_flags)
continue;
MemberInfo eb = e.EventBuilder;
- if (eb != null && filter (eb, criteria) == true)
+ if (eb != null && filter (eb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (e.EventBuilder);
+ }
}
+ }
}
if ((mt & MemberTypes.Property) != 0){
- if (properties != null)
- foreach (Property p in properties) {
+ if (properties != null) {
+ int len = properties.Count;
+ for (int i = 0; i < len; i++) {
+ Property p = (Property) properties [i];
+
if ((p.ModFlags & modflags) == 0)
continue;
if ((p.ModFlags & static_mask) != static_flags)
MemberInfo pb = p.PropertyBuilder;
if (pb != null && filter (pb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (p.PropertyBuilder);
}
}
+ }
- if (indexers != null)
- foreach (Indexer ix in indexers) {
+ if (indexers != null) {
+ int len = indexers.Count;
+ for (int i = 0; i < len; i++) {
+ Indexer ix = (Indexer) indexers [i];
+
if ((ix.ModFlags & modflags) == 0)
continue;
if ((ix.ModFlags & static_mask) != static_flags)
MemberInfo ib = ix.PropertyBuilder;
if (ib != null && filter (ib, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (ix.PropertyBuilder);
}
}
+ }
}
if ((mt & MemberTypes.NestedType) != 0) {
- if (types != null){
- foreach (TypeContainer t in types) {
+ if (types != null) {
+ int len = types.Count;
+ for (int i = 0; i < len; i++) {
+ TypeContainer t = (TypeContainer) types [i];
+
if ((t.ModFlags & modflags) == 0)
continue;
TypeBuilder tb = t.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
- members.Add (tb);
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
+ members.Add (tb);
+ }
}
}
- if (enums != null){
- foreach (Enum en in enums){
+ if (enums != null) {
+ int len = enums.Count;
+ for (int i = 0; i < len; i++) {
+ Enum en = (Enum) enums [i];
+
if ((en.ModFlags & modflags) == 0)
continue;
TypeBuilder tb = en.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (tb);
+ }
}
}
- if (delegates != null){
- foreach (Delegate d in delegates){
+ if (delegates != null) {
+ int len = delegates.Count;
+ for (int i = 0; i < len; i++) {
+ Delegate d = (Delegate) delegates [i];
+
if ((d.ModFlags & modflags) == 0)
continue;
TypeBuilder tb = d.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (tb);
+ }
}
}
- if (interfaces != null){
- foreach (Interface iface in interfaces){
+ if (interfaces != null) {
+ int len = interfaces.Count;
+ for (int i = 0; i < len; i++) {
+ Interface iface = (Interface) interfaces [i];
+
if ((iface.ModFlags & modflags) == 0)
continue;
TypeBuilder tb = iface.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true))
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (tb);
+ }
}
}
}
if ((mt & MemberTypes.Constructor) != 0){
if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
- foreach (Constructor c in instance_constructors){
+ int len = instance_constructors.Count;
+ for (int i = 0; i < len; i++) {
+ Constructor c = (Constructor) instance_constructors [i];
+
ConstructorBuilder cb = c.ConstructorBuilder;
- if (cb != null)
- if (filter (cb, criteria) == true)
- members.Add (cb);
+ if (cb != null && filter (cb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
+ members.Add (cb);
+ }
}
}
ConstructorBuilder cb =
default_static_constructor.ConstructorBuilder;
- if (cb != null)
- if (filter (cb, criteria) == true)
+ if (cb != null && filter (cb, criteria) == true) {
+ if (members == null)
+ members = new ArrayList ();
+
members.Add (cb);
+ }
}
}
//
// Lookup members in parent if requested.
//
- if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
- MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
- members.AddRange (list);
+ 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)
+ members = new ArrayList ();
+
+ members.AddRange (list);
+ }
+ }
+ if (base_inteface_types != null) {
+ foreach (Type base_type in base_inteface_types) {
+ MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria);
+
+ if (list.Count > 0) {
+ if (members == null)
+ members = new ArrayList ();
+ members.AddRange (list);
+ }
+ }
+ }
}
Timer.StopTimer (TimerType.TcFindMembers);
- return new MemberList (members);
+ if (members == null)
+ return MemberList.Empty;
+ else
+ return new MemberList (members);
}
public override MemberCache MemberCache {
public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
MemberFilter filter, object criteria)
{
- TypeContainer tc = TypeManager.LookupTypeContainer (t);
+ DeclSpace ds = TypeManager.LookupDeclSpace (t);
- if (tc != null)
- return tc.FindMembers (mt, bf, filter, criteria);
+ if (ds != null)
+ return ds.FindMembers (mt, bf, filter, criteria);
else
return new MemberList (t.FindMembers (mt, bf, filter, criteria));
- }
+
+ }
//
// FindMethods will look for methods not only in the type `t', but in
{
if (constants != null)
foreach (Const con in constants)
- con.EmitConstant (this);
+ con.Emit (this);
return;
}
- /// <summary>
- /// Emits the code, this step is performed after all
- /// the types, enumerations, constructors
- /// </summary>
- public void Emit ()
+ protected virtual void VerifyMembers (EmitContext ec)
{
- if (instance_constructors != null)
- foreach (Constructor c in instance_constructors)
- c.Emit (this);
-
- if (default_static_constructor != null)
- default_static_constructor.Emit (this);
-
- if (methods != null)
- foreach (Method m in methods)
- m.Emit (this);
-
- if (operators != null)
- foreach (Operator o in operators)
- o.Emit (this);
-
- if (properties != null)
- foreach (Property p in properties)
- p.Emit (this);
-
- if (indexers != null){
- foreach (Indexer ix in indexers)
- ix.Emit (this);
-
- CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
- this, IndexerName, ModFlags, Location);
- TypeBuilder.SetCustomAttribute (cb);
- }
-
- if (fields != null)
- foreach (Field f in fields)
- f.Emit (this);
-
- if (events != null){
- foreach (Event e in Events)
- e.Emit (this);
- }
-
- 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.PUBLIC) != 0)
+ if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
continue;
- if (f.status == 0){
+ if ((f.status & Field.Status.USED) == 0){
Report.Warning (
169, f.Location, "Private field " +
MakeName (f.Name) + " is never used");
}
}
}
+ }
+
+ /// <summary>
+ /// Emits the code, this step is performed after all
+ /// the types, enumerations, constructors
+ /// </summary>
+ public void Emit ()
+ {
+ if (OptAttributes != null)
+ OptAttributes.Emit (ec, this);
+
+ Emit (this);
+
+ if (instance_constructors != null) {
+ if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && IsClsCompliaceRequired (this)) {
+ bool has_compliant_args = false;
+
+ foreach (Constructor c in instance_constructors) {
+ c.Emit (this);
+
+ if (has_compliant_args)
+ continue;
+
+ has_compliant_args = c.HasCompliantArgs;
+ }
+ if (!has_compliant_args)
+ Report.Error_T (3015, Location, GetSignatureForError ());
+ } else {
+ foreach (Constructor c in instance_constructors)
+ c.Emit (this);
+ }
+ }
+
+ if (default_static_constructor != null)
+ default_static_constructor.Emit (this);
+
+ if (methods != null)
+ foreach (Method m in methods)
+ m.Emit (this);
+
+ if (operators != null)
+ foreach (Operator o in operators)
+ o.Emit (this);
+
+ if (properties != null)
+ foreach (Property p in properties)
+ p.Emit (this);
+
+ if (indexers != null){
+ foreach (Indexer ix in indexers)
+ ix.Emit (this);
+ if (IndexerName != null) {
+ CustomAttributeBuilder cb = EmitDefaultMemberAttr ();
+ TypeBuilder.SetCustomAttribute (cb);
+ }
+ }
+
+ if (fields != null)
+ foreach (Field f in fields)
+ f.Emit (this);
+
+ if (events != null){
+ foreach (Event e in Events)
+ e.Emit (this);
+ }
+
+ if (delegates != null) {
+ foreach (Delegate d in Delegates) {
+ d.Emit (this);
+ }
+ }
+
+ if (Pending != null)
+ if (Pending.VerifyPendingMethods ())
+ return;
+
+ VerifyMembers (ec);
// if (types != null)
// foreach (TypeContainer tc in types)
// tc.Emit ();
}
-
+
+ CustomAttributeBuilder EmitDefaultMemberAttr ()
+ {
+ EmitContext ec = new EmitContext (this, Location, null, null, ModFlags);
+
+ Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
+ ".ctor", MemberTypes.Constructor,
+ BindingFlags.Public | BindingFlags.Instance,
+ Location.Null);
+
+ MethodGroupExpr mg = (MethodGroupExpr) ml;
+
+ MethodBase constructor = mg.Methods [0];
+
+ string [] vals = { IndexerName };
+
+ CustomAttributeBuilder cb = null;
+ try {
+ cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
+ } catch {
+ Report.Warning (-100, "Can not set the indexer default member attribute");
+ }
+
+ return cb;
+ }
+
public override void CloseType ()
{
+ if ((caching_flags & Flags.CloseTypeCreated) != 0)
+ return;
+
try {
- if (!Created){
- Created = true;
- TypeBuilder.CreateType ();
- }
+ caching_flags |= Flags.CloseTypeCreated;
+ TypeBuilder.CreateType ();
} catch (TypeLoadException){
//
// This is fine, the code still created the type
if (Delegates != null)
foreach (Delegate d in Delegates)
d.CloseType ();
+
+ types = null;
+ properties = null;
+ enums = null;
+ delegates = null;
+ fields = null;
+ initialized_fields = null;
+ initialized_static_fields = null;
+ constants = null;
+ interfaces = null;
+ interface_order = null;
+ methods = null;
+ events = null;
+ indexers = null;
+ operators = null;
+ ec = null;
+ default_constructor = null;
+ default_static_constructor = null;
+ type_bases = null;
+ OptAttributes = null;
+ ifaces = null;
+ parent_container = null;
+ member_cache = null;
}
public string MakeName (string n)
mi.ReflectedType.Name + "." + mi.Name + "'");
}
- public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
+ 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 ok;
}
- // Access level of a type.
- enum AccessLevel {
- Public = 0,
- ProtectedInternal = 1,
- Internal = 2,
- Protected = 3,
- Private = 4
- }
-
- // Check whether `flags' denotes a more restricted access than `level'
- // and return the new level.
- static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
- {
- AccessLevel old_level = level;
-
- if ((flags & Modifiers.INTERNAL) != 0) {
- if ((flags & Modifiers.PROTECTED) != 0) {
- if ((int) level < (int) AccessLevel.ProtectedInternal)
- level = AccessLevel.ProtectedInternal;
- } else {
- if ((int) level < (int) AccessLevel.Internal)
- level = AccessLevel.Internal;
- }
- } else if ((flags & Modifiers.PROTECTED) != 0) {
- if ((int) level < (int) AccessLevel.Protected)
- level = AccessLevel.Protected;
- } else if ((flags & Modifiers.PRIVATE) != 0)
- level = AccessLevel.Private;
-
- return level;
- }
-
- // Return the access level for a new member which is defined in the current
- // TypeContainer with access modifiers `flags'.
- AccessLevel GetAccessLevel (int flags)
- {
- if ((flags & Modifiers.PRIVATE) != 0)
- return AccessLevel.Private;
-
- AccessLevel level;
- if (!IsTopLevel && (Parent != null))
- level = Parent.GetAccessLevel (flags);
- else
- level = AccessLevel.Public;
-
- return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
- }
-
- // Return the access level for type `t', but don't give more access than `flags'.
- static AccessLevel GetAccessLevel (Type t, int flags)
- {
- if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
- return AccessLevel.Private;
-
- AccessLevel level;
- if (TypeManager.IsBuiltinType (t))
- return AccessLevel.Public;
- else if ((t.DeclaringType != null) && (t != t.DeclaringType))
- level = GetAccessLevel (t.DeclaringType, flags);
- else {
- level = CheckAccessLevel (AccessLevel.Public, flags);
- }
-
- if (t.IsNestedPublic)
- return level;
-
- if (t.IsNestedAssembly || t.IsNotPublic) {
- if ((int) level < (int) AccessLevel.Internal)
- level = AccessLevel.Internal;
- }
-
- if (t.IsNestedFamily) {
- if ((int) level < (int) AccessLevel.Protected)
- level = AccessLevel.Protected;
- }
-
- if (t.IsNestedFamORAssem) {
- if ((int) level < (int) AccessLevel.ProtectedInternal)
- level = AccessLevel.ProtectedInternal;
- }
-
- return level;
- }
-
- //
- // Returns true if `parent' is as accessible as the flags `flags'
- // given for this member.
- //
- public bool AsAccessible (Type parent, int flags)
- {
- while (parent.IsArray || parent.IsPointer || parent.IsByRef)
- parent = parent.GetElementType ();
-
- AccessLevel level = GetAccessLevel (flags);
- AccessLevel level2 = GetAccessLevel (parent, flags);
-
- return (int) level >= (int) level2;
- }
-
Hashtable builder_and_args;
public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
return true;
}
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ // parent_container is null for System.Object
+ if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
+ Report.Error_T (3009, Location, GetSignatureForError (), TypeManager.CSharpName (parent_container.Type));
+ }
+ return true;
+ }
+
+
/// <summary>
/// Performs checks for an explicit interface implementation. First it
/// checks whether the `interface_type' is a base inteface implementation.
bool found = false;
if (ifaces != null){
- foreach (Type t in ifaces){
- if (t == interface_type){
+ foreach (TypeExpr t in ifaces){
+ if (t.Type == interface_type){
found = true;
break;
}
return true;
}
- public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
- {
- Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
- }
-
//
// IMemberContainer
//
bool IMemberContainer.IsInterface {
get {
- return false;
+ return this is Interface;
}
}
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){
switch (op.OperatorType){
case Operator.OpType.Equality:
- reg = 1; break;
+ reg = 1;
+ has_equality_or_inequality = true;
+ break;
case Operator.OpType.Inequality:
- reg = 2; break;
+ reg = 2;
+ has_equality_or_inequality = true;
+ break;
case Operator.OpType.True:
true_op = op;
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)) {
+ 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]);
+
+ 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);
+
+ 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 (!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 class Class : TypeContainer {
+ public class ClassOrStruct : TypeContainer {
+ bool hasExplicitLayout = false;
+ public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
+ {
+ }
+
+ 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);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.struct_layout_attribute_type
+ && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
+ hasExplicitLayout = true;
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+ }
+
+ public class Class : ClassOrStruct {
// <summary>
// Modifiers allowed in a class declaration
// </summary>
Modifiers.SEALED |
Modifiers.UNSAFE;
- public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (parent, name, l)
+
+ // Information in the case we are an attribute type
+ AttributeUsageAttribute attribute_usage;
+
+ public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod,
+ Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
{
int accmods;
accmods = Modifiers.PRIVATE;
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
- this.attributes = attrs;
+ 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)
+ attribute_usage = a.UsageAttribute;
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public AttributeUsageAttribute AttributeUsage {
+ get {
+ return attribute_usage;
+ }
}
//
}
}
- public class Struct : TypeContainer {
+ public class Struct : ClassOrStruct {
// <summary>
// Modifiers allowed in a struct declaration
// </summary>
Modifiers.UNSAFE |
Modifiers.PRIVATE;
- public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
- : base (parent, name, l)
+ public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
{
int accmods;
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
this.ModFlags |= Modifiers.SEALED;
- this.attributes = attrs;
-
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Struct;
+ }
+ }
+
+
//
// FIXME: Allow the user to specify a different set of attributes
// in some cases (Sealed for example is mandatory for a class,
}
}
+ /// <summary>
+ /// Interfaces
+ /// </summary>
+ public class Interface : TypeContainer, IMemberContainer {
+ /// <summary>
+ /// Modifiers allowed in a class declaration
+ /// </summary>
+ public const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.UNSAFE |
+ Modifiers.PRIVATE;
+
+ public Interface (NamespaceEntry ns, TypeContainer parent, string name, int mod,
+ Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
+ {
+ int accmods;
+
+ if (parent.Parent == null)
+ accmods = Modifiers.INTERNAL;
+ else
+ accmods = Modifiers.PRIVATE;
+
+ this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Interface;
+ }
+ }
+
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr |
+ TypeAttributes.AutoLayout |
+ TypeAttributes.Abstract |
+ TypeAttributes.Interface;
+ }
+ }
+ }
+
public abstract class MethodCore : MemberBase {
public readonly Parameters Parameters;
protected Block block;
+ public DeclSpace ds;
//
// Parameters, cached for semantic analysis.
protected InternalParameters parameter_info;
protected Type [] parameter_types;
- public MethodCore (Expression type, int mod, int allowed_mod, string name,
- Attributes attrs, Parameters parameters, Location loc)
- : base (type, mod, allowed_mod, name, attrs, loc)
+ // <summary>
+ // This is set from TypeContainer.DefineMembers if this method overrides something.
+ // </summary>
+ public bool OverridesSomething;
+
+ // Whether this is an operator method.
+ public bool IsOperator;
+
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
+ bool is_interface, string name, Attributes attrs,
+ Parameters parameters, Location loc)
+ : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
{
Parameters = parameters;
+ IsInterface = is_interface;
+ this.ds = ds;
}
//
}
}
- protected virtual bool DoDefineParameters (TypeContainer container)
+ protected virtual bool DoDefineParameters ()
{
// Check if arguments were correct
- parameter_types = Parameters.GetParameterInfo (container);
- if ((parameter_types == null) || !CheckParameters (container, parameter_types))
+ parameter_types = Parameters.GetParameterInfo (ds);
+ if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
return false;
- parameter_info = new InternalParameters (container, Parameters);
+ parameter_info = new InternalParameters (ds, Parameters);
+
+ Parameter array_param = Parameters.ArrayParameter;
+ if ((array_param != null) &&
+ (!array_param.ParameterType.IsArray ||
+ (array_param.ParameterType.GetArrayRank () != 1))) {
+ Report.Error (225, Location, "params parameter has to be a single dimensional array");
+ return false;
+ }
return true;
}
- public CallingConventions GetCallingConvention (bool is_class)
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
{
- CallingConventions cc = 0;
-
- cc = Parameters.GetCallingConvention ();
+ if (!base.VerifyClsCompliance (ds)) {
+ if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
+ Report.Error_T (3011, Location, GetSignatureForError ());
+ }
+ return false;
+ }
- if (is_class)
- if ((ModFlags & Modifiers.STATIC) == 0)
- cc |= CallingConventions.HasThis;
+ AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
- // FIXME: How is `ExplicitThis' used in C#?
-
- return cc;
+ if (!AttributeTester.IsClsCompliant (MemberType)) {
+ Report.Error_T (3002, Location, GetSignatureForError ());
+ }
+
+ 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
- //
- public void LabelParameters (EmitContext ec, MethodBase builder, Attributes method_attrs)
+ protected bool IsDuplicateImplementation (TypeContainer tc, MethodCore method)
{
- //
- // 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 (builder is MethodBuilder)
- mb = (MethodBuilder) builder;
- else
- cb = (ConstructorBuilder) builder;
+ if ((method == this) || (method.Name != Name))
+ return false;
- 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);
+ Type[] param_types = method.ParameterTypes;
+ if (param_types == null)
+ return false;
- if (par_attr == ParameterAttributes.Out){
- if (attr.Contains (TypeManager.in_attribute_type))
- Report.Error (36, Location, "Can not use [In] attribute on out parameter");
- }
- }
- }
- }
+ if (param_types.Length != ParameterTypes.Length)
+ return false;
- if (Parameters.ArrayParameter != null){
- ParameterBuilder pb;
- Parameter array_param = Parameters.ArrayParameter;
-
- 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);
- }
+ for (int i = 0; i < param_types.Length; i++)
+ if (param_types [i] != ParameterTypes [i])
+ return false;
//
- // And now for the return type attribute decoration
+ // Try to report 663: method only differs on out/ref
//
- ParameterBuilder ret_pb;
- Attributes ret_attrs = null;
-
- if (mb == null || method_attrs == null)
- return;
+ 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;
+ }
+ }
- foreach (AttributeSection asec in method_attrs.AttributeSections) {
+ Report.Error (111, Location, "Class `{0}' already defines a " +
+ "member called `{1}' with the same parameter types",
+ tc.Name, Name);
+ return true;
+ }
- if (asec.Target != "return")
- continue;
+ public CallingConventions GetCallingConvention (bool is_class)
+ {
+ CallingConventions cc = 0;
+
+ cc = Parameters.GetCallingConvention ();
- if (ret_attrs == null)
- ret_attrs = new Attributes (asec);
- else
- ret_attrs.AddAttributeSection (asec);
- }
+ if (is_class)
+ if ((ModFlags & Modifiers.STATIC) == 0)
+ cc |= CallingConventions.HasThis;
- if (ret_attrs != null) {
- try {
- ret_pb = mb.DefineParameter (0, ParameterAttributes.None, "");
- Attribute.ApplyAttributes (ec, ret_pb, ret_pb, ret_attrs);
- } catch (ArgumentOutOfRangeException) {
- Report.Warning (
- -24, Location,
- ".NET SDK 1.0 does not permit to set custom attributes to the return type of a method");
- }
- }
+ // FIXME: How is `ExplicitThis' used in C#?
+
+ return cc;
}
}
- public class Method : MethodCore, IIteratorContainer {
+ public class Method : MethodCore, IIteratorContainer, IMethodData {
public MethodBuilder MethodBuilder;
public MethodData MethodData;
+ ReturnParameter return_attributes;
/// <summary>
/// Modifiers allowed in a class declaration
Modifiers.OVERRIDE |
Modifiers.ABSTRACT |
Modifiers.UNSAFE |
+ Modifiers.METHOD_YIELDS |
Modifiers.EXTERN;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW | Modifiers.UNSAFE;
+
//
// return_type can be "null" for VOID values.
//
- public Method (Expression return_type, int mod, string name, Parameters parameters,
- Attributes attrs, Location l)
- : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
- { }
+ public Method (DeclSpace ds, Expression return_type, int mod, bool is_iface,
+ string name, Parameters parameters, Attributes attrs, Location l)
+ : base (ds, return_type, mod,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, name, attrs, parameters, l)
+ {
+ }
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method | AttributeTargets.ReturnValue;
+ }
+ }
+
//
// Returns the `System.Type' for the ReturnType of this
// function. Provides a nice cache. (used between semantic analysis
return MemberType;
}
- // Whether this is an operator method.
- public bool IsOperator;
+ public override string GetSignatureForError()
+ {
+ return TypeManager.CSharpSignature (MethodBuilder);
+ }
void DuplicateEntryPoint (MethodInfo b, Location location)
{
Type t = pinfo.ParameterType(0);
if (t.IsArray &&
(t.GetArrayRank() == 1) &&
- (t.GetElementType() == TypeManager.string_type) &&
+ (TypeManager.GetElementType(t) == TypeManager.string_type) &&
(pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
return true;
else
return false;
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+ MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
+ }
+
+ if (a.Type == TypeManager.dllimport_type)
+ return;
+
+ MethodBuilder.SetCustomAttribute (cb);
+ }
+
//
// Checks our base implementation if any
//
base.CheckBase (container);
// Check whether arguments were correct.
- if (!DoDefineParameters (container))
+ if (!DoDefineParameters ())
return false;
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;
+ //
+ // Check in our class for dups
+ //
+ ArrayList ar = container.Methods;
+ if (ar != null) {
+ int arLen = ar.Count;
+
+ for (int i = 0; i < arLen; i++) {
+ Method m = (Method) ar [i];
+ if (IsDuplicateImplementation (container, m))
+ return false;
+ }
}
- }
+ }
+
//
// Verify if the parent has a type with the same name, and then
Type ptype = container.TypeBuilder.BaseType;
// ptype is only null for System.Object while compiling corlib.
- if (ptype != null){
- MemberList mi, mi_static, mi_instance;
-
- mi_instance = TypeContainer.FindMembers (
- ptype, MemberTypes.Method,
- BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
- MethodSignature.inheritable_method_signature_filter,
- ms);
-
- 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 (mi_static.Count > 0)
- mi = mi_static;
- else
- mi = null;
+ if (ptype != null) {
+
+ //
+ // Explicit implementations do not have `parent' methods, however,
+ // the member cache stores them there. Without this check, we get
+ // an incorrect warning in corlib.
+ //
+ if (! IsExplicitImpl) {
+ parent_method = (MethodInfo)((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
+ container.TypeBuilder, Name, ParameterTypes, false);
}
-
- if (mi != null && mi.Count > 0){
- parent_method = (MethodInfo) mi [0];
+
+ if (parent_method != null) {
string name = parent_method.DeclaringType.Name + "." +
parent_method.Name;
}
}
} else {
- if ((ModFlags & Modifiers.NEW) != 0)
+ if (!OverridesSomething && ((ModFlags & Modifiers.NEW) != 0))
WarningNotHiding (container);
if ((ModFlags & Modifiers.OVERRIDE) != 0){
if (!CheckBase (container))
return false;
- CallingConventions cc = GetCallingConvention (container is Class);
-
- MethodData = new MethodData (this, null, MemberType, ParameterTypes,
- ParameterInfo, cc, OptAttributes,
- ModFlags, flags, true);
+ MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, true, this);
if (!MethodData.Define (container))
return false;
// This is used to track the Entry Point,
//
if (Name == "Main" &&
- ((ModFlags & Modifiers.STATIC) != 0) &&
+ ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint &&
(RootContext.MainClass == null ||
RootContext.MainClass == container.TypeBuilder.FullName)){
if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
//
// Emits the code
//
- public void Emit (TypeContainer container)
+ public override void Emit (TypeContainer container)
{
- MethodData.Emit (container, Block, this);
+ MethodData.Emit (container, this);
+ base.Emit (container);
Block = null;
+ MethodData = null;
}
void IIteratorContainer.SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;
}
+
+ protected override bool IsIdentifierClsCompliant (DeclSpace ds)
+ {
+ return IsIdentifierAndParamClsCompliant (ds, Name, MethodBuilder, parameter_types);
+ }
+
+ #region IMethodData Members
+
+ public CallingConventions CallingConventions {
+ get {
+ CallingConventions cc = Parameters.GetCallingConvention ();
+
+ 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 string MethodName {
+ get {
+ return ShortName;
+ }
+ }
+
+ 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);
+ }
+ #endregion
}
public abstract class ConstructorInitializer {
ArrayList argument_list;
- ConstructorInfo parent_constructor;
+ protected ConstructorInfo parent_constructor;
Parameters parameters;
Location loc;
}
}
- public bool Resolve (EmitContext ec)
+ public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
{
Expression parent_constructor_group;
Type t;
- ec.CurrentBlock = new Block (null, Block.Flags.Implicit, parameters);
+ ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
if (argument_list != null){
foreach (Argument a in argument_list){
t = ec.ContainerType;
parent_constructor_group = Expression.MemberLookup (
- ec, t, null, t, ".ctor",
- 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;
}
"Can not find a constructor for this argument list");
return false;
}
+
+ if (parent_constructor == caller_builder){
+ Report.Error (515, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
+ return false;
+ }
return true;
}
if (ec.IsStatic)
Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
else
- Invocation.EmitCall (ec, true, false, ec.This, parent_constructor, argument_list, loc);
+ Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
+ }
+ }
+
+ /// <summary>
+ /// Method search for base ctor. (We do not cache it).
+ /// </summary>
+ 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;
+ }
+
+ if (c.ParameterTypes.Length != Arguments.Count)
+ continue;
+
+ for (int i = 0; i < Arguments.Count; ++i)
+ if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type)
+ continue;
+
+ return c;
}
+
+ throw new InternalErrorException ();
+ }
+
+ //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);
}
}
base (argument_list, pars, l)
{
}
+
+ public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
+ if (parent_constructor == null)
+ return;
+
+ TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_classs_type);
+ 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 {
public class Constructor : MethodCore {
public ConstructorBuilder ConstructorBuilder;
public ConstructorInitializer Initializer;
- new public Attributes OptAttributes;
// <summary>
// Modifiers allowed for a constructor.
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 (string name, Parameters args, ConstructorInitializer init, Location l)
- : base (null, 0, AllowedModifiers, name, null, args, l)
+ public Constructor (DeclSpace ds, string name, int mod, Parameters args,
+ ConstructorInitializer init, Location l)
+ : base (ds, null, mod, AllowedModifiers, false, name, null, args, l)
{
Initializer = init;
}
+ public override string GetSignatureForError()
+ {
+ 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
//
(Initializer.Arguments == null);
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ ConstructorBuilder.SetCustomAttribute (cb);
+ }
+
+ protected override bool CheckBase (TypeContainer container)
+ {
+ base.CheckBase (container);
+
+ // Check whether arguments were correct.
+ if (!DoDefineParameters ())
+ return false;
+
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ return true;
+
+ if (container is Struct && ParameterTypes.Length == 0) {
+ Report.Error (568, Location,
+ "Structs can not contain explicit parameterless " +
+ "constructors");
+ return false;
+ }
+
+ //
+ // Check in our class for dups
+ //
+ ArrayList ar = container.InstanceConstructors;
+ if (ar != null) {
+ int arLen = ar.Count;
+
+ for (int i = 0; i < arLen; i++) {
+ Constructor m = (Constructor) ar [i];
+ if (IsDuplicateImplementation (container, m))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
//
// Creates the ConstructorBuilder
//
{
MethodAttributes ca = (MethodAttributes.RTSpecialName |
MethodAttributes.SpecialName);
-
- // Check if arguments were correct.
- if (!DoDefineParameters (container))
- return false;
-
- if ((ModFlags & Modifiers.STATIC) != 0)
- ca |= MethodAttributes.Static;
- else {
- if (container is Struct && ParameterTypes.Length == 0){
- Report.Error (
- 568, Location,
- "Structs can not contain explicit parameterless " +
- "constructors");
- return false;
- }
+
+ if ((ModFlags & Modifiers.STATIC) != 0) {
+ ca |= MethodAttributes.Static | MethodAttributes.Private;
+ } else {
ca |= MethodAttributes.HideBySig;
if ((ModFlags & Modifiers.PUBLIC) != 0)
else
ca |= MethodAttributes.Private;
}
+
+ // Check if arguments were correct.
+ if (!CheckBase (container))
+ return false;
ConstructorBuilder = container.TypeBuilder.DefineConstructor (
ca, GetCallingConvention (container is Class), ParameterTypes);
+ if ((ModFlags & Modifiers.UNSAFE) != 0)
+ ConstructorBuilder.InitLocals = false;
+
//
// 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;
}
//
// Emits the code
//
- public void Emit (TypeContainer container)
+ public override void Emit (TypeContainer container)
{
ILGenerator ig = ConstructorBuilder.GetILGenerator ();
EmitContext ec = new EmitContext (container, Location, ig, null, ModFlags, true);
// `this' access
//
ec.IsStatic = true;
- if (Initializer != null && !Initializer.Resolve (ec))
+ if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
return;
ec.IsStatic = false;
}
- LabelParameters (ec, ConstructorBuilder, OptAttributes);
+ 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)) {
-
+ !Location.IsNull (block.EndLocation) &&
+ (Location.SymbolDocument != null)) {
sw.OpenMethod (container, ConstructorBuilder, Location, block.EndLocation);
generate_debugging = true;
// Classes can have base initializers and instance field initializers.
//
if (container is Class){
- if ((ModFlags & Modifiers.STATIC) == 0)
- container.EmitFieldInitializers (ec);
+ if ((ModFlags & Modifiers.STATIC) == 0){
+
+ //
+ // If we use a "this (...)" constructor initializer, then
+ // do not emit field initializers, they are initialized in the other constructor
+ //
+ if (!(Initializer != null && Initializer is ConstructorThisInitializer))
+ container.EmitFieldInitializers (ec);
+ }
}
- if (Initializer != null)
+ if (Initializer != null) {
+ Initializer.CheckObsoleteAttribute (container, Location);
Initializer.Emit (ec);
+ }
if ((ModFlags & Modifiers.STATIC) != 0)
container.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 (generate_debugging)
sw.CloseMethod ();
+ base.Emit (container);
+
block = null;
}
- }
-
- //
- // Encapsulates most of the Method's state
- //
- public class MethodData {
- //
- // The return type of this method
- //
- public readonly Type ReturnType;
- public readonly Type[] ParameterTypes;
- public readonly InternalParameters ParameterInfo;
- public readonly CallingConventions CallingConventions;
- public readonly Attributes OptAttributes;
- public readonly Location Location;
+
+ // For constructors is needed to test only parameters
+ protected override bool IsIdentifierClsCompliant (DeclSpace ds)
+ {
+ if (parameter_types == null || parameter_types.Length == 0)
+ return true;
+
+ TypeContainer tc = ds as TypeContainer;
+
+ for (int i = 0; i < tc.InstanceConstructors.Count; i++) {
+ Constructor c = (Constructor) tc.InstanceConstructors [i];
+
+ if (c == this || c.ParameterTypes.Length == 0)
+ continue;
+
+ if (!c.IsClsCompliaceRequired (ds))
+ continue;
+
+ if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, c.ParameterTypes)) {
+ Report.Error_T (3006, Location, GetSignatureForError ());
+ return false;
+ }
+ }
+
+ if (tc.TypeBuilder.BaseType == null)
+ return true;
+
+ DeclSpace temp_ds = TypeManager.LookupDeclSpace (tc.TypeBuilder.BaseType);
+ if (temp_ds != null)
+ return IsIdentifierClsCompliant (temp_ds);
+
+ MemberInfo[] ml = tc.TypeBuilder.BaseType.FindMembers (MemberTypes.Constructor, BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance, null, null);
+ // Skip parameter-less ctor
+ if (ml.Length < 2)
+ return true;
+
+ foreach (ConstructorInfo ci in ml) {
+ object[] cls_attribute = ci.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+ if (cls_attribute.Length == 1 && (!((CLSCompliantAttribute)cls_attribute[0]).IsCompliant))
+ continue;
+
+ if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, TypeManager.GetArgumentTypes (ci))) {
+ Report.Error_T (3006, Location, GetSignatureForError ());
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
+ return false;
+ }
+
+ if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
+ foreach (Type param in parameter_types) {
+ if (param.IsArray) {
+ return false;
+ }
+ }
+ }
+ has_compliant_args = true;
+ return true;
+ }
+
+ }
+
+ /// <summary>
+ /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
+ /// </summary>
+ public interface IMethodData
+ {
+ CallingConventions CallingConventions { get; }
+ Location Location { get; }
+ string MethodName { get; }
+ Type[] ParameterTypes { get; }
+ Type ReturnType { get; }
+
+ Attributes OptAttributes { get; }
+ Block Block { get; }
+
+ EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
+ ObsoleteAttribute GetObsoleteAttribute ();
+ }
+
+ //
+ // Encapsulates most of the Method's state
+ //
+ public class MethodData {
+
+ readonly IMethodData method;
+
+ //
+ // The return type of this method
+ //
+ public readonly InternalParameters ParameterInfo;
//
// Are we implementing an interface ?
protected int modifiers;
protected MethodAttributes flags;
protected bool is_method;
- protected string accessor_name;
//
// It can either hold a string with the condition, or an arraylist of conditions.
}
}
- public MethodData (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 MethodData (MemberBase member, InternalParameters parameters,
+ int modifiers, MethodAttributes flags, bool is_method, IMethodData method)
{
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;
+
+ this.method = method;
}
//
// Attributes.
//
Attribute dllimport_attribute = null;
- string obsolete = null;
- bool obsolete_error = false;
- public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
+ public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method,
+ EmitContext ec)
{
- if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
+ if ((opt_attrs == null) || (opt_attrs.Attrs == 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;
+ foreach (Attribute a in opt_attrs.Attrs) {
+ Type attr_type = a.ResolveType (ec, true);
+ if (attr_type == TypeManager.conditional_attribute_type) {
+ if (!ApplyConditionalAttribute (a))
+ return false;
+ } else if (attr_type == TypeManager.dllimport_type) {
+ if (!is_method) {
+ Attribute.Error_AttributeNotValidForElement (a, method.Location);
+ return false;
}
+ if (!ApplyDllImportAttribute (a))
+ return false;
}
}
{
const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
if ((modifiers & extern_static) != extern_static) {
- Report.Error (601, Location,
+ Report.Error (601, method.Location,
"The DllImport attribute must be specified on a method " +
"marked `static' and `extern'.");
return false;
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.
//
{
// The Conditional attribute is only valid on methods.
if (!is_method) {
- Attribute.Error_AttributeNotValidForElement (a, Location);
+ Attribute.Error_AttributeNotValidForElement (a, method.Location);
return false;
}
if (condition == null)
return false;
- if (ReturnType != TypeManager.void_type) {
- Report.Error (578, Location,
+ if (method.ReturnType != TypeManager.void_type) {
+ Report.Error (578, method.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,
+ Report.Error (243, method.Location,
"Conditional not valid on `" + member.Name + "' " +
"because it is an override method");
return false;
}
if (member.IsExplicitImpl) {
- Report.Error (577, Location,
+ Report.Error (577, method.Location,
"Conditional not valid on `" + member.Name + "' " +
"because it is an explicit interface implementation");
return false;
}
if (IsImplementing) {
- Report.Error (623, Location,
+ Report.Error (623, method.Location,
"Conditional not valid on `" + member.Name + "' " +
"because it is an interface method");
return false;
{
TypeManager.MethodFlags flags = 0;
- 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 + "'");
-
- flags |= TypeManager.MethodFlags.IsObsolete;
- }
-
if (ShouldIgnore (loc))
flags |= TypeManager.MethodFlags.ShouldIgnore;
return flags;
}
- public virtual bool Define (TypeContainer container)
+ public bool Define (TypeContainer container)
{
MethodInfo implementing = null;
- string method_name, name, prefix;
+ string prefix;
- if (OptAttributes != null)
- if (!ApplyAttributes (OptAttributes, is_method))
+ EmitContext ec = method.CreateEmitContext (container, null);
+
+ if (method.OptAttributes != null)
+ if (!ApplyAttributes (method.OptAttributes, is_method, ec))
return false;
if (member.IsExplicitImpl)
else
prefix = "";
- if (accessor_name != null)
- name = accessor_name + "_" + member.ShortName;
- else
- name = member.ShortName;
- method_name = prefix + name;
+ string name = method.MethodName;
+ 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){
- TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
- Location, name);
+ Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
return false;
}
}
//
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 {
- //
- // We already catch different accessibility settings
- // so we just need to check that we are not private
- //
- if ((modifiers & Modifiers.PRIVATE) != 0)
+ } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
+ if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
+ //
+ // If this is an interface method implementation,
+ // check for public accessibility
+ //
+ implementing = null;
+ } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
+ // We may never be private.
+ implementing = null;
+ } else if ((modifiers & Modifiers.OVERRIDE) == 0){
+ //
+ // We may be protected if we're overriding something.
+ //
implementing = null;
+ }
}
//
//
if ((modifiers & Modifiers.STATIC) != 0){
implementing = null;
- Modifiers.Error_InvalidModifier (Location, "static");
+ Modifiers.Error_InvalidModifier (method.Location, "static");
}
}
//
if (implementing != null){
//
- // When implementing interface methods, set NewSlot.
+ // When implementing interface methods, set NewSlot
+ // unless, we are overwriting a method.
//
- if (implementing.DeclaringType.IsInterface)
- flags |= MethodAttributes.NewSlot;
-
+ if (implementing.DeclaringType.IsInterface){
+ if ((modifiers & Modifiers.OVERRIDE) == 0)
+ flags |= MethodAttributes.NewSlot;
+ }
flags |=
MethodAttributes.Virtual |
MethodAttributes.HideBySig;
+ // Set Final unless we're virtual, abstract or already overriding a method.
+ 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;
//
if ((flags & MethodAttributes.PinvokeImpl) != 0) {
if ((modifiers & Modifiers.STATIC) == 0) {
- Report.Error (601, Location,
+ Report.Error (601, method.Location,
"The DllImport attribute must be specified on " +
"a method marked 'static' and 'extern'.");
return false;
}
- EmitContext ec = new EmitContext (
- container, Location, null, ReturnType, modifiers);
-
builder = dllimport_attribute.DefinePInvokeMethod (
ec, container.TypeBuilder, method_name, flags,
- ReturnType, ParameterTypes);
+ method.ReturnType, ParameterTypes);
} else
builder = container.TypeBuilder.DefineMethod (
- method_name, flags, CallingConventions,
- ReturnType, ParameterTypes);
+ method_name, flags, method.CallingConventions,
+ method.ReturnType, ParameterTypes);
if (builder == null)
return false;
- if (IsImplementing) {
+ if ((modifiers & Modifiers.UNSAFE) != 0)
+ builder.InitLocals = false;
+
+ if (IsImplementing){
//
// clear the pending implemntation flag
//
if (member is Indexer) {
container.Pending.ImplementIndexer (
- member.InterfaceType, builder, ReturnType,
+ member.InterfaceType, builder, method.ReturnType,
ParameterTypes, true);
} else
container.Pending.ImplementMethod (
- member.InterfaceType, name, ReturnType,
+ member.InterfaceType, name, method.ReturnType,
ParameterTypes, member.IsExplicitImpl);
if (member.IsExplicitImpl)
container.TypeBuilder.DefineMethodOverride (
builder, implementing);
+
}
if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
- Report.Error (111, Location,
+ Report.Error (111, method.Location,
"Class `" + container.Name +
"' already contains a definition with the " +
"same return value and parameter types as the " +
}
TypeManager.AddMethod (builder, this);
+ TypeManager.AddMethod2 (builder, method);
return true;
}
//
// 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, Location, ig, ReturnType, modifiers);
+ 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) member).LabelParameters (ec, MethodBuilder, OptAttributes);
+ ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
+ SymbolWriter sw = CodeGen.SymbolWriter;
+ 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);
+ if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0) &&
+ !Location.IsNull (loc) &&
+ (method.Location.SymbolDocument != null)) {
+ sw.OpenMethod (container, MethodBuilder, loc, loc);
sw.CloseMethod ();
}
//
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");
//
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");
//
// FIXME: This code generates buggy code
//
- if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
- EmitDestructor (ec, block);
- else {
- SymbolWriter sw = CodeGen.SymbolWriter;
+ if ((sw != null) && !Location.IsNull (loc) &&
+ !Location.IsNull (block.EndLocation) &&
+ (loc.SymbolDocument != null)) {
+ sw.OpenMethod (container, MethodBuilder, loc, block.EndLocation);
- if ((sw != null) && !Location.IsNull (Location) &&
- !Location.IsNull (block.EndLocation)) {
- sw.OpenMethod (container, MethodBuilder, Location, block.EndLocation);
-
- ec.EmitTopBlock (block, ParameterInfo, Location);
+ if (member is Destructor)
+ EmitDestructor (ec, block);
+ else
+ ec.EmitTopBlock (block, ParameterInfo, loc);
- sw.CloseMethod ();
- } else
- ec.EmitTopBlock (block, ParameterInfo, Location);
+ sw.CloseMethod ();
+ } else {
+ if (member is Destructor)
+ EmitDestructor (ec, block);
+ else
+ ec.EmitTopBlock (block, ParameterInfo, loc);
}
}
ILGenerator ig = ec.ig;
Label finish = ig.DefineLabel ();
- bool old_in_try = ec.InTry;
+
+ block.SetDestructor ();
ig.BeginExceptionBlock ();
- ec.InTry = true;
ec.ReturnLabel = finish;
ec.HasReturnLabel = true;
- ec.EmitTopBlock (block, null, Location);
- ec.InTry = old_in_try;
+ ec.EmitTopBlock (block, null, method.Location);
// ig.MarkLabel (finish);
- bool old_in_finally = ec.InFinally;
- ec.InFinally = true;
ig.BeginFinallyBlock ();
if (ec.ContainerType.BaseType != null) {
Expression member_lookup = Expression.MemberLookup (
ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
- "Finalize", MemberTypes.Method, Expression.AllBindingFlags, Location);
+ "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
if (member_lookup != null){
MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
}
}
- ec.InFinally = old_in_finally;
ig.EndExceptionBlock ();
//ig.MarkLabel (ec.ReturnLabel);
}
}
+ public class Destructor : Method {
+
+ public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
+ Parameters parameters, Attributes attrs, Location l)
+ : base (ds, return_type, mod, false, name, parameters, attrs, l)
+ { }
+
+ }
+
abstract public class MemberBase : MemberCore {
public Expression Type;
- public readonly Attributes OptAttributes;
- protected MethodAttributes flags;
+ public MethodAttributes flags;
+
+ protected readonly int explicit_mod_flags;
//
// The "short" name of this property / indexer / event. This is the
//
public string ExplicitInterfaceName = null;
+ //
+ // Whether this is an interface member.
+ //
+ public bool IsInterface;
+
//
// If true, the interface type we are explicitly implementing
//
//
// The constructor is only exposed to our children
//
- protected MemberBase (Expression type, int mod, int allowed_mod, string name,
+ protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
Attributes attrs, Location loc)
- : base (name, loc)
+ : base (name, attrs, loc)
{
+ explicit_mod_flags = mod;
Type = type;
- ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PRIVATE, loc);
- OptAttributes = attrs;
+ ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
}
protected virtual bool CheckBase (TypeContainer container)
return true;
}
- protected virtual bool CheckParameters (TypeContainer container, Type [] parameters)
+ 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");
+
+ }
+
+ 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 + "'");
+ }
+
+ //
+ // 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 (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;
+ }
+ }
+ }
+
+ return ok;
+ }
+
+ 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 (container))
+ if (!UnsafeOK (ds))
error = true;
- if (!TypeManager.VerifyUnManaged (partype.GetElementType (), Location))
+ if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
error = true;
}
- if (container.AsAccessible (partype, ModFlags))
+ if (ds.AsAccessible (partype, ModFlags))
continue;
if (this is Indexer)
"Inconsistent accessibility: parameter type `" +
TypeManager.CSharpName (partype) + "' is less " +
"accessible than indexer `" + Name + "'");
+ else if ((this is Method) && ((Method) this).IsOperator)
+ Report.Error (57, Location,
+ "Inconsistent accessibility: parameter type `" +
+ TypeManager.CSharpName (partype) + "' is less " +
+ "accessible than operator `" + Name + "'");
else
Report.Error (51, Location,
"Inconsistent accessibility: parameter type `" +
if (Name == null)
Name = "this";
- if (!container.MethodModifiersValid (ModFlags, Name, Location))
- return false;
+ if (IsInterface) {
+ ModFlags = Modifiers.PUBLIC |
+ Modifiers.ABSTRACT |
+ Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE);
- flags = Modifiers.MethodAttr (ModFlags);
+ flags = MethodAttributes.Public |
+ MethodAttributes.Abstract |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.Virtual;
+ } else {
+ if (!container.MethodModifiersValid (ModFlags, Name, Location))
+ return false;
+
+ flags = Modifiers.MethodAttr (ModFlags);
+ }
// Lookup Type, verify validity
MemberType = container.ResolveType (Type, false, Location);
"Inconsistent accessibility: indexer return type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than indexer `" + Name + "'");
- else if (this is Method)
- Report.Error (50, Location,
- "Inconsistent accessibility: return type `" +
- TypeManager.CSharpName (MemberType) + "' is less " +
- "accessible than method `" + Name + "'");
- else
+ else if (this is Method) {
+ if (((Method) this).IsOperator)
+ Report.Error (56, Location,
+ "Inconsistent accessibility: return type `" +
+ TypeManager.CSharpName (MemberType) + "' is less " +
+ "accessible than operator `" + Name + "'");
+ else
+ Report.Error (50, Location,
+ "Inconsistent accessibility: return type `" +
+ TypeManager.CSharpName (MemberType) + "' is less " +
+ "accessible than method `" + Name + "'");
+ } else
Report.Error (52, Location,
"Inconsistent accessibility: field type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
//
// Check for explicit interface implementation
//
- if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
- int pos = Name.LastIndexOf (".");
+ if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
+ int pos = Name.LastIndexOf ('.');
ExplicitInterfaceName = Name.Substring (0, pos);
ShortName = Name.Substring (pos + 1);
if (InterfaceType == null)
return false;
+ if (InterfaceType.IsClass) {
+ Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
+ return false;
+ }
+
// Compute the full name that we need to export.
Name = InterfaceType.FullName + "." + ShortName;
if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
return false;
+ Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
+
IsExplicitImpl = true;
} else
IsExplicitImpl = false;
return true;
}
+
+ protected override bool IsIdentifierClsCompliant (DeclSpace ds)
+ {
+ return IsIdentifierAndParamClsCompliant (ds, Name, null, null);
+ }
+
+ protected override bool VerifyClsCompliance(DeclSpace ds)
+ {
+ if (base.VerifyClsCompliance (ds)) {
+ return true;
+ }
+
+ if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
+ Report.Error_T (3010, Location, GetSignatureForError ());
+ }
+ return false;
+ }
+
+
}
//
[Flags]
public enum Status : byte { ASSIGNED = 1, USED = 2 }
+ static string[] attribute_targets = new string [] { "field" };
+
//
// 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, name, attrs, loc)
+ : base (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_T (-24, a.Location);
+ return;
+ }
+
+
+ FieldBuilder.SetCustomAttribute (cb);
+ }
+
//
// Whether this field has an initializer.
//
return init_expr;
}
+
+ protected override bool DoDefine (TypeContainer container)
+ {
+ if (!base.DoDefine (container))
+ return false;
+
+ if (MemberType == TypeManager.void_type) {
+ Report.Error (1547, Location,
+ "Keyword 'void' cannot be used in this context");
+ return false;
+ }
+
+ return true;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return TypeManager.GetFullNameSignature (FieldBuilder);
+ }
+
+ protected 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_T (3003, Location, GetSignatureForError ());
+ }
+ return true;
+ }
+
+
+ public void SetAssigned ()
+ {
+ status |= Status.ASSIGNED;
+ }
}
//
public override bool Define (TypeContainer container)
{
- Type t = container.ResolveType (Type, false, Location);
+ MemberType = container.ResolveType (Type, false, Location);
- if (t == null)
+ if (MemberType == null)
return false;
CheckBase (container);
- if (!container.AsAccessible (t, ModFlags)) {
+ if (!container.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 (MemberType.IsPointer && !UnsafeOK (container))
+ return false;
+
if (RootContext.WarningLevel > 1){
Type ptype = container.TypeBuilder.BaseType;
}
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) +
" A volatile field can not be of type `" +
if (container is Struct &&
((fa & FieldAttributes.Static) == 0) &&
- t == container.TypeBuilder &&
- !TypeManager.IsBuiltinType (t)){
+ MemberType == container.TypeBuilder &&
+ !TypeManager.IsBuiltinType (MemberType)){
Report.Error (523, Location, "Struct member `" + container.Name + "." + Name +
"' causes a cycle in the structure layout");
return false;
}
- FieldBuilder = container.TypeBuilder.DefineField (
- Name, t, Modifiers.FieldAttr (ModFlags));
+ try {
+ FieldBuilder = container.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;
+ }
- TypeManager.RegisterFieldBase (FieldBuilder, this);
return true;
}
- public void Emit (TypeContainer tc)
+ public override void Emit (TypeContainer tc)
{
- EmitContext ec = new EmitContext (tc, Location, null,
- FieldBuilder.FieldType, ModFlags);
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (tc, Location, null, FieldBuilder.FieldType, ModFlags);
+ OptAttributes.Emit (ec, this);
+ }
- Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes);
+ base.Emit (tc);
}
}
// Null if the accessor is empty, or a Block if not
//
public Block Block;
- public Attributes OptAttributes;
+ public Attributes Attributes;
public Accessor (Block b, Attributes attrs)
{
Block = b;
- OptAttributes = attrs;
+ Attributes = attrs;
}
}
// their common bits.
//
abstract public class PropertyBase : MethodCore {
- public Accessor Get, Set;
+
+ public class GetMethod: PropertyMethod
+ {
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public GetMethod (MethodCore method, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override MethodBuilder Define(TypeContainer container)
+ {
+ method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, false, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string MethodName {
+ get {
+ return "get_" + method.ShortName;
+ }
+ }
+
+ public override Type ReturnType {
+ get {
+ return method.MemberType;
+ }
+ }
+
+ protected 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, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "param") {
+ 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, false, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string MethodName {
+ get {
+ return "set_" + method.ShortName;
+ }
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ return new Type[] { method.MemberType };
+ }
+ }
+
+ public override Type ReturnType {
+ get {
+ return TypeManager.void_type;
+ }
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+
+ static string[] attribute_targets = new string [] { "property" };
+
+ public abstract class PropertyMethod: Attributable, IMethodData
+ {
+ protected readonly MethodCore method;
+ protected MethodData method_data;
+ Block block;
+
+ ReturnParameter return_attributes;
+
+ public PropertyMethod (MethodCore method, Accessor accessor):
+ base (accessor.Attributes)
+ {
+ this.method = method;
+ this.block = accessor.Block;
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method | AttributeTargets.ReturnValue;
+ }
+ }
+
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
+ }
+
+ public InternalParameters ParameterInfo
+ {
+ get {
+ return method_data.ParameterInfo;
+ }
+ }
+
+ #region IMethodData Members
+
+ public Block Block {
+ get {
+ return block;
+ }
+ }
+
+ public CallingConventions CallingConventions {
+ get {
+ return CallingConventions.Standard;
+ }
+ }
+
+ public abstract MethodBuilder Define (TypeContainer container);
+
+ public void Emit (TypeContainer container)
+ {
+ method_data.Emit (container, this);
+ block = null;
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ method_data.MethodBuilder.SetCustomAttribute (cb);
+ }
+
+ public virtual Type[] ParameterTypes {
+ get {
+ return TypeManager.NoTypes;
+ }
+ }
+
+ public abstract Type ReturnType { get; }
+
+ public Location Location {
+ get {
+ return method.Location;
+ }
+ }
+
+ public abstract string MethodName { get; }
+
+ public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+ {
+ return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
+ }
+
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.ds);
+ }
+ #endregion
+ }
+
+
+ public PropertyMethod Get, Set;
public PropertyBuilder PropertyBuilder;
public MethodBuilder GetBuilder, SetBuilder;
- public MethodData GetData, SetData;
protected EmitContext ec;
- public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
- Parameters parameters, Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
+ public PropertyBase (DeclSpace ds, Expression type, int mod_flags,
+ int allowed_mod, bool is_iface, string name,
+ Parameters parameters, Attributes attrs,
+ Location loc)
+ : base (ds, type, mod_flags, allowed_mod, is_iface, name,
+ attrs, parameters, loc)
+ {
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- Get = get_block;
- Set = set_block;
+ PropertyBuilder.SetCustomAttribute (cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Property;
+ }
}
protected override bool DoDefine (TypeContainer container)
return true;
}
+ public override string GetSignatureForError()
+ {
+ return TypeManager.CSharpSignature (PropertyBuilder, false);
+ }
+
+ protected virtual string RealMethodName {
+ get {
+ return Name;
+ }
+ }
+
+ protected override bool IsIdentifierClsCompliant (DeclSpace ds)
+ {
+ if (!IsIdentifierAndParamClsCompliant (ds, RealMethodName, null, null))
+ return false;
+
+ if (Get != null && !IsIdentifierAndParamClsCompliant (ds, "get_" + RealMethodName, null, null))
+ return false;
+
+ if (Set != null && !IsIdentifierAndParamClsCompliant (ds, "set_" + RealMethodName, null, null))
+ return false;
+
+ return true;
+ }
+
+
//
// Checks our base implementation if any
//
base.CheckBase (container);
// Check whether arguments were correct.
- if (!DoDefineParameters (container))
+ if (!DoDefineParameters ())
return false;
if (IsExplicitImpl)
return true;
+ //
+ // Check in our class for dups
+ //
+ ArrayList ar = container.Properties;
+ if (ar != null) {
+ int arLen = ar.Count;
+
+ for (int i = 0; i < arLen; i++) {
+ Property m = (Property) ar [i];
+ if (IsDuplicateImplementation (container, m))
+ return false;
+ }
+ }
+
+ if (IsInterface)
+ return true;
+
string report_name;
MethodSignature ms, base_ms;
if (this is Indexer) {
return true;
}
- MemberList props_this;
-
- 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;
+ MemberInfo parent_member = null;
+
+ //
+ // Explicit implementations do not have `parent' methods, however,
+ // the member cache stores them there. Without this check, we get
+ // an incorrect warning in corlib.
+ //
+ if (! IsExplicitImpl) {
+ parent_member = ((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
+ container.TypeBuilder, Name, ParameterTypes, true);
}
- 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);
+ if (parent_member is PropertyInfo) {
+ PropertyInfo parent_property = (PropertyInfo)parent_member;
- if (mi_props.Count > 0){
- PropertyInfo parent_property = (PropertyInfo) mi_props [0];
string name = parent_property.DeclaringType.Name + "." +
parent_property.Name;
return false;
}
}
- } else {
+ } else if (parent_member == null){
if ((ModFlags & Modifiers.NEW) != 0)
WarningNotHiding (container);
return true;
}
- public void Emit (TypeContainer tc)
+ public override void Emit (TypeContainer tc)
{
//
// 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 (GetData != null) {
- GetData.Emit (tc, Get.Block, Get);
- Get.Block = null;
- }
+ if (Get != null)
+ Get.Emit (tc);
- if (SetData != null) {
- SetData.Emit (tc, Set.Block, Set);
- Set.Block = null;
+ if (Set != null)
+ Set.Emit (tc);
+
+ base.Emit (tc);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
}
}
}
- public class Property : PropertyBase {
+ public class Property : PropertyBase, IIteratorContainer {
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
Modifiers.ABSTRACT |
Modifiers.UNSAFE |
Modifiers.EXTERN |
+ Modifiers.METHOD_YIELDS |
Modifiers.VIRTUAL;
- public Property (Expression type, string name, int mod_flags,
- Accessor get_block, Accessor set_block,
- Attributes attrs, Location loc)
- : base (type, name, mod_flags, AllowedModifiers,
- Parameters.EmptyReadOnlyParameters,
- get_block, set_block, attrs, loc)
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
+
+ public Property (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
+ string name, Attributes attrs, Accessor get_block,
+ Accessor set_block, Location loc)
+ : base (ds, type, mod_flags,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
+ loc)
{
+ if (get_block != null)
+ Get = new GetMethod (this, get_block);
+
+ if (set_block != null)
+ Set = new SetMethod (this, set_block);
}
public override bool Define (TypeContainer container)
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
if (Get != null) {
- Type [] parameters = TypeManager.NoTypes;
-
- InternalParameters ip = new InternalParameters (
- container, Parameters.EmptyReadOnlyParameters);
-
- GetData = new MethodData (this, "get", MemberType,
- parameters, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
- if (!GetData.Define (container))
+ GetBuilder = Get.Define (container);
+ if (GetBuilder == null)
return false;
- GetBuilder = GetData.MethodBuilder;
+ //
+ // Setup iterator if we are one
+ //
+ if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+ IteratorHandler ih = new IteratorHandler (
+ "get", container, MemberType,
+ TypeManager.NoTypes, Get.ParameterInfo, ModFlags, Location);
+
+ Block new_block = ih.Setup (block);
+ if (new_block == null)
+ return false;
+ block = new_block;
+ }
}
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 (this, "set", TypeManager.void_type,
- parameters, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (container))
+ SetBuilder = Set.Define (container);
+ if (SetBuilder == null)
return false;
- SetBuilder = SetData.MethodBuilder;
SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
}
// FIXME - PropertyAttributes.HasDefault ?
- PropertyAttributes prop_attr =
- PropertyAttributes.RTSpecialName |
- PropertyAttributes.SpecialName;
+ PropertyAttributes prop_attr = PropertyAttributes.None;
+ if (!IsInterface)
+ prop_attr |= PropertyAttributes.RTSpecialName |
+ PropertyAttributes.SpecialName;
if (!IsExplicitImpl){
PropertyBuilder = container.TypeBuilder.DefineProperty (
}
return true;
}
+
+ public void SetYields ()
+ {
+ ModFlags |= Modifiers.METHOD_YIELDS;
+ }
}
/// </summary>
return null;
}
- public override object [] GetCustomAttributes (Type t, bool inherit)
- {
- // FIXME : Same here !
- return null;
- }
+ public override object [] GetCustomAttributes (Type t, bool inherit)
+ {
+ // FIXME : Same here !
+ return null;
+ }
+
+ public override bool IsDefined (Type t, bool b)
+ {
+ return true;
+ }
+
+ public override EventAttributes Attributes {
+ get {
+ return attributes;
+ }
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ public override Type DeclaringType {
+ get {
+ return declaring_type;
+ }
+ }
+
+ public override Type ReflectedType {
+ get {
+ return reflected_type;
+ }
+ }
+
+ public Type EventType {
+ get {
+ return event_type;
+ }
+ }
+
+ public void SetUsed ()
+ {
+ if (my_event != null)
+ my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
+ }
+ }
+
+ /// <summary>
+ /// For case when event is declared like property (with add and remove accessors).
+ /// </summary>
+ public class EventProperty: Event {
+
+ static string[] attribute_targets = new string [] { "event", "property" };
+
+ public EventProperty (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
+ Object init, Attributes attrs, Accessor add, Accessor remove, Location loc)
+ : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this, add);
+ Remove = new RemoveDelegateMethod (this, remove);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event is declared like field.
+ /// </summary>
+ public class EventField: Event {
+
+ static string[] attribute_targets = new string [] { "method", "field", "event" };
+
+ public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
+ Object init, Attributes attrs, Location loc)
+ : base (ds, 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 == "field") {
+ FieldBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ if (a.Target == "method") {
+ AddBuilder.SetCustomAttribute (cb);
+ RemoveBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public abstract class Event : FieldBase {
+
+ protected sealed class AddDelegateMethod: DelegateMethod
+ {
+ public AddDelegateMethod (Event method):
+ base (method)
+ {
+ }
+
+ public AddDelegateMethod (Event method, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override string MethodName {
+ get {
+ return "add_" + method.ShortName;
+ }
+ }
+
+ protected override MethodInfo DelegateMethodInfo {
+ get {
+ return TypeManager.delegate_combine_delegate_delegate;
+ }
+ }
+
+ }
+
+ protected sealed class RemoveDelegateMethod: DelegateMethod
+ {
+ public RemoveDelegateMethod (Event method):
+ base (method)
+ {
+ }
+
+ public RemoveDelegateMethod (Event method, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override string MethodName {
+ get {
+ return "remove_" + method.ShortName;
+ }
+ }
+
+ protected override MethodInfo DelegateMethodInfo {
+ get {
+ return TypeManager.delegate_remove_delegate_delegate;
+ }
+ }
+
+ }
+
+ public abstract class DelegateMethod: Attributable, IMethodData
+ {
+ protected readonly Event method;
+ protected MethodData method_data;
+ Block block;
+ ReturnParameter return_attributes;
+ ImplicitParameter param_attr;
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+
+ public DelegateMethod (Event method):
+ base (null)
+ {
+ this.method = method;
+ }
+
+ public DelegateMethod (Event method, Accessor accessor):
+ base (accessor.Attributes)
+ {
+ this.method = method;
+ this.block = accessor.Block;
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ if (a.Target == "param") {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ method_data.MethodBuilder.SetCustomAttribute (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, false, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ MethodBuilder mb = method_data.MethodBuilder;
+ mb.DefineParameter (1, ParameterAttributes.None, "value");
+ return mb;
+ }
+
+ #region IMethodData Members
+
+ public Block Block {
+ get {
+ return block;
+ }
+ }
+
+ public CallingConventions CallingConventions {
+ get {
+ return CallingConventions.Standard;
+ }
+ }
+
+ public void Emit (TypeContainer tc)
+ {
+ if (block != null) {
+ method_data.Emit (tc, this);
+ block = null;
+ return;
+ }
+
+ ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
+ EmitContext ec = CreateEmitContext (tc, ig);
+ FieldInfo field_info = (FieldInfo)method.FieldBuilder;
- public override bool IsDefined (Type t, bool b)
- {
- return true;
- }
+ 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);
+ }
- public override EventAttributes Attributes {
- get {
- return attributes;
+ protected abstract MethodInfo DelegateMethodInfo { get; }
+
+ public Type[] ParameterTypes {
+ get {
+ return new Type[] { method.MemberType };
+ }
}
- }
- public override string Name {
- get {
- return name;
+ public Type ReturnType {
+ get {
+ return TypeManager.void_type;
+ }
}
- }
- public override Type DeclaringType {
- get {
- return declaring_type;
+ public Location Location {
+ get {
+ return method.Location;
+ }
}
- }
- public override Type ReflectedType {
- get {
- return reflected_type;
+ public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+ {
+ return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
}
- }
- public Type EventType {
- get {
- return event_type;
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.ds);
+ }
+
+ public abstract string MethodName { get; }
+
+ #endregion
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
}
}
-
- public void SetUsed ()
- {
- if (my_event != null)
- my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
- }
- }
-
- public class Event : FieldBase {
+
+
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
Modifiers.UNSAFE |
Modifiers.ABSTRACT;
- public readonly Accessor Add;
- public readonly Accessor Remove;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
+
+ protected DelegateMethod Add, Remove;
public MyEventBuilder EventBuilder;
+ public MethodBuilder AddBuilder, RemoveBuilder;
+ public DeclSpace ds;
- 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 (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
+ Object init, Attributes attrs, Location loc)
+ : base (type, mod_flags, is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ name, init, attrs, loc)
+ {
+ IsInterface = is_iface;
+ this.ds = ds;
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
- Add = add;
- Remove = remove;
+ EventBuilder.SetCustomAttribute (cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Event;
+ }
}
public override bool Define (TypeContainer container)
{
- EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
+ EventAttributes e_attr;
+ if (IsInterface)
+ e_attr = EventAttributes.None;
+ else
+ e_attr = EventAttributes.RTSpecialName |
+ EventAttributes.SpecialName;
if (!DoDefine (container))
return false;
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 (
//
// Now define the accessors
//
- AddData = new MethodData (this, "add", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Add != null) ? Add.OptAttributes : null,
- ModFlags, flags, false);
- if (!AddData.Define (container))
+ AddBuilder = Add.Define (container, ip);
+ if (AddBuilder == null)
return false;
- AddBuilder = AddData.MethodBuilder;
- AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
-
- RemoveData = new MethodData (this, "remove", TypeManager.void_type,
- parameter_types, ip, CallingConventions.Standard,
- (Remove != null) ? Remove.OptAttributes : null,
- ModFlags, flags, false);
-
- if (!RemoveData.Define (container))
+ RemoveBuilder = Remove.Define (container, 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);
- if (Add == null && Remove == null) {
+ if (Add.Block == null && Remove.Block == null &&
+ !IsInterface) {
FieldBuilder = container.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
return true;
}
- void EmitDefaultMethod (EmitContext ec, bool is_add)
+ public override void Emit (TypeContainer tc)
{
- 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 (tc, Location, null, MemberType, ModFlags);
+ OptAttributes.Emit (ec, this);
}
- ig.Emit (OpCodes.Ret);
- }
-
- public void Emit (TypeContainer tc)
- {
- EmitContext ec;
-
- ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
- Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes);
- 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);
+ if (!IsInterface) {
+ Add.Emit (tc);
+ Remove.Emit (tc);
}
- 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);
- }
+ base.Emit (tc);
}
-
}
//
public class Indexer : PropertyBase {
+ class GetIndexerMethod: GetMethod
+ {
+ public GetIndexerMethod (MethodCore method, Accessor accessor):
+ base (method, accessor)
+ {
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ return method.ParameterTypes;
+ }
+ }
+ }
+
+ class SetIndexerMethod: SetMethod
+ {
+ readonly Parameters parameters;
+
+ 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 |
Modifiers.PUBLIC |
Modifiers.EXTERN |
Modifiers.ABSTRACT;
+ const int AllowedInterfaceModifiers =
+ Modifiers.NEW;
+
public string IndexerName;
public string InterfaceIndexerName;
//
// Are we implementing an interface ?
//
- bool IsImplementing = false;
-
- public Indexer (Expression type, string int_type, int flags, Parameters parameters,
- Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
- : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
- attrs, loc)
+ public Indexer (DeclSpace ds, Expression type, string int_type, int mod_flags,
+ bool is_iface, Parameters parameters, Attributes attrs,
+ Accessor get_block, Accessor set_block, Location loc)
+ : base (ds, type, mod_flags,
+ is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+ is_iface, "", parameters, attrs, loc)
{
ExplicitInterfaceName = int_type;
- }
+ if (get_block != null)
+ Get = new GetIndexerMethod (this, get_block);
+
+ if (set_block != null)
+ Set = new SetIndexerMethod (this, parameters, set_block);
+ }
+
public override bool Define (TypeContainer container)
{
PropertyAttributes prop_attr =
if (!DoDefine (container))
return false;
- IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
+ if (OptAttributes != null)
+ IndexerName = OptAttributes.ScanForIndexerName (ec);
+
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.");
+ else {
+ if (! Tokenizer.IsValidIdentifier (IndexerName)) {
+ Report.Error (633, Location, "The IndexerName specified is an invalid identifier");
+ return false;
+ }
+
+ if (IsExplicitImpl) {
+ Report.Error (592, Location,
+ "Attribute 'IndexerName' is not valid on explicit implementations.");
+ return false;
+ }
+ }
ShortName = IndexerName;
if (IsExplicitImpl) {
Name = ShortName;
}
+ if (!CheckNameCollision (container))
+ return false;
+
if (!CheckBase (container))
return false;
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
if (Get != null){
- InternalParameters ip = new InternalParameters (container, Parameters);
-
- GetData = new MethodData (this, "get", MemberType,
- ParameterTypes, ip, CallingConventions.Standard,
- Get.OptAttributes, ModFlags, flags, false);
-
- if (!GetData.Define (container))
+ GetBuilder = Get.Define (container);
+ 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 (this, "set", TypeManager.void_type,
- set_pars, ip, CallingConventions.Standard,
- Set.OptAttributes, ModFlags, flags, false);
-
- if (!SetData.Define (container))
+ SetBuilder = Set.Define (container);
+ if (SetBuilder == null)
return false;
-
- SetBuilder = SetData.MethodBuilder;
}
//
if (i != ParameterTypes.Length) {
Parameter array_param = Parameters.ArrayParameter;
+
SetBuilder.DefineParameter (
i + 1, array_param.Attributes, array_param.Name);
}
}
- if (GetData != null)
- IsImplementing = GetData.IsImplementing;
- else if (SetData != null)
- IsImplementing = SetData.IsImplementing;
-
//
// Define the PropertyBuilder if one of the following conditions are met:
// a) we're not implementing an interface indexer.
PropertyBuilder = container.TypeBuilder.DefineProperty (
IndexerName, prop_attr, MemberType, ParameterTypes);
- if (GetData != null)
+ if (Get != null)
PropertyBuilder.SetGetMethod (GetBuilder);
- if (SetData != null)
+ if (Set != null)
PropertyBuilder.SetSetMethod (SetBuilder);
TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
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)
+ {
+ object value = container.GetDefinition (fullname);
+
+ if (value != null) {
+ return value.GetType () != GetType () ? false : true;
+ }
+
+ container.DefineName (fullname, this);
+ return true;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return TypeManager.CSharpSignature (PropertyBuilder, true);
+ }
+
+ protected override string RealMethodName {
+ get {
+ return IndexerName;
+ }
+ }
}
- public class Operator : MemberCore {
+ public class Operator : MemberBase, IIteratorContainer {
const int AllowedModifiers =
Modifiers.PUBLIC |
public readonly Expression FirstArgType, SecondArgType;
public readonly string FirstArgName, SecondArgName;
public Block Block;
- public Attributes OptAttributes;
public MethodBuilder OperatorMethodBuilder;
public string MethodName;
public Method OperatorMethod;
- public Operator (OpType type, Expression ret_type, int flags,
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public Operator (OpType type, Expression ret_type, int mod_flags,
Expression arg1type, string arg1name,
Expression arg2type, string arg2name,
Block block, Attributes attrs, Location loc)
- : base ("", loc)
+ : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
{
OperatorType = type;
+ Name = "op_" + OperatorType;
ReturnType = ret_type;
- ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
FirstArgType = arg1type;
FirstArgName = arg1name;
SecondArgType = arg2type;
SecondArgName = arg2name;
Block = block;
- OptAttributes = attrs;
}
string Prototype (TypeContainer container)
return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
SecondArgType + ")";
}
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ OperatorMethod.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
public override bool Define (TypeContainer container)
{
param_list[1] = new Parameter (SecondArgType, SecondArgName,
Parameter.Modifier.NONE, null);
- OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
- new Parameters (param_list, null, Location),
- OptAttributes, Location);
+ OperatorMethod = new Method (
+ container, ReturnType, ModFlags, false, MethodName,
+ new Parameters (param_list, null, Location),
+ OptAttributes, Location);
+ OperatorMethod.Block = Block;
OperatorMethod.IsOperator = true;
OperatorMethod.Define (container);
return true;
}
- public void Emit (TypeContainer container)
+ public override void Emit (TypeContainer container)
{
- EmitContext ec = new EmitContext (container, Location, null, null, ModFlags);
- Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes);
-
//
// abstract or extern methods have no bodies
//
if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
return;
- OperatorMethod.Block = Block;
OperatorMethod.Emit (container);
Block = null;
}
GetName (OperatorType),
param_types [0], param_types [1]);
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
+ public void SetYields ()
+ {
+ ModFlags |= Modifiers.METHOD_YIELDS;
+ }
}
//
/// This delegate is used to extract methods which have the
/// same signature as the argument
/// </summary>
- public static MemberFilter method_signature_filter;
-
- /// <summary>
- /// 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
- /// </summary>
- 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)
{
}
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){
- if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
- return true;
- else
- return false;
- }
-
- // Anything else (FamOrAssembly and Public) is fine
- return true;
- }
}
}