2010-05-31 Jb Evain <jbevain@novell.com>
[mcs.git] / tools / linker / Mono.Linker / LinkContext.cs
blob4873df001bf5e96fd8ad5bf64c212a1a6e286ffd
1 //
2 // LinkContext.cs
3 //
4 // Author:
5 // Jb Evain (jbevain@gmail.com)
6 //
7 // (C) 2006 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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System.Collections;
30 using System.IO;
31 using Mono.Cecil;
33 namespace Mono.Linker {
35 public class LinkContext {
37 Pipeline _pipeline;
38 AssemblyAction _coreAction;
39 Hashtable _actions;
40 string _outputDirectory;
41 Hashtable _parameters;
42 bool _linkSymbols;
44 AssemblyResolver _resolver;
46 public Pipeline Pipeline {
47 get { return _pipeline; }
50 public string OutputDirectory {
51 get { return _outputDirectory; }
52 set { _outputDirectory = value; }
55 public AssemblyAction CoreAction {
56 get { return _coreAction; }
57 set { _coreAction = value; }
60 public bool LinkSymbols {
61 get { return _linkSymbols; }
62 set { _linkSymbols = value; }
65 public IDictionary Actions {
66 get { return _actions; }
69 public AssemblyResolver Resolver {
70 get { return _resolver; }
73 public LinkContext (Pipeline pipeline)
74 : this (pipeline, new AssemblyResolver ())
78 public LinkContext (Pipeline pipeline, AssemblyResolver resolver)
80 _pipeline = pipeline;
81 _resolver = resolver;
82 _actions = new Hashtable ();
83 _parameters = new Hashtable ();
86 public TypeDefinition GetType (string type)
88 int pos = type.IndexOf (",");
89 type = type.Replace ("+", "/");
90 if (pos == -1) {
91 foreach (AssemblyDefinition asm in GetAssemblies ())
92 if (asm.MainModule.Types.Contains (type))
93 return asm.MainModule.Types [type];
95 return null;
98 string asmname = type.Substring (pos + 1);
99 type = type.Substring (0, pos);
100 AssemblyDefinition assembly = Resolve (AssemblyNameReference.Parse (asmname));
101 return assembly.MainModule.Types [type];
104 public AssemblyDefinition Resolve (string name)
106 if (File.Exists (name)) {
107 AssemblyDefinition assembly = AssemblyFactory.GetAssembly (name);
108 _resolver.CacheAssembly (assembly);
109 SafeLoadSymbols (assembly);
110 return assembly;
111 } else {
112 AssemblyNameReference reference = new AssemblyNameReference ();
113 reference.Name = name;
114 return Resolve (reference);
118 public AssemblyDefinition Resolve (IMetadataScope scope)
120 AssemblyNameReference reference = GetReference (scope);
122 AssemblyDefinition assembly = _resolver.Resolve (reference);
124 if (SeenFirstTime (assembly)) {
125 SetAction (assembly);
126 SafeLoadSymbols (assembly);
129 return assembly;
132 public void SafeLoadSymbols (AssemblyDefinition assembly)
134 if (!_linkSymbols)
135 return;
137 try {
138 assembly.MainModule.LoadSymbols ();
139 Annotations.SetHasSymbols (assembly);
140 } catch {
141 return; // resharper loves this
145 static bool SeenFirstTime (AssemblyDefinition assembly)
147 return !Annotations.HasAction (assembly);
150 static AssemblyNameReference GetReference (IMetadataScope scope)
152 AssemblyNameReference reference;
153 if (scope is ModuleDefinition) {
154 AssemblyDefinition asm = ((ModuleDefinition) scope).Assembly;
155 reference = asm.Name;
156 } else
157 reference = (AssemblyNameReference) scope;
159 return reference;
162 void SetAction (AssemblyDefinition assembly)
164 AssemblyAction action = AssemblyAction.Link;
166 AssemblyNameDefinition name = assembly.Name;
168 if (_actions.Contains (name.Name))
169 action = (AssemblyAction) _actions [name.Name];
170 else if (IsCore (name))
171 action = _coreAction;
173 Annotations.SetAction (assembly, action);
176 static bool IsCore (AssemblyNameReference name)
178 switch (name.Name) {
179 case "mscorlib":
180 case "Accessibility":
181 case "Mono.Security":
182 return true;
183 default:
184 return name.Name.StartsWith ("System")
185 || name.Name.StartsWith ("Microsoft");
189 public AssemblyDefinition [] GetAssemblies ()
191 IDictionary cache = _resolver.AssemblyCache;
192 AssemblyDefinition [] asms = new AssemblyDefinition [cache.Count];
193 cache.Values.CopyTo (asms, 0);
194 return asms;
197 public void SetParameter (string key, string value)
199 _parameters [key] = value;
202 public bool HasParameter (string key)
204 return _parameters.Contains (key);
207 public string GetParameter (string key)
209 return (string) _parameters [key];