using System;
using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
-using System.Text;
using System.Linq;
#if NET_2_1
using XmlElement = System.Object;
-#else
-using System.Xml;
#endif
-using Mono.CompilerServices.SymbolWriter;
+#if STATIC
+using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
+using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
+using System.Reflection;
+using System.Reflection.Emit;
+#endif
namespace Mono.CSharp {
get { return tc.IsStatic; }
}
+ public ModuleContainer Module {
+ get { return tc.Module; }
+ }
+
public string GetSignatureForError ()
{
return tc.GetSignatureForError ();
}
- public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
+ public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
{
return null;
}
List<MemberCore> operators;
// Holds the compiler generated classes
- List<CompilerGeneratedClass> compiler_generated;
+ protected List<CompilerGeneratedClass> compiler_generated;
+
+ Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
+
+ Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
//
// Pointers to the default constructor and the default static constructor
// This is an arbitrary choice. We are interested in looking at _some_ non-static field,
// and the first one's as good as any.
//
- FieldBase first_nonstatic_field = null;
+ FieldBase first_nonstatic_field;
//
// This one is computed after we can distinguish interfaces
// from classes from the arraylist `type_bases'
//
- TypeExpr base_type;
+ protected TypeSpec base_type;
+ protected TypeExpr base_type_expr;
protected TypeExpr[] iface_exprs;
protected List<FullNamedExpression> type_bases;
List<TypeContainer> partial_parts;
+ public int DynamicSitesCounter;
+
/// <remarks>
/// The pending methods that need to be implemented
// (interfaces or abstract methods)
}
}
+ public virtual AssemblyDefinition DeclaringAssembly {
+ get {
+ return Module.DeclaringAssembly;
+ }
+ }
+
+ IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
+ get {
+ return Module.DeclaringAssembly;
+ }
+ }
+
public TypeSpec Definition {
get {
return spec;
return AddToContainer (symbol, symbol.MemberName.Basename);
}
+ public bool AddMember (MemberCore symbol, string name)
+ {
+ return AddToContainer (symbol, name);
+ }
+
protected virtual bool AddMemberType (TypeContainer ds)
{
return AddToContainer (ds, ds.Basename);
tc.ModFlags |= next_part.ModFlags;
}
+ tc.spec.Modifiers = tc.ModFlags;
+
if (next_part.attributes != null) {
if (tc.attributes == null)
tc.attributes = next_part.attributes;
RemoveMemberType (next_part);
}
- public void AddDelegate (Delegate d)
+ public virtual TypeSpec AddDelegate (Delegate d)
{
AddTypeContainer (d);
+ return null;
}
private void AddMemberToList (MemberCore mc, List<MemberCore> alist, bool isexplicit)
public void AddConstructor (Constructor c)
{
bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
- if (!AddToContainer (c, is_static ?
- ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
+ if (!AddToContainer (c, is_static ? Constructor.ConstructorName : Constructor.TypeConstructorName))
return;
if (is_static && c.ParameterInfo.IsEmpty){
public void AddProperty (Property prop)
{
- if (!AddMember (prop) ||
- !AddMember (prop.Get) || !AddMember (prop.Set))
+ if (!AddMember (prop))
return;
if (properties == null)
if (!AddMember (e))
return;
- if (e is EventProperty) {
- if (!AddMember (e.Add))
- return;
-
- if (!AddMember (e.Remove))
- return;
- }
-
if (events == null)
events = new List<MemberCore> ();
}
}
- public virtual TypeSpec BaseType {
+ public TypeSpec BaseType {
get {
return spec.BaseType;
}
}
}
- public IList<CompilerGeneratedClass> CompilerGeneratedClasses {
- get {
- return compiler_generated;
- }
- }
-
protected override TypeAttributes TypeAttr {
get {
- return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
+ return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
}
}
if (OptAttributes == null)
return false;
- return OptAttributes.Contains (PredefinedAttributes.Get.ComImport);
+ return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
}
}
return;
for (int i = 0; i < initialized_fields.Count; ++i) {
- FieldInitializer fi = (FieldInitializer) initialized_fields [i];
+ FieldInitializer fi = initialized_fields [i];
ExpressionStatement s = fi.ResolveStatement (ec);
if (s == null)
continue;
if (OptAttributes == null)
return null;
- Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CoClass);
+ Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
if (a == null)
return null;
a = OptAttributes.Search (pa);
}
- if (a == null) {
- if (BaseType != TypeManager.attribute_type)
- return BaseType.GetAttributeUsage (pa);
-
+ if (a == null)
return null;
- }
return a.GetAttributeUsageAttribute ();
}
continue;
if (i == 0 && Kind == MemberKind.Class && !fne_resolved.Type.IsInterface) {
- if (fne_resolved.Type == InternalType.Dynamic)
+ if (fne_resolved.Type == InternalType.Dynamic) {
Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
GetSignatureForError ());
- else
- base_class = fne_resolved;
+
+ continue;
+ }
+
+ base_type = fne_resolved.Type;
+ base_class = fne_resolved;
continue;
}
if (fne_resolved.Type.IsInterface) {
for (int ii = 0; ii < j; ++ii) {
- if (TypeManager.IsEqual (fne_resolved.Type, ifaces [ii].Type)) {
+ if (fne_resolved.Type == ifaces [ii].Type) {
Report.Error (528, Location, "`{0}' is already listed in interface list",
fne_resolved.GetSignatureForError ());
break;
return ifaces;
}
- TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
+ TypeExpr[] GetNormalPartialBases ()
{
var ifaces = new List<TypeExpr> (0);
if (iface_exprs != null)
foreach (TypeContainer part in partial_parts) {
TypeExpr new_base_class;
TypeExpr[] new_ifaces = part.ResolveBaseTypes (out new_base_class);
- if (new_base_class != TypeManager.system_object_expr) {
- if (base_class == TypeManager.system_object_expr)
- base_class = new_base_class;
- else {
- if (new_base_class != null && !TypeManager.IsEqual (new_base_class.Type, base_class.Type)) {
- Report.SymbolRelatedToPreviousError (base_class.Location, "");
- Report.Error (263, part.Location,
- "Partial declarations of `{0}' must not specify different base classes",
- part.GetSignatureForError ());
-
- return null;
- }
+ if (new_base_class != null) {
+ if (base_type_expr != null && new_base_class.Type != base_type) {
+ Report.SymbolRelatedToPreviousError (new_base_class.Location, "");
+ Report.Error (263, part.Location,
+ "Partial declarations of `{0}' must not specify different base classes",
+ part.GetSignatureForError ());
+ } else {
+ base_type_expr = new_base_class;
+ base_type = base_type_expr.Type;
}
}
if (o_b == null || o_b.OperatorType != matching_type)
continue;
- if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
+ if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
continue;
- if (!TypeSpecComparer.Default.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
+ if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
continue;
operators[i] = null;
int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
if (IsTopLevel) {
- if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
+ // TODO: Completely wrong
+ if (Module.GlobalRootNamespace.IsNamespace (Name)) {
Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
- return false;
}
- ModuleBuilder builder = Module.Compiled.Builder;
- TypeBuilder = builder.DefineType (Name, TypeAttr, null, type_size);
+ TypeBuilder = Module.CreateBuilder (Name, TypeAttr, type_size);
} else {
- TypeBuilder builder = Parent.TypeBuilder;
-
- TypeBuilder = builder.DefineNestedType (Basename, TypeAttr, null, type_size);
+ TypeBuilder = Parent.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
}
+ if (DeclaringAssembly.Importer != null)
+ DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
+
spec.SetMetaInfo (TypeBuilder);
spec.MemberCache = new MemberCache (this);
spec.DeclaringType = Parent.CurrentType;
return true;
}
+ //
+ // Creates a proxy base method call inside this container for hoisted base member calls
+ //
+ public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
+ {
+ Method proxy_method;
+
+ //
+ // One proxy per base method is enough
+ //
+ if (hoisted_base_call_proxies == null) {
+ hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
+ proxy_method = null;
+ } else {
+ hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
+ }
+
+ if (proxy_method == null) {
+ string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
+ var base_parameters = new Parameter[method.Parameters.Count];
+ for (int i = 0; i < base_parameters.Length; ++i) {
+ var base_param = method.Parameters.FixedParameters[i];
+ base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location),
+ base_param.Name, base_param.ModFlags, null, Location);
+ base_parameters[i].Resolve (this, i);
+ }
+
+ var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
+ if (method.Parameters.HasArglist) {
+ cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
+ cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (Location);
+ }
+
+ GenericMethod generic_method;
+ MemberName member_name;
+ if (method.IsGeneric) {
+ //
+ // Copy all base generic method type parameters info
+ //
+ var hoisted_tparams = method.GenericDefinition.TypeParameters;
+ var targs = new TypeArguments ();
+ var type_params = new TypeParameter[hoisted_tparams.Length];
+ for (int i = 0; i < type_params.Length; ++i) {
+ var tp = hoisted_tparams[i];
+ targs.Add (new TypeParameterName (tp.Name, null, Location));
+ type_params[i] = new TypeParameter (tp, null, null, new MemberName (tp.Name), null);
+ }
+
+ member_name = new MemberName (name, targs, Location);
+ generic_method = new GenericMethod (NamespaceEntry, this, member_name, type_params,
+ new TypeExpression (method.ReturnType, Location), cloned_params);
+ } else {
+ member_name = new MemberName (name);
+ generic_method = null;
+ }
+
+ // Compiler generated proxy
+ proxy_method = new Method (this, generic_method, new TypeExpression (method.ReturnType, Location),
+ Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
+ member_name, cloned_params, null);
+
+ var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location);
+
+ var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
+ mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
+
+ // Get all the method parameters and pass them as arguments
+ var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
+ Statement statement;
+ if (method.ReturnType == TypeManager.void_type)
+ statement = new StatementExpression (real_base_call);
+ else
+ statement = new Return (real_base_call, Location);
+
+ block.AddStatement (statement);
+ proxy_method.Block = block;
+
+ methods.Add (proxy_method);
+ proxy_method.Define ();
+
+ hoisted_base_call_proxies.Add (method, proxy_method);
+ }
+
+ return proxy_method.Spec;
+ }
+
bool DefineBaseTypes ()
{
- iface_exprs = ResolveBaseTypes (out base_type);
+ iface_exprs = ResolveBaseTypes (out base_type_expr);
if (partial_parts != null) {
- iface_exprs = GetNormalPartialBases (ref base_type);
+ iface_exprs = GetNormalPartialBases ();
}
var cycle = CheckRecursiveDefinition (this);
Report.Error (529, Location,
"Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
GetSignatureForError (), cycle.GetSignatureForError ());
+
+ iface_exprs = null;
} else {
Report.Error (146, Location,
"Circular base class dependency involving `{0}' and `{1}'",
GetSignatureForError (), cycle.GetSignatureForError ());
- }
- base_type = null;
+ base_type = null;
+ }
}
if (iface_exprs != null) {
return true;
}
- TypeSpec base_ts;
- if (base_type != null)
- base_ts = base_type.Type;
- else if (spec.IsStruct)
- base_ts = TypeManager.value_type;
- else if (spec.IsEnum)
- base_ts = TypeManager.enum_type;
- else if (spec.IsDelegate)
- base_ts = TypeManager.multicast_delegate_type;
- else
- base_ts = null;
-
- if (base_ts != null) {
- spec.BaseType = base_ts;
+ if (base_type != null) {
+ spec.BaseType = base_type;
// Set base type after type creation
- TypeBuilder.SetParent (base_ts.GetMetaInfo ());
+ TypeBuilder.SetParent (base_type.GetMetaInfo ());
+ } else {
+ TypeBuilder.SetParent (null);
}
return true;
if (instance_constructors != null) {
foreach (MethodCore m in instance_constructors) {
var p = m.ParameterInfo;
- if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
- var rc = new ResolveContext (m);
- p.ResolveDefaultValues (rc);
+ if (!p.IsEmpty) {
+ p.ResolveDefaultValues (m);
}
}
}
if (methods != null) {
foreach (MethodCore m in methods) {
var p = m.ParameterInfo;
- if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
- var rc = new ResolveContext (m);
- p.ResolveDefaultValues (rc);
+ if (!p.IsEmpty) {
+ p.ResolveDefaultValues (m);
}
}
}
if (indexers != null) {
foreach (Indexer i in indexers) {
- var p = i.ParameterInfo;
- if (p[p.Count - 1].HasDefaultValue) {
- var rc = new ResolveContext (i);
- p.ResolveDefaultValues (rc);
- }
+ i.ParameterInfo.ResolveDefaultValues (i);
}
}
//
// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
//
- public TypeBuilder CreateType ()
+ public bool CreateType ()
{
if (TypeBuilder != null)
- return TypeBuilder;
+ return !error;
if (error)
- return null;
+ return false;
if (!CreateTypeBuilder ()) {
error = true;
- return null;
+ return false;
}
if (partial_parts != null) {
if (Types != null) {
foreach (TypeContainer tc in Types) {
- if (tc.CreateType () == null) {
- error = true;
- return null;
- }
+ tc.CreateType ();
}
}
- return TypeBuilder;
+ return true;
}
- public override TypeBuilder DefineType ()
+ public override void DefineType ()
{
if (error)
- return null;
+ return;
if (type_defined)
- return TypeBuilder;
+ return;
type_defined = true;
if (!DefineBaseTypes ()) {
error = true;
- return null;
+ return;
}
if (!DefineNestedTypes ()) {
error = true;
- return null;
+ return;
}
-
- return TypeBuilder;
}
public override void SetParameterInfo (List<Constraints> constraints_list)
// Replaces normal spec with predefined one when compiling corlib
// and this type container defines predefined type
//
- public void SetPredefinedSpec (PredefinedTypeSpec spec)
- {
+ public void SetPredefinedSpec (BuildinTypeSpec spec)
+ {
+ // When compiling build-in types we start with two
+ // version of same type. One is of BuildinTypeSpec and
+ // second one is ordinary TypeSpec. The unification
+ // happens at later stage when we know which type
+ // really matches the buildin type signature. However
+ // that means TypeSpec create during CreateType of this
+ // type has to be replaced with buildin one
+ //
+ spec.SetMetaInfo (TypeBuilder);
+ spec.MemberCache = this.spec.MemberCache;
+ spec.DeclaringType = this.spec.DeclaringType;
+
this.spec = spec;
+ current_type = null;
}
void UpdateTypeParameterConstraints (TypeContainer part)
{
if (Types != null) {
foreach (TypeContainer tc in Types)
- if (tc.DefineType () == null)
- return false;
+ tc.DefineType ();
}
return true;
InTransit = tc;
- if (base_type != null && base_type.Type != null) {
- var ptc = base_type.Type.MemberDefinition as TypeContainer;
+ if (base_type_expr != null) {
+ var ptc = base_type.MemberDefinition as TypeContainer;
if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
- return base_type.Type;
+ return base_type;
}
if (iface_exprs != null) {
{
if (iface_exprs != null) {
foreach (TypeExpr iface in iface_exprs) {
+ if (iface == null)
+ continue;
+
var iface_type = iface.Type;
// Ensure the base is always setup
ct.CheckConstraints (this);
- if (ct.HasDynamicArguments ()) {
+ if (ct.HasDynamicArguments () && !IsCompilerGenerated) {
Report.Error (1966, iface.Location,
"`{0}': cannot implement a dynamic interface `{1}'",
GetSignatureForError (), iface.GetSignatureForError ());
}
if (base_type != null) {
- ObsoleteAttribute obsolete_attr = base_type.Type.GetAttributeObsolete ();
+ ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
if (obsolete_attr != null && !IsObsolete)
AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report);
- var ct = base_type as GenericTypeExpr;
+ var ct = base_type_expr as GenericTypeExpr;
if (ct != null)
ct.CheckConstraints (this);
- var baseContainer = base_type.Type.MemberDefinition as ClassOrStruct;
+ if (base_type.Interfaces != null) {
+ foreach (var iface in base_type.Interfaces)
+ spec.AddInterface (iface);
+ }
+
+ var baseContainer = base_type.MemberDefinition as ClassOrStruct;
if (baseContainer != null) {
baseContainer.Define ();
}
}
- if (!IsTopLevel) {
- MemberSpec candidate;
- var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
- if (conflict_symbol == null && candidate == null) {
- if ((ModFlags & Modifiers.NEW) != 0)
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
- GetSignatureForError ());
- } else {
- if ((ModFlags & Modifiers.NEW) == 0) {
- if (candidate == null)
- candidate = conflict_symbol;
-
- Report.SymbolRelatedToPreviousError (candidate);
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), candidate.GetSignatureForError ());
- }
- }
- }
-
DefineContainerMembers (constants);
DefineContainerMembers (fields);
ComputeIndexerName();
CheckEqualsAndGetHashCode();
+ if (Kind == MemberKind.Interface && iface_exprs != null) {
+ MemberCache.RemoveHiddenMembers (spec);
+ }
+
return true;
}
protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList<MemberCore>
{
if (mcal != null) {
- foreach (MemberCore mc in mcal) {
+ for (int i = 0; i < mcal.Count; ++i) {
+ MemberCore mc = (MemberCore) mcal[i];
try {
mc.Define ();
} catch (Exception e) {
if (!seen_normal_indexers)
return;
- PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
+ PredefinedAttribute pa = Module.PredefinedAttributes.DefaultMember;
if (pa.Constructor == null &&
!pa.ResolveConstructor (Location, TypeManager.string_type))
return;
- CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { GetAttributeDefaultMember () });
- TypeBuilder.SetCustomAttribute (cb);
+ var encoder = new AttributeEncoder ();
+ encoder.Encode (GetAttributeDefaultMember ());
+ encoder.EncodeEmptyNamedArguments ();
+
+ pa.EmitAttribute (TypeBuilder, encoder);
}
protected virtual void CheckEqualsAndGetHashCode ()
if (f.OptAttributes != null || PartialContainer.HasStructLayout)
continue;
- Constant c = New.Constantify (f.MemberType);
+ Constant c = New.Constantify (f.MemberType, f.Location);
Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
f.GetSignatureForError (), c == null ? "null" : c.AsString ());
}
public override void Emit ()
{
+ if (!IsTopLevel) {
+ MemberSpec candidate;
+ var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
+ if (conflict_symbol == null && candidate == null) {
+ if ((ModFlags & Modifiers.NEW) != 0)
+ Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+ GetSignatureForError ());
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ if (candidate == null)
+ candidate = conflict_symbol;
+
+ Report.SymbolRelatedToPreviousError (candidate);
+ Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+ GetSignatureForError (), candidate.GetSignatureForError ());
+ }
+ }
+ }
+
if (all_tp_builders != null) {
int current_starts_index = CurrentTypeParametersStartIndex;
for (int i = 0; i < all_tp_builders.Length; i++) {
}
if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
- PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder);
+ Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
+
+#if STATIC
+ if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
+ TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
+#endif
base.Emit ();
}
}
}
- public void CloseType ()
+ public virtual void CloseType ()
{
if ((caching_flags & Flags.CloseTypeCreated) != 0)
return;
// Close base type container first to avoid TypeLoadException
if (spec.BaseType != null) {
var btype = spec.BaseType.MemberDefinition as TypeContainer;
- if (btype != null)
+ if (btype != null) {
btype.CloseType ();
+
+ if ((caching_flags & Flags.CloseTypeCreated) != 0)
+ return;
+ }
}
try {
// Performs the validation on a Method's modifiers (properties have
// the same properties).
//
+ // TODO: Why is it not done at parse stage ?
+ //
public bool MethodModifiersValid (MemberCore mc)
{
const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
- const Modifiers va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
bool ok = true;
var flags = mc.ModFlags;
}
}
- if (Kind == MemberKind.Struct){
- if ((flags & va) != 0){
- ModifiersExtensions.Error_InvalidModifier (mc.Location, "virtual or abstract", Report);
- ok = false;
- }
- }
-
if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
mc.GetSignatureForError ());
var ifaces = spec.Interfaces;
if (ifaces != null) {
foreach (TypeSpec t in ifaces){
- if (TypeManager.IsEqual (t, mb.InterfaceType))
+ if (t == mb.InterfaceType)
return true;
}
}
return false;
}
- public MemberCache LoadMembers (TypeSpec declaringType)
+ bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
+ {
+ return Module.DeclaringAssembly == assembly;
+ }
+
+ public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
{
throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
}
+ //
+ // Public function used to locate types.
+ //
+ // Set 'ignore_cs0104' to true if you want to ignore cs0104 errors.
+ //
+ // Returns: Type or null if they type can not be found.
+ //
+ public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
+ {
+ FullNamedExpression e;
+ if (arity == 0 && Cache.TryGetValue (name, out e))
+ return e;
+
+ e = null;
+ int errors = Report.Errors;
+
+ if (arity == 0) {
+ TypeParameter[] tp = CurrentTypeParameters;
+ if (tp != null) {
+ TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
+ if (tparam != null)
+ e = new TypeParameterExpr (tparam, Location.Null);
+ }
+ }
+
+ if (e == null) {
+ TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
+
+ if (t != null)
+ e = new TypeExpression (t, Location.Null);
+ else if (Parent != null) {
+ e = Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
+ } else
+ e = NamespaceEntry.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
+ }
+
+ // TODO MemberCache: How to cache arity stuff ?
+ if (errors == Report.Errors && arity == 0)
+ Cache[name] = e;
+
+ return e;
+ }
+
+ TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
+ {
+ // TODO: GenericMethod only
+ if (PartialContainer == null)
+ return null;
+
+ // Has any nested type
+ // Does not work, because base type can have
+ //if (PartialContainer.Types == null)
+ // return null;
+
+ var container = PartialContainer.CurrentType;
+
+ // Is not Root container
+ if (container == null)
+ return null;
+
+ var t = MemberCache.FindNestedType (container, name, arity);
+ if (t == null)
+ return null;
+
+ // FIXME: Breaks error reporting
+ if (!t.IsAccessible (CurrentType))
+ return null;
+
+ return t;
+ }
+
public void Mark_HasEquals ()
{
cached_method |= CachedMethods.Equals;
public abstract class ClassOrStruct : TypeContainer
{
- Dictionary<SecurityAction, PermissionSet> declarative_security;
+ SecurityType declarative_security;
public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
MemberName name, Attributes attrs, MemberKind kind)
protected override bool AddToContainer (MemberCore symbol, string name)
{
- if (name == MemberName.Name) {
+ if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
if (symbol is TypeParameter) {
Report.Error (694, symbol.Location,
"Type parameter `{0}' has same name as containing type, or method",
symbol.GetSignatureForError ());
return false;
}
-
+
InterfaceMemberBase imb = symbol as InterfaceMemberBase;
if (imb == null || !imb.IsExplicitImpl) {
Report.SymbolRelatedToPreviousError (this);
Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
}
}
+
+ if (types != null) {
+ foreach (var t in types)
+ t.VerifyMembers ();
+ }
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsValidSecurityAttribute ()) {
- if (declarative_security == null)
- declarative_security = new Dictionary<SecurityAction, PermissionSet> ();
-
- a.ExtractSecurityPermissionSet (declarative_security);
+ a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
return;
}
if (a.Type == pa.StructLayout) {
PartialContainer.HasStructLayout = true;
-
- if (a.GetLayoutKindValue () == LayoutKind.Explicit)
+ if (a.IsExplicitLayoutKind ())
PartialContainer.HasExplicitLayout = true;
}
if (declarative_security != null) {
foreach (var de in declarative_security) {
+#if STATIC
+ TypeBuilder.__AddDeclarativeSecurity (de);
+#else
TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
+#endif
}
}
}
- public override ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
+ public override IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
{
DeclSpace top_level = Parent;
if (top_level != null) {
top_level = top_level.Parent;
var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name, arity);
- if (candidates != null)
- return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
+ if (candidates != null) {
+ scope = NamespaceEntry;
+ return candidates;
+ }
}
- return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, loc);
+ return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, ref scope);
}
protected override TypeAttributes TypeAttr {
base.Emit ();
if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
- PredefinedAttributes.Get.Extension.EmitAttribute (TypeBuilder);
+ Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
+
+ if (base_type != null && base_type.HasDynamicElement) {
+ Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
+ }
}
protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
if (base_class == null) {
if (spec != TypeManager.object_type)
- base_class = TypeManager.system_object_expr;
+ base_type = TypeManager.object_type;
} else {
- var base_type = base_class.Type;
-
if (base_type.IsGenericParameter){
Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
GetSignatureForError (), base_type.GetSignatureForError ());
Report.SymbolRelatedToPreviousError (base_class.Type);
Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
GetSignatureForError (), base_type.GetSignatureForError ());
- } else if (base_type.IsSealed){
+ } else if (base_type.IsSealed) {
Report.SymbolRelatedToPreviousError (base_class.Type);
Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
GetSignatureForError (), base_type.GetSignatureForError ());
+ } else if (PartialContainer.IsStatic && base_class.Type != TypeManager.object_type) {
+ Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
+ GetSignatureForError (), base_class.GetSignatureForError ());
}
- if (base_type is PredefinedTypeSpec && !(spec is PredefinedTypeSpec) &&
+ if (base_type is BuildinTypeSpec && !(spec is BuildinTypeSpec) &&
(base_type == TypeManager.enum_type || base_type == TypeManager.value_type || base_type == TypeManager.multicast_delegate_type ||
base_type == TypeManager.delegate_type || base_type == TypeManager.array_type)) {
Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
GetSignatureForError (), base_type.GetSignatureForError ());
- base_class = TypeManager.system_object_expr;
+
+ base_type = TypeManager.object_type;
}
if (!IsAccessibleAs (base_type)) {
}
}
- if (PartialContainer.IsStatic) {
- if (base_class.Type != TypeManager.object_type) {
- Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
- GetSignatureForError (), base_class.GetSignatureForError ());
- return ifaces;
- }
-
- if (ifaces != null) {
- foreach (TypeExpr t in ifaces)
- Report.SymbolRelatedToPreviousError (t.Type);
- Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
- }
+ if (PartialContainer.IsStatic && ifaces != null) {
+ foreach (TypeExpr t in ifaces)
+ Report.SymbolRelatedToPreviousError (t.Type);
+ Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
}
return ifaces;
if (OptAttributes == null)
return null;
- Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
+ Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
if (attrs == null)
return null;
//
// When struct constains fixed fixed and struct layout has explicitly
// set CharSet, its value has to be propagated to compiler generated
- // fixed field types
+ // fixed types
//
- if (a.Type == pa.StructLayout && Fields != null && a.HasField ("CharSet")) {
+ if (a.Type == pa.StructLayout && Fields != null) {
+ var value = a.GetNamedValue ("CharSet");
+ if (value == null)
+ return;
+
for (int i = 0; i < Fields.Count; ++i) {
FixedField ff = Fields [i] as FixedField;
- if (ff != null)
- ff.SetCharSet (TypeBuilder.Attributes);
+ if (ff == null)
+ continue;
+
+ ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
}
}
}
if (!ftype.IsStruct)
continue;
- if (ftype is PredefinedTypeSpec)
+ if (ftype is BuildinTypeSpec)
continue;
foreach (var targ in ftype.TypeArguments) {
while (mt.IsPointer)
mt = TypeManager.GetElementType (mt);
- if (mt.MemberDefinition == this) {
- for (var p = Parent; p != null; p = p.Parent) {
- if (p.Kind == MemberKind.Class) {
- has_unmanaged_check_done = true;
- return false;
- }
- }
- continue;
+ if (mt.IsGenericOrParentIsGeneric || mt.IsGenericParameter) {
+ has_unmanaged_check_done = true;
+ return false;
}
if (TypeManager.IsUnmanagedType (mt))
protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
{
TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
- base_class = TypeManager.system_valuetype_expr;
+ base_type = TypeManager.value_type;
return ifaces;
}
}
}
- public abstract class InterfaceMemberBase : MemberBase {
+ public abstract class InterfaceMemberBase : MemberBase
+ {
+ //
+ // Common modifiers allowed in a class declaration
+ //
+ protected const Modifiers AllowedModifiersClass =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.STATIC |
+ Modifiers.VIRTUAL |
+ Modifiers.SEALED |
+ Modifiers.OVERRIDE |
+ Modifiers.ABSTRACT |
+ Modifiers.UNSAFE |
+ Modifiers.EXTERN;
+
+ //
+ // Common modifiers allowed in a struct declaration
+ //
+ protected const Modifiers AllowedModifiersStruct =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.STATIC |
+ Modifiers.OVERRIDE |
+ Modifiers.UNSAFE |
+ Modifiers.EXTERN;
+
+ //
+ // Common modifiers allowed in a interface declaration
+ //
+ protected const Modifiers AllowedModifiersInterface =
+ Modifiers.NEW |
+ Modifiers.UNSAFE;
+
//
// Whether this is an interface member.
//
ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
if (oa != null) {
- if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+ if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
}
} else {
- if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+ if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
} else {
if ((ModFlags & Modifiers.NEW) == 0) {
ModFlags |= Modifiers.NEW;
- Report.SymbolRelatedToPreviousError (base_member);
- if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
- Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
- GetSignatureForError (), base_member.GetSignatureForError ());
- } else {
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), base_member.GetSignatureForError ());
+ if (!IsCompilerGenerated) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
+ Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
+ GetSignatureForError (), base_member.GetSignatureForError ());
+ } else {
+ Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+ GetSignatureForError (), base_member.GetSignatureForError ());
+ }
}
}
- if (!IsInterface && base_member.IsAbstract) {
+ if (!IsInterface && base_member.IsAbstract && candidate == null) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
GetSignatureForError (), base_member.GetSignatureForError ());
{
bool ok = true;
- if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED)) == 0) {
+ if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Error (506, Location,
"`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
+ //
+ // It must be at least "protected"
+ //
+ if ((thisp & Modifiers.PROTECTED) == 0) {
+ return false;
+ }
+
//
// when overriding protected internal, the method can be declared
// protected internal only within the same assembly or assembly
// which has InternalsVisibleTo
//
- if ((thisp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
- return TypeManager.IsThisOrFriendAssembly (this_member.Assembly, base_member.Assembly);
- }
- if ((thisp & Modifiers.PROTECTED) != Modifiers.PROTECTED) {
- //
- // if it's not "protected internal", it must be "protected"
- //
-
- return false;
- }
- if (this_member.Parent.PartialContainer.Module.Assembly == base_member.Assembly) {
- //
- // protected within the same assembly - an error
- //
- return false;
+ if ((thisp & Modifiers.INTERNAL) != 0) {
+ return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
}
- if ((thisp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL)) !=
- (base_classp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL))) {
- //
- // protected ok, but other attributes differ - report an error
- //
+
+ //
+ // protected overriding protected internal inside same assembly
+ // requires internal modifier as well
+ //
+ if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
return false;
}
+
return true;
}
protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
{
+ var base_modifiers = base_member.Modifiers;
+
+ // Remove internal modifier from types which are not internally accessible
+ if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
+ !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
+ base_modifiers = Modifiers.PROTECTED;
+
Report.SymbolRelatedToPreviousError (base_member);
Report.Error (507, member.Location,
"`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
member.GetSignatureForError (),
- ModifiersExtensions.AccessibilityName (base_member.Modifiers),
+ ModifiersExtensions.AccessibilityName (base_modifiers),
base_member.GetSignatureForError ());
}
GenericMethod.ModFlags = ModFlags;
}
+ #region Properties
+
+ public TypeSpec MemberType {
+ get {
+ return member_type;
+ }
+ }
+
+ public FullNamedExpression TypeExpression {
+ get {
+ return type_expr;
+ }
+ }
+
+ #endregion
+
//
// Main member define entry
//
return true;
}
- public TypeSpec MemberType {
- get { return member_type; }
- }
-
protected virtual bool ResolveMemberType ()
{
if (member_type != null)