~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/mono-addins/Mono.Addins.CecilReflector/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// BaseAssemblyResolver.cs
 
3
//
 
4
// Author:
 
5
//   Jb Evain (jbevain@gmail.com)
 
6
//
 
7
// Copyright (c) 2008 - 2010 Jb Evain
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
//
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
//
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
using System;
 
30
using System.Collections.Generic;
 
31
using System.IO;
 
32
using System.Text;
 
33
 
 
34
using Mono.Collections.Generic;
 
35
 
 
36
namespace Mono.Cecil {
 
37
 
 
38
        public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference);
 
39
 
 
40
        public sealed class AssemblyResolveEventArgs : EventArgs {
 
41
 
 
42
                readonly AssemblyNameReference reference;
 
43
 
 
44
                public AssemblyNameReference AssemblyReference {
 
45
                        get { return reference; }
 
46
                }
 
47
 
 
48
                public AssemblyResolveEventArgs (AssemblyNameReference reference)
 
49
                {
 
50
                        this.reference = reference;
 
51
                }
 
52
        }
 
53
 
 
54
        public abstract class BaseAssemblyResolver : IAssemblyResolver {
 
55
 
 
56
                static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;
 
57
 
 
58
                readonly Collection<string> directories;
 
59
 
 
60
#if !SILVERLIGHT && !CF
 
61
                Collection<string> gac_paths;
 
62
#endif
 
63
 
 
64
                public void AddSearchDirectory (string directory)
 
65
                {
 
66
                        directories.Add (directory);
 
67
                }
 
68
 
 
69
                public void RemoveSearchDirectory (string directory)
 
70
                {
 
71
                        directories.Remove (directory);
 
72
                }
 
73
 
 
74
                public string [] GetSearchDirectories ()
 
75
                {
 
76
                        var directories = new string [this.directories.size];
 
77
                        Array.Copy (this.directories.items, directories, directories.Length);
 
78
                        return directories;
 
79
                }
 
80
 
 
81
                public virtual AssemblyDefinition Resolve (string fullName)
 
82
                {
 
83
                        return Resolve (fullName, new ReaderParameters ());
 
84
                }
 
85
 
 
86
                public virtual AssemblyDefinition Resolve (string fullName, ReaderParameters parameters)
 
87
                {
 
88
                        if (fullName == null)
 
89
                                throw new ArgumentNullException ("fullName");
 
90
 
 
91
                        return Resolve (AssemblyNameReference.Parse (fullName), parameters);
 
92
                }
 
93
 
 
94
                public event AssemblyResolveEventHandler ResolveFailure;
 
95
 
 
96
                protected BaseAssemblyResolver ()
 
97
                {
 
98
                        directories = new Collection<string> (2) { ".", "bin" };
 
99
                }
 
100
 
 
101
                AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
 
102
                {
 
103
                        if (parameters.AssemblyResolver == null)
 
104
                                parameters.AssemblyResolver = this;
 
105
 
 
106
                        return ModuleDefinition.ReadModule (file, parameters).Assembly;
 
107
                }
 
108
 
 
109
                public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
 
110
                {
 
111
                        return Resolve (name, new ReaderParameters ());
 
112
                }
 
113
 
 
114
                public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
 
115
                {
 
116
                        if (name == null)
 
117
                                throw new ArgumentNullException ("name");
 
118
                        if (parameters == null)
 
119
                                parameters = new ReaderParameters ();
 
120
 
 
121
                        var assembly = SearchDirectory (name, directories, parameters);
 
122
                        if (assembly != null)
 
123
                                return assembly;
 
124
 
 
125
#if !SILVERLIGHT && !CF
 
126
                        var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
 
127
 
 
128
                        if (IsZero (name.Version)) {
 
129
                                assembly = SearchDirectory (name, new [] { framework_dir }, parameters);
 
130
                                if (assembly != null)
 
131
                                        return assembly;
 
132
                        }
 
133
 
 
134
                        if (name.Name == "mscorlib") {
 
135
                                assembly = GetCorlib (name, parameters);
 
136
                                if (assembly != null)
 
137
                                        return assembly;
 
138
                        }
 
139
 
 
140
                        assembly = GetAssemblyInGac (name, parameters);
 
141
                        if (assembly != null)
 
142
                                return assembly;
 
143
 
 
144
                        assembly = SearchDirectory (name, new [] { framework_dir }, parameters);
 
145
                        if (assembly != null)
 
146
                                return assembly;
 
147
#endif
 
148
 
 
149
                        if (ResolveFailure != null) {
 
150
                                assembly = ResolveFailure (this, name);
 
151
                                if (assembly != null)
 
152
                                        return assembly;
 
153
                        }
 
154
 
 
155
                        throw new FileNotFoundException ("Could not resolve: " + name);
 
156
                }
 
157
 
 
158
                AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
 
159
                {
 
160
                        var extensions = new [] { ".exe", ".dll" };
 
161
                        foreach (var directory in directories) {
 
162
                                foreach (var extension in extensions) {
 
163
                                        string file = Path.Combine (directory, name.Name + extension);
 
164
                                        if (File.Exists (file))
 
165
                                                return GetAssembly (file, parameters);
 
166
                                }
 
167
                        }
 
168
 
 
169
                        return null;
 
170
                }
 
171
 
 
172
                static bool IsZero (Version version)
 
173
                {
 
174
                        return version == null || (version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0);
 
175
                }
 
176
 
 
177
#if !SILVERLIGHT && !CF
 
178
                AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
 
179
                {
 
180
                        var version = reference.Version;
 
181
                        var corlib = typeof (object).Assembly.GetName ();
 
182
 
 
183
                        if (corlib.Version == version || IsZero (version))
 
184
                                return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters);
 
185
 
 
186
                        var path = Directory.GetParent (
 
187
                                Directory.GetParent (
 
188
                                        typeof (object).Module.FullyQualifiedName).FullName
 
189
                                ).FullName;
 
190
 
 
191
                        if (on_mono) {
 
192
                                if (version.Major == 1)
 
193
                                        path = Path.Combine (path, "1.0");
 
194
                                else if (version.Major == 2) {
 
195
                                        if (version.MajorRevision == 5)
 
196
                                                path = Path.Combine (path, "2.1");
 
197
                                        else
 
198
                                                path = Path.Combine (path, "2.0");
 
199
                                } else if (version.Major == 4)
 
200
                                        path = Path.Combine (path, "4.0");
 
201
                                else
 
202
                                        throw new NotSupportedException ("Version not supported: " + version);
 
203
                        } else {
 
204
                                switch (version.Major) {
 
205
                                case 1:
 
206
                                        if (version.MajorRevision == 3300)
 
207
                                                path = Path.Combine (path, "v1.0.3705");
 
208
                                        else
 
209
                                                path = Path.Combine (path, "v1.0.5000.0");
 
210
                                        break;
 
211
                                case 2:
 
212
                                        path = Path.Combine (path, "v2.0.50727");
 
213
                                        break;
 
214
                                case 4:
 
215
                                        path = Path.Combine (path, "v4.0.30319");
 
216
                                        break;
 
217
                                default:
 
218
                                        throw new NotSupportedException ("Version not supported: " + version);
 
219
                                }
 
220
                        }
 
221
 
 
222
                        var file = Path.Combine (path, "mscorlib.dll");
 
223
                        if (File.Exists (file))
 
224
                                return GetAssembly (file, parameters);
 
225
 
 
226
                        return null;
 
227
                }
 
