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 if (name == "ValueType" && baseType.Namespace == "System")
59 return MemberKind.Struct;
61 if (name == "Enum" && baseType.Namespace == "System")
62 return MemberKind.Enum;
64 if (name == "MulticastDelegate" && baseType.Namespace == "System")
65 return MemberKind.Delegate;
67 return MemberKind.Class;
70 protected override bool HasVolatileModifier (MetaType[] modifiers)
72 foreach (var t in modifiers) {
73 if (t.Name == "IsVolatile" && t.Namespace == CompilerServicesNamespace)
80 public override void GetCustomAttributeTypeName (CustomAttributeData cad, out string typeNamespace, out string typeName)
82 cad.__ReadTypeName (out typeNamespace, out typeName);
85 public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
87 // It can be used more than once when importing same assembly
88 // into 2 or more global aliases
89 var definition = GetAssemblyDefinition (assembly);
91 var all_types = assembly.GetTypes ();
92 ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod);
95 public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace)
97 var module_definition = new ImportedModuleDefinition (module, this);
98 module_definition.ReadAttributes ();
100 var all_types = module.GetTypes ();
101 ImportTypes (all_types, targetNamespace, false);
103 return module_definition;
106 public void InitializeBuildinTypes (BuildinTypes buildin, Assembly corlib)
109 // Setup mapping for build-in types to avoid duplication of their definition
111 foreach (var type in buildin.AllTypes) {
112 buildin_types.Add (corlib.GetType (type.FullName), type);
118 class AssemblyDefinitionStatic : AssemblyDefinition
121 // Assembly container with file output
123 public AssemblyDefinitionStatic (ModuleContainer module, string name, string fileName)
124 : base (module, name, fileName)
129 // Initializes the code generator
131 public bool Create (StaticLoader loader)
133 ResolveAssemblySecurityAttributes ();
134 var an = CreateAssemblyName ();
136 Builder = loader.Domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save, Path.GetDirectoryName (file_name));
138 if (loader.Corlib != null) {
139 Builder.__SetImageRuntimeVersion (loader.Corlib.ImageRuntimeVersion, 0x20000);
141 // Sets output file metadata version when there is no mscorlib
142 switch (RootContext.StdLibRuntimeVersion) {
143 case RuntimeVersion.v4:
144 Builder.__SetImageRuntimeVersion ("v4.0.30319", 0x20000);
146 case RuntimeVersion.v2:
147 Builder.__SetImageRuntimeVersion ("v2.0.50727", 0x20000);
149 case RuntimeVersion.v1:
150 // Compiler does not do any checks whether the produced metadata
151 // are valid in the context of 1.0 stream version
152 Builder.__SetImageRuntimeVersion ("v1.1.4322", 0x10000);
155 throw new NotImplementedException ();
159 builder_extra = new AssemblyBuilderIKVM (Builder, Compiler);
163 public Module IncludeModule (RawModule moduleFile)
165 return Builder.__AddModule (moduleFile);
168 protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
170 module.Builder.__Save (pekind, machine);
174 class StaticLoader : AssemblyReferencesLoader<Assembly>, IDisposable
176 readonly StaticImporter importer;
177 readonly Universe domain;
180 public StaticLoader (StaticImporter importer, CompilerContext compiler)
183 this.importer = importer;
184 domain = new Universe ();
185 domain.AssemblyResolve += AssemblyReferenceResolver;
187 // TODO: profile specific
188 paths.Add (Path.GetDirectoryName (typeof (object).Assembly.Location));
191 public Assembly Corlib {
200 public Universe Domain {
206 Assembly AssemblyReferenceResolver (object sender, IKVM.Reflection.ResolveEventArgs args)
208 if (args.Name == "mscorlib")
211 // AssemblyReference has not been found in the domain
212 // create missing reference and continue
213 return new MissingAssembly (domain, args.Name);
216 public void Dispose ()
221 protected override string[] GetDefaultReferences ()
224 // For now the "default config" is harcoded into the compiler
225 // we can move this outside later
227 var default_references = new List<string> (4);
229 default_references.Add ("System.dll");
230 default_references.Add ("System.Xml.dll");
232 if (RootContext.Version > LanguageVersion.ISO_2)
233 default_references.Add ("System.Core.dll");
234 if (RootContext.Version > LanguageVersion.V_3)
235 default_references.Add ("Microsoft.CSharp.dll");
237 return default_references.ToArray ();
240 public override bool HasObjectType (Assembly assembly)
242 return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
245 public override Assembly LoadAssemblyFile (string fileName)
247 bool? has_extension = null;
248 foreach (var path in paths) {
249 var file = Path.Combine (path, fileName);
250 if (!File.Exists (file)) {
251 if (!has_extension.HasValue)
252 has_extension = fileName.EndsWith (".dll", StringComparison.Ordinal) || fileName.EndsWith (".exe", StringComparison.Ordinal);
254 if (has_extension.Value)
258 if (!File.Exists (file))
263 using (RawModule module = domain.OpenRawModule (file)) {
264 if (!module.IsManifestModule) {
265 Error_AssemblyIsModule (fileName);
269 return domain.LoadAssembly (module);
272 Error_FileCorrupted (file);
277 Error_FileNotFound (fileName);
281 public RawModule LoadModuleFile (string moduleName)
283 foreach (var path in paths) {
284 var file = Path.Combine (path, moduleName);
285 if (!File.Exists (file)) {
286 if (moduleName.EndsWith (".netmodule", StringComparison.Ordinal))
289 file += ".netmodule";
290 if (!File.Exists (file))
295 return domain.OpenRawModule (file);
297 Error_FileCorrupted (file);
302 Error_FileNotFound (moduleName);
307 // Optimized default assembly loader version
309 public override Assembly LoadAssemblyDefault (string assembly)
311 foreach (var path in paths) {
312 var file = Path.Combine (path, assembly);
313 if (!File.Exists (file))
317 return domain.LoadFile (file);
319 // Default assemblies can fail to load without error
327 public override void LoadReferences (ModuleContainer module)
329 List<Tuple<RootNamespace, Assembly>> loaded;
330 base.LoadReferencesCore (module, out corlib, out loaded);
332 if (corlib != null) {
333 importer.InitializeBuildinTypes (compiler.BuildinTypes, corlib);
334 importer.ImportAssembly (corlib, module.GlobalRootNamespace);
337 foreach (var entry in loaded) {
338 importer.ImportAssembly (entry.Item2, entry.Item1);
342 public void LoadModules (AssemblyDefinitionStatic assembly, RootNamespace targetNamespace)
344 if (RootContext.Modules.Count == 0)
347 foreach (var moduleName in RootContext.Modules) {
348 var m = LoadModuleFile (moduleName);
352 if (m.IsManifestModule) {
353 Error_FileCorrupted (moduleName);
357 var md = importer.ImportModule (assembly.IncludeModule (m), targetNamespace);
358 assembly.AddModule (md);
364 // Represents missing assembly reference
366 public class MissingAssembly : Assembly
368 class MissingModule : Module
370 readonly Assembly assembly;
372 public MissingModule (Universe universe, Assembly assembly)
375 this.assembly = assembly;
378 public override int MDStreamVersion {
380 throw new NotImplementedException ();
384 public override Assembly Assembly {
390 public override string FullyQualifiedName {
392 throw new NotImplementedException ();
396 public override string Name {
398 throw new NotImplementedException ();
402 public override Guid ModuleVersionId {
404 throw new NotImplementedException ();
408 public override MetaType ResolveType (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
410 throw new NotImplementedException ();
413 public override MethodBase ResolveMethod (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
415 throw new NotImplementedException ();
418 public override FieldInfo ResolveField (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
420 throw new NotImplementedException ();
423 public override MemberInfo ResolveMember (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
425 throw new NotImplementedException ();
428 public override string ResolveString (int metadataToken)
430 throw new NotImplementedException ();
433 public override MetaType[] __ResolveOptionalParameterTypes (int metadataToken)
435 throw new NotImplementedException ();
438 public override string ScopeName {
440 throw new NotImplementedException ();
444 internal override MetaType GetTypeImpl (string typeName)
446 throw new NotImplementedException ();
449 internal override void GetTypesImpl (List<MetaType> list)
451 throw new NotImplementedException ();
454 public override AssemblyName[] __GetReferencedAssemblies ()
456 throw new NotImplementedException ();
459 internal override MetaType GetModuleType ()
461 throw new NotImplementedException ();
464 internal override IKVM.Reflection.Reader.ByteReader GetBlob (int blobIndex)
466 throw new NotImplementedException ();
470 readonly string full_name;
471 readonly Module module;
472 Dictionary<string, MetaType> types;
474 public MissingAssembly (Universe universe, string fullName)
477 this.full_name = fullName;
478 this.module = new MissingModule (universe, this);
479 types = new Dictionary<string, MetaType> ();
482 public override MetaType[] GetTypes ()
484 throw new NotImplementedException ();
487 public override string FullName {
493 public override AssemblyName GetName ()
495 return new AssemblyName (full_name);
498 public override string ImageRuntimeVersion {
500 throw new NotImplementedException ();
504 public override Module ManifestModule {
510 public override MethodInfo EntryPoint {
512 throw new NotImplementedException ();
516 public override string Location {
518 throw new NotImplementedException ();
522 public override AssemblyName[] GetReferencedAssemblies ()
524 throw new NotImplementedException ();
527 public override Module[] GetModules (bool getResourceModules)
529 throw new NotImplementedException ();
532 public override Module[] GetLoadedModules (bool getResourceModules)
534 throw new NotImplementedException ();
537 public override Module GetModule (string name)
539 throw new NotImplementedException ();
542 public override string[] GetManifestResourceNames ()
544 throw new NotImplementedException ();
547 public override ManifestResourceInfo GetManifestResourceInfo (string resourceName)
549 throw new NotImplementedException ();
552 public override Stream GetManifestResourceStream (string resourceName)
554 throw new NotImplementedException ();
557 internal override MetaType GetTypeImpl (string typeName)
560 // We are loading a type from missing reference
561 // this itself is fine. The error will be reported
562 // later when the type is actually used
565 if (!types.TryGetValue (typeName, out t)) {
566 t = new MissingType (typeName, this);
567 types.Add (typeName, t);
573 internal override IList<CustomAttributeData> GetCustomAttributesData (MetaType attributeType)
575 throw new NotImplementedException ();
579 public class MissingType : MetaType
581 readonly string full_name;
582 readonly MissingAssembly assembly;
584 public MissingType (string typeName, MissingAssembly assembly)
586 this.full_name = typeName;
587 this.assembly = assembly;
590 public override TypeAttributes Attributes {
592 // TODO: Don't know yet
593 return TypeAttributes.Public;
597 public override MetaType BaseType {
603 public override string FullName {
609 internal override MetaType GetGenericTypeArgument (int index)
611 return new MissingType ("#" + index.ToString (), assembly);
614 public override MetaType GetNestedType (string name, BindingFlags bindingAttr)
616 return new MissingType (full_name + name, assembly);
619 public override bool IsGenericTypeDefinition {
621 return full_name.IndexOf ('`') > 0;
625 public override Module Module {
627 return assembly.ManifestModule;
632 class AssemblyBuilderIKVM : AssemblyBuilderExtension
634 readonly AssemblyBuilder builder;
636 public AssemblyBuilderIKVM (AssemblyBuilder builder, CompilerContext ctx)
639 this.builder = builder;
642 public override void AddTypeForwarder (TypeSpec type, Location loc)
644 builder.__AddTypeForwarder (type.GetMetaInfo ());
647 public override void DefineWin32IconResource (string fileName)
649 builder.__DefineIconResource (File.ReadAllBytes (fileName));
652 public override void SetAlgorithmId (uint value, Location loc)
654 builder.__SetAssemblyAlgorithmId ((AssemblyHashAlgorithm) value);
657 public override void SetCulture (string culture, Location loc)
659 builder.__SetAssemblyCulture (culture);
662 public override void SetFlags (uint flags, Location loc)
664 builder.__SetAssemblyFlags ((AssemblyNameFlags) flags);
667 public override void SetVersion (Version version, Location loc)
669 builder.__SetAssemblyVersion (version);