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 ();
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
}
}
+ public virtual AssemblyDefinition DeclaringAssembly {
+ get {
+ return Module.DeclaringAssembly;
+ }
+ }
+
+ IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
+ get {
+ return Module.DeclaringAssembly;
+ }
+ }
+
public TypeSpec Definition {
get {
return spec;
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 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 (Compiler.PredefinedAttributes.ComImport);
+ return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
}
}
if (OptAttributes == null)
return null;
- Attribute a = OptAttributes.Search (Compiler.PredefinedAttributes.CoClass);
+ Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
if (a == null)
return null;
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_type = fne_resolved.Type;
+ continue;
+ }
+
+ base_type = fne_resolved.Type;
base_class = fne_resolved;
continue;
}
int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
if (IsTopLevel) {
- if (Compiler.GlobalRootNamespace.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;
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] = TypeManager.runtime_argument_handle_type;
+ cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (Location);
}
GenericMethod generic_method;
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) {
// Set base type after type creation
TypeBuilder.SetParent (base_type.GetMetaInfo ());
+ } else {
+ TypeBuilder.SetParent (null);
}
return true;
//
// 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;
{
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
}
}
- if (base_type_expr != null) {
+ if (base_type != null) {
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_expr as GenericTypeExpr;
if (ct != null)
ct.CheckConstraints (this);
- }
- if (base_type != null) {
+ 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 ();
ComputeIndexerName();
CheckEqualsAndGetHashCode();
+ if (Kind == MemberKind.Interface && iface_exprs != null) {
+ MemberCache.RemoveHiddenMembers (spec);
+ }
+
return true;
}
if (!seen_normal_indexers)
return;
- PredefinedAttribute pa = Compiler.PredefinedAttributes.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 ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
- Compiler.PredefinedAttributes.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 {
return false;
}
+ 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)
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
}
}
}
base.Emit ();
if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
- Compiler.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
+ Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
- var trans_flags = TypeManager.HasDynamicTypeUsed (base_type);
- if (trans_flags != null) {
- var pa = Compiler.PredefinedAttributes.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
- TypeBuilder.SetCustomAttribute (new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags }));
- }
+ if (base_type != null && base_type.HasDynamicElement) {
+ Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
}
}
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}'",
if (OptAttributes == null)
return null;
- Attribute[] attrs = OptAttributes.SearchMulti (Compiler.PredefinedAttributes.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) {
ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
if (oa != null) {
- if (OptAttributes == null || !OptAttributes.Contains (Compiler.PredefinedAttributes.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 (Compiler.PredefinedAttributes.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 ());
+ }
}
}
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 ());
}