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