//
// roottypes.cs: keeps a tree representation of the generated code
//
-// Author: Miguel de Icaza (miguel@gnu.org)
+// Authors: Miguel de Icaza (miguel@gnu.org)
+// Marek Safar (marek.safar@gmail.com)
//
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
-using System.IO;
+using System.Runtime.InteropServices;
namespace Mono.CSharp
{
- // <summary>
- // We store here all the toplevel types that we have parsed,
- // this is the root of all information we have parsed.
- // </summary>
- public sealed class RootTypes : TypeContainer
+ //
+ // Module container, it can be used as a top-level type
+ //
+ public class ModuleContainer : TypeContainer
+ {
+ public CharSet DefaultCharSet = CharSet.Ansi;
+ public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
+
+ protected Assembly assembly;
+
+ public ModuleContainer (Assembly assembly)
+ : base (null, null, MemberName.Null, null, Kind.Root)
+ {
+ this.assembly = assembly;
+ }
+
+ public Assembly Assembly {
+ get { return assembly; }
+ }
+
+ // FIXME: Remove this evil one day
+ public ModuleCompiled Compiled {
+ get { return (ModuleCompiled) this; }
+ }
+
+ public override ModuleContainer Module {
+ get {
+ return this;
+ }
+ }
+ }
+
+ //
+ // Compiled top-level types
+ //
+ public class ModuleCompiled : ModuleContainer
{
// TODO: It'd be so nice to have generics
Hashtable anonymous_types;
-
- public RootTypes ()
- : base (null, null, MemberName.Null, null, Kind.Root)
+ readonly bool is_unsafe;
+ readonly CompilerContext context;
+
+ ModuleBuilder builder;
+
+ bool has_default_charset;
+
+ static readonly string[] attribute_targets = new string[] { "module" };
+
+ public ModuleCompiled (CompilerContext context, bool isUnsafe)
+ : base (null)
{
+ this.is_unsafe = isUnsafe;
+ this.context = context;
+
types = new ArrayList ();
anonymous_types = new Hashtable ();
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Module;
+ }
+ }
+
public void AddAnonymousType (AnonymousTypeClass type)
{
ArrayList existing = (ArrayList)anonymous_types [type.Parameters.Count];
existing.Add (type);
}
- public override bool IsClsComplianceRequired ()
+ public void AddAttributes (ArrayList attrs)
{
- return true;
+ foreach (Attribute a in attrs)
+ a.AttachTo (this, CodeGen.Assembly);
+
+ if (attributes == null) {
+ attributes = new Attributes (attrs);
+ return;
+ }
+
+ attributes.AddAttributes (attrs);
+ }
+
+ public override TypeContainer AddPartial (TypeContainer nextPart)
+ {
+ return AddPartial (nextPart, nextPart.Name);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
+ {
+ if (a.Type == pa.CLSCompliant) {
+ if (CodeGen.Assembly.ClsCompliantAttribute == null) {
+ Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
+ } else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
+ Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
+ Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
+ return;
+ }
+ }
+
+ builder.SetCustomAttribute (cb);
+ }
+
+ public ModuleBuilder Builder {
+ get {
+ return builder;
+ }
+
+ set {
+ builder = value;
+ assembly = builder.Assembly;
+ }
+ }
+
+ public override CompilerContext Compiler {
+ get { return context; }
+ }
+
+ public override void Emit ()
+ {
+ if (OptAttributes != null)
+ OptAttributes.Emit ();
+
+ if (is_unsafe) {
+ Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", Kind.Class, true);
+ if (t != null) {
+ ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
+ if (unverifiable_code_ctor != null)
+ builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
+ }
+ }
}
public AnonymousTypeClass GetAnonymousType (ArrayList parameters)
return CodeGen.Assembly.IsClsCompliant;
}
+ public bool HasDefaultCharSet {
+ get {
+ return has_default_charset;
+ }
+ }
+
public override string GetSignatureForError ()
{
- return "";
+ return "<module>";
+ }
+
+ public override bool IsClsComplianceRequired ()
+ {
+ return true;
}
protected override bool AddMemberType (DeclSpace ds)
ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename);
base.RemoveMemberType (ds);
}
-
- public override TypeContainer AddPartial (TypeContainer nextPart)
+
+ /// <summary>
+ /// It is called very early therefore can resolve only predefined attributes
+ /// </summary>
+ public void Resolve ()
{
- return AddPartial (nextPart, nextPart.Name);
+ if (OptAttributes == null)
+ return;
+
+ if (!OptAttributes.CheckTargets ())
+ return;
+
+ Attribute a = ResolveAttribute (PredefinedAttributes.Get.DefaultCharset);
+ if (a != null) {
+ has_default_charset = true;
+ DefaultCharSet = a.GetCharSetValue ();
+ switch (DefaultCharSet) {
+ case CharSet.Ansi:
+ case CharSet.None:
+ break;
+ case CharSet.Auto:
+ DefaultCharSetType = TypeAttributes.AutoClass;
+ break;
+ case CharSet.Unicode:
+ DefaultCharSetType = TypeAttributes.UnicodeClass;
+ break;
+ default:
+ Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
+ break;
+ }
+ }
}
+ Attribute ResolveAttribute (PredefinedAttribute a_type)
+ {
+ Attribute a = OptAttributes.Search (a_type);
+ if (a != null) {
+ a.Resolve ();
+ }
+ return a;
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
- public class RootDeclSpace : DeclSpace {
+ class RootDeclSpace : DeclSpace {
public RootDeclSpace (NamespaceEntry ns)
: base (ns, null, MemberName.Null, null)
{
get { throw new InternalErrorException ("should not be called"); }
}
+ public override CompilerContext Compiler {
+ get {
+ return PartialContainer.Compiler;
+ }
+ }
+
public override string DocCommentHeader {
get { throw new InternalErrorException ("should not be called"); }
}
get { return PartialContainer.MemberCache; }
}
+ public override ModuleContainer Module {
+ get {
+ return PartialContainer.Module;
+ }
+ }
+
public override bool GetClsCompliantAttributeValue ()
{
return PartialContainer.GetClsCompliantAttributeValue ();
{
return PartialContainer.IsClsComplianceRequired ();
}
+
+ public override FullNamedExpression LookupNamespaceAlias (string name)
+ {
+ return NamespaceEntry.LookupNamespaceAlias (name);
+ }
}
}