228
 
 
229
                static Collection<string> GetGacPaths ()
 
230
                {
 
231
                        if (on_mono)
 
232
                                return GetDefaultMonoGacPaths ();
 
233
 
 
234
                        var paths = new Collection<string> (2);
 
235
                        var windir = Environment.GetEnvironmentVariable ("WINDIR");
 
236
                        if (windir == null)
 
237
                                return paths;
 
238
 
 
239
                        paths.Add (Path.Combine (windir, "assembly"));
 
240
                        paths.Add (Path.Combine (windir, Path.Combine ("Microsoft.NET", "assembly")));
 
241
                        return paths;
 
242
                }
 
243
 
 
244
                static Collection<string> GetDefaultMonoGacPaths ()
 
245
                {
 
246
                        var paths = new Collection<string> (1);
 
247
                        var gac = GetCurrentMonoGac ();
 
248
                        if (gac != null)
 
249
                                paths.Add (gac);
 
250
 
 
251
                        var gac_paths_env = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX");
 
252
                        if (string.IsNullOrEmpty (gac_paths_env))
 
253
                                return paths;
 
254
 
 
255
                        var prefixes = gac_paths_env.Split (Path.PathSeparator);
 
256
                        foreach (var prefix in prefixes) {
 
257
                                if (string.IsNullOrEmpty (prefix))
 
258
                                        continue;
 
259
 
 
260
                                var gac_path = Path.Combine (Path.Combine (Path.Combine (prefix, "lib"), "mono"), "gac");
 
261
                                if (Directory.Exists (gac_path) && !paths.Contains (gac))
 
262
                                        paths.Add (gac_path);
 
263
                        }
 
264
 
 
265
                        return paths;
 
266
                }
 
