Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitek Karas <vitek.karas@microsoft.com>2020-07-24 01:01:43 +0300
committerGitHub <noreply@github.com>2020-07-24 01:01:43 +0300
commit5e37f44535e0753ff3e4dbdef4ef148ca8bb09e0 (patch)
treef462504d65aab086df9fda33ae0f1d9b4b85819a /Test/Mono.Cecil.Tests
parentcd450b0f09615c0e1e9c6663bbf7ae00ad96a7bc (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.cs77
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);
+ }
}
}