2 // ikvm.cs: IKVM.Reflection and IKVM.Reflection.Emit specific implementations
4 // Author: Marek Safar (marek.safar@gmail.com)
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 // Copyright 2009-2010 Novell, Inc.
13 using System.Collections.Generic;
14 using MetaType = IKVM.Reflection.Type;
15 using IKVM.Reflection;
16 using IKVM.Reflection.Emit;
18 using System.Configuration.Assemblies;
23 public class StaticImporter
25 public StaticImporter (BuildinTypes buildin)
27 throw new NotSupportedException ();
30 public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
32 throw new NotSupportedException ();
35 public void ImportModule (Module module, RootNamespace targetNamespace)
37 throw new NotSupportedException ();
40 public TypeSpec ImportType (System.Type type)
42 throw new NotSupportedException ();
48 sealed class StaticImporter : MetadataImporter
50 public StaticImporter ()
54 protected override MemberKind DetermineKindFromBaseType (MetaType baseType)
56 string name = baseType.Name;
58 // TODO: namespace check
59 if (name == "ValueType")
60 return MemberKind.Struct;
63 return MemberKind.Enum;
65 if (name == "MulticastDelegate")
66 return MemberKind.Delegate;
68 return MemberKind.Class;
71 protected override bool HasVolatileModifier (MetaType[] modifiers)
73 foreach (var t in modifiers) {
74 if (t.Name == "IsVolatile" && t.Namespace == CompilerServicesNamespace)
81 public override void GetCustomAttributeTypeName (CustomAttributeData cad, out string typeNamespace, out string typeName)
83 cad.__ReadTypeName (out typeNamespace, out typeName);
86 public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
88 // It can be used more than once when importing same assembly
89 // into 2 or more global aliases
90 var definition = GetAssemblyDefinition (assembly);
92 var all_types = assembly.GetTypes ();
93 ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod);
96 public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace)
98 var module_definition = new ImportedModuleDefinition (module, this);
99 module_definition.ReadAttributes ();
101 var all_types = module.GetTypes ();
102 ImportTypes (all_types, targetNamespace, false);
104 return module_definition;
107 public void InitializeBuildinTypes (BuildinTypes buildin, Assembly corlib)
110 // Setup mapping for build-in types to avoid duplication of their definition
112 foreach (var type in buildin.AllTypes) {
113 buildin_types.Add (corlib.GetType (type.FullName), type);
119 class AssemblyDefinitionStatic : AssemblyDefinition
122 // Assembly container with file output
124 public AssemblyDefinitionStatic (ModuleContainer module, string name, string fileName)
125 : base (module, name, fileName)
130 // Initializes the code generator
132 public bool Create (Universe domain)
134 ResolveAssemblySecurityAttributes ();
135 var an = CreateAssemblyName ();
137 Builder = domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save, Path.GetDirectoryName (file_name));
139 // Sets output file metadata version, this makes sense for mscorlib
140 // compilation only but won't restrict that for now
141 switch (RootContext.StdLibRuntimeVersion){
142 case RuntimeVersion.v4:
143 Builder.__SetImageRuntimeVersion ("v4.0.30319", 0x20000);
145 case RuntimeVersion.v2:
146 Builder.__SetImageRuntimeVersion ("v2.0.50727", 0x20000);
148 case RuntimeVersion.v1:
149 // Compiler does not do any checks whether the produced metadata
150 // are valid in the context of 1.0 stream version
151 Builder.__SetImageRuntimeVersion ("v1.1.4322", 0x10000);
154 throw new NotImplementedException ();
157 builder_extra = new AssemblyBuilderIKVM (Builder, Compiler);
161 public Module IncludeModule (RawModule moduleFile)
163 return Builder.__AddModule (moduleFile);
166 protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
168 module.Builder.__Save (pekind, machine);
172 class StaticLoader : AssemblyReferencesLoader<Assembly>, IDisposable
174 readonly StaticImporter importer;
175 readonly Universe domain;
178 public StaticLoader (StaticImporter importer, CompilerContext compiler)
181 this.importer = importer;
182 domain = new Universe ();
183 domain.AssemblyResolve += AssemblyReferenceResolver;
186 public Assembly Corlib {
195 public Universe Domain {
201 Assembly AssemblyReferenceResolver (object sender, IKVM.Reflection.ResolveEventArgs args)
203 if (args.Name == "mscorlib")
206 // AssemblyReference has not been found in the domain
207 // create missing reference and continue
208 return new MissingAssembly (domain, args.Name);
211 public void Dispose ()
216 protected override string[] GetDefaultReferences ()
219 // For now the "default config" is harcoded into the compiler
220 // we can move this outside later
222 var default_references = new List<string> (8);
224 default_references.Add ("System.dll");
225 default_references.Add ("System.Xml.dll");
227 default_references.Add ("System.Net.dll");
228 default_references.Add ("System.Windows.dll");
229 default_references.Add ("System.Windows.Browser.dll");
232 // TODO: Will have to do it based on mscorlib version or something like that
234 if (RootContext.Version > LanguageVersion.ISO_2)
235 default_references.Add ("System.Core.dll");
236 if (RootContext.Version > LanguageVersion.V_3)
237 default_references.Add ("Microsoft.CSharp.dll");
239 return default_references.ToArray ();
242 public override bool HasObjectType (Assembly assembly)
244 return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
247 public override Assembly LoadAssemblyFile (string fileName)
249 bool? has_extension = null;
250 foreach (var path in paths) {
251 var file = Path.Combine (path, fileName);
252 if (!File.Exists (file)) {
253 if (!has_extension.HasValue)
254 has_extension = fileName.EndsWith (".dll", StringComparison.Ordinal) || fileName.EndsWith (".exe", StringComparison.Ordinal);
256 if (has_extension.Value)
260 if (!File.Exists (file))
265 using (RawModule module = domain.OpenRawModule (file)) {
266 if (!module.IsManifestModule) {
267 Error_AssemblyIsModule (fileName);
271 return domain.LoadAssembly (module);
274 Error_FileCorrupted (file);
279 Error_FileNotFound (fileName);
283 public RawModule LoadModuleFile (string moduleName)
285 foreach (var path in paths) {
286 var file = Path.Combine (path, moduleName);
287 if (!File.Exists (file)) {
288 if (moduleName.EndsWith (".netmodule", StringComparison.Ordinal))
291 file += ".netmodule";
292 if (!File.Exists (file))
297 return domain.OpenRawModule (file);
299 Error_FileCorrupted (file);
304 Error_FileNotFound (moduleName);
309 // Optimized default assembly loader version
311 public override Assembly LoadAssemblyDefault (string assembly)
313 foreach (var path in paths) {
314 var file = Path.Combine (path, assembly);
315 if (!File.Exists (file))
319 return domain.LoadFile (file);
321 // Default assemblies can fail to load without error
329 public override void LoadReferences (ModuleContainer module)
331 List<Tuple<RootNamespace, Assembly>> loaded;
332 base.LoadReferencesCore (module, out corlib, out loaded);
334 if (corlib != null) {
335 importer.InitializeBuildinTypes (compiler.BuildinTypes, corlib);
336 importer.ImportAssembly (corlib, module.GlobalRootNamespace);
339 foreach (var entry in loaded) {
340 importer.ImportAssembly (entry.Item2, entry.Item1);
344 public void LoadModules (AssemblyDefinitionStatic assembly, RootNamespace targetNamespace)
346 if (RootContext.Modules.Count == 0)
349 foreach (var moduleName in RootContext.Modules) {
350 var m = LoadModuleFile (moduleName);
354 if (m.IsManifestModule) {
355 Error_FileCorrupted (moduleName);
359 var md = importer.ImportModule (assembly.IncludeModule (m), targetNamespace);
360 assembly.AddModule (md);
366 // Represents missing assembly reference
368 class MissingAssembly : Assembly
370 class MissingModule : Module
372 readonly Assembly assembly;
374 public MissingModule (Universe universe, Assembly assembly)
377 this.assembly = assembly;
380 public override int MDStreamVersion {
382 throw new NotImplementedException ();
386 public override Assembly Assembly {
392 public override string FullyQualifiedName {
394 throw new NotImplementedException ();
398 public override string Name {
400 throw new NotImplementedException ();
404 public override Guid ModuleVersionId {
406 throw new NotImplementedException ();
410 public override MetaType ResolveType (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
412 throw new NotImplementedException ();
415 public override MethodBase ResolveMethod (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
417 throw new NotImplementedException ();
420 public override FieldInfo ResolveField (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
422 throw new NotImplementedException ();
425 public override MemberInfo ResolveMember (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
427 throw new NotImplementedException ();
430 public override string ResolveString (int metadataToken)
432 throw new NotImplementedException ();
435 public override MetaType[] __ResolveOptionalParameterTypes (int metadataToken)
437 throw new NotImplementedException ();
440 public override string ScopeName {
442 throw new NotImplementedException ();
446 internal override MetaType GetTypeImpl (string typeName)
448 throw new NotImplementedException ();
451 internal override void GetTypesImpl (List<MetaType> list)
453 throw new NotImplementedException ();
456 public override AssemblyName[] __GetReferencedAssemblies ()
458 throw new NotImplementedException ();
461 internal override MetaType GetModuleType ()
463 throw new NotImplementedException ();
466 internal override IKVM.Reflection.Reader.ByteReader GetBlob (int blobIndex)
468 throw new NotImplementedException ();
472 readonly string full_name;
473 readonly Module module;
474 Dictionary<string, MetaType> types;
476 public MissingAssembly (Universe universe, string fullName)
479 this.full_name = fullName;
480 this.module = new MissingModule (universe, this);
481 types = new Dictionary<string, MetaType> ();
484 public override MetaType[] GetTypes ()
486 throw new NotImplementedException ();
489 public override string FullName {
495 public override AssemblyName GetName ()
497 throw new NotImplementedException ();
500 public override string ImageRuntimeVersion {
502 throw new NotImplementedException ();
506 public override Module ManifestModule {
512 public override MethodInfo EntryPoint {
514 throw new NotImplementedException ();
518 public override string Location {
520 throw new NotImplementedException ();
524 public override AssemblyName[] GetReferencedAssemblies ()
526 throw new NotImplementedException ();
529 public override Module[] GetModules (bool getResourceModules)
531 throw new NotImplementedException ();
534 public override Module[] GetLoadedModules (bool getResourceModules)
536 throw new NotImplementedException ();
539 public override Module GetModule (string name)
541 throw new NotImplementedException ();
544 public override string[] GetManifestResourceNames ()
546 throw new NotImplementedException ();
549 public override ManifestResourceInfo GetManifestResourceInfo (string resourceName)
551 throw new NotImplementedException ();
554 public override Stream GetManifestResourceStream (string resourceName)
556 throw new NotImplementedException ();
559 internal override MetaType GetTypeImpl (string typeName)
562 // We are loading a type from missing reference
563 // this itself is fine. The error will be reported
564 // later when the type is actually used
567 if (!types.TryGetValue (typeName, out t)) {
568 t = new MissingType (typeName, this);
569 types.Add (typeName, t);
575 internal override IList<CustomAttributeData> GetCustomAttributesData (MetaType attributeType)
577 throw new NotImplementedException ();
581 class MissingType : MetaType
583 readonly string full_name;
584 readonly MissingAssembly assembly;
586 public MissingType (string typeName, MissingAssembly assembly)
588 this.full_name = typeName;
589 this.assembly = assembly;
592 public override TypeAttributes Attributes {
594 // TODO: Don't know yet
595 return TypeAttributes.Public;
599 public override MetaType BaseType {
605 public override string FullName {
611 internal override MetaType GetGenericTypeArgument (int index)
613 return new MissingType ("#" + index.ToString (), assembly);
616 public override bool IsGenericTypeDefinition {
618 return full_name.IndexOf ('`') > 0;
622 public override Module Module {
624 return assembly.ManifestModule;
629 class AssemblyBuilderIKVM : AssemblyBuilderExtension
631 readonly AssemblyBuilder builder;
633 public AssemblyBuilderIKVM (AssemblyBuilder builder, CompilerContext ctx)
636 this.builder = builder;
639 public override void AddTypeForwarder (TypeSpec type, Location loc)
641 builder.__AddTypeForwarder (type.GetMetaInfo ());
644 public override void DefineWin32IconResource (string fileName)
646 builder.__DefineIconResource (File.ReadAllBytes (fileName));
649 public override void SetAlgorithmId (uint value, Location loc)
651 builder.__SetAssemblyAlgorithmId ((AssemblyHashAlgorithm) value);
654 public override void SetCulture (string culture, Location loc)
656 builder.__SetAssemblyCulture (culture);
659 public override void SetFlags (uint flags, Location loc)
661 builder.__SetAssemblyFlags ((AssemblyNameFlags) flags);
664 public override void SetVersion (Version version, Location loc)
666 builder.__SetAssemblyVersion (version);