2 // roottypes.cs: keeps a tree representation of the generated code
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Marek Safar (marek.safar@gmail.com)
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
14 using System
.Collections
;
15 using System
.Reflection
;
16 using System
.Reflection
.Emit
;
17 using System
.Runtime
.InteropServices
;
22 // Compiled top-level types
24 public sealed class ModuleContainer
: TypeContainer
26 // TODO: It'd be so nice to have generics
27 Hashtable anonymous_types
;
28 public ModuleBuilder Builder
;
29 readonly bool is_unsafe
;
30 readonly CompilerContext context
;
32 bool has_default_charset
;
34 public CharSet DefaultCharSet
= CharSet
.Ansi
;
35 public TypeAttributes DefaultCharSetType
= TypeAttributes
.AnsiClass
;
37 static readonly string[] attribute_targets
= new string[] { "module" }
;
39 public ModuleContainer (CompilerContext context
, bool isUnsafe
)
40 : base (null, null, MemberName
.Null
, null, Kind
.Root
)
42 this.is_unsafe
= isUnsafe
;
43 this.context
= context
;
45 types
= new ArrayList ();
46 anonymous_types
= new Hashtable ();
49 public override AttributeTargets AttributeTargets
{
51 return AttributeTargets
.Module
;
55 public void AddAnonymousType (AnonymousTypeClass type
)
57 ArrayList existing
= (ArrayList
)anonymous_types
[type
.Parameters
.Count
];
58 if (existing
== null) {
59 existing
= new ArrayList ();
60 anonymous_types
.Add (type
.Parameters
.Count
, existing
);
65 public void AddAttributes (ArrayList attrs
)
67 foreach (Attribute a
in attrs
)
68 a
.AttachTo (this, CodeGen
.Assembly
);
70 if (attributes
== null) {
71 attributes
= new Attributes (attrs
);
75 attributes
.AddAttributes (attrs
);
78 public override TypeContainer
AddPartial (TypeContainer nextPart
)
80 return AddPartial (nextPart
, nextPart
.Name
);
83 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
85 if (a
.Type
== pa
.CLSCompliant
) {
86 if (CodeGen
.Assembly
.ClsCompliantAttribute
== null) {
87 Report
.Warning (3012, 1, a
.Location
, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
88 } else if (CodeGen
.Assembly
.IsClsCompliant
!= a
.GetBoolean ()) {
89 Report
.SymbolRelatedToPreviousError (CodeGen
.Assembly
.ClsCompliantAttribute
.Location
, CodeGen
.Assembly
.ClsCompliantAttribute
.GetSignatureForError ());
90 Report
.Warning (3017, 1, a
.Location
, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
95 Builder
.SetCustomAttribute (cb
);
98 public override CompilerContext Compiler
{
99 get { return context; }
102 public override void Emit ()
104 if (OptAttributes
!= null)
105 OptAttributes
.Emit ();
108 Type t
= TypeManager
.CoreLookupType (context
, "System.Security", "UnverifiableCodeAttribute", Kind
.Class
, true);
110 ConstructorInfo unverifiable_code_ctor
= TypeManager
.GetPredefinedConstructor (t
, Location
.Null
, Type
.EmptyTypes
);
111 if (unverifiable_code_ctor
!= null)
112 Builder
.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor
, new object [0]));
117 public AnonymousTypeClass
GetAnonymousType (ArrayList parameters
)
119 ArrayList candidates
= (ArrayList
) anonymous_types
[parameters
.Count
];
120 if (candidates
== null)
124 foreach (AnonymousTypeClass at
in candidates
) {
125 for (i
= 0; i
< parameters
.Count
; ++i
) {
126 if (!parameters
[i
].Equals (at
.Parameters
[i
]))
130 if (i
== parameters
.Count
)
137 public override bool GetClsCompliantAttributeValue ()
139 return CodeGen
.Assembly
.IsClsCompliant
;
142 public bool HasDefaultCharSet
{
144 return has_default_charset
;
148 public override string GetSignatureForError ()
153 public override bool IsClsComplianceRequired ()
158 public override ModuleContainer Module
{
164 protected override bool AddMemberType (DeclSpace ds
)
166 if (!AddToContainer (ds
, ds
.Name
))
168 ds
.NamespaceEntry
.NS
.AddDeclSpace (ds
.Basename
, ds
);
172 protected override void RemoveMemberType (DeclSpace ds
)
174 ds
.NamespaceEntry
.NS
.RemoveDeclSpace (ds
.Basename
);
175 base.RemoveMemberType (ds
);
179 /// It is called very early therefore can resolve only predefined attributes
181 public void Resolve ()
183 if (OptAttributes
== null)
186 if (!OptAttributes
.CheckTargets ())
189 Attribute a
= ResolveAttribute (PredefinedAttributes
.Get
.DefaultCharset
);
191 has_default_charset
= true;
192 DefaultCharSet
= a
.GetCharSetValue ();
193 switch (DefaultCharSet
) {
198 DefaultCharSetType
= TypeAttributes
.AutoClass
;
200 case CharSet
.Unicode
:
201 DefaultCharSetType
= TypeAttributes
.UnicodeClass
;
204 Report
.Error (1724, a
.Location
, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
210 Attribute
ResolveAttribute (PredefinedAttribute a_type
)
212 Attribute a
= OptAttributes
.Search (a_type
);
219 public override string[] ValidAttributeTargets
{
221 return attribute_targets
;
226 class RootDeclSpace
: DeclSpace
{
227 public RootDeclSpace (NamespaceEntry ns
)
228 : base (ns
, null, MemberName
.Null
, null)
230 PartialContainer
= RootContext
.ToplevelTypes
;
233 public override AttributeTargets AttributeTargets
{
234 get { throw new InternalErrorException ("should not be called"); }
237 public override CompilerContext Compiler
{
239 return PartialContainer
.Compiler
;
243 public override string DocCommentHeader
{
244 get { throw new InternalErrorException ("should not be called"); }
247 public override bool Define ()
249 throw new InternalErrorException ("should not be called");
252 public override TypeBuilder
DefineType ()
254 throw new InternalErrorException ("should not be called");
257 public override MemberCache MemberCache
{
258 get { return PartialContainer.MemberCache; }
261 public override ModuleContainer Module
{
263 return PartialContainer
.Module
;
267 public override bool GetClsCompliantAttributeValue ()
269 return PartialContainer
.GetClsCompliantAttributeValue ();
272 public override bool IsClsComplianceRequired ()
274 return PartialContainer
.IsClsComplianceRequired ();
277 public override FullNamedExpression
LookupNamespaceAlias (string name
)
279 return NamespaceEntry
.LookupNamespaceAlias (name
);