PageRenderTime 33ms CodeModel.GetById 10ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs

http://github.com/jbevain/cecil
C# | 469 lines | 366 code | 103 blank | 0 comment | 5 complexity | d75e4610ed0f6179ead8d26262210cc4 MD5 | raw file
  1using System.IO;
  2using System.Linq;
  3
  4using Mono.Cecil.Cil;
  5using Mono.Cecil.Pdb;
  6
  7using NUnit.Framework;
  8
  9namespace Mono.Cecil.Tests {
 10
 11	[TestFixture]
 12	public class PdbTests : BaseTestFixture {
 13
 14		[Test]
 15		public void Main ()
 16		{
 17			TestModule ("test.exe", module => {
 18				var type = module.GetType ("Program");
 19				var main = type.GetMethod ("Main");
 20
 21				AssertCode (@"
 22	.locals init (System.Int32 i, System.Int32 CS$1$0000, System.Boolean CS$4$0001)
 23	.line 6,6:2,3 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 24	IL_0000: nop
 25	.line 7,7:8,18 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 26	IL_0001: ldc.i4.0
 27	IL_0002: stloc.0
 28	.line hidden 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 29	IL_0003: br.s IL_0012
 30	.line 8,8:4,21 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 31	IL_0005: ldarg.0
 32	IL_0006: ldloc.0
 33	IL_0007: ldelem.ref
 34	IL_0008: call System.Void Program::Print(System.String)
 35	IL_000d: nop
 36	.line 7,7:36,39 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 37	IL_000e: ldloc.0
 38	IL_000f: ldc.i4.1
 39	IL_0010: add
 40	IL_0011: stloc.0
 41	.line 7,7:19,34 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 42	IL_0012: ldloc.0
 43	IL_0013: ldarg.0
 44	IL_0014: ldlen
 45	IL_0015: conv.i4
 46	IL_0016: clt
 47	IL_0018: stloc.2
 48	.line hidden 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 49	IL_0019: ldloc.2
 50	IL_001a: brtrue.s IL_0005
 51	.line 10,10:3,12 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 52	IL_001c: ldc.i4.0
 53	IL_001d: stloc.1
 54	IL_001e: br.s IL_0020
 55	.line 11,11:2,3 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs'
 56	IL_0020: ldloc.1
 57	IL_0021: ret
 58", main);
 59			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
 60		}
 61
 62		[Test]
 63		public void DebuggerHiddenVariable ()
 64		{
 65			TestModule ("test.exe", module => {
 66				var type = module.GetType ("Program");
 67				var method = type.GetMethod ("Main");
 68
 69				var scope = method.DebugInformation.Scope;
 70
 71				Assert.IsTrue (scope.HasVariables);
 72				var variables = scope.Variables;
 73
 74				Assert.AreEqual ("CS$1$0000", variables [0].Name);
 75				Assert.IsTrue (variables [0].IsDebuggerHidden);
 76				Assert.AreEqual ("CS$4$0001", variables [1].Name);
 77				Assert.IsTrue (variables [1].IsDebuggerHidden);
 78
 79				Assert.AreEqual (1, scope.Scopes.Count);
 80				scope = scope.Scopes [0];
 81				variables = scope.Variables;
 82
 83				Assert.AreEqual ("i", variables [0].Name);
 84				Assert.IsFalse (variables [0].IsDebuggerHidden);
 85			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
 86		}
 87
 88		[Test]
 89		public void Document ()
 90		{
 91			TestModule ("test.exe", module => {
 92				var type = module.GetType ("Program");
 93				var method = type.GetMethod ("Main");
 94
 95				var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null);
 96				var document = sequence_point.Document;
 97
 98				Assert.IsNotNull (document);
 99
100				Assert.AreEqual (@"c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs", document.Url);
101				Assert.AreEqual (DocumentType.Text, document.Type);
102				Assert.AreEqual (DocumentHashAlgorithm.MD5, document.HashAlgorithm);
103				Assert.AreEqual (new byte [] { 228, 176, 152, 54, 82, 238, 238, 68, 237, 156, 5, 142, 118, 160, 118, 245 }, document.Hash);
104				Assert.AreEqual (DocumentLanguage.CSharp, document.Language);
105				Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
106			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
107		}
108
109		[Test]
110		public void BasicDocument ()
111		{
112			TestModule ("VBConsApp.exe", module => {
113				var type = module.GetType ("VBConsApp.Program");
114				var method = type.GetMethod ("Main");
115
116				var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null);
117				var document = sequence_point.Document;
118
119				Assert.IsNotNull (document);
120
121				Assert.AreEqual (@"c:\tmp\VBConsApp\Program.vb", document.Url);
122				Assert.AreEqual (DocumentType.Text, document.Type);
123				Assert.AreEqual (DocumentHashAlgorithm.MD5, document.HashAlgorithm);
124				Assert.AreEqual (new byte [] { 184, 188, 100, 23, 27, 123, 187, 201, 175, 206, 110, 198, 242, 139, 154, 119 }, document.Hash);
125				Assert.AreEqual (DocumentLanguage.Basic, document.Language);
126				Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
127			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
128		}
129
130		[Test]
131		public void FSharpDocument ()
132		{
133			TestModule ("fsapp.exe", module => {
134				var type = module.GetType ("Program");
135				var method = type.GetMethod ("fact");
136
137				var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null);
138				var document = sequence_point.Document;
139
140				Assert.IsNotNull (document);
141
142				Assert.AreEqual (@"c:\tmp\fsapp\Program.fs", document.Url);
143				Assert.AreEqual (DocumentType.Text, document.Type);
144				Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm);
145				Assert.AreEqual (DocumentLanguage.FSharp, document.Language);
146				Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
147			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
148		}
149
150		[Test]
151		public void EmptyEnumerable ()
152		{
153			TestModule ("empty-iterator.dll", module => {
154			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
155		}
156
157		[Test]
158		public void EmptyRootNamespace ()
159		{
160			TestModule ("EmptyRootNamespace.dll", module => {
161			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
162		}
163
164		[Test]
165		public void VisualBasicNamespace ()
166		{
167			TestModule ("AVbTest.exe", module => {
168			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
169
170		}
171
172		[Test]
173		public void LocalVariables ()
174		{
175			TestModule ("ComplexPdb.dll", module => {
176				var type = module.GetType ("ComplexPdb.Program");
177				var method = type.GetMethod ("Bar");
178				var debug_info = method.DebugInformation;
179
180				Assert.IsNotNull (debug_info.Scope);
181				Assert.IsTrue (debug_info.Scope.HasScopes);
182				Assert.AreEqual (2, debug_info.Scope.Scopes.Count);
183
184				var scope = debug_info.Scope.Scopes [0];
185
186				Assert.IsNotNull (scope);
187				Assert.IsTrue (scope.HasVariables);
188				Assert.AreEqual (1, scope.Variables.Count);
189
190				var variable = scope.Variables [0];
191
192				Assert.AreEqual ("s", variable.Name);
193				Assert.IsFalse (variable.IsDebuggerHidden);
194				Assert.AreEqual (2, variable.Index);
195
196				scope = debug_info.Scope.Scopes [1];
197
198				Assert.IsNotNull (scope);
199				Assert.IsTrue (scope.HasVariables);
200				Assert.AreEqual (1, scope.Variables.Count);
201
202				variable = scope.Variables [0];
203
204				Assert.AreEqual ("s", variable.Name);
205				Assert.IsFalse (variable.IsDebuggerHidden);
206				Assert.AreEqual (3, variable.Index);
207
208				Assert.IsTrue (scope.HasScopes);
209				Assert.AreEqual (1, scope.Scopes.Count);
210
211				scope = scope.Scopes [0];
212
213				Assert.IsNotNull (scope);
214				Assert.IsTrue (scope.HasVariables);
215				Assert.AreEqual (1, scope.Variables.Count);
216
217				variable = scope.Variables [0];
218
219				Assert.AreEqual ("u", variable.Name);
220				Assert.IsFalse (variable.IsDebuggerHidden);
221				Assert.AreEqual (5, variable.Index);
222			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
223		}
224
225		[Test]
226		public void LocalConstants ()
227		{
228			TestModule ("ComplexPdb.dll", module => {
229				var type = module.GetType ("ComplexPdb.Program");
230				var method = type.GetMethod ("Bar");
231				var debug_info = method.DebugInformation;
232
233				Assert.IsNotNull (debug_info.Scope);
234				Assert.IsTrue (debug_info.Scope.HasScopes);
235				Assert.AreEqual (2, debug_info.Scope.Scopes.Count);
236
237				var scope = debug_info.Scope.Scopes [1];
238
239				Assert.IsNotNull (scope);
240				Assert.IsTrue (scope.HasConstants);
241				Assert.AreEqual (2, scope.Constants.Count);
242
243				var constant = scope.Constants [0];
244
245				Assert.AreEqual ("b", constant.Name);
246				Assert.AreEqual (12, constant.Value);
247				Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType);
248
249				constant = scope.Constants [1];
250				Assert.AreEqual ("c", constant.Name);
251				Assert.AreEqual ((decimal) 74, constant.Value);
252				Assert.AreEqual (MetadataType.ValueType, constant.ConstantType.MetadataType);
253
254				method = type.GetMethod ("Foo");
255				debug_info = method.DebugInformation;
256
257				Assert.IsNotNull (debug_info.Scope);
258				Assert.IsTrue (debug_info.Scope.HasConstants);
259				Assert.AreEqual (4, debug_info.Scope.Constants.Count);
260
261				constant = debug_info.Scope.Constants [0];
262				Assert.AreEqual ("s", constant.Name);
263				Assert.AreEqual ("const string", constant.Value);
264				Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType);
265
266				constant = debug_info.Scope.Constants [1];
267				Assert.AreEqual ("f", constant.Name);
268				Assert.AreEqual (1, constant.Value);
269				Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType);
270
271				constant = debug_info.Scope.Constants [2];
272				Assert.AreEqual ("o", constant.Name);
273				Assert.AreEqual (null, constant.Value);
274				Assert.AreEqual (MetadataType.Object, constant.ConstantType.MetadataType);
275
276				constant = debug_info.Scope.Constants [3];
277				Assert.AreEqual ("u", constant.Name);
278				Assert.AreEqual (null, constant.Value);
279				Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType);
280			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
281		}
282
283		[Test]
284		public void ImportScope ()
285		{
286			TestModule ("ComplexPdb.dll", module => {
287				var type = module.GetType ("ComplexPdb.Program");
288				var method = type.GetMethod ("Bar");
289				var debug_info = method.DebugInformation;
290
291				Assert.IsNotNull (debug_info.Scope);
292
293				var import = debug_info.Scope.Import;
294				Assert.IsNotNull (import);
295
296				Assert.IsTrue (import.HasTargets);
297				Assert.AreEqual (6, import.Targets.Count);
298				var target = import.Targets [0];
299
300				Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind);
301				Assert.AreEqual ("System", target.Namespace);
302
303				target = import.Targets [1];
304
305				Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind);
306				Assert.AreEqual ("System.Collections.Generic", target.Namespace);
307
308				target = import.Targets [2];
309
310				Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind);
311				Assert.AreEqual ("System.Threading.Tasks", target.Namespace);
312
313				target = import.Targets [3];
314
315				Assert.AreEqual (ImportTargetKind.ImportType, target.Kind);
316				Assert.AreEqual ("System.Console", target.Type.FullName);
317
318				target = import.Targets [4];
319
320				Assert.AreEqual (ImportTargetKind.DefineTypeAlias, target.Kind);
321				Assert.AreEqual ("Foo1", target.Alias);
322				Assert.AreEqual ("System.Console", target.Type.FullName);
323
324				target = import.Targets [5];
325
326				Assert.AreEqual (ImportTargetKind.DefineNamespaceAlias, target.Kind);
327				Assert.AreEqual ("Foo2", target.Alias);
328				Assert.AreEqual ("System.Reflection", target.Namespace);
329			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
330		}
331
332		[Test]
333		public void StateMachineKickOff ()
334		{
335			TestModule ("ComplexPdb.dll", module => {
336				var state_machine = module.GetType ("ComplexPdb.Program/<TestAsync>d__2");
337				var move_next = state_machine.GetMethod ("MoveNext");
338				var symbol = move_next.DebugInformation;
339
340				Assert.IsNotNull (symbol);
341				Assert.IsNotNull (symbol.StateMachineKickOffMethod);
342				Assert.AreEqual ("System.Threading.Tasks.Task ComplexPdb.Program::TestAsync()", symbol.StateMachineKickOffMethod.FullName);
343			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
344		}
345
346		[Test]
347		public void Iterators ()
348		{
349			TestModule ("ComplexPdb.dll", module => {
350				var state_machine = module.GetType ("ComplexPdb.Program/<TestAsync>d__2");
351				var move_next = state_machine.GetMethod ("MoveNext");
352
353				Assert.IsTrue (move_next.DebugInformation.HasCustomDebugInformations);
354				Assert.AreEqual (2, move_next.DebugInformation.CustomDebugInformations.Count);
355
356				var state_machine_scope = move_next.DebugInformation.CustomDebugInformations [0] as StateMachineScopeDebugInformation;
357				Assert.IsNotNull (state_machine_scope);
358				Assert.AreEqual (1, state_machine_scope.Scopes.Count);
359				Assert.AreEqual (142, state_machine_scope.Scopes [0].Start.Offset);
360				Assert.AreEqual (319, state_machine_scope.Scopes [0].End.Offset);
361
362				var async_body = move_next.DebugInformation.CustomDebugInformations [1] as AsyncMethodBodyDebugInformation;
363				Assert.IsNotNull (async_body);
364				Assert.AreEqual (-1, async_body.CatchHandler.Offset);
365
366				Assert.AreEqual (2, async_body.Yields.Count);
367				Assert.AreEqual (68, async_body.Yields [0].Offset);
368				Assert.AreEqual (197, async_body.Yields [1].Offset);
369
370				Assert.AreEqual (2, async_body.Resumes.Count);
371				Assert.AreEqual (98, async_body.Resumes [0].Offset);
372				Assert.AreEqual (227, async_body.Resumes [1].Offset);
373
374				Assert.AreEqual (move_next, async_body.ResumeMethods [0]);
375				Assert.AreEqual (move_next, async_body.ResumeMethods [1]);
376			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
377		}
378
379		[Test]
380		public void ImportsForFirstMethod ()
381		{
382			TestModule ("CecilTest.exe", module => {
383				var type = module.GetType ("CecilTest.Program");
384				var method = type.GetMethod ("Main");
385
386				var debug = method.DebugInformation;
387				var scope = debug.Scope;
388
389				Assert.IsTrue (scope.End.IsEndOfMethod);
390
391				var import = scope.Import;
392
393				Assert.IsNotNull (import);
394				Assert.AreEqual (5, import.Targets.Count);
395
396				var ns = new [] {
397					"System",
398					"System.Collections.Generic",
399					"System.Linq",
400					"System.Text",
401					"System.Threading.Tasks",
402				};
403
404				for (int i = 0; i < import.Targets.Count; i++) {
405					var target = import.Targets [i];
406
407					Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind);
408					Assert.AreEqual (ns [i], target.Namespace);
409				}
410
411				Assert.AreEqual ("System", import.Targets [0].Namespace);
412			}, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
413		}
414
415		[Test]
416		public void CreateMethodFromScratch ()
417		{
418			if (!Platform.HasNativePdbSupport)
419				Assert.Ignore ();
420
421			var module = ModuleDefinition.CreateModule ("Pan", ModuleKind.Dll);
422			var type = new TypeDefinition ("Pin", "Pon", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference (typeof (object)));
423			module.Types.Add (type);
424
425			var method = new MethodDefinition ("Pang", MethodAttributes.Public | MethodAttributes.Static, module.ImportReference (typeof (string)));
426			type.Methods.Add (method);
427
428			var body = method.Body;
429
430			body.InitLocals = true;
431
432			var il = body.GetILProcessor ();
433			var temp = new VariableDefinition (module.ImportReference (typeof (string)));
434			body.Variables.Add (temp);
435
436			il.Emit (OpCodes.Nop);
437			il.Emit (OpCodes.Ldstr, "hello");
438			il.Emit (OpCodes.Stloc, temp);
439			il.Emit (OpCodes.Ldloc, temp);
440			il.Emit (OpCodes.Ret);
441
442			var sequence_point = new SequencePoint (body.Instructions [0], new Document (@"C:\test.cs")) {
443				StartLine = 0,
444				StartColumn = 0,
445				EndLine = 0,
446				EndColumn = 4,
447			};
448
449			method.DebugInformation.SequencePoints.Add (sequence_point);
450
451			method.DebugInformation.Scope = new ScopeDebugInformation  (body.Instructions [0], null) {
452				Variables = { new VariableDebugInformation (temp, "temp") }
453			};
454
455			var file = Path.Combine (Path.GetTempPath (), "Pan.dll");
456			module.Write (file, new WriterParameters {
457				SymbolWriterProvider = new PdbWriterProvider (),
458			});
459
460			module = ModuleDefinition.ReadModule (file, new ReaderParameters {
461				SymbolReaderProvider = new PdbReaderProvider (),
462			});
463
464			method = module.GetType ("Pin.Pon").GetMethod ("Pang");
465
466			Assert.AreEqual ("temp", method.DebugInformation.Scope.Variables [0].Name);
467		}
468	}
469}