PageRenderTime 18ms CodeModel.GetById 2ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/symbols/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs

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