~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.GtkCore/libsteticui/AssemblyResolver.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

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
// (C) 2007 Novell, Inc.
 
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
// This code is a modified version of the assembly resolver implemented in Cecil.
 
30
// Keep in synch as much as possible.
 
31
 
 
32
using System;
 
33
using System.Collections;
 
34
using System.Collections.Specialized;
 
35
using System.IO;
 
36
using System.Text;
 
37
using Mono.Cecil;
 
38
 
 
39
namespace Stetic {
 
40
 
 
41
        internal class AssemblyResolver : BaseAssemblyResolver {
 
42
 
 
43
                Hashtable _assemblies;
 
44
                ApplicationBackend app;
 
45
 
 
46
                public IDictionary AssemblyCache {
 
47
                        get { return _assemblies; }
 
48
                }
 
49
 
 
50
                public AssemblyResolver (ApplicationBackend app)
 
51
                {
 
52
                        this.app = app;
 
53
                        _assemblies = new Hashtable ();
 
54
                }
 
55
 
 
56
                public StringCollection Directories = new StringCollection ();
 
57
 
 
58
                public override AssemblyDefinition Resolve (AssemblyNameReference name)
 
59
                {
 
60
                        AssemblyDefinition asm = (AssemblyDefinition) _assemblies [name.Name];
 
61
                        if (asm == null) {
 
62
                                if (app != null) {
 
63
                                        string ares = app.ResolveAssembly (name.Name);
 
64
                                        if (ares != null) {
 
65
                                                asm = AssemblyFactory.GetAssembly (ares);
 
66
                                                asm.Resolver = this;
 
67
                                                _assemblies [name.Name] = asm;
 
68
                                                return asm;
 
69
                                        }
 
70
                                }
 
71
                                asm = base.Resolve (name);
 
72
                                asm.Resolver = this;
 
73
                                _assemblies [name.Name] = asm;
 
74
                        }
 
75
 
 
76
                        return asm;
 
77
                }
 
78
 
 
79
                public TypeDefinition Resolve (TypeReference type)
 
80
                {
 
81
                        if (type is TypeDefinition)
 
82
                                return (TypeDefinition) type;
 
83
 
 
84
                        AssemblyNameReference reference = type.Scope as AssemblyNameReference;
 
85
                        if (reference != null) {
 
86
                                AssemblyDefinition assembly = Resolve (reference);
 
87
                                return assembly.MainModule.Types [type.FullName];
 
88
                        }
 
89
 
 
90
                        ModuleDefinition module = type.Scope as ModuleDefinition;
 
91
                        if (module != null)
 
92
                                return module.Types [type.FullName];
 
93
 
 
94
                        throw new NotImplementedException ();
 
95
                }
 
96
 
 
97
                public void CacheAssembly (AssemblyDefinition assembly)
 
98
                {
 
99
                        _assemblies [assembly.Name.FullName] = assembly;
 
100
                        assembly.Resolver = this;
 
101
                }
 
102
 
 
103
                public string Resolve (string assemblyName, string basePath)
 
104
                {
 
105
                        if (app != null) {
 
106
                                string ares = app.ResolveAssembly (assemblyName);
 
107
                                if (ares != null)
 
108
                                        return ares;
 
109
                        }
 
110
                        
 
111
                        StringCollection col = new StringCollection ();
 
112
                        col.Add (basePath);
 
113
                        foreach (string s in Directories)
 
114
                                col.Add (s);
 
115
                        
 
116
                        try {
 
117
                                return Resolve (AssemblyNameReference.Parse (assemblyName), col);
 
118
                        } catch {
 
119
                        }
 
120
                        return null;
 
121
                }
 
122
 
 
123
                public string Resolve (AssemblyNameReference name, StringCollection basePaths)
 
124
                {
 
125
                        string [] exts = new string [] { ".dll", ".exe" };
 
126
 
 
127
                        if (basePaths != null) {
 
128
                                foreach (string dir in basePaths) {
 
129
                                        foreach (string ext in exts) {
 
130
                                                string file = Path.Combine (dir, name.Name + ext);
 
131
                                                if (File.Exists (file))
 
132
                                                        return file;
 
133
                                        }
 
134
                                }
 
135
                        }
 
136
 
 
137
                        if (name.Name == "mscorlib")
 
138
                                return GetCorlib (name);
 
139
 
 
140
                        string asm = GetAssemblyInGac (name);
 
141
                        if (asm != null)
 
142
                                return asm;
 
143
 
 
144
                        throw new FileNotFoundException ("Could not resolve: " + name);
 
145
                }
 
146
 
 
147
                string GetCorlib (AssemblyNameReference reference)
 
148
                {
 
149
                        if (typeof (object).Assembly.GetName ().Version == reference.Version)
 
150
                                return typeof (object).Assembly.Location;
 
151
 
 
152
                        string path = Directory.GetParent (
 
153
                                Directory.GetParent (
 
154
                                        typeof (object).Module.FullyQualifiedName).FullName
 
155
                                ).FullName;
 
156
 
 
157
                        if (OnMono ()) {
 
158
                                if (reference.Version.Major == 1)
 
159
                                        path = Path.Combine (path, "1.0");
 
160
                                else if (reference.Version.Major == 2)
 
161
                                        path = Path.Combine (path, "2.0");
 
162
                                else
 
163
                                        throw new NotSupportedException ("Version not supported: " + reference.Version);
 
164
                        } else {
 
165
                                if (reference.Version.ToString () == "1.0.3300.0")
 
166
                                        path = Path.Combine (path, "v1.0.3705");
 
167
                                else if (reference.Version.ToString () == "1.0.5000.0")
 
168
                                        path = Path.Combine (path, "v1.1.4322");
 
169
                                else if (reference.Version.ToString () == "2.0.0.0")
 
170
                                        path = Path.Combine (path, "v2.0.50727");
 
171
                                else
 
172
                                        throw new NotSupportedException ("Version not supported: " + reference.Version);
 
173
                        }
 
174
 
 
175
                        return Path.Combine (path, "mscorlib.dll");
 
176
                }
 
177
 
 
178
                static string GetAssemblyInGac (AssemblyNameReference reference)
 
179
                {
 
180
                        if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
 
181
                                return null;
 
182
 
 
183
                        string currentGac = GetCurrentGacPath ();
 
184
                        if (OnMono ()) {
 
185
                                string s = GetAssemblyFile (reference, currentGac);
 
186
                                if (File.Exists (s))
 
187
                                        return s;
 
188
                        } else {
 
189
                                string [] gacs = new string [] {"GAC_MSIL", "GAC_32", "GAC"};
 
190
                                for (int i = 0; i < gacs.Length; i++) {
 
191
                                        string gac = Path.Combine (Directory.GetParent (currentGac).FullName, gacs [i]);
 
192
                                        string asm = GetAssemblyFile (reference, gac);
 
193
                                        if (Directory.Exists (gac) && File.Exists (asm))
 
194
                                                return asm;
 
195
                                }
 
196
                        }
 
197
 
 
198
                        return null;
 
199
                }
 
200
 
 
201
                static string GetAssemblyFile (AssemblyNameReference reference, string gac)
 
202
                {
 
203
                        StringBuilder sb = new StringBuilder ();
 
204
                        sb.Append (reference.Version);
 
205
                        sb.Append ("__");
 
206
                        for (int i = 0; i < reference.PublicKeyToken.Length; i++)
 
207
                                sb.Append (reference.PublicKeyToken [i].ToString ("x2"));
 
208
 
 
209
                        return Path.Combine (
 
210
                                Path.Combine (
 
211
                                        Path.Combine (gac, reference.Name), sb.ToString ()),
 
212
                                        string.Concat (reference.Name, ".dll"));
 
213
                }
 
214
 
 
215
                static string GetCurrentGacPath ()
 
216
                {
 
217
                        return Directory.GetParent (
 
218
                                Directory.GetParent (
 
219
                                        Path.GetDirectoryName (
 
220
                                                typeof (Uri).Module.FullyQualifiedName)
 
221
                                        ).FullName
 
222
                                ).FullName;
 
223
                }
 
224
        }
 
225
}