Attributes attrs, Kind kind, Location l)
: base (ns, parent, name, attrs, l)
{
+ if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
+ throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
+
this.Kind = kind;
types = new ArrayList ();
public bool AddToMemberContainer (MemberCore symbol)
{
- return AddToContainer (symbol, String.Concat (Name, '.', symbol.Name), symbol.Name);
+ return AddToContainer (symbol, String.Concat (Name, ".", symbol.Name), symbol.Name);
}
bool AddToTypeContainer (DeclSpace ds)
interfaces.Add (iface);
}
- public void AddField (Field field)
+ public void AddField (FieldMember field)
{
if (!AddToMemberContainer (field))
return;
public override AttributeTargets AttributeTargets {
get {
- throw new NotSupportedException ();
+ switch (Kind) {
+ case Kind.Class:
+ return AttributeTargets.Class;
+ case Kind.Struct:
+ return AttributeTargets.Struct;
+ case Kind.Interface:
+ return AttributeTargets.Interface;
+ default:
+ throw new NotSupportedException ();
+ }
}
}
//
// Emits the instance field initializers
//
- public bool EmitFieldInitializers (EmitContext ec)
+ public virtual bool EmitFieldInitializers (EmitContext ec)
{
ArrayList fields;
Expression instance_expr;
if (a == null)
return false;
+ if (RootContext.Optimize) {
+ Constant c = e as Constant;
+ if (c != null) {
+ if (c.IsDefaultValue)
+ continue;
+ }
+ }
+
a.EmitStatement (ec);
}
else if ((ModFlags & Modifiers.ABSTRACT) != 0)
mods = Modifiers.PROTECTED;
- c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
+ TypeContainer constructor_parent = this;
+ if (Parts != null)
+ constructor_parent = (TypeContainer) Parts [0];
+
+ c = new Constructor (constructor_parent, Basename, mods,
+ Parameters.EmptyReadOnlyParameters,
new ConstructorBaseInitializer (
null, Parameters.EmptyReadOnlyParameters,
Location),
/// </remarks>
public PendingImplementation Pending;
- public abstract void Register ();
-
public abstract PendingImplementation GetPendingImplementations ();
TypeExpr[] GetPartialBases (out TypeExpr base_class, out bool error)
base_class = null;
int count = Bases.Count;
- int start, i, j;
+ int start = 0, i, j;
if (Kind == Kind.Class){
TypeExpr name = ResolveBaseTypeExpr (
return null;
}
- if (name.IsClass){
+ if (!name.IsInterface) {
+ // base_class could be a class, struct, enum, delegate.
+ // This is validated in GetClassBases.
base_class = name;
start = 1;
- } else {
- start = 0;
}
- } else {
- start = 0;
}
TypeExpr [] ifaces = new TypeExpr [count-start];
for (i = 0; i < count; i++) {
TypeExpr iface = (TypeExpr) ifaces [i];
- if ((Kind != Kind.Class) && !iface.IsInterface){
- string what = Kind == Kind.Struct ?
- "Struct" : "Interface";
-
- Report.Error (527, Location,
- "In {0} `{1}', type `{2}' is not "+
- "an interface", what, Name, iface.Name);
+ if (!iface.IsInterface) {
error = true;
- return null;
- }
- if (iface.IsClass) {
- if (base_class != null)
+ if (Kind != Kind.Class) {
+ string what = Kind == Kind.Struct ? "Struct" : "Interface";
+
+ Report.Error (527, Location,
+ "In {0} `{1}', type `{2}' is not "+
+ "an interface", what, Name, iface.Name);
+ }
+ else if (base_class != null)
Report.Error (1721, Location,
"In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
Name, iface.Name);
"In Class `{0}', `{1}' is not " +
"an interface, a base class must be listed first", Name, iface.Name);
}
- error = true;
- return null;
+ continue;
}
for (int x = 0; x < i; x++) {
"`{0}' is already listed in " +
"interface list", iface.Name);
error = true;
- return null;
}
}
if ((Kind == Kind.Interface) &&
- !iface.AsAccessible (Parent, ModFlags))
+ !iface.AsAccessible (Parent, ModFlags)) {
Report.Error (61, Location,
"Inconsistent accessibility: base " +
"interface `{0}' is less accessible " +
"than interface `{1}'", iface.Name,
Name);
+ error = true;
+ }
}
+ if (error)
+ return null;
+
return ifaces;
}
InTransit = true;
- ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
-
TypeExpr[] iface_exprs = GetClassBases (out base_type, out error);
if (error)
return null;
if (base_type != null) {
// FIXME: I think this should be ...ResolveType (Parent.EmitContext).
// However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
- ptype = base_type.ResolveType (ec);
+ ptype = base_type.ResolveType (TypeResolveEmitContext);
if (ptype == null) {
error = true;
return null;
Name, type_attributes, ptype, null);
} else {
- TypeBuilder builder = Parent.DefineType ();
+ TypeBuilder builder = Parent.TypeBuilder;
if (builder == null)
return null;
Report.RuntimeMissingSupport (Location, "static classes");
return null;
}
-
+
+ if (Parts != null) {
+ ec = null;
+ foreach (ClassPart part in Parts) {
+ part.TypeBuilder = TypeBuilder;
+ part.ptype = ptype;
+ part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
+ part.ec.ContainerType = TypeBuilder;
+ }
+ }
+ else {
+ ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
+ ec.ContainerType = TypeBuilder;
+ }
+
//
// Structs with no fields need to have at least one byte.
// The right thing would be to set the PackingSize in a DefineType
if (iface_exprs != null) {
// FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
// However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
- ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
+ TypeResolveEmitContext.ContainerType = TypeBuilder;
+ ifaces = TypeManager.ExpandInterfaces (TypeResolveEmitContext, iface_exprs);
if (ifaces == null) {
error = true;
return null;
TypeManager.RegisterBuilder (TypeBuilder, ifaces);
}
- //
- // Finish the setup for the EmitContext
- //
- ec.ContainerType = TypeBuilder;
-
TypeManager.AddUserType (Name, TypeBuilder, this);
- if ((base_type != null) && base_type.IsAttribute) {
- RootContext.RegisterAttribute (this);
- } else if (!(this is Iterator))
+ if (!(this is Iterator))
RootContext.RegisterOrder (this);
if (!DefineNestedTypes ()) {
return false;
}
- if (Parts != null) {
- foreach (ClassPart part in Parts) {
- part.TypeBuilder = TypeBuilder;
- part.ptype = ptype;
- part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
- }
- }
-
return true;
}
bool DoDefineMembers ()
{
- //
- // We need to be able to use the member cache while we are checking/defining
- //
- if (TypeBuilder.BaseType != null)
- base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
-
- if (TypeBuilder.IsInterface)
- base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
-
if (IsTopLevel) {
if ((ModFlags & Modifiers.NEW) != 0)
Error_KeywordNotAllowed (Location);
} else {
- // HACK: missing implemenation
- // This is not fully functional. Better way how to handle this is to have recursive definition of containers
- // instead of flat as we have now.
- // Now we are not able to check inner attribute class because its parent had not been defined.
-
- // TODO: remove this if
- if (Parent.MemberCache != null) {
- MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
- if (conflict_symbol == null) {
- if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
- Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
- } else {
- if ((ModFlags & Modifiers.NEW) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
- }
+ MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
+ if (conflict_symbol == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
}
- }
+ }
}
DefineContainerMembers (constants);
DefineContainerMembers (fields);
- if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
+ if ((Kind == Kind.Class) && !(this is ClassPart)){
if ((instance_constructors == null) &&
!(this is StaticClass)) {
if (default_constructor == null)
return false;
}
}
+
+ public override Type FindNestedType (string name)
+ {
+ ArrayList [] lists = { types, enums, delegates, interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; ++i) {
+ DeclSpace ds = (DeclSpace) list [i];
+ if (ds.Basename == name) {
+ ds.DefineType ();
+ return ds.TypeBuilder;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private void FindMembers_NestedTypes (int modflags,
+ BindingFlags bf, MemberFilter filter, object criteria,
+ ref ArrayList members)
+ {
+ ArrayList [] lists = { types, enums, delegates, interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; i++) {
+ DeclSpace ds = (DeclSpace) list [i];
+
+ if ((ds.ModFlags & modflags) == 0)
+ continue;
+
+ TypeBuilder tb = ds.TypeBuilder;
+ if (tb == null) {
+ if (!(criteria is string) || ds.Basename.Equals (criteria))
+ tb = ds.DefineType ();
+ }
+
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
+ members.Add (tb);
+ }
+ }
+ }
+ }
/// <summary>
/// This method returns the members of this type just like Type.FindMembers would
if (fields != null) {
int len = fields.Count;
for (int i = 0; i < len; i++) {
- Field f = (Field) fields [i];
+ FieldMember f = (FieldMember) fields [i];
if ((f.ModFlags & modflags) == 0)
continue;
continue;
FieldBuilder fb = con.FieldBuilder;
+ if (fb == null) {
+ if (con.Define ())
+ fb = con.FieldBuilder;
+ }
if (fb != null && filter (fb, criteria) == true) {
if (members == null)
members = new ArrayList ();
}
}
- if ((mt & MemberTypes.NestedType) != 0) {
- 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)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- 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 (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- 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 (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (interfaces != null) {
- int len = interfaces.Count;
- for (int i = 0; i < len; i++) {
- TypeContainer iface = (TypeContainer) interfaces [i];
-
- if ((iface.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = iface.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
- }
+ if ((mt & MemberTypes.NestedType) != 0)
+ FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
if ((mt & MemberTypes.Constructor) != 0){
if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
}
if (fields != null)
- foreach (Field f in fields)
+ foreach (FieldMember f in fields)
f.Emit ();
if (events != null){
public virtual MemberCache BaseCache {
get {
+ if (base_cache != null)
+ return base_cache;
+ if (TypeBuilder.BaseType != null)
+ base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
+ if (TypeBuilder.IsInterface)
+ base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
return base_cache;
}
}
return pc;
}
- pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
+ if (parent is ClassPart)
+ parent = ((ClassPart) parent).PartialContainer;
+
+ pc = new PartialContainer (ns.NS, parent, member_name, mod_flags, kind, loc);
RootContext.Tree.RecordDecl (full_name, pc);
- parent.AddType (pc);
- pc.Register ();
+
+ if (kind == Kind.Interface)
+ parent.AddInterface (pc);
+ else if (kind == Kind.Class || kind == Kind.Struct)
+ parent.AddClassOrStruct (pc);
+ else
+ throw new InvalidOperationException ();
+
return pc;
}
if (pc == null) {
// An error occured; create a dummy container, but don't
// register it.
- pc = new PartialContainer (ns, parent, name, mod, kind, loc);
+ pc = new PartialContainer (ns.NS, parent, name, mod, kind, loc);
}
- ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
+ ClassPart part = new ClassPart (ns, pc, parent, mod, attrs, kind, loc);
pc.AddPart (part);
return part;
}
- protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
+ protected PartialContainer (Namespace ns, TypeContainer parent,
MemberName name, int mod, Kind kind, Location l)
- : base (ns, parent, name, null, kind, l)
+ : base (null, parent, name, null, kind, l)
{
- this.Namespace = ns.NS;
+ this.Namespace = ns;
switch (kind) {
case Kind.Class:
this.OriginalModFlags = mod;
}
- public override void Register ()
- {
- if (Kind == Kind.Interface)
- Parent.AddInterface (this);
- else if (Kind == Kind.Class || Kind == Kind.Struct)
- Parent.AddClassOrStruct (this);
- else
- throw new InvalidOperationException ();
- }
-
public override PendingImplementation GetPendingImplementations ()
{
return PendingImplementation.GetPendingImplementations (this);
}
- public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
- Location l)
- {
- ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
- AddPart (part);
- return part;
- }
-
public override TypeAttributes TypeAttr {
get {
return base.TypeAttr | DefaultTypeAttributes;
public readonly PartialContainer PartialContainer;
public readonly bool IsPartial;
- public ClassPart (NamespaceEntry ns, PartialContainer parent,
+ public ClassPart (NamespaceEntry ns, PartialContainer pc, TypeContainer parent,
int mod, Attributes attrs, Kind kind, Location l)
- : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
+ : base (ns, parent, pc.MemberName, attrs, kind, l)
{
- this.PartialContainer = parent;
+ this.PartialContainer = pc;
this.IsPartial = true;
int accmods;
- if (parent.Parent == null)
+ if (parent == null || parent == RootContext.Tree.Types)
accmods = Modifiers.INTERNAL;
else
accmods = Modifiers.PRIVATE;
- this.ModFlags = Modifiers.Check (
- parent.AllowedModifiers, mod, accmods, l);
- }
-
- public override void Register ()
- {
+ this.ModFlags = Modifiers.Check (pc.AllowedModifiers, mod, accmods, l);
}
public override PendingImplementation GetPendingImplementations ()
interface_type, full, name, loc);
}
+ public override bool EmitFieldInitializers (EmitContext ec)
+ {
+ return PartialContainer.EmitFieldInitializers (ec);
+ }
+
+ public override Type FindNestedType (string name)
+ {
+ return PartialContainer.FindNestedType (name);
+ }
+
public override MemberCache BaseCache {
get {
return PartialContainer.BaseCache;
return;
}
- if (a.Type == TypeManager.struct_layout_attribute_type
- && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
+ if (a.Type == TypeManager.struct_layout_attribute_type &&
+ a.GetLayoutKindValue () == LayoutKind.Explicit)
hasExplicitLayout = true;
base.ApplyAttributeBuilder (a, cb);
}
}
}
-
- public override void Register ()
- {
- Parent.AddClassOrStruct (this);
- }
}
/// <summary>
{
if (RootContext.Version == LanguageVersion.ISO_1) {
Report.FeatureIsNotStandardized (l, "static classes");
- Environment.Exit (1);
}
}
continue;
}
- if ((m.ModFlags & Modifiers.STATIC) != 0)
+ if ((m.ModFlags & Modifiers.PROTECTED) != 0)
+ Report.Warning (628, 4, m.Location, "'{0}': new protected member declared in static class", m.GetSignatureForError (this));
+
+ if (m is Indexer) {
+ Report.Error (720, m.Location, "'{0}': cannot declare indexers in a static class", m.GetSignatureForError (this));
+ continue;
+ }
+
+ if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
continue;
if (m is Constructor) {
Modifiers.SEALED |
Modifiers.UNSAFE;
- // Information in the case we are an attribute type
- AttributeUsageAttribute attribute_usage;
-
public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
Attributes attrs, Location l)
: base (ns, parent, name, attrs, Kind.Class, l)
{
this.ModFlags = mod;
- attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
}
virtual protected int AllowedModifiersProp {
}
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Class;
- }
- }
-
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
- if (a.UsageAttribute != null) {
+ if (a.Type == TypeManager.attribute_usage_type) {
if (ptype != TypeManager.attribute_type && !ptype.IsSubclassOf (TypeManager.attribute_type) &&
TypeBuilder.FullName != "System.Attribute") {
Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
}
- attribute_usage = a.UsageAttribute;
}
base.ApplyAttributeBuilder (a, cb);
}
- public AttributeUsageAttribute AttributeUsage {
- get {
- return attribute_usage;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.AutoLayout | TypeAttributes.Class;
this.ModFlags |= Modifiers.SEALED;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Struct;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.SequentialLayout |
TypeAttributes.Sealed |
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
}
- public override void Register ()
- {
- Parent.AddInterface (this);
- }
-
public override PendingImplementation GetPendingImplementations ()
{
return null;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Interface;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.AutoLayout |
TypeAttributes.Abstract |
if ((ModFlags & Modifiers.NEW) == 0) {
if (MemberType != TypeManager.TypeToCoreType (base_ret_type)) {
Report.SymbolRelatedToPreviousError (base_method);
- Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
- "change return type when overriding inherited member");
+ if (this is PropertyBase) {
+ Report.Error (1715, Location, "'{0}': type must be '{1}' to match overridden member '{2}'",
+ GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
+ }
+ else {
+ Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
+ "change return type when overriding inherited member");
+ }
return false;
}
} else {
// Now we check that the overriden method is not final
if (base_method.IsFinal) {
- // This happens when implementing interface methods.
- if (base_method.IsHideBySig && base_method.IsVirtual) {
- Report.Error (
- 506, Location, Parent.MakeName (Name) +
- ": cannot override inherited member `" +
- name + "' because it is not " +
- "virtual, abstract or override");
- } else
- Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
- "override inherited member `" + name +
- "' because it is sealed.");
+ Report.SymbolRelatedToPreviousError (base_method);
+ Report.Error (239, Location, "'{0}': cannot override inherited member '{1}' because it is sealed",
+ GetSignatureForError (), TypeManager.CSharpSignature (base_method));
ok = false;
}
//
}
Report.SymbolRelatedToPreviousError (method);
- Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
+ if (this is Operator && method is Operator)
+ Report.Error (557, Location, "Duplicate user-defined conversion in type '{0}'", Parent.Name);
+ else
+ Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
return true;
}
return;
}
- if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+ if (a.Type == TypeManager.methodimpl_attr_type &&
+ (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
}
if (!DoDefine ())
return false;
+ if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
+ Error1599 (Location, ReturnType);
+ return false;
+ }
+
if (!CheckBase ())
return false;
MethodData = null;
}
+ public static void Error1599 (Location loc, Type t)
+ {
+ Report.Error (1599, loc, "Method or delegate cannot return type '{0}'", TypeManager.CSharpName (t));
+ }
+
protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
{
MethodInfo mi = (MethodInfo) container.BaseCache.FindMemberToOverride (
}
}
+ protected override bool CheckBase() {
+ if (!base.CheckBase ())
+ return false;
+
+ // TODO: Destructor should derive from MethodCore
+ if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
+ base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
+ Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
+ return false;
+ }
+
+ return true;
+ }
+
public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
{
return new EmitContext (
{
Expression base_constructor_group;
Type t;
+ bool error = false;
ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
loc);
if (base_constructor_group == null){
+ error = true;
base_constructor_group = Expression.MemberLookup (
- ec, t, ".ctor", MemberTypes.Constructor,
+ ec, t, null, t, ".ctor", MemberTypes.Constructor,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
loc);
+ }
- if (base_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");
+ int errors = Report.Errors;
+ if (base_constructor_group != null)
+ base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
+ ec, (MethodGroupExpr) base_constructor_group, argument_list,
+ false, loc);
+
+ if (base_constructor == null) {
+ if (errors == Report.Errors)
+ Report.Error (1501, loc, "Can not find a constructor for this argument list");
return false;
}
-
- base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
- ec, (MethodGroupExpr) base_constructor_group, argument_list,
- false, loc);
-
- if (base_constructor == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
+
+ if (error) {
+ Report.Error (122, loc, "`{0}' is inaccessible due to its protection level",
+ TypeManager.CSharpSignature (base_constructor));
+ base_constructor = null;
return false;
}
if (base_constructor == caller_builder){
- Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
+ Report.Error (516, loc, "Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder));
return false;
}
}
}
if (Initializer != null) {
- if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
+ if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent) == null)
Initializer.CheckObsoleteAttribute (Parent, Location);
else
ec.TestObsoleteMethodUsage = false;
Type[] ParameterTypes = method.ParameterTypes;
if (container.Pending != null){
- if (member is Indexer)
+ if (member is Indexer) // TODO: test it, but it should work without this IF
implementing = container.Pending.IsInterfaceIndexer (
member.InterfaceType, method.ReturnType, ParameterTypes);
else
if (member.InterfaceType != null){
if (implementing == null){
- Report.Error (539, method.Location,
- "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () );
+ if (member is PropertyBase) {
+ Report.Error (550, method.Location, "'{0}' is an accessor not found in interface member '{1}'",
+ method.GetSignatureForError (container), member.ExplicitInterfaceName);
+
+ } else {
+ Report.Error (539, method.Location,
+ "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () );
+ }
+ return false;
+ }
+ if (implementing.IsSpecialName && !((member is PropertyBase || member is EventProperty))) {
+ Report.SymbolRelatedToPreviousError (implementing);
+ Report.Error (683, method.Location, "'{0}' explicit method implementation cannot implement '{1}' because it is an accessor",
+ member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
return false;
}
method_name = member.InterfaceType.FullName + "." + name;
+ } else {
+ if (implementing != null && method is AbstractPropertyEventMethod && !implementing.IsSpecialName) {
+ Report.SymbolRelatedToPreviousError (implementing);
+ Report.Error (686, method.Location, "Accessor '{0}' cannot implement interface member '{1}' for type '{2}'. Use an explicit interface implementation",
+ method.GetSignatureForError (container), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
+ return false;
+ }
}
}
else
ec = method.CreateEmitContext (container, null);
- if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
+ if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container) != null)
ec.TestObsoleteMethodUsage = false;
Location loc = method.Location;
}
}
+ // Should derive from MethodCore
public class Destructor : Method {
public Destructor (TypeContainer ds, Expression return_type, int mod,
else
e = new ArrayCreation (Type, "", (ArrayList)init, Location);
- ec.IsFieldInitializer = true;
- e = e.DoResolve (ec);
- ec.IsFieldInitializer = false;
+ EmitContext parent_ec = Parent.EmitContext;
+
+ bool old_is_static = parent_ec.IsStatic;
+ parent_ec.IsStatic = ec.IsStatic;
+ parent_ec.IsFieldInitializer = true;
+ e = e.DoResolve (parent_ec);
+ parent_ec.IsFieldInitializer = false;
+ parent_ec.IsStatic = old_is_static;
init_expr = e;
init_expr_initialized = true;
}
if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
- }
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+ }
return true;
}
return TypeManager.GetFullNameSignature (FieldBuilder);
}
+ protected virtual bool IsFieldClsCompliant {
+ get {
+ if (FieldBuilder == null)
+ return true;
+
+ return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
+ }
+ }
+
public override string[] ValidAttributeTargets {
get {
return attribute_targets;
if (!base.VerifyClsCompliance (ds))
return false;
- if (FieldBuilder == null) {
- return true;
- }
-
- if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
+ if (!IsFieldClsCompliant) {
Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
}
return true;
public abstract class FieldMember: FieldBase
{
-
-
protected FieldMember (TypeContainer parent, Expression type, int mod,
int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
- : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
+ : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, init, attrs, loc)
{
+ if ((mod & Modifiers.ABSTRACT) != 0)
+ Report.Error (681, loc, "The modifier 'abstract' is not valid on fields. Try using a property instead");
}
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
MemberType = texpr.ResolveType (ec);
+ ec.InUnsafe = old_unsafe;
+
if (MemberType == TypeManager.void_type) {
Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
return false;
}
- ec.InUnsafe = old_unsafe;
-
if (!CheckBase ())
return false;
public override void Emit ()
{
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (Parent, Location, null, FieldBuilder.FieldType, ModFlags);
+ OptAttributes.Emit (ec, this);
+ }
+
if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
}
}
}
+ interface IFixedBuffer
+ {
+ FieldInfo Element { get; }
+ Type ElementType { get; }
+ }
+
+ public class FixedFieldExternal: IFixedBuffer
+ {
+ FieldInfo element_field;
+
+ public FixedFieldExternal (FieldInfo fi)
+ {
+ element_field = fi.FieldType.GetField (FixedField.FixedElementName);
+ }
+
+ #region IFixedField Members
+
+ public FieldInfo Element {
+ get {
+ return element_field;
+ }
+ }
+
+ public Type ElementType {
+ get {
+ return element_field.FieldType;
+ }
+ }
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Fixed buffer implementation
+ /// </summary>
+ public class FixedField: FieldMember, IFixedBuffer
+ {
+ public const string FixedElementName = "FixedElementField";
+ static int GlobalCounter = 0;
+ static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
+ static FieldInfo[] fi;
+
+ TypeBuilder fixed_buffer_type;
+ FieldBuilder element;
+ Expression size_expr;
+ int buffer_size;
+
+ const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE;
+
+ public FixedField (TypeContainer parent, Expression type, int mod, string name,
+ Expression size_expr, Attributes attrs, Location loc):
+ base (parent, type, mod, AllowedModifiers, new MemberName (name), null, attrs, loc)
+ {
+ if (RootContext.Version == LanguageVersion.ISO_1)
+ Report.FeatureIsNotStandardized (loc, "fixed sized buffers");
+
+ this.size_expr = size_expr;
+ }
+
+ public override bool Define()
+ {
+#if !NET_2_0
+ if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
+ Report.Warning (-23, Location, "Only not private or internal fixed sized buffers are supported by .NET 1.x");
+#endif
+
+ if (Parent.Kind != Kind.Struct) {
+ Report.Error (1642, Location, "Fixed buffer fields may only be members of structs");
+ return false;
+ }
+
+ if (!base.Define ())
+ return false;
+
+ if (!MemberType.IsPrimitive) {
+ Report.Error (1663, Location, "Fixed sized buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double");
+ return false;
+ }
+
+ Expression e = size_expr.Resolve (Parent.EmitContext);
+ if (e == null)
+ return false;
+
+ Constant c = e as Constant;
+ if (c == null) {
+ Report.Error (133, Location, "The expression being assigned to '{0}' must be constant", GetSignatureForError ());
+ return false;
+ }
+
+ buffer_size = (int)c.GetValue ();
+ if (buffer_size <= 0) {
+ Report.Error (1665, Location, "Fixed sized buffer '{0}' must have a length greater than zero", GetSignatureForError ());
+ return false;
+ }
+ buffer_size *= Expression.GetTypeSize (MemberType);
+
+ // Define nested
+ string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
+
+ fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
+ TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
+ element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
+ RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
+
+ FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
+ TypeManager.RegisterFieldBase (FieldBuilder, this);
+
+ return true;
+ }
+
+ public override void Emit()
+ {
+ if (fi == null)
+ fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
+
+ object[] fi_val = new object[1];
+ fi_val [0] = buffer_size;
+
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
+ ctor_args, fi, fi_val);
+ fixed_buffer_type.SetCustomAttribute (cab);
+
+#if NET_2_0
+ cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
+ FieldBuilder.SetCustomAttribute (cab);
+#endif
+ base.Emit ();
+ }
+
+ protected override bool IsFieldClsCompliant {
+ get {
+ return false;
+ }
+ }
+
+ #region IFixedField Members
+
+ public FieldInfo Element {
+ get {
+ return element;
+ }
+ }
+
+ public Type ElementType {
+ get {
+ return MemberType;
+ }
+ }
+
+ #endregion
+ }
+
//
// The Field class is used to represents class/struct fields during parsing.
//
return true;
}
-
- public override void Emit ()
- {
- if (OptAttributes != null) {
- EmitContext ec = new EmitContext (
- Parent, Location, null, FieldBuilder.FieldType,
- ModFlags);
- OptAttributes.Emit (ec, this);
- }
-
- base.Emit ();
- }
}
//
if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
Report.FeatureIsNotStandardized (Location, "accessor modifiers");
- Environment.Exit (1);
}
}
{
}
+ // TODO: one GetSignatureForError is enough (reuse Parent member)
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ string core = base.GetSignatureForError (tc);
+ return core.Replace (TypeContainer.DefaultIndexerName,
+ String.Format ("this[{0}]", TypeManager.CSharpName (ParameterTypes)));
+ }
+
public override Type[] ParameterTypes {
get {
return method.ParameterTypes;
if (IsExplicitImpl) {
Report.Error (415, indexer_attr.Location,
- "The 'IndexerName' attribute is valid only on an" +
+ "The 'IndexerName' attribute is valid only on an " +
"indexer that is not an explicit interface member declaration");
return false;
}