Merge pull request #271 from pruiz/xamarin-bug-4108
[mono.git] / mcs / class / IKVM.Reflection / Assembly.cs
1 /*
2   Copyright (C) 2009-2012 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26
27 namespace IKVM.Reflection
28 {
29         public abstract class Assembly : ICustomAttributeProvider
30         {
31                 internal readonly Universe universe;
32                 protected string fullName;      // AssemblyBuilder needs access to this field to clear it when the name changes
33
34                 internal Assembly(Universe universe)
35                 {
36                         this.universe = universe;
37                 }
38
39                 public abstract Type[] GetTypes();
40                 public abstract AssemblyName GetName();
41                 public abstract string ImageRuntimeVersion { get; }
42                 public abstract Module ManifestModule { get; }
43                 public abstract MethodInfo EntryPoint { get; }
44                 public abstract string Location { get; }
45                 public abstract AssemblyName[] GetReferencedAssemblies();
46                 public abstract Module[] GetModules(bool getResourceModules);
47                 public abstract Module[] GetLoadedModules(bool getResourceModules);
48                 public abstract Module GetModule(string name);
49                 public abstract string[] GetManifestResourceNames();
50                 public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName);
51                 public abstract System.IO.Stream GetManifestResourceStream(string name);
52
53                 internal abstract Type FindType(TypeName name);
54                 internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName);
55
56                 // The differences between ResolveType and FindType are:
57                 // - ResolveType is only used when a type is assumed to exist (because another module's metadata claims it)
58                 // - ResolveType can return a MissingType
59                 internal Type ResolveType(TypeName typeName)
60                 {
61                         return FindType(typeName) ?? universe.GetMissingTypeOrThrow(this.ManifestModule, null, typeName);
62                 }
63
64                 public string FullName
65                 {
66                         get { return fullName ?? (fullName = GetName().FullName); }
67                 }
68
69                 public Module[] GetModules()
70                 {
71                         return GetModules(true);
72                 }
73
74                 public Module[] GetLoadedModules()
75                 {
76                         return GetLoadedModules(true);
77                 }
78
79                 public AssemblyName GetName(bool copiedName)
80                 {
81                         return GetName();
82                 }
83
84                 public bool ReflectionOnly
85                 {
86                         get { return true; }
87                 }
88
89                 public Type[] GetExportedTypes()
90                 {
91                         List<Type> list = new List<Type>();
92                         foreach (Type type in GetTypes())
93                         {
94                                 if (type.IsVisible)
95                                 {
96                                         list.Add(type);
97                                 }
98                         }
99                         return list.ToArray();
100                 }
101
102                 public Type GetType(string name)
103                 {
104                         return GetType(name, false);
105                 }
106
107                 public Type GetType(string name, bool throwOnError)
108                 {
109                         return GetType(name, throwOnError, false);
110                 }
111
112                 public Type GetType(string name, bool throwOnError, bool ignoreCase)
113                 {
114                         TypeNameParser parser = TypeNameParser.Parse(name, throwOnError);
115                         if (parser.Error)
116                         {
117                                 return null;
118                         }
119                         if (parser.AssemblyName != null)
120                         {
121                                 if (throwOnError)
122                                 {
123                                         throw new ArgumentException("Type names passed to Assembly.GetType() must not specify an assembly.");
124                                 }
125                                 else
126                                 {
127                                         return null;
128                                 }
129                         }
130                         TypeName typeName = TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart));
131                         Type type = ignoreCase
132                                 ? FindTypeIgnoreCase(typeName.ToLowerInvariant())
133                                 : FindType(typeName);
134                         if (type == null && __IsMissing)
135                         {
136                                 throw new MissingAssemblyException((MissingAssembly)this);
137                         }
138                         return parser.Expand(type, this, throwOnError, name, false, ignoreCase);
139                 }
140
141                 public virtual Module LoadModule(string moduleName, byte[] rawModule)
142                 {
143                         throw new NotSupportedException();
144                 }
145
146                 public Module LoadModule(string moduleName, byte[] rawModule, byte[] rawSymbolStore)
147                 {
148                         return LoadModule(moduleName, rawModule);
149                 }
150
151                 public bool IsDefined(Type attributeType, bool inherit)
152                 {
153                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
154                 }
155
156                 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
157                 {
158                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
159                 }
160
161                 public static string CreateQualifiedName(string assemblyName, string typeName)
162                 {
163                         return assemblyName == null ? typeName : typeName + ", " + assemblyName;
164                 }
165
166                 public static Assembly GetAssembly(Type type)
167                 {
168                         return type.Assembly;
169                 }
170
171                 public string CodeBase
172                 {
173                         get
174                         {
175                                 string path = this.Location.Replace(System.IO.Path.DirectorySeparatorChar, '/');
176                                 if (!path.StartsWith("/"))
177                                 {
178                                         path = "/" + path;
179                                 }
180                                 return "file://" + path;
181                         }
182                 }
183
184                 public virtual bool __IsMissing
185                 {
186                         get { return false; }
187                 }
188
189                 public virtual AssemblyNameFlags __AssemblyFlags
190                 {
191                         get { return GetName().Flags; }
192                 }
193
194                 internal abstract IList<CustomAttributeData> GetCustomAttributesData(Type attributeType);
195         }
196 }