5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2005 Novell, Inc. http://www.novell.com
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
32 using System
.Reflection
;
33 using System
.Reflection
.Emit
;
34 using System
.Runtime
.CompilerServices
;
35 using System
.Collections
;
37 using System
.Diagnostics
.SymbolStore
;
39 namespace Mono
.CompilerServices
.SymbolWriter
41 public class SymbolWriterImpl
: ISymbolWriter
48 Stack namespaceStack
= new Stack ();
51 Hashtable documents
= new Hashtable ();
55 delegate Guid
GetGuidFunc (ModuleBuilder mb
);
56 GetGuidFunc get_guid_func
;
58 public SymbolWriterImpl (ModuleBuilder mb
)
65 MethodInfo mi
= typeof (ModuleBuilder
).GetMethod (
67 BindingFlags
.Static
| BindingFlags
.NonPublic
);
71 get_guid_func
= (GetGuidFunc
) System
.Delegate
.CreateDelegate (
72 typeof (GetGuidFunc
), mi
);
74 msw
.WriteSymbolFile (get_guid_func (mb
));
79 public SymbolWriterImpl (Guid guid
)
86 msw
.WriteSymbolFile (guid
);
90 public void CloseMethod ()
99 public void CloseNamespace ()
101 namespaceStack
.Pop ();
102 msw
.CloseNamespace ();
105 public void CloseScope (int endOffset
)
107 msw
.CloseScope (endOffset
);
110 public ISymbolDocumentWriter
DefineDocument (
116 SymbolDocumentWriterImpl doc
= (SymbolDocumentWriterImpl
) documents
[url
];
118 SourceFileEntry entry
= msw
.DefineDocument (url
);
119 CompileUnitEntry comp_unit
= msw
.DefineCompilationUnit (entry
);
120 doc
= new SymbolDocumentWriterImpl (comp_unit
);
121 documents
[url
] = doc
;
126 public void DefineField (
129 FieldAttributes attributes
,
131 SymAddressKind addrKind
,
138 public void DefineGlobalVariable (
140 FieldAttributes attributes
,
142 SymAddressKind addrKind
,
149 public void DefineLocalVariable (
151 FieldAttributes attributes
,
153 SymAddressKind addrKind
,
160 msw
.DefineLocalVariable (nextLocalIndex
++, name
);
163 public void DefineParameter (
165 ParameterAttributes attributes
,
167 SymAddressKind addrKind
,
174 public void DefineSequencePoints (
175 ISymbolDocumentWriter document
,
182 SymbolDocumentWriterImpl doc
= (SymbolDocumentWriterImpl
) document
;
183 SourceFileEntry file
= doc
!= null ? doc
.Entry
.SourceFile
: null;
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])
188 msw
.MarkSequencePoint (offsets
[n
], file
, lines
[n
], columns
[n
], false);
192 public void Initialize (IntPtr emitter
, string filename
, bool fFullBuild
)
194 msw
= new MonoSymbolWriter (filename
);
197 public void OpenMethod (SymbolToken method
)
199 currentToken
= method
.GetToken ();
202 public void OpenNamespace (string name
)
204 NamespaceInfo n
= new NamespaceInfo ();
207 namespaceStack
.Push (n
);
210 public int OpenScope (int startOffset
)
212 return msw
.OpenScope (startOffset
);
215 public void SetMethodSourceRange (
216 ISymbolDocumentWriter startDoc
,
219 ISymbolDocumentWriter endDoc
,
223 int nsId
= GetCurrentNamespace (startDoc
);
224 SourceMethodImpl sm
= new SourceMethodImpl (methodName
, currentToken
, nsId
);
225 msw
.OpenMethod (((ICompileUnit
)startDoc
).Entry
, nsId
, sm
);
229 public void SetScopeRange (int scopeID
, int startOffset
, int endOffset
)
233 public void SetSymAttribute (SymbolToken parent
, string name
, byte[] data
)
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
);
241 public void SetUnderlyingWriter (IntPtr underlyingWriter
)
245 public void SetUserEntryPoint (SymbolToken entryMethod
)
249 public void UsingNamespace (string fullName
)
251 if (namespaceStack
.Count
== 0) {
255 NamespaceInfo ni
= (NamespaceInfo
) namespaceStack
.Peek ();
256 if (ni
.NamespaceID
!= -1) {
257 NamespaceInfo old
= ni
;
259 OpenNamespace (old
.Name
);
260 ni
= (NamespaceInfo
) namespaceStack
.Peek ();
261 ni
.UsingClauses
= old
.UsingClauses
;
263 ni
.UsingClauses
.Add (fullName
);
266 int GetCurrentNamespace (ISymbolDocumentWriter doc
)
268 if (namespaceStack
.Count
== 0) {
272 NamespaceInfo ni
= (NamespaceInfo
) namespaceStack
.Peek ();
273 if (ni
.NamespaceID
== -1)
275 string[] usings
= (string[]) ni
.UsingClauses
.ToArray (typeof(string));
278 if (namespaceStack
.Count
> 1) {
279 namespaceStack
.Pop ();
280 parentId
= ((NamespaceInfo
) namespaceStack
.Peek ()).NamespaceID
;
281 namespaceStack
.Push (ni
);
284 ni
.NamespaceID
= msw
.DefineNamespace (ni
.Name
, ((ICompileUnit
)doc
).Entry
, usings
, parentId
);
286 return ni
.NamespaceID
;
291 class SymbolDocumentWriterImpl
: ISymbolDocumentWriter
, ISourceFile
, ICompileUnit
293 CompileUnitEntry comp_unit
;
295 public SymbolDocumentWriterImpl (CompileUnitEntry comp_unit
)
297 this.comp_unit
= comp_unit
;
300 public void SetCheckSum (Guid algorithmId
, byte[] checkSum
)
304 public void SetSource (byte[] source
)
308 SourceFileEntry ISourceFile
.Entry
{
309 get { return comp_unit.SourceFile; }
312 public CompileUnitEntry Entry
{
313 get { return comp_unit; }
317 class SourceMethodImpl
: IMethodDef
323 public SourceMethodImpl (string name
, int token
, int namespaceID
)
327 this.namespaceID
= namespaceID
;
334 public int NamespaceID
{
335 get { return namespaceID; }
339 get { return token; }
346 public int NamespaceID
;
347 public ArrayList UsingClauses
= new ArrayList ();