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
.Generic
;
15 using System
.Reflection
;
16 using System
.Reflection
.Emit
;
17 using System
.Runtime
.InteropServices
;
22 // Module container, it can be used as a top-level type
24 public class ModuleContainer
: TypeContainer
26 public CharSet DefaultCharSet
= CharSet
.Ansi
;
27 public TypeAttributes DefaultCharSetType
= TypeAttributes
.AnsiClass
;
29 protected Assembly assembly
;
31 public ModuleContainer (Assembly assembly
)
32 : base (null, null, MemberName
.Null
, null, 0)
34 this.assembly
= assembly
;
37 public Assembly Assembly
{
38 get { return assembly; }
41 // FIXME: Remove this evil one day
42 public ModuleCompiled Compiled
{
43 get { return (ModuleCompiled) this; }
46 public override ModuleContainer Module
{
54 // Compiled top-level types
56 public class ModuleCompiled
: ModuleContainer
58 Dictionary
<int, List
<AnonymousTypeClass
>> anonymous_types
;
59 readonly bool is_unsafe
;
60 readonly CompilerContext context
;
62 ModuleBuilder builder
;
64 bool has_default_charset
;
66 static readonly string[] attribute_targets
= new string[] { "module" }
;
68 public ModuleCompiled (CompilerContext context
, bool isUnsafe
)
71 this.is_unsafe
= isUnsafe
;
72 this.context
= context
;
74 types
= new List
<TypeContainer
> ();
75 anonymous_types
= new Dictionary
<int, List
<AnonymousTypeClass
>> ();
78 public override AttributeTargets AttributeTargets
{
80 return AttributeTargets
.Module
;
84 public void AddAnonymousType (AnonymousTypeClass type
)
86 List
<AnonymousTypeClass
> existing
;
87 if (!anonymous_types
.TryGetValue (type
.Parameters
.Count
, out existing
))
88 if (existing
== null) {
89 existing
= new List
<AnonymousTypeClass
> ();
90 anonymous_types
.Add (type
.Parameters
.Count
, existing
);
96 public void AddAttributes (List
<Attribute
> attrs
)
98 foreach (Attribute a
in attrs
)
99 a
.AttachTo (this, CodeGen
.Assembly
);
101 if (attributes
== null) {
102 attributes
= new Attributes (attrs
);
106 attributes
.AddAttributes (attrs
);
109 public override TypeContainer
AddPartial (TypeContainer nextPart
)
111 return AddPartial (nextPart
, nextPart
.Name
);
114 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
116 if (a
.Type
== pa
.CLSCompliant
) {
117 if (CodeGen
.Assembly
.ClsCompliantAttribute
== null) {
118 Report
.Warning (3012, 1, a
.Location
, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
119 } else if (CodeGen
.Assembly
.IsClsCompliant
!= a
.GetBoolean ()) {
120 Report
.SymbolRelatedToPreviousError (CodeGen
.Assembly
.ClsCompliantAttribute
.Location
, CodeGen
.Assembly
.ClsCompliantAttribute
.GetSignatureForError ());
121 Report
.Warning (3017, 1, a
.Location
, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
126 builder
.SetCustomAttribute (cb
);
129 public ModuleBuilder Builder
{
136 assembly
= builder
.Assembly
;
140 public override CompilerContext Compiler
{
141 get { return context; }
144 public override void Emit ()
146 if (OptAttributes
!= null)
147 OptAttributes
.Emit ();
150 Type t
= TypeManager
.CoreLookupType (context
, "System.Security", "UnverifiableCodeAttribute", MemberKind
.Class
, true);
152 ConstructorInfo unverifiable_code_ctor
= TypeManager
.GetPredefinedConstructor (t
, Location
.Null
, Type
.EmptyTypes
);
153 if (unverifiable_code_ctor
!= null)
154 builder
.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor
, new object [0]));
159 public AnonymousTypeClass
GetAnonymousType (IList
<AnonymousTypeParameter
> parameters
)
161 List
<AnonymousTypeClass
> candidates
;
162 if (!anonymous_types
.TryGetValue (parameters
.Count
, out candidates
))
166 foreach (AnonymousTypeClass at
in candidates
) {
167 for (i
= 0; i
< parameters
.Count
; ++i
) {
168 if (!parameters
[i
].Equals (at
.Parameters
[i
]))
172 if (i
== parameters
.Count
)
179 public override bool GetClsCompliantAttributeValue ()
181 return CodeGen
.Assembly
.IsClsCompliant
;
184 public bool HasDefaultCharSet
{
186 return has_default_charset
;
190 public override string GetSignatureForError ()
195 public override bool IsClsComplianceRequired ()
200 protected override bool AddMemberType (DeclSpace ds
)
202 if (!AddToContainer (ds
, ds
.Name
))
204 ds
.NamespaceEntry
.NS
.AddDeclSpace (ds
.Basename
, ds
);
208 protected override void RemoveMemberType (DeclSpace ds
)
210 ds
.NamespaceEntry
.NS
.RemoveDeclSpace (ds
.Basename
);
211 base.RemoveMemberType (ds
);
215 /// It is called very early therefore can resolve only predefined attributes
217 public void Resolve ()
219 if (OptAttributes
== null)
222 if (!OptAttributes
.CheckTargets ())
225 Attribute a
= ResolveAttribute (PredefinedAttributes
.Get
.DefaultCharset
);
227 has_default_charset
= true;
228 DefaultCharSet
= a
.GetCharSetValue ();
229 switch (DefaultCharSet
) {
234 DefaultCharSetType
= TypeAttributes
.AutoClass
;
236 case CharSet
.Unicode
:
237 DefaultCharSetType
= TypeAttributes
.UnicodeClass
;
240 Report
.Error (1724, a
.Location
, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
246 Attribute
ResolveAttribute (PredefinedAttribute a_type
)
248 Attribute a
= OptAttributes
.Search (a_type
);
255 public override string[] ValidAttributeTargets
{
257 return attribute_targets
;
262 class RootDeclSpace
: DeclSpace
{
263 public RootDeclSpace (NamespaceEntry ns
)
264 : base (ns
, null, MemberName
.Null
, null)
266 PartialContainer
= RootContext
.ToplevelTypes
;
269 public override AttributeTargets AttributeTargets
{
270 get { throw new InternalErrorException ("should not be called"); }
273 public override CompilerContext Compiler
{
275 return PartialContainer
.Compiler
;
279 public override string DocCommentHeader
{
280 get { throw new InternalErrorException ("should not be called"); }
283 public override bool Define ()
285 throw new InternalErrorException ("should not be called");
288 public override TypeBuilder
DefineType ()
290 throw new InternalErrorException ("should not be called");
293 public override MemberCache MemberCache
{
294 get { return PartialContainer.MemberCache; }
297 public override ModuleContainer Module
{
299 return PartialContainer
.Module
;
303 public override bool GetClsCompliantAttributeValue ()
305 return PartialContainer
.GetClsCompliantAttributeValue ();
308 public override bool IsClsComplianceRequired ()
310 return PartialContainer
.IsClsComplianceRequired ();
313 public override FullNamedExpression
LookupNamespaceAlias (string name
)
315 return NamespaceEntry
.LookupNamespaceAlias (name
);