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 (StaticLoader loader)
134 ResolveAssemblySecurityAttributes ();
135 var an = CreateAssemblyName ();
137 Builder = loader.Domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save, Path.GetDirectoryName (file_name));
139 if (loader.Corlib != null) {
140 Builder.__SetImageRuntimeVersion (loader.Corlib.ImageRuntimeVersion, 0x20000);
142 // Sets output file metadata version when there is no mscorlib
143 switch (RootContext.StdLibRuntimeVersion) {
144 case RuntimeVersion.v4:
145 Builder.__SetImageRuntimeVersion ("v4.0.30319", 0x20000);
147 case RuntimeVersion.v2:
148 Builder.__SetImageRuntimeVersion ("v2.0.50727", 0x20000);
150 case RuntimeVersion.v1:
151 // Compiler does not do any checks whether the produced metadata
152 // are valid in the context of 1.0 stream version
153 Builder.__SetImageRuntimeVersion ("v1.1.4322", 0x10000);
156 throw new NotImplementedException ();
160 builder_extra = new AssemblyBuilderIKVM (Builder, Compiler);
164 public Module IncludeModule (RawModule moduleFile)
166 return Builder.__AddModule (moduleFile);
169 protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
171 module.Builder.__Save (pekind, machine);
175 class StaticLoader : AssemblyReferencesLoader<Assembly>, IDisposable
177 readonly StaticImporter importer;
178 readonly Universe domain;
181 public StaticLoader (StaticImporter importer, CompilerContext compiler)
184 this.importer = importer;
185 domain = new Universe ();
186 domain.AssemblyResolve += AssemblyReferenceResolver;
188 // TODO: profile specific
189 paths.Add (Path.GetDirectoryName (typeof (object).Assembly.Location));
192 public Assembly Corlib {
201 public Universe Domain {
207 Assembly AssemblyReferenceResolver (object sender, IKVM.Reflection.ResolveEventArgs args)
209 if (args.Name == "mscorlib")
212 // AssemblyReference has not been found in the domain
213 // create missing reference and continue
214 return new MissingAssembly (domain, args.Name);
217 public void Dispose ()
222 protected override string[] GetDefaultReferences ()
225 // For now the "default config" is harcoded into the compiler
226 // we can move this outside later
228 var default_references = new List<string> (4);
230 default_references.Add ("System.dll");
231 default_references.Add ("System.Xml.dll");
233 if (RootContext.Version > LanguageVersion.ISO_2)
234 default_references.Add ("System.Core.dll");
235 if (RootContext.Version > LanguageVersion.V_3)
236 default_references.Add ("Microsoft.CSharp.dll");
238 return default_references.ToArray ();
241 public override bool HasObjectType (Assembly assembly)
243 return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
246 public override Assembly LoadAssemblyFile (string fileName)
248 bool? has_extension = null;
249 foreach (var path in paths) {
250 var file = Path.Combine (path, fileName);
251 if (!File.Exists (file)) {
252 if (!has_extension.HasValue)
253 has_extension = fileName.EndsWith (".dll", StringComparison.Ordinal) || fileName.EndsWith (".exe", StringComparison.Ordinal);
255 if (has_extension.Value)
259 if (!File.Exists (file))
264 using (RawModule module = domain.OpenRawModule (file)) {
265 if (!module.IsManifestModule) {
266 Error_AssemblyIsModule (fileName);
270 return domain.LoadAssembly (module);
273 Error_FileCorrupted (file);
278 Error_FileNotFound (fileName);
282 public RawModule LoadModuleFile (string moduleName)
284 foreach (var path in paths) {
285 var file = Path.Combine (path, moduleName);
286 if (!File.Exists (file)) {
287 if (moduleName.EndsWith (".netmodule", StringComparison.Ordinal))
290 file += ".netmodule";
291 if (!File.Exists (file))
296 return domain.OpenRawModule (file);
298 Error_FileCorrupted (file);
303 Error_FileNotFound (moduleName);
308 // Optimized default assembly loader version
310 public override Assembly LoadAssemblyDefault (string assembly)
312 foreach (var path in paths) {
313 var file = Path.Combine (path, assembly);
314 if (!File.Exists (file))
318 return domain.LoadFile (file);
320 // Default assemblies can fail to load without error
328 public override void LoadReferences (ModuleContainer module)
330 List<Tuple<RootNamespace, Assembly>> loaded;
331 base.LoadReferencesCore (module, out corlib, out loaded);
333 if (corlib != null) {
334 importer.InitializeBuildinTypes (compiler.BuildinTypes, corlib);
335 importer.ImportAssembly (corlib, module.GlobalRootNamespace);
338 foreach (var entry in loaded) {
339 importer.ImportAssembly (entry.Item2, entry.Item1);
343 public void LoadModules (AssemblyDefinitionStatic assembly, RootNamespace targetNamespace)
345 if (RootContext.Modules.Count == 0)
348 foreach (var moduleName in RootContext.Modules) {
349 var m = LoadModuleFile (moduleName);
353 if (m.IsManifestModule) {
354 Error_FileCorrupted (moduleName);
358 var md = importer.ImportModule (assembly.IncludeModule (m), targetNamespace);
359 assembly.AddModule (md);
365 // Represents missing assembly reference
367 public class MissingAssembly : Assembly
369 class MissingModule : Module
371 readonly Assembly assembly;
373 public MissingModule (Universe universe, Assembly assembly)
376 this.assembly = assembly;
379 public override int MDStreamVersion {
381 throw new NotImplementedException ();
385 public override Assembly Assembly {
391 public override string FullyQualifiedName {
393 throw new NotImplementedException ();
397 public override string Name {
399 throw new NotImplementedException ();
403 public override Guid ModuleVersionId {
405 throw new NotImplementedException ();
409 public override MetaType ResolveType (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
411 throw new NotImplementedException ();
414 public override MethodBase ResolveMethod (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
416 throw new NotImplementedException ();
419 public override FieldInfo ResolveField (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
421 throw new NotImplementedException ();
424 public override MemberInfo ResolveMember (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
426 throw new NotImplementedException ();
429 public override string ResolveString (int metadataToken)
431 throw new NotImplementedException ();
434 public override MetaType[] __ResolveOptionalParameterTypes (int metadataToken)
436 throw new NotImplementedException ();
439 public override string ScopeName {
441 throw new NotImplementedException ();
445 internal override MetaType GetTypeImpl (string typeName)
447 throw new NotImplementedException ();
450 internal override void GetTypesImpl (List<MetaType> list)
452 throw new NotImplementedException ();
455 public override AssemblyName[] __GetReferencedAssemblies ()
457 throw new NotImplementedException ();
460 internal override MetaType GetModuleType ()
462 throw new NotImplementedException ();
465 internal override IKVM.Reflection.Reader.ByteReader GetBlob (int blobIndex)
467 throw new NotImplementedException ();
471 readonly string full_name;
472 readonly Module module;
473 Dictionary<string, MetaType> types;
475 public MissingAssembly (Universe universe, string fullName)
478 this.full_name = fullName;
479 this.module = new MissingModule (universe, this);
480 types = new Dictionary<string, MetaType> ();
483 public override MetaType[] GetTypes ()
485 throw new NotImplementedException ();
488 public override string FullName {
494 public override AssemblyName GetName ()
496 throw new NotImplementedException ();
499 public override string ImageRuntimeVersion {
501 throw new NotImplementedException ();
505 public override Module ManifestModule {
511 public override MethodInfo EntryPoint {
513 throw new NotImplementedException ();
517 public override string Location {
519 throw new NotImplementedException ();
523 public override AssemblyName[] GetReferencedAssemblies ()
525 throw new NotImplementedException ();
528 public override Module[] GetModules (bool getResourceModules)
530 throw new NotImplementedException ();
533 public override Module[] GetLoadedModules (bool getResourceModules)
535 throw new NotImplementedException ();
538 public override Module GetModule (string name)
540 throw new NotImplementedException ();
543 public override string[] GetManifestResourceNames ()
545 throw new NotImplementedException ();
548 public override ManifestResourceInfo GetManifestResourceInfo (string resourceName)
550 throw new NotImplementedException ();
553 public override Stream GetManifestResourceStream (string resourceName)
555 throw new NotImplementedException ();
558 internal override MetaType GetTypeImpl (string typeName)
561 // We are loading a type from missing reference
562 // this itself is fine. The error will be reported
563 // later when the type is actually used
566 if (!types.TryGetValue (typeName, out t)) {
567 t = new MissingType (typeName, this);
568 types.Add (typeName, t);
574 internal override IList<CustomAttributeData> GetCustomAttributesData (MetaType attributeType)
576 throw new NotImplementedException ();
580 public class MissingType : MetaType
582 readonly string full_name;
583 readonly MissingAssembly assembly;
585 public MissingType (string typeName, MissingAssembly assembly)
587 this.full_name = typeName;
588 this.assembly = assembly;
591 public override TypeAttributes Attributes {
593 // TODO: Don't know yet
594 return TypeAttributes.Public;
598 public override MetaType BaseType {
604 public override string FullName {
610 internal override MetaType GetGenericTypeArgument (int index)
612 return new MissingType ("#" + index.ToString (), assembly);
615 public override bool IsGenericTypeDefinition {
617 return full_name.IndexOf ('`') > 0;
621 public override Module Module {
623 return assembly.ManifestModule;
628 class AssemblyBuilderIKVM : AssemblyBuilderExtension
630 readonly AssemblyBuilder builder;
632 public AssemblyBuilderIKVM (AssemblyBuilder builder, CompilerContext ctx)
635 this.builder = builder;
638 public override void AddTypeForwarder (TypeSpec type, Location loc)
640 builder.__AddTypeForwarder (type.GetMetaInfo ());
643 public override void DefineWin32IconResource (string fileName)
645 builder.__DefineIconResource (File.ReadAllBytes (fileName));
648 public override void SetAlgorithmId (uint value, Location loc)
650 builder.__SetAssemblyAlgorithmId ((AssemblyHashAlgorithm) value);
653 public override void SetCulture (string culture, Location loc)
655 builder.__SetAssemblyCulture (culture);
658 public override void SetFlags (uint flags, Location loc)
660 builder.__SetAssemblyFlags ((AssemblyNameFlags) flags);
663 public override void SetVersion (Version version, Location loc)
665 builder.__SetAssemblyVersion (version);