Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2893_BNLR/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Symbols/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 7.8 KB
Line 
1//
2// SymbolWriterImpl.cs
3//
4// Author:
5//   Lluis Sanchez Gual (lluis@novell.com)
6//
7// (C) 2005 Novell, Inc.  http://www.novell.com
8//
9//
10// Permission is hereby granted, free of charge, to any person obtaining
11// a copy of this software and associated documentation files (the
12// "Software"), to deal in the Software without restriction, including
13// without limitation the rights to use, copy, modify, merge, publish,
14// distribute, sublicense, and/or sell copies of the Software, and to
15// permit persons to whom the Software is furnished to do so, subject to
16// the following conditions:
17//
18// The above copyright notice and this permission notice shall be
19// included in all copies or substantial portions of the Software.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28//
29
30
31using System;
32using System.Reflection;
33using System.Reflection.Emit;
34using System.Runtime.CompilerServices;
35using System.Collections;
36using System.IO;
37using System.Diagnostics.SymbolStore;
38
39namespace Mono.CompilerServices.SymbolWriter
40{
41  public class SymbolWriterImpl: ISymbolWriter
42  {
43    MonoSymbolWriter msw;
44
45    int nextLocalIndex;
46    int currentToken;
47    string methodName;
48    Stack namespaceStack = new Stack ();
49    bool methodOpened;
50
51    Hashtable documents = new Hashtable ();
52
53#if !CECIL
54    ModuleBuilder mb;
55    delegate Guid GetGuidFunc (ModuleBuilder mb);
56    GetGuidFunc get_guid_func;
57
58    public SymbolWriterImpl (ModuleBuilder mb)
59    {
60      this.mb = mb;
61    }
62
63    public void Close ()
64    {
65      MethodInfo mi = typeof (ModuleBuilder).GetMethod (
66        "Mono_GetGuid",
67        BindingFlags.Static | BindingFlags.NonPublic);
68      if (mi == null)
69        return;
70
71      get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
72        typeof (GetGuidFunc), mi);
73
74      msw.WriteSymbolFile (get_guid_func (mb));
75    }
76#else
77    Guid guid;
78
79    public SymbolWriterImpl (Guid guid)
80    {
81      this.guid = guid;
82    }
83
84    public void Close ()
85    {
86      msw.WriteSymbolFile (guid);
87    }
88#endif
89
90    public void CloseMethod ()
91    {
92      if (methodOpened) {
93        methodOpened = false;
94        nextLocalIndex = 0;
95        msw.CloseMethod ();
96      }
97    }
98
99    public void CloseNamespace ()
100    {
101      namespaceStack.Pop ();
102      msw.CloseNamespace ();
103    }
104
105    public void CloseScope (int endOffset)
106    {
107      msw.CloseScope (endOffset);
108    }
109
110    public ISymbolDocumentWriter DefineDocument (
111      string url,
112      Guid language,
113      Guid languageVendor,
114      Guid documentType)
115    {
116      SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl) documents [url];
117      if (doc == null) {
118        SourceFileEntry entry = msw.DefineDocument (url);
119        CompileUnitEntry comp_unit = msw.DefineCompilationUnit (entry);
120        doc = new SymbolDocumentWriterImpl (comp_unit);
121        documents [url] = doc;
122      }
123      return doc;
124    }
125
126    public void DefineField (
127      SymbolToken parent,
128      string name,
129      FieldAttributes attributes,
130      byte[] signature,
131      SymAddressKind addrKind,
132      int addr1,
133      int addr2,
134      int addr3)
135    {
136    }
137
138    public void DefineGlobalVariable (
139      string name,
140      FieldAttributes attributes,
141      byte[] signature,
142      SymAddressKind addrKind,
143      int addr1,
144      int addr2,
145      int addr3)
146    {
147    }
148
149    public void DefineLocalVariable (
150      string name,
151      FieldAttributes attributes,
152      byte[] signature,
153      SymAddressKind addrKind,
154      int addr1,
155      int addr2,
156      int addr3,
157      int startOffset,
158      int endOffset)
159    {
160      msw.DefineLocalVariable (nextLocalIndex++, name);
161    }
162
163    public void DefineParameter (
164      string name,
165      ParameterAttributes attributes,
166      int sequence,
167      SymAddressKind addrKind,
168      int addr1,
169      int addr2,
170      int addr3)
171    {
172    }
173
174    public void DefineSequencePoints (
175      ISymbolDocumentWriter document,
176      int[] offsets,
177      int[] lines,
178      int[] columns,
179      int[] endLines,
180      int[] endColumns)
181    {
182      SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl) document;
183      SourceFileEntry file = doc != null ? doc.Entry.SourceFile : null;
184
185      for (int n=0; n<offsets.Length; n++) {
186        if (n > 0 && offsets[n] == offsets[n-1] && lines[n] == lines[n-1] && columns[n] == columns[n-1])
187          continue;
188        msw.MarkSequencePoint (offsets[n], file, lines[n], columns[n], false);
189      }
190    }
191
192    public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
193    {
194      msw = new MonoSymbolWriter (filename);
195    }
196
197    public void OpenMethod (SymbolToken method)
198    {
199      currentToken = method.GetToken ();
200    }
201
202    public void OpenNamespace (string name)
203    {
204      NamespaceInfo n = new NamespaceInfo ();
205      n.NamespaceID = -1;
206      n.Name = name;
207      namespaceStack.Push (n);
208    }
209
210    public int OpenScope (int startOffset)
211    {
212      return msw.OpenScope (startOffset);
213    }
214
215    public void SetMethodSourceRange (
216      ISymbolDocumentWriter startDoc,
217      int startLine,
218      int startColumn,
219      ISymbolDocumentWriter endDoc,
220      int endLine,
221      int endColumn)
222    {
223      int nsId = GetCurrentNamespace (startDoc);
224      SourceMethodImpl sm = new SourceMethodImpl (methodName, currentToken, nsId);
225      msw.OpenMethod (((ICompileUnit)startDoc).Entry, nsId, sm);
226      methodOpened = true;
227    }
228
229    public void SetScopeRange (int scopeID, int startOffset, int endOffset)
230    {
231    }
232
233    public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
234    {
235      // This is a hack! but MonoSymbolWriter needs the method name
236      // and ISymbolWriter does not have any method for providing it
237      if (name == "__name")
238        methodName = System.Text.Encoding.UTF8.GetString (data);
239    }
240
241    public void SetUnderlyingWriter (IntPtr underlyingWriter)
242    {
243    }
244
245    public void SetUserEntryPoint (SymbolToken entryMethod)
246    {
247    }
248
249    public void UsingNamespace (string fullName)
250    {
251      if (namespaceStack.Count == 0) {
252        OpenNamespace ("");
253      }
254
255      NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
256      if (ni.NamespaceID != -1) {
257        NamespaceInfo old = ni;
258        CloseNamespace ();
259        OpenNamespace (old.Name);
260        ni = (NamespaceInfo) namespaceStack.Peek ();
261        ni.UsingClauses = old.UsingClauses;
262      }
263      ni.UsingClauses.Add (fullName);
264    }
265
266    int GetCurrentNamespace (ISymbolDocumentWriter doc)
267    {
268      if (namespaceStack.Count == 0) {
269        OpenNamespace ("");
270      }
271
272      NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
273      if (ni.NamespaceID == -1)
274      {
275        string[] usings = (string[]) ni.UsingClauses.ToArray (typeof(string));
276
277        int parentId = 0;
278        if (namespaceStack.Count > 1) {
279          namespaceStack.Pop ();
280          parentId = ((NamespaceInfo) namespaceStack.Peek ()).NamespaceID;
281          namespaceStack.Push (ni);
282        }
283
284        ni.NamespaceID = msw.DefineNamespace (ni.Name, ((ICompileUnit)doc).Entry, usings, parentId);
285      }
286      return ni.NamespaceID;
287    }
288
289  }
290
291  class SymbolDocumentWriterImpl: ISymbolDocumentWriter, ISourceFile, ICompileUnit
292  {
293    CompileUnitEntry comp_unit;
294
295    public SymbolDocumentWriterImpl (CompileUnitEntry comp_unit)
296    {
297      this.comp_unit = comp_unit;
298    }
299
300    public void SetCheckSum (Guid algorithmId, byte[] checkSum)
301    {
302    }
303
304    public void SetSource (byte[] source)
305    {
306    }
307
308    SourceFileEntry ISourceFile.Entry {
309      get { return comp_unit.SourceFile; }
310    }
311
312    public CompileUnitEntry Entry {
313      get { return comp_unit; }
314    }
315  }
316
317  class SourceMethodImpl: IMethodDef
318  {
319    string name;
320    int token;
321    int namespaceID;
322
323    public SourceMethodImpl (string name, int token, int namespaceID)
324    {
325      this.name = name;
326      this.token = token;
327      this.namespaceID = namespaceID;
328    }
329
330    public string Name {
331      get { return name; }
332    }
333
334    public int NamespaceID {
335      get { return namespaceID; }
336    }
337
338    public int Token {
339      get { return token; }
340    }
341  }
342
343  class NamespaceInfo
344  {
345    public string Name;
346    public int NamespaceID;
347    public ArrayList UsingClauses = new ArrayList ();
348  }
349}
Note: See TracBrowser for help on using the repository browser.