diff options
author | Vitek Karas <vitek.karas@microsoft.com> | 2020-07-24 01:01:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-24 01:01:43 +0300 |
commit | 5e37f44535e0753ff3e4dbdef4ef148ca8bb09e0 (patch) | |
tree | f462504d65aab086df9fda33ae0f1d9b4b85819a /Test/Mono.Cecil.Tests | |
parent | cd450b0f09615c0e1e9c6663bbf7ae00ad96a7bc (diff) |
Automatically update local variable debug info (#676)
* Automatically update local variable debug info
When manipulating the local variables collection on a method body, automatically update the debug info for all affected local variables.
When removing a local variable, also remove the debug info for that local variable from the scopes.
When removing or inserting update the indeces of local variable debug infos which are afected by the action. Note the local variable debug info either holds just a backpointer to the local variable in which case it doesn't store the index at all (and thus nothing to do), or it stores the index explicitly in which case it needs to be updated.
Added tests for both insert and remove cases.
* Add internal properties on `VariableOffset` to make it easier to manipulate it.
Reworked the `UpdateVariableIndeces` to only loop over variables once and also to handle removal of resolved variable debug infos.
* Simplify the code a little and add comments
* PR feedback
Diffstat (limited to 'Test/Mono.Cecil.Tests')
-rw-r--r-- | Test/Mono.Cecil.Tests/VariableTests.cs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/Test/Mono.Cecil.Tests/VariableTests.cs b/Test/Mono.Cecil.Tests/VariableTests.cs index 577e56f..5454b93 100644 --- a/Test/Mono.Cecil.Tests/VariableTests.cs +++ b/Test/Mono.Cecil.Tests/VariableTests.cs @@ -81,6 +81,45 @@ namespace Mono.Cecil.Tests { } [Test] + public void RemoveVariableWithDebugInfo () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ret); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + var z2 = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (y); + body.Variables.Add (z); + body.Variables.Add (z2); + + var scope = new ScopeDebugInformation (body.Instructions [0], body.Instructions [0]); + method.DebugInformation = new MethodDebugInformation (method) { + Scope = scope + }; + scope.Variables.Add (new VariableDebugInformation (x.index, nameof (x))); + scope.Variables.Add (new VariableDebugInformation (y.index, nameof (y))); + scope.Variables.Add (new VariableDebugInformation (z.index, nameof (z))); + scope.Variables.Add (new VariableDebugInformation (z2, nameof (z2))); + + body.Variables.Remove (y); + + Assert.AreEqual (3, scope.Variables.Count); + Assert.AreEqual (x.Index, scope.Variables [0].Index); + Assert.AreEqual (nameof (x), scope.Variables [0].Name); + Assert.AreEqual (z.Index, scope.Variables [1].Index); + Assert.AreEqual (nameof (z), scope.Variables [1].Name); + Assert.AreEqual (z2.Index, scope.Variables [2].Index); + Assert.AreEqual (nameof (z2), scope.Variables [2].Name); + } + + [Test] public void InsertVariableIndex () { var object_ref = new TypeReference ("System", "Object", null, null, false); @@ -104,5 +143,43 @@ namespace Mono.Cecil.Tests { Assert.AreEqual (1, y.Index); Assert.AreEqual (2, z.Index); } + + [Test] + public void InsertVariableWithDebugInfo () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ret); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + var z2 = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (z); + body.Variables.Add (z2); + + var scope = new ScopeDebugInformation (body.Instructions [0], body.Instructions [0]); + method.DebugInformation = new MethodDebugInformation (method) { + Scope = scope + }; + scope.Variables.Add (new VariableDebugInformation (x.index, nameof (x))); + scope.Variables.Add (new VariableDebugInformation (z.index, nameof (z))); + scope.Variables.Add (new VariableDebugInformation (z2, nameof (z2))); + + body.Variables.Insert (1, y); + + // Adding local variable doesn't add debug info for it (since there's no way to deduce the name of the variable) + Assert.AreEqual (3, scope.Variables.Count); + Assert.AreEqual (x.Index, scope.Variables [0].Index); + Assert.AreEqual (nameof (x), scope.Variables [0].Name); + Assert.AreEqual (z.Index, scope.Variables [1].Index); + Assert.AreEqual (nameof (z), scope.Variables [1].Name); + Assert.AreEqual (z2.Index, scope.Variables [2].Index); + Assert.AreEqual (nameof (z2), scope.Variables [2].Name); + } } } |