* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Mono.CompilerServices.SymbolWriter / SymbolWriterImpl.cs
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
31 using System;
32 using System.Reflection;
33 using System.Reflection.Emit;
34 using System.Runtime.CompilerServices;
35 using System.Collections;
36 using System.IO;
37 using System.Diagnostics.SymbolStore;
38         
39 namespace Mono.CompilerServices.SymbolWriter
40 {
41         public class SymbolWriterImpl: ISymbolWriter
42         {
43                 MonoSymbolWriter msw;
44                 ModuleBuilder mb;
45
46                 delegate Guid GetGuidFunc (ModuleBuilder mb);
47                 GetGuidFunc get_guid_func;
48                 
49                 int nextLocalIndex;
50                 int currentToken;
51                 string methodName;
52                 Stack namespaceStack = new Stack ();
53                 bool methodOpened;
54                 
55                 Hashtable documents = new Hashtable ();
56                 
57                 public SymbolWriterImpl (ModuleBuilder mb)
58                 {
59                         this.mb = mb;
60                 }
61                 
62                 public void Close ()
63                 {
64                         MethodInfo mi = typeof (ModuleBuilder).GetMethod (
65                                 "Mono_GetGuid",
66                                 BindingFlags.Static | BindingFlags.NonPublic);
67                         if (mi == null)
68                                 return;
69
70                         get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
71                                 typeof (GetGuidFunc), mi);
72                         
73                         msw.WriteSymbolFile (get_guid_func (mb));
74                 }
75                 
76                 public void CloseMethod ()
77                 {
78                         if (methodOpened) {
79                                 methodOpened = false;
80                                 nextLocalIndex = 0;
81                                 msw.CloseMethod ();
82                         }
83                 }
84                 
85                 public void CloseNamespace ()
86                 {
87                         namespaceStack.Pop ();
88                         msw.CloseNamespace ();
89                 }
90                 
91                 public void CloseScope (int endOffset)
92                 {
93                         msw.CloseScope (endOffset);
94                 }
95                 
96                 public ISymbolDocumentWriter DefineDocument (
97                         string url,
98                         Guid language,
99                         Guid languageVendor,
100                         Guid documentType)
101                 {
102                         SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl) documents [url];
103                         if (doc == null) {
104                                 doc = new SymbolDocumentWriterImpl (msw.DefineDocument (url));
105                                 documents [url] = doc;
106                         }
107                         return doc;
108                 }
109                         
110                 public void DefineField (
111                         SymbolToken parent,
112                         string name,
113                         FieldAttributes attributes,
114                         byte[] signature,
115                         SymAddressKind addrKind,
116                         int addr1,
117                         int addr2,
118                         int addr3)
119                 {
120                 }
121                 
122                 public void DefineGlobalVariable (
123                         string name,
124                         FieldAttributes attributes,
125                         byte[] signature,
126                         SymAddressKind addrKind,
127                         int addr1,
128                         int addr2,
129                         int addr3)
130                 {
131                 }
132                 
133                 public void DefineLocalVariable (
134                         string name,
135                         FieldAttributes attributes,
136                         byte[] signature,
137                         SymAddressKind addrKind,
138                         int addr1,
139                         int addr2,
140                         int addr3,
141                         int startOffset,
142                         int endOffset)
143                 {
144                         msw.DefineLocalVariable (nextLocalIndex++, name, signature);
145                 }
146                 
147                 public void DefineParameter (
148                         string name,
149                         ParameterAttributes attributes,
150                         int sequence,
151                         SymAddressKind addrKind,
152                         int addr1,
153                         int addr2,
154                         int addr3)
155                 {
156                 }
157
158                 public void DefineSequencePoints (
159                         ISymbolDocumentWriter document,
160                         int[] offsets,
161                         int[] lines,
162                         int[] columns,
163                         int[] endLines,
164                         int[] endColumns)
165                 {
166                         for (int n=0; n<offsets.Length; n++) {
167                                 if (n > 0 && offsets[n] == offsets[n-1] && lines[n] == lines[n-1] && columns[n] == columns[n-1])
168                                         continue;
169                                 msw.MarkSequencePoint (offsets[n], lines[n], columns[n]);
170                         }
171                 }
172                 
173                 public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
174                 {
175                         msw = new MonoSymbolWriter (filename);
176                 }
177                 
178                 public void OpenMethod (SymbolToken method)
179                 {
180                         currentToken = method.GetToken ();
181                 }
182                 
183                 public void OpenNamespace (string name)
184                 {
185                         NamespaceInfo n = new NamespaceInfo ();
186                         n.NamespaceID = -1;
187                         n.Name = name;
188                         namespaceStack.Push (n);
189                 }
190                 
191                 public int OpenScope (int startOffset)
192                 {
193                         return msw.OpenScope (startOffset);
194                 }
195                 
196                 public void SetMethodSourceRange (
197                         ISymbolDocumentWriter startDoc,
198                         int startLine,
199                         int startColumn,
200                         ISymbolDocumentWriter endDoc,
201                         int endLine,
202                         int endColumn)
203                 {
204                         SourceMethodImpl sm = new SourceMethodImpl (methodName, currentToken, GetCurrentNamespace (startDoc));
205                         msw.OpenMethod (startDoc as ISourceFile, sm, startLine, startColumn, endLine, endColumn);
206                         methodOpened = true;
207                 }
208                 
209                 public void SetScopeRange (int scopeID, int startOffset, int endOffset)
210                 {
211                 }
212                 
213                 public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
214                 {
215                         // This is a hack! but MonoSymbolWriter needs the method name
216                         // and ISymbolWriter does not have any method for providing it
217                         if (name == "__name")
218                                 methodName = System.Text.Encoding.UTF8.GetString (data);
219                 }
220                 
221                 public void SetUnderlyingWriter (IntPtr underlyingWriter)
222                 {
223                 }
224                 
225                 public void SetUserEntryPoint (SymbolToken entryMethod)
226                 {
227                 }
228
229                 public void UsingNamespace (string fullName)
230                 {
231                         if (namespaceStack.Count == 0) {
232                                 OpenNamespace ("");
233                         }
234                         
235                         NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
236                         if (ni.NamespaceID != -1) {
237                                 NamespaceInfo old = ni;
238                                 CloseNamespace ();
239                                 OpenNamespace (old.Name);
240                                 ni = (NamespaceInfo) namespaceStack.Peek ();
241                                 ni.UsingClauses = old.UsingClauses;
242                         }
243                         ni.UsingClauses.Add (fullName);
244                 }
245                 
246                 int GetCurrentNamespace (ISymbolDocumentWriter doc)
247                 {
248                         if (namespaceStack.Count == 0) {
249                                 OpenNamespace ("");
250                         }
251
252                         NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
253                         if (ni.NamespaceID == -1)
254                         {
255                                 string[] usings = (string[]) ni.UsingClauses.ToArray (typeof(string));
256                                 
257                                 int parentId = 0;
258                                 if (namespaceStack.Count > 1) {
259                                         namespaceStack.Pop ();
260                                         parentId = ((NamespaceInfo) namespaceStack.Peek ()).NamespaceID;
261                                         namespaceStack.Push (ni);
262                                 }
263                                         
264                                 ni.NamespaceID = msw.DefineNamespace (ni.Name, ((ISourceFile)doc).Entry, usings, parentId);
265                         }
266                         return ni.NamespaceID;
267                 }
268         }
269         
270         class SymbolDocumentWriterImpl: ISymbolDocumentWriter, ISourceFile
271         {
272                 SourceFileEntry entry;
273                 
274                 public SymbolDocumentWriterImpl (SourceFileEntry e)
275                 {
276                         entry = e;
277                 }
278                 
279                 public void SetCheckSum (Guid algorithmId, byte[] checkSum)
280                 {
281                 }
282                 
283                 public void SetSource (byte[] source)
284                 {
285                 }
286                 
287                 public SourceFileEntry Entry {
288                         get { return entry; }
289                 }
290         }
291         
292         class SourceMethodImpl: ISourceMethod
293         {
294                 string name;
295                 int token;
296                 int namespaceID;
297                 
298                 public SourceMethodImpl (string name, int token, int namespaceID)
299                 {
300                         this.name = name;
301                         this.token = token;
302                         this.namespaceID = namespaceID;
303                 }
304                 
305                 public string Name {
306                         get { return name; }
307                 }
308
309                 public int NamespaceID {
310                         get { return namespaceID; }
311                 }
312
313                 public int Token {
314                         get { return token; }
315                 }
316         }
317         
318         class NamespaceInfo
319         {
320                 public string Name;
321                 public int NamespaceID;
322                 public ArrayList UsingClauses = new ArrayList ();
323         }
324 }