// class.cs: Class and Struct handlers
//
// Authors: Miguel de Icaza (miguel@gnu.org)
-// Martin Baulig (martin@gnome.org)
+// Martin Baulig (martin@ximian.com)
// Marek Safar (marek.safar@seznam.cz)
//
// Licensed under the terms of the GNU GPL
//
// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
//
//
// 2002-10-11 Miguel de Icaza <miguel@ximian.com>
using System;
using System.Text;
using System.Collections;
+using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Xml;
using Mono.CompilerServices.SymbolWriter;
// Holds the parts of a partial class;
ArrayList parts;
- // The emit context for toplevel objects.
- EmitContext ec;
-
//
// Pointers to the default constructor and the default static constructor
//
protected Type[] ifaces;
protected Type ptype;
- // The parent member container and our member cache
- IMemberContainer parent_container;
+ // The parent member cache and our member cache
+ MemberCache parent_cache;
MemberCache member_cache;
public const string DefaultIndexerName = "Item";
int start, i, j;
if (Kind == Kind.Class){
- TypeExpr name = ResolveTypeExpr (
- (Expression) Bases [0], false, Location);
+ TypeExpr name = ResolveTypeExpr ((Expression) Bases [0], Location);
if (name == null){
error = true;
for (i = start, j = 0; i < count; i++, j++){
Expression name = (Expression) Bases [i];
- TypeExpr resolved = ResolveTypeExpr (name, false, Location);
+ TypeExpr resolved = ResolveTypeExpr (name, Location);
if (resolved == null) {
error = true;
return null;
return null;
}
- if (!parent.AsAccessible (this, ModFlags))
- Report.Error (60, Location,
- "Inconsistent accessibility: base class `" +
- parent.Name + "' is less accessible than class `" +
- Name + "'");
+ if (!parent.AsAccessible (this, ModFlags)) {
+ Report.SymbolRelatedToPreviousError (parent.Type);
+ Report.Error (60, Location, "Inconsistent accessibility: base class '{0}' is less accessible than class '{1}'",
+ TypeManager.CSharpName (parent.Type), GetSignatureForError ());
+ }
}
if (parent != null)
}
if (iface.IsClass) {
- if (parent != null){
- Report.Error (527, Location,
+ if (parent != null)
+ Report.Error (1721, Location,
+ "In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
+ Name, iface.Name);
+ else {
+ Report.Error (1722, Location,
"In Class `{0}', `{1}' is not " +
- "an interface", Name, iface.Name);
- error = true;
- return null;
+ "an interface, a base class must be listed first", Name, iface.Name);
}
+ error = true;
+ return null;
}
for (int x = 0; x < i; x++) {
if (iface == t)
continue;
- if (!TypeManager.MayBecomeEqualGenericInstances (iface, t))
+ Type[] infered = new Type [CountTypeParameters];
+ if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, infered, null))
continue;
Report.Error (
}
}
catch (ArgumentException) {
- Report.RuntimeMissingSupport ("static classes");
+ Report.RuntimeMissingSupport (Location, "static classes");
return null;
}
TypeManager.AddUserType (Name, TypeBuilder, this);
- if (IsGeneric) {
- foreach (TypeParameter type_param in TypeParameters) {
- if (!type_param.Resolve (this)) {
- error = true;
- return null;
- }
- }
-
- CurrentType = new ConstructedType (
- Name, TypeParameters, Location);
+ TypeExpr current_type = null;
+ if (IsGeneric) {
string[] param_names = new string [TypeParameters.Length];
for (int i = 0; i < TypeParameters.Length; i++)
param_names [i] = TypeParameters [i].Name;
GenericTypeParameterBuilder[] gen_params;
-
gen_params = TypeBuilder.DefineGenericParameters (param_names);
- for (int i = 0; i < gen_params.Length; i++)
- TypeParameters [i].Define (gen_params [i]);
+ int offset = CountTypeParameters - CurrentTypeParameters.Length;
+ for (int i = offset; i < gen_params.Length; i++)
+ CurrentTypeParameters [i - offset].Define (gen_params [i]);
+
+ foreach (TypeParameter type_param in CurrentTypeParameters) {
+ if (!type_param.Resolve (this)) {
+ error = true;
+ return null;
+ }
+ }
+
+ for (int i = offset; i < gen_params.Length; i++)
+ CurrentTypeParameters [i - offset].DefineConstraints ();
+
+ current_type = new ConstructedType (Name, TypeParameters, Location);
}
if (IsGeneric) {
}
}
- ConstructedType constructed = parent_type as ConstructedType;
- if ((constructed == null) && (parent_type != null))
- ptype = parent_type.ResolveType (ec);
- else
- ptype = null;
-
- if (constructed != null) {
- ptype = constructed.ResolveType (ec);
- if (ptype == null) {
+ if (parent_type != null) {
+ parent_type = parent_type.ResolveAsTypeTerminal (ec);
+ if (parent_type == null) {
error = true;
return null;
}
+
+ ptype = parent_type.Type;
}
if (!CheckRecursiveDefinition ()) {
}
}
+ if (current_type != null) {
+ current_type = current_type.ResolveAsTypeTerminal (ec);
+ if (current_type == null) {
+ error = true;
+ return null;
+ }
+
+ CurrentType = current_type.Type;
+ }
+
//
// Finish the setup for the EmitContext
//
foreach (ClassPart part in Parts) {
part.TypeBuilder = TypeBuilder;
part.parent_type = parent_type;
+ part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
}
}
return members_defined_ok;
}
- bool DoDefineMembers ()
+ protected virtual bool DoDefineMembers ()
{
//
// We need to be able to use the member cache while we are checking/defining
//
if (TypeBuilder.BaseType != null)
- parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
+ parent_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
- // TODO:
- //if (TypeBuilder.IsInterface) {
- // parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types);
- //}
+ if (TypeBuilder.IsInterface)
+ parent_cache = TypeManager.LookupParentInterfacesCache (TypeBuilder);
if (IsTopLevel) {
if ((ModFlags & Modifiers.NEW) != 0)
DefineContainerMembers (delegates);
if (CurrentType != null) {
- GenericType = CurrentType.ResolveType (ec);
+ GenericType = CurrentType;
ec.ContainerType = GenericType;
}
#if CACHE
if (!(this is ClassPart))
- member_cache = new MemberCache (this);
+ member_cache = new MemberCache (this);
#endif
if (parts != null) {
public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
{
- return ParentContainer.MemberCache.FindMemberWithSameName (name, ignore_methods, null);
+ return ParentCache.FindMemberWithSameName (name, ignore_methods, null);
}
/// <summary>
type_bases = null;
OptAttributes = null;
ifaces = null;
- parent_container = null;
+ parent_cache = null;
member_cache = null;
}
}
}
+ public Constructor DefaultStaticConstructor {
+ get { return default_static_constructor; }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds))
VerifyClsName ();
- // parent_container is null for System.Object
- if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
- Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (parent_container.Type));
+ if (IsGeneric) {
+ Report.Error (3024, Location, "'{0}': type parameters are not CLS-compliant",
+ GetSignatureForError ());
+ return false;
+ }
+
+ Type base_type = TypeBuilder.BaseType;
+ if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
+ Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
}
return true;
}
/// </summary>
void VerifyClsName ()
{
- Hashtable parent_members = parent_container == null ?
+ Hashtable parent_members = parent_cache == null ?
new Hashtable () :
- parent_container.MemberCache.GetPublicMembers ();
+ parent_cache.GetPublicMembers ();
Hashtable this_members = new Hashtable ();
foreach (DictionaryEntry entry in defined_names) {
return FindMembers (mt, new_bf, null, null);
}
- public virtual IMemberContainer ParentContainer {
+ //
+ // Generates xml doc comments (if any), and if required,
+ // handle warning report.
+ //
+ internal override void GenerateDocComment (DeclSpace ds)
+ {
+ DocUtil.GenerateTypeDocComment (this, ds);
+ }
+
+ public override string DocCommentHeader {
+ get { return "T:"; }
+ }
+
+ public virtual MemberCache ParentCache {
get {
- return parent_container;
+ return parent_cache;
}
}
public readonly TypeAttributes DefaultTypeAttributes;
static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
- MemberName name, int mod_flags, Kind kind,
+ MemberName member_name, int mod_flags, Kind kind,
Location loc)
{
PartialContainer pc;
- string full_name = name.GetName (true);
+ string full_name = member_name.GetName (true);
DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
if (ds != null) {
pc = ds as PartialContainer;
260, ds.Location, "Missing partial modifier " +
"on declaration of type `{0}'; another " +
"partial implementation of this type exists",
- name);
+ member_name.GetTypeName());
Report.LocationOfPreviousError (loc);
return null;
Report.Error (
261, loc, "Partial declarations of `{0}' " +
"must be all classes, all structs or " +
- "all interfaces", name);
+ "all interfaces", member_name.GetTypeName ());
return null;
}
Report.Error (
262, loc, "Partial declarations of `{0}' " +
"have conflicting accessibility modifiers",
- name);
+ member_name.GetTypeName ());
return null;
}
return pc;
}
- pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc);
+ pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
RootContext.Tree.RecordDecl (full_name, pc);
parent.AddType (pc);
pc.Register ();
interface_type, full, name, loc);
}
- public override IMemberContainer ParentContainer {
+ public override MemberCache ParentCache {
get {
- return PartialContainer.ParentContainer;
+ return PartialContainer.ParentCache;
}
}
}
public abstract class ClassOrStruct : TypeContainer {
bool hasExplicitLayout = false;
+ ListDictionary declarative_security;
public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
MemberName name, Attributes attrs, Kind kind,
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+ if (declarative_security == null)
+ declarative_security = new ListDictionary ();
+
+ a.ExtractSecurityPermissionSet (declarative_security);
+ return;
+ }
+
if (a.Type == TypeManager.struct_layout_attribute_type
&& (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
hasExplicitLayout = true;
base.ApplyAttributeBuilder (a, cb);
}
+ public override void Emit()
+ {
+ base.Emit ();
+
+ if (declarative_security != null) {
+ foreach (DictionaryEntry de in declarative_security) {
+ TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+ }
+ }
+ }
+
public override void Register ()
{
Parent.AddClassOrStruct (this);
public readonly Parameters Parameters;
public readonly GenericMethod GenericMethod;
public readonly DeclSpace ds;
- protected Block block;
+ protected ToplevelBlock block;
//
// Parameters, cached for semantic analysis.
}
}
- public Block Block {
+ public ToplevelBlock Block {
get {
return block;
}
return true;
// Is null for System.Object while compiling corlib and base interfaces
- if (Parent.ParentContainer == null) {
+ if (Parent.ParentCache == null) {
if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
}
"change return type when overriding inherited member");
return false;
}
+ } else {
+ if (parent_method.IsAbstract && !IsInterface) {
+ Report.SymbolRelatedToPreviousError (parent_method);
+ Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
+ return false;
+ }
+ }
+
+ if (parent_method.IsSpecialName && !(this is PropertyBase)) {
+ Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method));
+ return false;
}
if (RootContext.WarningLevel > 2) {
return true;
}
+ MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ if (conflict_symbol != null) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ if (this is PropertyBase)
+ Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
+ else
+ Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
+ } else
Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
return false;
}
- MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
if (conflict_symbol == null) {
if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
- //
- // special case for "protected internal"
- //
-
- if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- //
- // when overriding protected internal, the method can be declared
- // protected internal only within the same assembly
- //
-
- if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- if (Parent.TypeBuilder.Assembly != parent_method.DeclaringType.Assembly){
- //
- // assemblies differ - report an error
- //
-
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- } else if (thisp != parentp) {
- //
- // same assembly, but other attributes differ - report an error
- //
-
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- };
- } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
- //
- // if it's not "protected internal", it must be "protected"
- //
-
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- } else if (Parent.TypeBuilder.Assembly == parent_method.DeclaringType.Assembly) {
- //
- // protected within the same assembly - an error
- //
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
- (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
- //
- // protected ok, but other attributes differ - report an error
- //
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- }
- } else {
- if (thisp != parentp){
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
- ok = false;
- }
+ if (!CheckAccessModifiers (thisp, parentp, parent_method)) {
+ Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ ok = false;
}
}
Report.SymbolRelatedToPreviousError (parent_method);
if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
if (RootContext.WarningLevel >= 2)
- Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), parent_method);
+ Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method));
} else
Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
}
return ok;
}
+
+ protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes parentp, MethodInfo base_method)
+ {
+ 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 != base_method.DeclaringType.Assembly){
+ //
+ // assemblies differ - report an error
+ //
+
+ return false;
+ } else if (thisp != parentp) {
+ //
+ // same assembly, but other attributes differ - report an error
+ //
+
+ return false;
+ };
+ } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
+ //
+ // if it's not "protected internal", it must be "protected"
+ //
+ return false;
+ } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
+ //
+ // protected within the same assembly - an error
+ //
+ return false;
+ } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
+ (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+ //
+ // protected ok, but other attributes differ - report an error
+ //
+ return false;
+ }
+ return true;
+ } else {
+ return (thisp == parentp);
+ }
+ }
+
void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
{
//
protected virtual bool DoDefineParameters ()
{
+ EmitContext ec = ds.EmitContext;
+ if (ec == null)
+ throw new InternalErrorException ("DoDefineParameters invoked too early");
+
+ bool old_unsafe = ec.InUnsafe;
+ ec.InUnsafe = InUnsafe;
// Check if arguments were correct
- parameter_types = Parameters.GetParameterInfo (ds);
+ parameter_types = Parameters.GetParameterInfo (ec);
+ ec.InUnsafe = old_unsafe;
+
if ((parameter_types == null) ||
!CheckParameters (ds, parameter_types))
return false;
TypeParameter[] tparam = ds.IsGeneric ? ds.TypeParameters : null;
- parameter_info = new InternalParameters (ds, Parameters, tparam);
+ parameter_info = new InternalParameters (parameter_types, Parameters, tparam);
Parameter array_param = Parameters.ArrayParameter;
if ((array_param != null) &&
return false;
}
- if (gc.HasConstructor != ogc.HasConstructor) {
- error_425 (ot, t, name);
- return false;
- }
-
- if (ogc.HasClassConstraint != gc.HasClassConstraint) {
+ if ((gc.Attributes != ogc.Attributes) ||
+ (gc.HasClassConstraint != ogc.HasClassConstraint)) {
error_425 (ot, t, name);
return false;
}
}
if (!AttributeTester.IsClsCompliant (MemberType)) {
- Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
+ if ((this is Property) || (this is Indexer))
+ Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
+ GetSignatureForError ());
+ else
+ Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant",
+ GetSignatureForError ());
}
AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
return true;
}
+ bool MayUnify (MethodCore first, MethodCore second)
+ {
+ int a_type_params = 0;
+ if (first.GenericMethod != null)
+ a_type_params = first.GenericMethod.CountTypeParameters;
+
+ int b_type_params = 0;
+ if (second.GenericMethod != null)
+ b_type_params = second.GenericMethod.CountTypeParameters;
+
+ if (a_type_params != b_type_params)
+ return false;
+
+ Type[] class_infered, method_infered;
+ if (Parent.CountTypeParameters > 0)
+ class_infered = new Type [Parent.CountTypeParameters];
+ else
+ class_infered = null;
+
+ if (a_type_params > 0)
+ method_infered = new Type [a_type_params];
+ else
+ method_infered = null;
+
+ return TypeManager.MayBecomeEqualGenericInstances (
+ first.ParameterTypes, second.ParameterTypes, class_infered, method_infered);
+ }
+
protected bool IsDuplicateImplementation (MethodCore method)
{
if ((method == this) ||
if (param_types.Length != ParameterTypes.Length)
return false;
- int type_params = 0;
- if (GenericMethod != null)
- type_params = GenericMethod.CountTypeParameters;
-
- int m_type_params = 0;
- if (method.GenericMethod != null)
- m_type_params = method.GenericMethod.CountTypeParameters;
-
- if (type_params != m_type_params)
- return false;
-
bool equal = true;
- bool may_unify;
-
- Type[] infered_types;
- if (type_params > 0)
- infered_types = new Type [type_params];
- else
- infered_types = null;
-
- may_unify = Invocation.InferTypeArguments (
- param_types, ParameterTypes, ref infered_types);
-
- if (!may_unify) {
- if (type_params > 0)
- infered_types = new Type [type_params];
- else
- infered_types = null;
-
- may_unify = Invocation.InferTypeArguments (
- ParameterTypes, param_types, ref infered_types);
- }
+ bool may_unify = MayUnify (this, method);
for (int i = 0; i < param_types.Length; i++) {
if (param_types [i] != ParameterTypes [i])
// TODO: make operator compatible with MethodCore to avoid this
if (this is Operator && method is Operator) {
if (MemberType != method.MemberType)
- equal = false;
+ equal = may_unify = false;
}
if (equal) {
Report.Error (408, Location,
"`{0}' cannot define overload members that " +
"may unify for some type parameter substitutions",
- Parent.Name);
+ Parent.MemberName);
return true;
}
return false;
}
+ //
+ // Returns a string that represents the signature for this
+ // member which should be used in XML documentation.
+ //
+ public override string GetDocCommentName (DeclSpace ds)
+ {
+ return DocUtil.GetMethodDocCommentName (this, ds);
+ }
+
+ //
+ // Raised (and passed an XmlElement that contains the comment)
+ // when GenerateDocComment is writing documentation expectedly.
+ //
+ // FIXME: with a few effort, it could be done with XmlReader,
+ // that means removal of DOM use.
+ //
+ internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
+ {
+ DocUtil.OnMethodGenerateDocComment (this, ds, el);
+ }
+
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { return "M:"; }
+ }
+
protected override void VerifyObsoleteAttribute()
{
base.VerifyObsoleteAttribute ();
public MethodBuilder MethodBuilder;
public MethodData MethodData;
ReturnParameter return_attributes;
+ ListDictionary declarative_security;
/// <summary>
/// Modifiers allowed in a class declaration
return;
}
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+ if (declarative_security == null)
+ declarative_security = new ListDictionary ();
+ a.ExtractSecurityPermissionSet (declarative_security);
+ return;
+ }
+
if (a.Type == TypeManager.conditional_attribute_type) {
if (IsOperator || IsExplicitImpl) {
Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
if (GenericMethod != null) {
string mname = MemberName.GetMethodName ();
mb = Parent.TypeBuilder.DefineGenericMethod (mname, flags);
- if (!GenericMethod.Define (mb))
+ if (!GenericMethod.Define (mb, ReturnType))
return false;
}
flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodData = new MethodData (this, ParameterInfo, ModFlags, flags,
- this, mb, GenericMethod);
+ this, mb, GenericMethod, parent_method);
if (!MethodData.Define (Parent))
return false;
{
MethodData.Emit (Parent, this);
base.Emit ();
+
+ if (declarative_security != null) {
+ foreach (DictionaryEntry de in declarative_security) {
+ MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+ }
+ }
+
Block = null;
MethodData = null;
}
protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
{
- MethodInfo mi = (MethodInfo) container.ParentContainer.MemberCache.FindMemberToOverride (
+ MethodInfo mi = (MethodInfo) container.ParentCache.FindMemberToOverride (
container.TypeBuilder, Name, ParameterTypes, false);
if (mi == null)
public class Constructor : MethodCore, IMethodData {
public ConstructorBuilder ConstructorBuilder;
public ConstructorInitializer Initializer;
+ ListDictionary declarative_security;
// <summary>
// Modifiers allowed for a constructor.
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+ if (declarative_security == null) {
+ declarative_security = new ListDictionary ();
+ }
+ a.ExtractSecurityPermissionSet (declarative_security);
+ return;
+ }
+
ConstructorBuilder.SetCustomAttribute (cb);
}
base.Emit ();
+ if (declarative_security != null) {
+ foreach (DictionaryEntry de in declarative_security) {
+ ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+ }
+ }
+
block = null;
}
GenericMethod GenericMethod { get; }
Attributes OptAttributes { get; }
- Block Block { get; }
+ ToplevelBlock Block { get; }
EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
ObsoleteAttribute GetObsoleteAttribute ();
protected int modifiers;
protected MethodAttributes flags;
protected Type declaring_type;
+ protected MethodInfo parent_method;
EmitContext ec;
public MethodData (MemberBase member, InternalParameters parameters,
int modifiers, MethodAttributes flags,
IMethodData method, MethodBuilder builder,
- GenericMethod generic)
+ GenericMethod generic, MethodInfo parent_method)
: this (member, parameters, modifiers, flags, method)
{
this.builder = builder;
this.GenericMethod = generic;
+ this.parent_method = parent_method;
}
static string RemoveArity (string name)
string prefix;
if (member.IsExplicitImpl)
- prefix = RemoveArity (member.InterfaceType.FullName) + ".";
+ prefix = member.InterfaceType.FullName + ".";
else
prefix = "";
- string name = method.MethodName.Name;
+ string name = method.MethodName.Basename;
string method_name = prefix + name;
-
+
Type[] ParameterTypes = method.ParameterTypes;
if (container.Pending != null){
implementing = container.Pending.IsInterfaceMethod (
member.InterfaceType, name, method.ReturnType, ParameterTypes);
- if (member.InterfaceType != null && implementing == null){
- Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
- return false;
+ if (member.InterfaceType != null){
+ if (implementing == null){
+ Report.Error (539, method.Location,
+ "'{0}' in explicit interface declaration is not an interface", method_name);
+ return false;
+ }
}
}
return false;
if (container.CurrentType != null)
- declaring_type = container.CurrentType.ResolveType (ec);
+ declaring_type = container.CurrentType;
else
declaring_type = container.TypeBuilder;
bool is_override = member.IsExplicitImpl |
((modifiers & Modifiers.OVERRIDE) != 0);
- is_override &= IsImplementing;
+ if (implementing != null)
+ parent_method = implementing;
- if (!GenericMethod.DefineType (
- ec, builder, implementing, is_override))
+ if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
return false;
}
if (member is MethodCore)
((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
- Block block = method.Block;
+ SymbolWriter sw = CodeGen.SymbolWriter;
+ ToplevelBlock block = method.Block;
//
// abstract or extern methods have no bodies
source.CloseMethod ();
}
- void EmitDestructor (EmitContext ec, Block block)
+ void EmitDestructor (EmitContext ec, ToplevelBlock block)
{
ILGenerator ig = ec.ig;
protected virtual bool DoDefineBase ()
{
+ EmitContext ec = Parent.EmitContext;
+ if (ec == null)
+ throw new InternalErrorException ("MemberBase.DoDefine called too early");
+
if (Name == null)
throw new InternalErrorException ();
protected virtual bool DoDefine (DeclSpace decl)
{
+ EmitContext ec = decl.EmitContext;
+ if (ec == null)
+ throw new InternalErrorException ("MemberBase.DoDefine called too early");
+
+ ec.InUnsafe = InUnsafe;
+
// Lookup Type, verify validity
- MemberType = decl.ResolveType (Type, false, Location);
- if (MemberType == null)
+ bool old_unsafe = ec.InUnsafe;
+ ec.InUnsafe = InUnsafe;
+ TypeExpr texpr = Type.ResolveAsTypeTerminal (ec);
+ ec.InUnsafe = old_unsafe;
+
+ if (texpr == null)
return false;
+ MemberType = texpr.Type;
+
if ((Parent.ModFlags & Modifiers.SEALED) != 0){
if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
Report.Error (549, Location, "Virtual method can not be contained in sealed class");
"Inconsistent accessibility: indexer return type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than indexer `" + Name + "'");
- else if (this is Method) {
- if (((Method) this).IsOperator)
+ else if (this is MethodCore) {
+ if (this is Operator)
Report.Error (56, Location,
"Inconsistent accessibility: return type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
"Inconsistent accessibility: return type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than method `" + Name + "'");
- } else
+ } else {
Report.Error (52, Location,
"Inconsistent accessibility: field type `" +
TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than field `" + Name + "'");
+ }
return false;
}
return false;
if (IsExplicitImpl) {
- InterfaceType = Parent.ResolveType (
- ExplicitInterfaceName.GetTypeExpression (Location), false, Location);
- if (InterfaceType == null)
+ Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
+ TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (ec);
+ if (iface_texpr == null)
return false;
- if (InterfaceType.IsClass) {
- Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
+ InterfaceType = iface_texpr.Type;
+
+ if (!InterfaceType.IsInterface) {
+ Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
return false;
}
public Status status;
[Flags]
- public enum Status : byte { ASSIGNED = 1, USED = 2 }
+ public enum Status : byte {
+ ASSIGNED = 1,
+ USED = 2,
+ HAS_OFFSET = 4 // Used by FieldMember.
+ }
static string[] attribute_targets = new string [] { "field" };
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = a.GetMarshal ();
+ UnmanagedMarshal marshal = a.GetMarshal (this);
if (marshal != null) {
FieldBuilder.SetMarshal (marshal);
+ }
return;
}
- Report.Warning (-24, a.Location, "The Microsoft Runtime cannot set this marshal info. Please use the Mono runtime instead.");
+
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+ a.Error_InvalidSecurityParent ();
return;
}
-
FieldBuilder.SetCustomAttribute (cb);
}
public abstract class FieldMember: FieldBase
{
- bool has_field_offset = false;
+
protected FieldMember (TypeContainer parent, Expression type, int mod,
int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
{
if (a.Type == TypeManager.field_offset_attribute_type)
{
- has_field_offset = true;
+ status |= Status.HAS_OFFSET;
if (!Parent.HasExplicitLayout) {
Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
public override bool Define()
{
- MemberType = Parent.ResolveType (Type, false, Location);
-
- if (MemberType == null)
+ EmitContext ec = Parent.EmitContext;
+ if (ec == null)
+ throw new InternalErrorException ("FieldMember.Define called too early");
+
+ bool old_unsafe = ec.InUnsafe;
+ ec.InUnsafe = InUnsafe;
+ TypeExpr texpr = Type.ResolveAsTypeTerminal (ec);
+ ec.InUnsafe = old_unsafe;
+ if (texpr == null)
return false;
+
+ MemberType = texpr.Type;
if (!CheckBase ())
return false;
public override void Emit ()
{
- if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) {
+ 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 ());
}
base.Emit ();
}
+
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { return "F:"; }
+ }
}
//
//
// Null if the accessor is empty, or a Block if not
//
- public Block Block;
+ public const int AllowedModifiers =
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE;
+
+ public ToplevelBlock Block;
public Attributes Attributes;
public Location Location;
+ public int ModFlags;
- public Accessor (Block b, Attributes attrs, Location loc)
+ public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
{
Block = b;
Attributes = attrs;
Location = loc;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
}
}
// When it will be possible move here a lot of child code and template method type.
public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
protected MethodData method_data;
- protected Block block;
+ protected ToplevelBlock block;
+ protected ListDictionary declarative_security;
// The accessor are created event if they are not wanted.
// But we need them because their names are reserved.
#region IMethodData Members
- public Block Block {
+ public ToplevelBlock Block {
get {
return block;
}
{
if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
a.Type == TypeManager.conditional_attribute_type) {
- Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+ Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on {1} declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+ return;
+ }
+
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+ if (declarative_security == null)
+ declarative_security = new ListDictionary ();
+ a.ExtractSecurityPermissionSet (declarative_security);
return;
}
public override bool Define()
{
- return false;
+ throw new NotSupportedException ();
}
public virtual void Emit (TypeContainer container)
{
method_data.Emit (container, this);
+
+ if (declarative_security != null) {
+ foreach (DictionaryEntry de in declarative_security) {
+ method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+ }
+ }
+
block = null;
}
}
}
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
+ }
+
protected override void VerifyObsoleteAttribute()
{
}
public override MethodBuilder Define(TypeContainer container)
{
- method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
+ base.Define (container);
+
+ method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
if (!method_data.Define (container))
return null;
base.ApplyAttributeBuilder (a, cb);
}
- protected virtual InternalParameters GetParameterInfo (TypeContainer container)
+ protected virtual InternalParameters GetParameterInfo (EmitContext ec)
{
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));
+ Parameters parameters = new Parameters (parms, null, method.Location);
+ Type [] types = parameters.GetParameterInfo (ec);
+ return new InternalParameters (types, parameters);
}
public override MethodBuilder Define(TypeContainer container)
{
- method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
+ if (container.EmitContext == null)
+ throw new InternalErrorException ("SetMethod.Define called too early");
+
+ base.Define (container);
+
+ method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
if (!method_data.Define (container))
return null;
public abstract class PropertyMethod: AbstractPropertyEventMethod {
protected readonly MethodCore method;
+ protected MethodAttributes flags;
public PropertyMethod (MethodCore method, string prefix)
: base (method, prefix)
: base (method, accessor, prefix)
{
this.method = method;
+ this.ModFlags = accessor.ModFlags;
+
+ if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
+ Report.FeatureIsNotStandardized (Location, "accessor modifiers");
+ Environment.Exit (1);
+ }
}
public override AttributeTargets AttributeTargets {
}
}
- public abstract MethodBuilder Define (TypeContainer container);
+ public virtual MethodBuilder Define (TypeContainer container)
+ {
+ //
+ // Check for custom access modifier
+ //
+ if (ModFlags == 0) {
+ ModFlags = method.ModFlags;
+ flags = method.flags;
+ } else {
+ CheckModifiers (container, ModFlags);
+ ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
+ flags = Modifiers.MethodAttr (ModFlags);
+ flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
+ }
+
+ return null;
+
+ }
public override Type[] ParameterTypes {
get {
{
return String.Concat (tc.Name, '.', method.Name);
}
+
+ void CheckModifiers (TypeContainer container, int modflags)
+ {
+ int flags = 0;
+ int mflags = method.ModFlags & Modifiers.Accessibility;
+
+ if ((mflags & Modifiers.PUBLIC) != 0) {
+ flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+ }
+ else if ((mflags & Modifiers.PROTECTED) != 0) {
+ if ((mflags & Modifiers.INTERNAL) != 0)
+ flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
+
+ flags |= Modifiers.PRIVATE;
+ }
+ else if ((mflags & Modifiers.INTERNAL) != 0)
+ flags |= Modifiers.PRIVATE;
+
+ if ((mflags == modflags) || (modflags & (~flags)) != 0)
+ Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
+ GetSignatureForError (container));
+ }
}
public PropertyMethod Get, Set;
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+ a.Error_InvalidSecurityParent ();
+ return;
+ }
+
PropertyBuilder.SetCustomAttribute (cb);
}
if (!base.DoDefine (ds))
return false;
+ //
+ // Accessors modifiers check
+ //
+ if (Get.ModFlags != 0 && Set.ModFlags != 0) {
+ Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
+ GetSignatureForError ());
+ return false;
+ }
+
+ if ((Get.IsDummy || Set.IsDummy)
+ && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
+ Report.Error (276, Location,
+ "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
+ GetSignatureForError ());
+ return false;
+ }
+
if (MemberType.IsAbstract && MemberType.IsSealed) {
Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
return false;
return true;
}
+ // TODO: rename to Resolve......
protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
{
- PropertyInfo parent_property = container.ParentContainer.MemberCache.FindMemberToOverride (
+ PropertyInfo parent_property = container.ParentCache.FindMemberToOverride (
container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
if (parent_property == null)
return null;
parent_ret_type = parent_property.PropertyType;
+ MethodInfo get_accessor = parent_property.GetGetMethod (true);
+ MethodInfo set_accessor = parent_property.GetSetMethod (true);
+ MethodAttributes get_accessor_access, set_accessor_access;
- MethodInfo temp_m;
- temp_m = parent_property.GetGetMethod (true);
- if (temp_m != null)
- return temp_m;
+ if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ if (Get != null && !Get.IsDummy && get_accessor == null) {
+ Report.SymbolRelatedToPreviousError (parent_property);
+ Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+ }
- System.Diagnostics.Debug.Assert (parent_property.GetSetMethod (true) != null, "Internal error property without get/set");
- return parent_property.GetSetMethod (true);
+ if (Set != null && !Set.IsDummy && set_accessor == null) {
+ Report.SymbolRelatedToPreviousError (parent_property);
+ Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+ }
+ }
+
+ //
+ // Check parent accessors access
+ //
+ get_accessor_access = set_accessor_access = 0;
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ if (get_accessor != null) {
+ MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
+ get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
+
+ if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
+ Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+ }
+
+ if (set_accessor != null) {
+ MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
+ set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
+
+ if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
+ Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
+ GetSignatureForError (container), TypeManager.GetFullNameSignature (parent_property));
+ }
+ }
+
+ //
+ // Get the less restrictive access
+ //
+ return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
}
public override void Emit ()
return attribute_targets;
}
}
+
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { return "P:"; }
+ }
}
public class Property : PropertyBase, IIteratorContainer {
prop_attr |= PropertyAttributes.RTSpecialName |
PropertyAttributes.SpecialName;
- if (!IsExplicitImpl){
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
Name, prop_attr, MemberType, null);
PropertyBuilder.SetSetMethod (SetBuilder);
TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
- }
return true;
}
{
Add = new AddDelegateMethod (this, add);
Remove = new RemoveDelegateMethod (this, remove);
+
+ // For this event syntax we don't report error CS0067
+ // because it is hard to do it.
+ SetAssigned ();
}
public override string[] ValidAttributeTargets {
public class EventField: Event {
static string[] attribute_targets = new string [] { "event", "field", "method" };
+ static string[] attribute_targets_interface = new string[] { "event", "method" };
public EventField (TypeContainer parent, Expression type, int mod_flags,
bool is_iface, MemberName name, Object init,
}
if (a.Target == AttributeTargets.Method) {
- AddBuilder.SetCustomAttribute (cb);
- RemoveBuilder.SetCustomAttribute (cb);
+ Add.ApplyAttributeBuilder (a, cb);
+ Remove.ApplyAttributeBuilder (a, cb);
return;
}
public override string[] ValidAttributeTargets {
get {
- return attribute_targets;
+ return IsInterface ? attribute_targets_interface : attribute_targets;
}
}
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+ a.Error_InvalidSecurityParent ();
+ return;
+ }
+
EventBuilder.SetCustomAttribute (cb);
}
{
EventAttributes e_attr;
e_attr = EventAttributes.None;
-;
+
if (!DoDefineBase ())
return false;
return false;
}
+ EmitContext ec = Parent.EmitContext;
+ if (ec == null)
+ throw new InternalErrorException ("Event.Define called too early?");
+ bool old_unsafe = ec.InUnsafe;
+ ec.InUnsafe = InUnsafe;
+
Parameter [] parms = new Parameter [1];
parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
- InternalParameters ip = new InternalParameters (
- Parent, new Parameters (parms, null, Location));
+ Parameters parameters = new Parameters (parms, null, Location);
+ Type [] types = parameters.GetParameterInfo (ec);
+ InternalParameters ip = new InternalParameters (types, parameters);
+
+ ec.InUnsafe = old_unsafe;
if (!CheckBase ())
return false;
if (RemoveBuilder == null)
return false;
- if (!IsExplicitImpl){
- EventBuilder = new MyEventBuilder (this,
- Parent.TypeBuilder, Name, e_attr, MemberType);
+ EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
- if (Add.Block == null && Remove.Block == null &&
- !IsInterface) {
+ if (Add.Block == null && Remove.Block == null && !IsInterface) {
FieldBuilder = Parent.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
- }
-
return true;
}
return TypeManager.GetFullNameSignature (EventBuilder);
}
+
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { return "E:"; }
+ }
}
}
}
- protected override InternalParameters GetParameterInfo (TypeContainer container)
+ protected override InternalParameters GetParameterInfo (EmitContext ec)
{
Parameter [] fixed_parms = parameters.FixedParameters;
method.Type, "value", Parameter.Modifier.NONE, null);
Parameters set_formal_params = new Parameters (tmp, null, method.Location);
+ Type [] types = set_formal_params.GetParameterInfo (ec);
- return new InternalParameters (container, set_formal_params);
+ return new InternalParameters (types, set_formal_params);
}
-
}
-
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
return false;
if (OptAttributes != null) {
- Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
+ Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
if (indexer_attr != null) {
+ // Remove the attribute from the list because it is not emitted
+ OptAttributes.Attrs.Remove (indexer_attr);
+
ShortName = indexer_attr.GetIndexerAttributeValue (ec);
if (IsExplicitImpl) {
- Report.Error (415, indexer_attr.Location, "The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration");
+ Report.Error (415, indexer_attr.Location,
+ "The 'IndexerName' attribute is valid only on an" +
+ "indexer that is not an explicit interface member declaration");
return false;
}
if ((ModFlags & Modifiers.OVERRIDE) != 0) {
- Report.Error (609, indexer_attr.Location, "Cannot set the 'IndexerName' attribute on an indexer marked override");
+ Report.Error (609, indexer_attr.Location,
+ "Cannot set the 'IndexerName' attribute on an indexer marked override");
return false;
}
if (!Tokenizer.IsValidIdentifier (ShortName)) {
- Report.Error (633, indexer_attr.Location, "The argument to the 'IndexerName' attribute must be a valid identifier");
+ Report.Error (633, indexer_attr.Location,
+ "The argument to the 'IndexerName' attribute must be a valid identifier");
return false;
}
}
}
- //
- // Define the PropertyBuilder if one of the following conditions are met:
- // a) we're not implementing an interface indexer.
- // b) the indexer has a different IndexerName and this is no
- // explicit interface implementation.
- //
- if (!IsExplicitImpl) {
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
- ShortName, prop_attr, MemberType, ParameterTypes);
+ Name, prop_attr, MemberType, ParameterTypes);
if (!Get.IsDummy)
PropertyBuilder.SetGetMethod (GetBuilder);
if (!Set.IsDummy)
PropertyBuilder.SetSetMethod (SetBuilder);
- TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
- ParameterTypes);
- }
+ TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
return true;
}
public Operator (TypeContainer parent, OpType type, Expression ret_type,
int mod_flags, Parameters parameters,
- Block block, Attributes attrs, Location loc)
+ ToplevelBlock block, Attributes attrs, Location loc)
: base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
new MemberName ("op_" + type), attrs, parameters, loc)
{
public override string GetSignatureForError (TypeContainer tc)
{
StringBuilder sb = new StringBuilder ();
- sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.ToString (), Parameters.FixedParameters [0].GetSignatureForError ());
+ sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
+ Parameters.FixedParameters [0].GetSignatureForError ());
if (Parameters.FixedParameters.Length > 1) {
sb.Append (",");