-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDebuggerVariable.cs
More file actions
162 lines (140 loc) · 5.54 KB
/
DebuggerVariable.cs
File metadata and controls
162 lines (140 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
namespace CustomDataTip
{
/// <summary>
/// Class representation of the EnvDTE variable for convenience.
/// </summary>
class DebuggerVariable
{
internal readonly SnapshotPoint Point;
internal readonly SnapshotSpan Span;
internal readonly String Name;
internal readonly String Type;
internal readonly String Value;
internal readonly EnvDTE.Expression Expression;
private static Regex _variableExtractor = new Regex("[a-zA-Z0-9_.]+");
private EnvDTE.Debugger debugger;
internal static DebuggerVariable FindUnderMousePointer(EnvDTE.Debugger debugger, MouseHoverEventArgs e)
{
Debug.Assert(debugger != null);
var point = e.TextPosition.GetPoint(e.TextPosition.AnchorBuffer, PositionAffinity.Predecessor);
if (!point.HasValue)
{
return null;
}
SnapshotSpan span;
var name = GetVariableNameAndSpan(point.Value, out span);
if (name == null)
{
return null;
}
var expression = debugger.GetExpression(name);
if (!expression.IsValidValue)
{
return null;
}
return new DebuggerVariable(debugger, point.Value, span, name, expression);
}
private static string GetVariableNameAndSpan(SnapshotPoint point, out SnapshotSpan span)
{
var line = point.GetContainingLine();
var hoveredIndex = point.Position - line.Start.Position;
var c = point.GetChar();
if (!Char.IsDigit(c) && !Char.IsLetter(c) && (c != '_'))
{
span = new SnapshotSpan();
return null;
}
// Find the name of the variable under the mouse pointer (ex: 'gesture.Pose.Name' when the mouse is hovering over the 'o' of pose)
var match = _variableExtractor.Matches(line.GetText()).OfType<Match>().SingleOrDefault(x => x.Index <= hoveredIndex && (x.Index + x.Length) >= hoveredIndex);
if ((match == null) || (match.Value.Length == 0))
{
span = new SnapshotSpan();
return null;
}
var name = match.Value;
// Find the first '.' after the hoveredIndex and cut it off
int relativeIndex = hoveredIndex - match.Index;
var lastIndex = name.IndexOf('.', relativeIndex);
if (lastIndex >= 0)
{
name = name.Substring(0, lastIndex);
}
else
{
lastIndex = name.Length;
}
var matchStartIndex = name.LastIndexOf('.', relativeIndex) + 1;
span = new SnapshotSpan(line.Start.Add(match.Index + matchStartIndex), lastIndex - matchStartIndex);
return name;
}
private DebuggerVariable(EnvDTE.Debugger debugger, SnapshotPoint point, SnapshotSpan span, string name, EnvDTE.Expression expression)
{
this.debugger = debugger;
this.Point = point;
this.Span = span;
this.Name = name;
this.Type = expression.Type;
this.Value = expression.Value;
this.Expression = expression;
}
internal string GetMemberString(string name)
{
var expression = debugger.GetExpression(this.Name + "." + name); // ex: "bitmap.ColorMode", "bitmap.Dimensions.Width", "bitmap.Buffers[0].Pitch"
if (!expression.IsValidValue)
{
return null;
}
else
{
if (expression.Type == "string")
{
return expression.Value.Substring(1, expression.Value.Length - 2); // Remove '"' string quotes at the beginning and the end
}
else
{
return expression.Value;
}
}
}
internal double? GetMemberDouble(string name)
{
var valueAsString = GetMemberString(name);
double value;
return Double.TryParse(valueAsString, out value) ? new double?(value) : null;
}
internal uint? GetMemberUInt32(string name)
{
var valueAsString = GetMemberString(name);
uint value;
return UInt32.TryParse(valueAsString, out value) ? new uint?(value) : null;
}
internal byte[] GetMemberIBuffer(string name)
{
// Serialize the IBuffer to string and copy from debuggee to debugger
var expressionText = "Convert.ToBase64String(System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(" + this.Name + "." + name + "));";
var expression = debugger.GetExpression(expressionText);
if (!expression.IsValidValue)
{
return null;
}
// Deserialize buffer
var bufferInBase64 = expression.Value.Substring(1, expression.Value.Length - 2); // Remove '"' string quotes at the beginning and the end
byte[] buffer;
try
{
buffer = Convert.FromBase64String(bufferInBase64);
}
catch (FormatException)
{
return null;
}
return buffer;
}
}
}