diff options
author | Jeffrey Stedfast <jestedfa@microsoft.com> | 2020-01-07 20:01:37 +0300 |
---|---|---|
committer | monojenkins <jo.shields+jenkins@xamarin.com> | 2020-01-09 22:05:02 +0300 |
commit | 8bb072ba83d16b16d46347e43ea2116547be97fa (patch) | |
tree | 3e233738a503588cab887146a409e3850a04485f /main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs | |
parent | 8858df29367828411b622b14af3e4852385da9b6 (diff) |
[VsCodeDebugger] code refactoring & performance improvements
Cache IsEnum checks and do more validation that a variable/expression
evaluation result is an enum before making an expensive debugger query
to find out if the type is indeed an enum type.
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1032065/
Diffstat (limited to 'main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs')
-rw-r--r-- | main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs new file mode 100644 index 0000000000..54af40f0dc --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeEvaluationSource.cs @@ -0,0 +1,118 @@ +using System; +using System.Globalization; + +using Mono.Debugging.Client; +using Mono.Debugging.Evaluation; + +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; + +namespace MonoDevelop.Debugger.VsCodeDebugProtocol +{ + class VSCodeEvaluationSource : VSCodeObjectSource + { + readonly EvaluateResponse response; + readonly string expression; + readonly string display; + readonly string value; + readonly string name; + readonly string type; + + public VSCodeEvaluationSource (VSCodeDebuggerSession session, string expression, EvaluateResponse response, int frameId) : base (session, 0, frameId) + { + this.expression = expression; + this.response = response; + + // FIXME: can we use PresentationHint.Attributes == VariablePresentationHint.AttributesValue.FailedEvaluation instead? + if (response.Type == null) { + if (IsCSError (118, "is a namespace but is used like a variable", response.Result, out string ns)) { + Flags = ObjectValueFlags.Namespace; + display = name = value = ns; + type = "<namespace>"; + return; + } + + if (IsCSError (119, "is a type, which is not valid in the given context", response.Result, out string vtype)) { + if (expression.StartsWith ("global::", StringComparison.Ordinal)) + vtype = expression.Substring ("global::".Length); + + display = name = value = ObjectValueAdaptor.GetCSharpTypeName (vtype); + Flags = ObjectValueFlags.Type; + type = "<type>"; + return; + } + } + + var actualType = GetActualTypeName (response.Type); + + // FIXME: can we use VariablePresentationHint.AttributesValue.ReadOnly/Constant/Static etc for Flags? + Flags = ObjectValueFlags.ReadOnly; + type = actualType.Replace (", ", ","); + name = expression; + + if (actualType != "void") + value = GetFixedValue (response.Result, type, actualType); + else + value = "No return value."; + display = response.Result; + + if (name[0] == '[') + Flags |= ObjectValueFlags.ArrayElement; + + if (type == null || value == $"'{name}' threw an exception of type '{type}'") + Flags |= ObjectValueFlags.Error; + } + + protected override string Display { + get { return display; } + } + + protected override string Expression { + get { return expression; } + } + + protected override string Name { + get { return name; } + } + + protected override string Type { + get { return type; } + } + + protected override string Value { + get { return value; } + } + + protected override int VariablesReference { + get { return response.VariablesReference; } + } + + static bool IsCSError (int code, string message, string value, out string newValue) + { + var prefix = string.Format (CultureInfo.InvariantCulture, "error CS{0:D4}: '", code); + + newValue = null; + + if (value == null || !value.StartsWith (prefix, StringComparison.Ordinal)) + return false; + + int startIndex = prefix.Length; + int index = startIndex; + + while (index < value.Length && value [index] != '\'') + index++; + + newValue = value.Substring (startIndex, index - startIndex); + index++; + + if (index >= value.Length || value [index] != ' ') + return false; + + index++; + + if (index + message.Length != value.Length) + return false; + + return string.CompareOrdinal (value, index, message, 0, message.Length) == 0; + } + } +} |