5 // Jb Evain (jbevain@novell.com)
7 // (C) 2007 Novell, Inc.
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.
30 using System.Collections;
31 using System.Collections.Generic;
33 using System.IO.Compression;
38 namespace Mono.Linker {
40 public class AnnotationStore {
42 readonly Dictionary<AssemblyDefinition, AssemblyAction> assembly_actions = new Dictionary<AssemblyDefinition, AssemblyAction> ();
43 readonly Dictionary<MethodDefinition, MethodAction> method_actions = new Dictionary<MethodDefinition, MethodAction> ();
44 readonly HashSet<IMetadataTokenProvider> marked = new HashSet<IMetadataTokenProvider> ();
45 readonly HashSet<IMetadataTokenProvider> processed = new HashSet<IMetadataTokenProvider> ();
46 readonly Dictionary<TypeDefinition, TypePreserve> preserved_types = new Dictionary<TypeDefinition, TypePreserve> ();
47 readonly Dictionary<IMemberDefinition, List<MethodDefinition>> preserved_methods = new Dictionary<IMemberDefinition, List<MethodDefinition>> ();
48 readonly HashSet<IMetadataTokenProvider> public_api = new HashSet<IMetadataTokenProvider> ();
49 readonly Dictionary<MethodDefinition, List<MethodDefinition>> override_methods = new Dictionary<MethodDefinition, List<MethodDefinition>> ();
50 readonly Dictionary<MethodDefinition, List<MethodDefinition>> base_methods = new Dictionary<MethodDefinition, List<MethodDefinition>> ();
51 readonly Dictionary<AssemblyDefinition, ISymbolReader> symbol_readers = new Dictionary<AssemblyDefinition, ISymbolReader> ();
53 readonly Dictionary<object, Dictionary<IMetadataTokenProvider, object>> custom_annotations = new Dictionary<object, Dictionary<IMetadataTokenProvider, object>> ();
55 Stack<object> dependency_stack;
56 System.Xml.XmlWriter writer;
59 public void PrepareDependenciesDump ()
61 PrepareDependenciesDump ("linker-dependencies.xml.gz");
64 public void PrepareDependenciesDump (string filename)
66 dependency_stack = new Stack<object> ();
67 System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
68 settings.Indent = true;
69 settings.IndentChars = "\t";
70 var depsFile = File.OpenWrite (filename);
71 zipStream = new GZipStream (depsFile, CompressionMode.Compress);
73 writer = System.Xml.XmlWriter.Create (zipStream, settings);
74 writer.WriteStartDocument ();
75 writer.WriteStartElement ("dependencies");
76 writer.WriteStartAttribute ("version");
77 writer.WriteString ("1.0");
78 writer.WriteEndAttribute ();
81 public AssemblyAction GetAction (AssemblyDefinition assembly)
83 AssemblyAction action;
84 if (assembly_actions.TryGetValue (assembly, out action))
87 throw new NotSupportedException ();
90 public MethodAction GetAction (MethodDefinition method)
93 if (method_actions.TryGetValue (method, out action))
96 return MethodAction.Nothing;
99 public void SetAction (AssemblyDefinition assembly, AssemblyAction action)
101 assembly_actions [assembly] = action;
104 public bool HasAction (AssemblyDefinition assembly)
106 return assembly_actions.ContainsKey (assembly);
109 public void SetAction (MethodDefinition method, MethodAction action)
111 method_actions [method] = action;
114 public void Mark (IMetadataTokenProvider provider)
116 marked.Add (provider);
117 AddDependency (provider);
120 public bool IsMarked (IMetadataTokenProvider provider)
122 return marked.Contains (provider);
125 public void Processed (IMetadataTokenProvider provider)
127 processed.Add (provider);
130 public bool IsProcessed (IMetadataTokenProvider provider)
132 return processed.Contains (provider);
135 public bool IsPreserved (TypeDefinition type)
137 return preserved_types.ContainsKey (type);
140 public void SetPreserve (TypeDefinition type, TypePreserve preserve)
142 preserved_types [type] = preserve;
145 public TypePreserve GetPreserve (TypeDefinition type)
147 TypePreserve preserve;
148 if (preserved_types.TryGetValue (type, out preserve))
151 throw new NotSupportedException ();
154 public void SetPublic (IMetadataTokenProvider provider)
156 public_api.Add (provider);
159 public bool IsPublic (IMetadataTokenProvider provider)
161 return public_api.Contains (provider);
164 public void AddOverride (MethodDefinition @base, MethodDefinition @override)
166 var methods = GetOverrides (@base);
167 if (methods == null) {
168 methods = new List<MethodDefinition> ();
169 override_methods [@base] = methods;
172 methods.Add (@override);
175 public List<MethodDefinition> GetOverrides (MethodDefinition method)
177 List<MethodDefinition> overrides;
178 if (override_methods.TryGetValue (method, out overrides))
184 public void AddBaseMethod (MethodDefinition method, MethodDefinition @base)
186 var methods = GetBaseMethods (method);
187 if (methods == null) {
188 methods = new List<MethodDefinition> ();
189 base_methods [method] = methods;
195 public List<MethodDefinition> GetBaseMethods (MethodDefinition method)
197 List<MethodDefinition> bases;
198 if (base_methods.TryGetValue (method, out bases))
204 public List<MethodDefinition> GetPreservedMethods (TypeDefinition type)
206 return GetPreservedMethods (type as IMemberDefinition);
209 public void AddPreservedMethod (TypeDefinition type, MethodDefinition method)
211 AddPreservedMethod (type as IMemberDefinition, method);
214 public List<MethodDefinition> GetPreservedMethods (MethodDefinition method)
216 return GetPreservedMethods (method as IMemberDefinition);
219 public void AddPreservedMethod (MethodDefinition key, MethodDefinition method)
221 AddPreservedMethod (key as IMemberDefinition, method);
224 List<MethodDefinition> GetPreservedMethods (IMemberDefinition definition)
226 List<MethodDefinition> preserved;
227 if (preserved_methods.TryGetValue (definition, out preserved))
233 void AddPreservedMethod (IMemberDefinition definition, MethodDefinition method)
235 var methods = GetPreservedMethods (definition);
236 if (methods == null) {
237 methods = new List<MethodDefinition> ();
238 preserved_methods [definition] = methods;
241 methods.Add (method);
244 public void AddSymbolReader (AssemblyDefinition assembly, ISymbolReader symbolReader)
246 symbol_readers [assembly] = symbolReader;
249 public void CloseSymbolReader (AssemblyDefinition assembly)
251 ISymbolReader symbolReader;
252 if (!symbol_readers.TryGetValue (assembly, out symbolReader))
255 symbol_readers.Remove (assembly);
256 symbolReader.Dispose ();
259 public Dictionary<IMetadataTokenProvider, object> GetCustomAnnotations (object key)
261 Dictionary<IMetadataTokenProvider, object> slots;
262 if (custom_annotations.TryGetValue (key, out slots))
265 slots = new Dictionary<IMetadataTokenProvider, object> ();
266 custom_annotations.Add (key, slots);
270 public void AddDependency (object o)
275 KeyValuePair<object, object> pair = new KeyValuePair<object, object> (dependency_stack.Count > 0 ? dependency_stack.Peek () : null, o);
276 writer.WriteStartElement ("edge");
277 writer.WriteAttributeString ("b", TokenString (pair.Key));
278 writer.WriteAttributeString ("e", TokenString (pair.Value));
279 writer.WriteEndElement ();
282 public void Push (object o)
287 if (dependency_stack.Count > 0)
289 dependency_stack.Push (o);
297 dependency_stack.Pop ();
300 string TokenString (object o)
305 if (o is IMetadataTokenProvider)
306 return (o as IMetadataTokenProvider).MetadataToken.TokenType + ":" + o;
311 public void SaveDependencies ()
316 writer.WriteEndElement ();
317 writer.WriteEndDocument ();
323 zipStream.Dispose ();
326 dependency_stack = null;