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;
185 // TODO: profile specific
186 paths.Add (Path.GetDirectoryName (typeof (object).Assembly.Location));
189 public Assembly Corlib {
198 public Universe Domain {
204 Assembly AssemblyReferenceResolver (object sender, IKVM.Reflection.ResolveEventArgs args)
206 if (args.Name == "mscorlib")
209 // AssemblyReference has not been found in the domain
210 // create missing reference and continue
211 return new MissingAssembly (domain, args.Name);
214 public void Dispose ()
219 protected override string[] GetDefaultReferences ()
222 // For now the "default config" is harcoded into the compiler
223 // we can move this outside later
225 var default_references = new List<string> (4);
227 default_references.Add ("System.dll");
228 default_references.Add ("System.Xml.dll");
230 if (RootContext.Version > LanguageVersion.ISO_2)
231 default_references.Add ("System.Core.dll");
232 if (RootContext.Version > LanguageVersion.V_3)
233 default_references.Add ("Microsoft.CSharp.dll");
235 return default_references.ToArray ();
238 public override bool HasObjectType (Assembly assembly)
240 return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
243 public override Assembly LoadAssemblyFile (string fileName)
245 bool? has_extension = null;
246 foreach (var path in paths) {
247 var file = Path.Combine (path, fileName);
248 if (!File.Exists (file)) {
249 if (!has_extension.HasValue)
250 has_extension = fileName.EndsWith (".dll", StringComparison.Ordinal) || fileName.EndsWith (".exe", StringComparison.Ordinal);
252 if (has_extension.Value)
256 if (!File.Exists (file))
261 using (RawModule module = domain.OpenRawModule (file)) {
262 if (!module.IsManifestModule) {
263 Error_AssemblyIsModule (fileName);
267 return domain.LoadAssembly (module);
270 Error_FileCorrupted (file);
275 Error_FileNotFound (fileName);
279 public RawModule LoadModuleFile (string moduleName)
281 foreach (var path in paths) {
282 var file = Path.Combine (path, moduleName);
283 if (!File.Exists (file)) {
284 if (moduleName.EndsWith (".netmodule", StringComparison.Ordinal))
287 file += ".netmodule";
288 if (!File.Exists (file))
293 return domain.OpenRawModule (file);
295 Error_FileCorrupted (file);
300 Error_FileNotFound (moduleName);
305 // Optimized default assembly loader version
307 public override Assembly LoadAssemblyDefault (string assembly)
309 foreach (var path in paths) {
310 var file = Path.Combine (path, assembly);
311 if (!File.Exists (file))
315 return domain.LoadFile (file);
317 // Default assemblies can fail to load without error
325 public override void LoadReferences (ModuleContainer module)
327 List<Tuple<RootNamespace, Assembly>> loaded;
328 base.LoadReferencesCore (module, out corlib, out loaded);
330 if (corlib != null) {
331 importer.InitializeBuildinTypes (compiler.BuildinTypes, corlib);
332 importer.ImportAssembly (corlib, module.GlobalRootNamespace);
335 foreach (var entry in loaded) {
336 importer.ImportAssembly (entry.Item2, entry.Item1);
340 public void LoadModules (AssemblyDefinitionStatic assembly, RootNamespace targetNamespace)
342 if (RootContext.Modules.Count == 0)
345 foreach (var moduleName in RootContext.Modules) {
346 var m = LoadModuleFile (moduleName);
350 if (m.IsManifestModule) {
351 Error_FileCorrupted (moduleName);
355 var md = importer.ImportModule (assembly.IncludeModule (m), targetNamespace);
356 assembly.AddModule (md);
362 // Represents missing assembly reference
364 class MissingAssembly : Assembly
366 class MissingModule : Module
368 readonly Assembly assembly;
370 public MissingModule (Universe universe, Assembly assembly)
373 this.assembly = assembly;
376 public override int MDStreamVersion {
378 throw new NotImplementedException ();
382 public override Assembly Assembly {
388 public override string FullyQualifiedName {
390 throw new NotImplementedException ();
394 public override string Name {
396 throw new NotImplementedException ();
400 public override Guid ModuleVersionId {
402 throw new NotImplementedException ();
406 public override MetaType ResolveType (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
408 throw new NotImplementedException ();
411 public override MethodBase ResolveMethod (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
413 throw new NotImplementedException ();
416 public override FieldInfo ResolveField (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
418 throw new NotImplementedException ();
421 public override MemberInfo ResolveMember (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
423 throw new NotImplementedException ();
426 public override string ResolveString (int metadataToken)
428 throw new NotImplementedException ();
431 public override MetaType[] __ResolveOptionalParameterTypes (int metadataToken)
433 throw new NotImplementedException ();
436 public override string ScopeName {
438 throw new NotImplementedException ();
442 internal override MetaType GetTypeImpl (string typeName)
444 throw new NotImplementedException ();
447 internal override void GetTypesImpl (List<MetaType> list)
449 throw new NotImplementedException ();
452 public override AssemblyName[] __GetReferencedAssemblies ()
454 throw new NotImplementedException ();
457 internal override MetaType GetModuleType ()
459 throw new NotImplementedException ();
462 internal override IKVM.Reflection.Reader.ByteReader GetBlob (int blobIndex)
464 throw new NotImplementedException ();
468 readonly string full_name;
469 readonly Module module;
470 Dictionary<string, MetaType> types;
472 public MissingAssembly (Universe universe, string fullName)
475 this.full_name = fullName;
476 this.module = new MissingModule (universe, this);
477 types = new Dictionary<string, MetaType> ();
480 public override MetaType[] GetTypes ()
482 throw new NotImplementedException ();
485 public override string FullName {
491 public override AssemblyName GetName ()
493 throw new NotImplementedException ();
496 public override string ImageRuntimeVersion {
498 throw new NotImplementedException ();
502 public override Module ManifestModule {
508 public override MethodInfo EntryPoint {
510 throw new NotImplementedException ();
514 public override string Location {
516 throw new NotImplementedException ();
520 public override AssemblyName[] GetReferencedAssemblies ()
522 throw new NotImplementedException ();
525 public override Module[] GetModules (bool getResourceModules)
527 throw new NotImplementedException ();
530 public override Module[] GetLoadedModules (bool getResourceModules)
532 throw new NotImplementedException ();
535 public override Module GetModule (string name)
537 throw new NotImplementedException ();
540 public override string[] GetManifestResourceNames ()
542 throw new NotImplementedException ();
545 public override ManifestResourceInfo GetManifestResourceInfo (string resourceName)
547 throw new NotImplementedException ();
550 public override Stream GetManifestResourceStream (string resourceName)
552 throw new NotImplementedException ();
555 internal override MetaType GetTypeImpl (string typeName)
558 // We are loading a type from missing reference
559 // this itself is fine. The error will be reported
560 // later when the type is actually used
563 if (!types.TryGetValue (typeName, out t)) {
564 t = new MissingType (typeName, this);
565 types.Add (typeName, t);
571 internal override IList<CustomAttributeData> GetCustomAttributesData (MetaType attributeType)
573 throw new NotImplementedException ();
577 class MissingType : MetaType
579 readonly string full_name;
580 readonly MissingAssembly assembly;
582 public MissingType (string typeName, MissingAssembly assembly)
584 this.full_name = typeName;
585 this.assembly = assembly;
588 public override TypeAttributes Attributes {
590 // TODO: Don't know yet
591 return TypeAttributes.Public;
595 public override MetaType BaseType {
601 public override string FullName {
607 internal override MetaType GetGenericTypeArgument (int index)
609 return new MissingType ("#" + index.ToString (), assembly);
612 public override bool IsGenericTypeDefinition {
614 return full_name.IndexOf ('`') > 0;
618 public override Module Module {
620 return assembly.ManifestModule;
625 class AssemblyBuilderIKVM : AssemblyBuilderExtension
627 readonly AssemblyBuilder builder;
629 public AssemblyBuilderIKVM (AssemblyBuilder builder, CompilerContext ctx)
632 this.builder = builder;
635 public override void AddTypeForwarder (TypeSpec type, Location loc)
637 builder.__AddTypeForwarder (type.GetMetaInfo ());
640 public override void DefineWin32IconResource (string fileName)
642 builder.__DefineIconResource (File.ReadAllBytes (fileName));
645 public override void SetAlgorithmId (uint value, Location loc)
647 builder.__SetAssemblyAlgorithmId ((AssemblyHashAlgorithm) value);
650 public override void SetCulture (string culture, Location loc)
652 builder.__SetAssemblyCulture (culture);
655 public override void SetFlags (uint flags, Location loc)
657 builder.__SetAssemblyFlags ((AssemblyNameFlags) flags);
660 public override void SetVersion (Version version, Location loc)
662 builder.__SetAssemblyVersion (version);