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
46 delegate Guid
GetGuidFunc (ModuleBuilder mb
);
47 GetGuidFunc get_guid_func
;
52 Stack namespaceStack
= new Stack ();
55 Hashtable documents
= new Hashtable ();
57 public SymbolWriterImpl (ModuleBuilder mb
)
64 MethodInfo mi
= typeof (ModuleBuilder
).GetMethod (
66 BindingFlags
.Static
| BindingFlags
.NonPublic
);
70 get_guid_func
= (GetGuidFunc
) System
.Delegate
.CreateDelegate (
71 typeof (GetGuidFunc
), mi
);
73 msw
.WriteSymbolFile (get_guid_func (mb
));
76 public void CloseMethod ()
85 public void CloseNamespace ()
87 namespaceStack
.Pop ();
88 msw
.CloseNamespace ();
91 public void CloseScope (int endOffset
)
93 msw
.CloseScope (endOffset
);
96 public ISymbolDocumentWriter
DefineDocument (
102 SymbolDocumentWriterImpl doc
= (SymbolDocumentWriterImpl
) documents
[url
];
104 doc
= new SymbolDocumentWriterImpl (msw
.DefineDocument (url
));
105 documents
[url
] = doc
;
110 public void DefineField (
113 FieldAttributes attributes
,
115 SymAddressKind addrKind
,
122 public void DefineGlobalVariable (
124 FieldAttributes attributes
,
126 SymAddressKind addrKind
,
133 public void DefineLocalVariable (
135 FieldAttributes attributes
,
137 SymAddressKind addrKind
,
144 msw
.DefineLocalVariable (nextLocalIndex
++, name
, signature
);
147 public void DefineParameter (
149 ParameterAttributes attributes
,
151 SymAddressKind addrKind
,
158 public void DefineSequencePoints (
159 ISymbolDocumentWriter document
,
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])
169 msw
.MarkSequencePoint (offsets
[n
], lines
[n
], columns
[n
]);
173 public void Initialize (IntPtr emitter
, string filename
, bool fFullBuild
)
175 msw
= new MonoSymbolWriter (filename
);
178 public void OpenMethod (SymbolToken method
)
180 currentToken
= method
.GetToken ();
183 public void OpenNamespace (string name
)
185 NamespaceInfo n
= new NamespaceInfo ();
188 namespaceStack
.Push (n
);
191 public int OpenScope (int startOffset
)
193 return msw
.OpenScope (startOffset
);
196 public void SetMethodSourceRange (
197 ISymbolDocumentWriter startDoc
,
200 ISymbolDocumentWriter endDoc
,
204 SourceMethodImpl sm
= new SourceMethodImpl (methodName
, currentToken
, GetCurrentNamespace (startDoc
));
205 msw
.OpenMethod (startDoc
as ISourceFile
, sm
, startLine
, startColumn
, endLine
, endColumn
);
209 public void SetScopeRange (int scopeID
, int startOffset
, int endOffset
)
213 public void SetSymAttribute (SymbolToken parent
, string name
, byte[] data
)
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
);
221 public void SetUnderlyingWriter (IntPtr underlyingWriter
)
225 public void SetUserEntryPoint (SymbolToken entryMethod
)
229 public void UsingNamespace (string fullName
)
231 if (namespaceStack
.Count
== 0) {
235 NamespaceInfo ni
= (NamespaceInfo
) namespaceStack
.Peek ();
236 if (ni
.NamespaceID
!= -1) {
237 NamespaceInfo old
= ni
;
239 OpenNamespace (old
.Name
);
240 ni
= (NamespaceInfo
) namespaceStack
.Peek ();
241 ni
.UsingClauses
= old
.UsingClauses
;
243 ni
.UsingClauses
.Add (fullName
);
246 int GetCurrentNamespace (ISymbolDocumentWriter doc
)
248 if (namespaceStack
.Count
== 0) {
252 NamespaceInfo ni
= (NamespaceInfo
) namespaceStack
.Peek ();
253 if (ni
.NamespaceID
== -1)
255 string[] usings
= (string[]) ni
.UsingClauses
.ToArray (typeof(string));
258 if (namespaceStack
.Count
> 1) {
259 namespaceStack
.Pop ();
260 parentId
= ((NamespaceInfo
) namespaceStack
.Peek ()).NamespaceID
;
261 namespaceStack
.Push (ni
);
264 ni
.NamespaceID
= msw
.DefineNamespace (ni
.Name
, ((ISourceFile
)doc
).Entry
, usings
, parentId
);
266 return ni
.NamespaceID
;
270 class SymbolDocumentWriterImpl
: ISymbolDocumentWriter
, ISourceFile
272 SourceFileEntry entry
;
274 public SymbolDocumentWriterImpl (SourceFileEntry e
)
279 public void SetCheckSum (Guid algorithmId
, byte[] checkSum
)
283 public void SetSource (byte[] source
)
287 public SourceFileEntry Entry
{
288 get { return entry; }
292 class SourceMethodImpl
: ISourceMethod
298 public SourceMethodImpl (string name
, int token
, int namespaceID
)
302 this.namespaceID
= namespaceID
;
309 public int NamespaceID
{
310 get { return namespaceID; }
314 get { return token; }
321 public int NamespaceID
;
322 public ArrayList UsingClauses
= new ArrayList ();