Moved ProviderCollectionTest.cs from System assembly to System.Configuration.
[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
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 #if FIXME
224                         SourceMethodImpl sm = new SourceMethodImpl (methodName, currentToken, GetCurrentNamespace (startDoc));
225                         msw.OpenMethod (startDoc as ISourceFile, sm, startLine, startColumn, endLine, endColumn);
226                         methodOpened = true;
227 #endif
228                 }
229                 
230                 public void SetScopeRange (int scopeID, int startOffset, int endOffset)
231                 {
232                 }
233                 
234                 public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
235                 {
236                         // This is a hack! but MonoSymbolWriter needs the method name
237                         // and ISymbolWriter does not have any method for providing it
238                         
239 //                      if (name == "__name")
240 //                              methodName = System.Text.Encoding.UTF8.GetString (data);
241                 }
242                 
243                 public void SetUnderlyingWriter (IntPtr underlyingWriter)
244                 {
245                 }
246                 
247                 public void SetUserEntryPoint (SymbolToken entryMethod)
248                 {
249                 }
250
251                 public void UsingNamespace (string fullName)
252                 {
253                         if (namespaceStack.Count == 0) {
254                                 OpenNamespace ("");
255                         }
256                         
257                         NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
258                         if (ni.NamespaceID != -1) {
259                                 NamespaceInfo old = ni;
260                                 CloseNamespace ();
261                                 OpenNamespace (old.Name);
262                                 ni = (NamespaceInfo) namespaceStack.Peek ();
263                                 ni.UsingClauses = old.UsingClauses;
264                         }
265                         ni.UsingClauses.Add (fullName);
266                 }
267 /*              
268                 int GetCurrentNamespace (ISymbolDocumentWriter doc)
269                 {
270                         if (namespaceStack.Count == 0) {
271                                 OpenNamespace ("");
272                         }
273
274                         NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek ();
275                         if (ni.NamespaceID == -1)
276                         {
277                                 string[] usings = (string[]) ni.UsingClauses.ToArray (typeof(string));
278                                 
279                                 int parentId = 0;
280                                 if (namespaceStack.Count > 1) {
281                                         namespaceStack.Pop ();
282                                         parentId = ((NamespaceInfo) namespaceStack.Peek ()).NamespaceID;
283                                         namespaceStack.Push (ni);
284                                 }
285                                         
286                                 ni.NamespaceID = msw.DefineNamespace (ni.Name, ((ICompileUnit)doc).Entry, usings, parentId);
287                         }
288                         return ni.NamespaceID;
289                 }
290 */
291         }
292         
293         class SymbolDocumentWriterImpl: ISymbolDocumentWriter, ISourceFile, ICompileUnit
294         {
295                 CompileUnitEntry comp_unit;
296                 
297                 public SymbolDocumentWriterImpl (CompileUnitEntry comp_unit)
298                 {
299                         this.comp_unit = comp_unit;
300                 }
301                 
302                 public void SetCheckSum (Guid algorithmId, byte[] checkSum)
303                 {
304                 }
305                 
306                 public void SetSource (byte[] source)
307                 {
308                 }
309
310                 SourceFileEntry ISourceFile.Entry {
311                         get { return comp_unit.SourceFile; }
312                 }
313                 
314                 public CompileUnitEntry Entry {
315                         get { return comp_unit; }
316                 }
317         }
318         
319         class SourceMethodImpl: IMethodDef
320         {
321                 string name;
322                 int token;
323                 int namespaceID;
324                 
325                 public SourceMethodImpl (string name, int token, int namespaceID)
326                 {
327                         this.name = name;
328                         this.token = token;
329                         this.namespaceID = namespaceID;
330                 }
331                 
332                 public string Name {
333                         get { return name; }
334                 }
335
336                 public int NamespaceID {
337                         get { return namespaceID; }
338                 }
339
340                 public int Token {
341                         get { return token; }
342                 }
343         }
344         
345         class NamespaceInfo
346         {
347                 public string Name;
348                 public int NamespaceID;
349                 public ArrayList UsingClauses = new ArrayList ();
350         }
351 }