267
 
 
268
                static string GetCurrentMonoGac ()
 
269
                {
 
270
                        return Path.Combine (
 
271
                                Directory.GetParent (
 
272
                                        Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName,
 
273
                                "gac");
 
274
                }
 
275
 
 
276
                AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
 
277
                {
 
278
                        if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
 
279
                                return null;
 
280
 
 
281
                        if (gac_paths == null)
 
282
                                gac_paths = GetGacPaths ();
 
283
 
 
284
                        if (on_mono)
 
285
                                return GetAssemblyInMonoGac (reference, parameters);
 
286
 
 
287
                        return GetAssemblyInNetGac (reference, parameters);
 
288
                }
 
289
 
 
290
                AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
 
291
                {
 
292
                        for (int i = 0; i < gac_paths.Count; i++) {
 
293
                                var gac_path = gac_paths [i];
 
294
                                var file = GetAssemblyFile (reference, string.Empty, gac_path);
 
295
                                if (File.Exists (file))
 
296
                                        return GetAssembly (file, parameters);
 
297
                        }
 
298
 
 
299
                        return null;
 
300
                }
 
301
 
 
302
                AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
 
303
                {
 
304
                        var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC" };
 
305
                        var prefixes = new [] { string.Empty, "v4.0_" };
 
306
 
 
307
                        for (int i = 0; i < 2; i++) {
 
308
                                for (int j = 0; j < gacs.Length; j++) {
 
309
                                        var gac = Path.Combine (gac_paths [i], gacs [j]);
 
310
                                        var file = GetAssemblyFile (reference, prefixes [i], gac);
 
311
                                        if (Directory.Exists (gac) && File.Exists (file))
 
312
                                                return GetAssembly (file, parameters);
 
313
                                }
 
314
                        }
 
315
 
 
316
                        return null;
 
317
                }
 
318
 
 
319
                static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
 
320
                {
 
321
                        var gac_folder = new StringBuilder ();
 
322
                        gac_folder.Append (prefix);
 
323
                        gac_folder.Append (reference.Version);
 
324
                        gac_folder.Append ("__");
 
325
                        for (int i = 0; i < reference.PublicKeyToken.Length; i++)
 
326
                                gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2"));
 
327
 
 
328
                        return Path.Combine (
 
329
                                Path.Combine (
 
330
                                        Path.Combine (gac, reference.Name), gac_folder.ToString ()),
 
331
                                reference.Name + ".dll");
 
332
                }
 
333
#endif
 
334
        }
 
335
}