提交 2fc666c3 编写于 作者: K Kevin Halverson

Refactor ResultProvider (incorporating Concord API changes)...

1.  DkmClrValue.InspectionContext has been removed, so a separate instance needs to be passed to all the methods that need it.
2.  DkmClrValue.EvaluateDebuggerDisplayString is now async.  In order to avoid complicated plumbing of completion routines through result expansion, I've moved the creation of DkmEvaluationResults from *Expansion to the ResultProvider.  Expansion now produces EvalResultDataItems that contain all the information necessary to produce DkmEvaluatoinResults in a single place, just before returning from the ResultProvider entry points.  New async plumbing/Exception handling is localized to the entry points.
3.  There are several places that the API now allows passing format specifiers.  We do not intend to support those scenarios in C#/VB, so we will ignore them.
上级 c29dc68a
......@@ -82,4 +82,4 @@
<Import Project="..\..\..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -88,20 +88,19 @@ class C
var bytesB = compilationB.EmitToArray();
var assemblyA = ReflectionUtilities.Load(bytesA);
var assemblyB = ReflectionUtilities.Load(bytesB);
DkmClrValue valueWithNonPublicHidden;
DkmClrValue value;
using (ReflectionUtilities.LoadAssemblies(assemblyA, assemblyB))
{
var runtime = new DkmClrRuntimeInstance(new[] { assemblyB });
var type = assemblyB.GetType("C", throwOnError: true);
valueWithNonPublicHidden = CreateDkmClrValue(
value = CreateDkmClrValue(
Activator.CreateInstance(type),
runtime.GetType((TypeImpl)type),
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
runtime.GetType((TypeImpl)type));
}
var rootExpr = "new C()";
var evalResult = FormatResult(rootExpr, valueWithNonPublicHidden);
var evalResult = FormatResult(rootExpr, value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
Verify(evalResult,
EvalResult(rootExpr, "{C}", "C", rootExpr, DkmEvaluationResultFlags.Expandable));
......@@ -250,20 +249,19 @@ class C
var bytesB = compilationB.EmitToArray();
var assemblyA = ReflectionUtilities.Load(bytesA);
var assemblyB = ReflectionUtilities.Load(bytesB);
DkmClrValue valueWithNonPublicHidden;
DkmClrValue value;
using (ReflectionUtilities.LoadAssemblies(assemblyA, assemblyB))
{
var runtime = new DkmClrRuntimeInstance(new[] { assemblyA });
var type = assemblyB.GetType("C", throwOnError: true);
valueWithNonPublicHidden = CreateDkmClrValue(
value = CreateDkmClrValue(
Activator.CreateInstance(type),
runtime.GetType((TypeImpl)type),
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
runtime.GetType((TypeImpl)type));
}
var rootExpr = "new C()";
var evalResult = FormatResult(rootExpr, valueWithNonPublicHidden);
var evalResult = FormatResult(rootExpr, value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
Verify(evalResult,
EvalResult(rootExpr, "{C}", "C", rootExpr, DkmEvaluationResultFlags.Expandable));
......@@ -360,9 +358,8 @@ public void NoModule()
var type = assembly.GetType("C");
var value = CreateDkmClrValue(
Activator.CreateInstance(type),
runtime.GetType((TypeImpl)type),
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
var evalResult = FormatResult("o", value);
runtime.GetType((TypeImpl)type));
var evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable));
}
......
......@@ -520,9 +520,8 @@ public C(params T[] items)
var value = CreateDkmClrValue(
value: type.Instantiate(1, 2, 3),
type: new DkmClrType(runtime.DefaultModule, runtime.DefaultAppDomain, (TypeImpl)type),
evalFlags: DkmEvaluationResultFlags.None,
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
var evalResult = FormatResult("o", value);
evalFlags: DkmEvaluationResultFlags.None);
var evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
Verify(evalResult,
EvalResult("o", "{C<int>}", "C<int>", "o", DkmEvaluationResultFlags.Expandable));
var children = GetChildren(evalResult);
......@@ -566,9 +565,8 @@ public class C
var value = CreateDkmClrValue(
value: type.Instantiate(),
type: new DkmClrType(runtime.DefaultModule, runtime.DefaultAppDomain, (TypeImpl)type),
evalFlags: DkmEvaluationResultFlags.None,
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
var evalResult = FormatResult("o", value);
evalFlags: DkmEvaluationResultFlags.None);
var evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers));
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable));
var children = GetChildren(evalResult);
......
......@@ -595,7 +595,8 @@ class B
bool f;
internal A P { get { return new A(); } }
internal A Q { get { while(f) { } return new A(); } }
}";
}
";
DkmClrRuntimeInstance runtime = null;
GetMemberValueDelegate getMemberValue = (v, m) => (m == "Q") ? CreateErrorValue(runtime.GetType("A"), "Function evaluation timed out") : null;
runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(GetAssembly(source)), getMemberValue: getMemberValue);
......@@ -612,6 +613,25 @@ class B
}
}
[Fact]
public void Exception()
{
var source =
@"using System.Diagnostics;
[DebuggerDisplay(""Value}"")]
class A
{
internal int Value;
}
";
var assembly = GetAssembly(source);
var typeA = assembly.GetType("A");
var instanceA = typeA.Instantiate();
var result = FormatResult("a", CreateDkmClrValue(instanceA));
Verify(result,
EvalFailedResult("a", "Unmatched closing brace in 'Value}'", null, null, DkmEvaluationResultFlags.None));
}
private IReadOnlyList<DkmEvaluationResult> DepthFirstSearch(DkmEvaluationResult root, int maxDepth)
{
var builder = ArrayBuilder<DkmEvaluationResult>.GetInstance();
......
......@@ -885,17 +885,15 @@ class D
// Non-null value.
var value = CreateDkmClrValue(Activator.CreateInstance(type),
type: type,
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
var evalResult = FormatResult("o", value);
type: type);
var evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.None));
// Null value.
value = CreateDkmClrValue(null,
type: type,
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
evalResult = FormatResult("o", value);
type: type);
evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
Verify(evalResult,
EvalResult("o", "null", "C", "o", DkmEvaluationResultFlags.None));
......@@ -940,9 +938,8 @@ public object PF
var assembly = GetAssembly(source);
var type = assembly.GetType("C");
var value = CreateDkmClrValue(Activator.CreateInstance(type),
type: type,
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
var evalResult = FormatResult("o", value);
type: type);
var evalResult = FormatResult("o", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.None));
......@@ -961,9 +958,8 @@ public object PF
[Fact]
public void NoExpansion_Array()
{
var value = CreateDkmClrValue(new[] { 1, 2, 3 },
inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
var evalResult = FormatResult("a", value);
var value = CreateDkmClrValue(new[] { 1, 2, 3 });
var evalResult = FormatResult("a", value, inspectionContext: CreateDkmInspectionContext(DkmEvaluationFlags.NoExpansion));
Verify(evalResult,
EvalResult("a", "{int[3]}", "int[]", "a", DkmEvaluationResultFlags.None));
}
......@@ -1677,8 +1673,8 @@ public void UnicodeChar()
EvalResult("c", "4660 '\u1234'", "char", "c", editableValue: "'\u1234'"));
// This char is not printable, so we expect the EditableValue to be the unicode escape representation.
value = CreateDkmClrValue('\u0007', typeof(char), inspectionContext: CreateDkmInspectionContext(radix: 16));
evalResult = FormatResult("c", value);
value = CreateDkmClrValue('\u0007', typeof(char));
evalResult = FormatResult("c", value, inspectionContext: CreateDkmInspectionContext(radix: 16));
Verify(evalResult,
EvalResult("c", "0x0007 '\u0007'", "char", "c", editableValue: "'\\u0007'"));
}
......
......@@ -27,9 +27,9 @@ public void SpecialTypes()
FormatResult("c", value, objectType),
EvalResult("c", "99 'c' {$2}", "object {char}", "c", DkmEvaluationResultFlags.HasObjectId, editableValue: "'c'"));
// char (hex)
value = CreateDkmClrValue(value: 'c', type: typeof(char), alias: "3", evalFlags: DkmEvaluationResultFlags.HasObjectId, inspectionContext: CreateDkmInspectionContext(radix: 16));
value = CreateDkmClrValue(value: 'c', type: typeof(char), alias: "3", evalFlags: DkmEvaluationResultFlags.HasObjectId);
Verify(
FormatResult("c", value, objectType),
FormatResult("c", value, objectType, inspectionContext: CreateDkmInspectionContext(radix: 16)),
EvalResult("c", "0x0063 'c' {$3}", "object {char}", "c", DkmEvaluationResultFlags.HasObjectId, editableValue: "'c'"));
// enum
value = CreateDkmClrValue(value: DkmEvaluationResultFlags.HasObjectId, type: typeof(DkmEvaluationResultFlags), alias: "Four", evalFlags: DkmEvaluationResultFlags.HasObjectId);
......
......@@ -29,7 +29,7 @@ internal AggregateExpansion(Expansion[] expansions)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
......@@ -39,7 +39,7 @@ private ArrayExpansion(ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lo
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -61,7 +61,7 @@ private ArrayExpansion(ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lo
index += _count;
}
private DkmEvaluationResult GetRow(
private EvalResultDataItem GetRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext,
DkmClrValue value,
......@@ -72,9 +72,9 @@ private ArrayExpansion(ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lo
var formatter = resultProvider.Formatter;
var name = formatter.GetArrayIndexExpression(indices);
var elementType = value.Type.ElementType;
var element = value.GetArrayElement(indices);
var element = value.GetArrayElement(indices, inspectionContext);
var fullName = GetFullName(parent, name, formatter);
var dataItem = resultProvider.CreateDataItem(
return resultProvider.CreateDataItem(
inspectionContext,
name,
typeDeclaringMember: null,
......@@ -88,7 +88,6 @@ private ArrayExpansion(ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lo
category: DkmEvaluationResultCategory.Other,
flags: element.EvalFlags,
evalFlags: inspectionContext.EvaluationFlags);
return resultProvider.GetResult(dataItem, element.Type, elementType, parent);
}
private int[] GetIndices(int index)
......
......@@ -52,7 +52,7 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
DkmClrValue proxyValue;
try
{
proxyValue = value.InstantiateProxyType(proxyType);
proxyValue = value.InstantiateProxyType(inspectionContext, proxyType);
}
catch
{
......@@ -62,6 +62,7 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
if (proxyValue != null)
{
return new DebuggerTypeProxyExpansion(
inspectionContext,
proxyValue,
name,
typeDeclaringMemberOpt,
......@@ -94,6 +95,7 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
private readonly string editableValue;
private DebuggerTypeProxyExpansion(
DkmInspectionContext inspectionContext,
DkmClrValue proxyValue,
string name,
Type typeDeclaringMemberOpt,
......@@ -110,6 +112,7 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
Debug.Assert(proxyValue != null);
var proxyType = proxyValue.Type.GetLmrType();
var proxyMembers = MemberExpansion.CreateExpansion(
inspectionContext,
proxyType,
proxyValue,
ExpansionFlags.IncludeBaseMembers,
......@@ -121,10 +124,13 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
null :
formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), childFullNamePrefix);
this.proxyItem = new EvalResultDataItem(
name: null,
ExpansionKind.Default,
name: string.Empty,
typeDeclaringMember: null,
declaredType: proxyType,
parent: null,
value: proxyValue,
displayValue: null,
expansion: proxyMembers,
childShouldParenthesize: false,
fullName: null,
......@@ -132,7 +138,8 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
formatSpecifiers: Formatter.NoFormatSpecifiers,
category: default(DkmEvaluationResultCategory),
flags: default(DkmEvaluationResultFlags),
editableValue: null);
editableValue: null,
inspectionContext: inspectionContext);
}
this.name = name;
......@@ -149,7 +156,7 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -171,29 +178,27 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
index++;
}
private DkmEvaluationResult CreateRawViewRow(
private EvalResultDataItem CreateRawViewRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext)
{
var dataItem = new EvalResultDataItem(
return new EvalResultDataItem(
ExpansionKind.RawView,
this.name,
this.typeDeclaringMemberOpt,
_declaredType,
this.value,
CreateRawView(resultProvider, inspectionContext, _declaredType, this.value),
this.childShouldParenthesize,
this.fullName,
this.childFullNamePrefix,
Formatter.AddFormatSpecifier(this.formatSpecifiers, "raw"),
DkmEvaluationResultCategory.Data,
this.flags | DkmEvaluationResultFlags.ReadOnly,
this.editableValue);
return ResultProvider.CreateEvaluationResult(
value,
Resources.RawView,
typeName: "",
display: null,
dataItem: dataItem);
parent: null,
value: this.value,
displayValue: null,
expansion: CreateRawView(resultProvider, inspectionContext, _declaredType, this.value),
childShouldParenthesize: this.childShouldParenthesize,
fullName: this.fullName,
childFullNamePrefixOpt: this.childFullNamePrefix,
formatSpecifiers: Formatter.AddFormatSpecifier(this.formatSpecifiers, "raw"),
category: DkmEvaluationResultCategory.Data,
flags: this.flags | DkmEvaluationResultFlags.ReadOnly,
editableValue: this.editableValue,
inspectionContext: inspectionContext);
}
private static Expansion CreateRawView(
......
......@@ -29,7 +29,7 @@ internal abstract class Expansion
/// </summary>
internal abstract void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......
......@@ -3,7 +3,6 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Microsoft.VisualStudio.Debugger.Metadata;
......@@ -21,6 +20,7 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator
internal sealed class MemberExpansion : Expansion
{
internal static Expansion CreateExpansion(
DkmInspectionContext inspectionContext,
Type declaredType,
DkmClrValue value,
ExpansionFlags flags,
......@@ -46,7 +46,7 @@ internal sealed class MemberExpansion : Expansion
// Expand members. (Ideally, this should be done lazily.)
var allMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance();
var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers;
var hideNonPublic = (value.InspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers;
var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers;
runtimeType.AppendTypeMembers(allMembers, predicate, declaredType, appDomain, includeInherited, hideNonPublic);
foreach (var member in allMembers)
......@@ -116,7 +116,7 @@ internal sealed class MemberExpansion : Expansion
// Include Results View if necessary.
if ((flags & ExpansionFlags.IncludeResultsView) != 0)
{
var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(value, formatter);
var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, formatter);
if (resultsViewExpansion != null)
{
expansions.Add(resultsViewExpansion);
......@@ -195,7 +195,7 @@ private MemberExpansion(MemberAndDeclarationInfo[] members)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -217,7 +217,7 @@ private MemberExpansion(MemberAndDeclarationInfo[] members)
index += _members.Length;
}
private static DkmEvaluationResult GetMemberRow(
private static EvalResultDataItem GetMemberRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext,
DkmClrValue value,
......@@ -225,18 +225,13 @@ private MemberExpansion(MemberAndDeclarationInfo[] members)
EvalResultDataItem parent)
{
var memberValue = GetMemberValue(value, member);
var dataItem = CreateMemberDataItem(
return CreateMemberDataItem(
resultProvider,
inspectionContext,
member,
memberValue,
parent,
ExpansionFlags.All);
return resultProvider.GetResult(
dataItem,
memberValue.Type,
DkmClrType.Create(memberValue.Type.AppDomain, member.Type),
parent);
}
private static DkmClrValue GetMemberValue(DkmClrValue container, MemberAndDeclarationInfo member)
......@@ -257,7 +252,7 @@ internal RootHiddenExpansion(MemberAndDeclarationInfo member)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -271,15 +266,7 @@ internal RootHiddenExpansion(MemberAndDeclarationInfo member)
{
if (InRange(startIndex, count, index))
{
var row = DkmFailedEvaluationResult.Create(
InspectionContext: value.InspectionContext,
StackFrame: value.StackFrame,
Name: Resources.ErrorName,
FullName: null,
ErrorMessage: (string)memberValue.HostObjectValue,
Flags: DkmEvaluationResultFlags.None,
Type: null,
DataItem: null);
var row = new EvalResultDataItem(Resources.ErrorName, errorMessage: (string)memberValue.HostObjectValue);
rows.Add(row);
}
index++;
......@@ -319,7 +306,7 @@ internal NonPublicMembersExpansion(Type declaredType, Expansion members)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -332,6 +319,7 @@ internal NonPublicMembersExpansion(Type declaredType, Expansion members)
{
rows.Add(GetRow(
resultProvider,
inspectionContext,
this.declaredType,
value,
this.members,
......@@ -343,18 +331,22 @@ internal NonPublicMembersExpansion(Type declaredType, Expansion members)
private static readonly ReadOnlyCollection<string> HiddenFormatSpecifiers = new ReadOnlyCollection<string>(new[] { "hidden" });
private static DkmEvaluationResult GetRow(
private static EvalResultDataItem GetRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext,
Type declaredType,
DkmClrValue value,
Expansion expansion,
EvalResultDataItem parent)
{
var dataItem = new EvalResultDataItem(
name: null,
return new EvalResultDataItem(
ExpansionKind.NonPublicMembers,
name: Resources.NonPublicMembers,
typeDeclaringMember: null,
declaredType: declaredType,
parent: null,
value: value,
displayValue: null,
expansion: expansion,
childShouldParenthesize: parent.ChildShouldParenthesize,
fullName: parent.FullNameWithoutFormatSpecifiers,
......@@ -362,13 +354,8 @@ internal NonPublicMembersExpansion(Type declaredType, Expansion members)
formatSpecifiers: HiddenFormatSpecifiers,
category: DkmEvaluationResultCategory.Data,
flags: DkmEvaluationResultFlags.ReadOnly,
editableValue: null);
return ResultProvider.CreateEvaluationResult(
value,
Resources.NonPublicMembers,
typeName: "",
display: null,
dataItem: dataItem);
editableValue: null,
inspectionContext: inspectionContext);
}
}
......@@ -388,7 +375,7 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -401,6 +388,7 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
{
rows.Add(GetRow(
resultProvider,
inspectionContext,
this.declaredType,
value,
this.members));
......@@ -409,19 +397,23 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
index++;
}
private static DkmEvaluationResult GetRow(
private static EvalResultDataItem GetRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext,
Type declaredType,
DkmClrValue value,
Expansion expansion)
{
var formatter = resultProvider.Formatter;
var fullName = formatter.GetTypeName(declaredType, escapeKeywordIdentifiers: true);
var dataItem = new EvalResultDataItem(
name: null,
return new EvalResultDataItem(
ExpansionKind.StaticMembers,
name: formatter.StaticMembersString,
typeDeclaringMember: null,
declaredType: declaredType,
parent: null,
value: value,
displayValue: null,
expansion: expansion,
childShouldParenthesize: false,
fullName: fullName,
......@@ -429,13 +421,8 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
formatSpecifiers: Formatter.NoFormatSpecifiers,
category: DkmEvaluationResultCategory.Class,
flags: DkmEvaluationResultFlags.ReadOnly,
editableValue: null);
return ResultProvider.CreateEvaluationResult(
value,
formatter.StaticMembersString,
typeName: "",
display: null,
dataItem: dataItem);
editableValue: null,
inspectionContext: inspectionContext);
}
}
......@@ -451,11 +438,6 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
string memberName;
var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType;
memberName = formatter.GetIdentifierEscapingPotentialKeywords(memberName);
// If the value is actually an exception that was thrown, we can't expect it to
// have any relation to the declared type of the value. Therefore, we will
// pretend that the exception type was the declared type for the purposes
// of creating the full name and expansion.
var declaredType = memberValue.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? memberValue.Type.GetLmrType() : member.Type;
var fullName = MakeFullName(
formatter,
memberName,
......@@ -467,7 +449,7 @@ internal StaticMembersExpansion(Type declaredType, Expansion members)
inspectionContext,
memberName,
typeDeclaringMember: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? typeDeclaringMember : null,
declaredType: declaredType,
declaredType: member.Type,
value: memberValue,
parent: parent,
expansionFlags: flags,
......
......@@ -20,7 +20,7 @@ public PointerDereferenceExpansion(Type elementType)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -37,37 +37,33 @@ public PointerDereferenceExpansion(Type elementType)
index++;
}
private static DkmEvaluationResult GetRow(
private static EvalResultDataItem GetRow(
ResultProvider resultProvider,
DkmInspectionContext inspectionContext,
DkmClrValue pointer,
Type elementType,
EvalResultDataItem parent)
{
var value = pointer.Dereference();
var valueType = value.Type.GetLmrType();
var value = pointer.Dereference(inspectionContext);
var wasExceptionThrown = value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown);
string debuggerDisplayName;
string debuggerDisplayValue;
string debuggerDisplayType;
value.GetDebuggerDisplayStrings(out debuggerDisplayName, out debuggerDisplayValue, out debuggerDisplayType);
var declaredType = elementType;
var typeName = debuggerDisplayType ?? pointer.InspectionContext.GetTypeName(DkmClrType.Create(pointer.Type.AppDomain, declaredType));
var expansion = wasExceptionThrown
? null
: resultProvider.GetTypeExpansion(inspectionContext, declaredType, value, ExpansionFlags.None);
var expansion = wasExceptionThrown ?
null :
resultProvider.GetTypeExpansion(inspectionContext, declaredType, value, ExpansionFlags.None);
var fullName = string.Format("*{0}", parent.ChildFullNamePrefix);
var editableValue = resultProvider.Formatter.GetEditableValue(value);
var editableValue = resultProvider.Formatter.GetEditableValue(value, inspectionContext);
// NB: Full name is based on the real (i.e. not DebuggerDisplay) name. This is a change from dev12,
// which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios.
var dataItem = new EvalResultDataItem(
name: null, // Okay for pointer dereferences.
return new EvalResultDataItem(
ExpansionKind.PointerDereference,
name: fullName,
typeDeclaringMember: null,
declaredType: declaredType,
parent: null,
value: value,
displayValue: wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName) : null,
expansion: expansion,
childShouldParenthesize: true,
fullName: fullName,
......@@ -75,18 +71,8 @@ public PointerDereferenceExpansion(Type elementType)
formatSpecifiers: Formatter.NoFormatSpecifiers,
category: DkmEvaluationResultCategory.Other,
flags: DkmEvaluationResultFlags.None,
editableValue: editableValue);
var name = debuggerDisplayName ?? fullName;
var display = debuggerDisplayValue ??
(wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName) : value.GetValueString());
return ResultProvider.CreateEvaluationResult(
value,
name,
typeName,
display,
dataItem);
editableValue: editableValue,
inspectionContext: inspectionContext);
}
}
}
......@@ -10,17 +10,18 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal sealed class ResultsViewExpansion : Expansion
{
internal static ResultsViewExpansion CreateExpansion(DkmClrValue value, Formatter formatter)
internal static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, Formatter formatter)
{
var enumerableType = GetEnumerableType(value);
if (enumerableType == null)
{
return null;
}
return CreateExpansion(value, enumerableType, formatter);
return CreateExpansion(inspectionContext, value, enumerableType, formatter);
}
internal static DkmEvaluationResult CreateResultsOnly(
internal static EvalResultDataItem CreateResultsOnlyRow(
DkmInspectionContext inspectionContext,
string name,
DkmClrType declaredType,
DkmClrValue value,
......@@ -41,10 +42,10 @@ internal static ResultsViewExpansion CreateExpansion(DkmClrValue value, Formatte
var enumerableType = GetEnumerableType(value);
if (enumerableType != null)
{
var expansion = CreateExpansion(value, enumerableType, formatter);
var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter);
if (expansion != null)
{
return expansion.CreateEvaluationResult(name, parent, formatter);
return expansion.CreateResultsViewRow(inspectionContext, name, parent, formatter);
}
errorMessage = Resources.ResultsViewNoSystemCore;
}
......@@ -55,15 +56,7 @@ internal static ResultsViewExpansion CreateExpansion(DkmClrValue value, Formatte
}
Debug.Assert(errorMessage != null);
return DkmFailedEvaluationResult.Create(
InspectionContext: value.InspectionContext,
StackFrame: value.StackFrame,
Name: name,
FullName: null,
ErrorMessage: errorMessage,
Flags: DkmEvaluationResultFlags.None,
Type: null,
DataItem: null);
return new EvalResultDataItem(name, errorMessage);
}
private static DkmClrType GetEnumerableType(DkmClrValue value)
......@@ -92,9 +85,9 @@ private static DkmClrType GetEnumerableType(DkmClrValue value)
return DkmClrType.Create(value.Type.AppDomain, enumerableType);
}
private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrType enumerableType, Formatter formatter)
private static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType enumerableType, Formatter formatter)
{
var proxyValue = value.InstantiateResultsViewProxy(enumerableType);
var proxyValue = value.InstantiateResultsViewProxy(inspectionContext, enumerableType);
// InstantiateResultsViewProxy may return null
// (if assembly is missing for instance).
if (proxyValue == null)
......@@ -103,6 +96,7 @@ private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrTyp
}
var proxyMembers = MemberExpansion.CreateExpansion(
inspectionContext,
proxyValue.Type.GetLmrType(),
proxyValue,
ExpansionFlags.None,
......@@ -125,7 +119,7 @@ private ResultsViewExpansion(DkmClrValue proxyValue, Expansion proxyMembers)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -136,14 +130,13 @@ private ResultsViewExpansion(DkmClrValue proxyValue, Expansion proxyMembers)
{
if (InRange(startIndex, count, index))
{
var evalResult = CreateEvaluationResult(Resources.ResultsView, parent, resultProvider.Formatter);
rows.Add(evalResult);
rows.Add(CreateResultsViewRow(inspectionContext, Resources.ResultsView, parent, resultProvider.Formatter));
}
index++;
}
private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataItem parent, Formatter formatter)
private EvalResultDataItem CreateResultsViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, Formatter formatter)
{
var proxyType = _proxyValue.Type.GetLmrType();
string fullName;
......@@ -165,11 +158,14 @@ private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataIt
var childFullNamePrefix = (fullName == null) ?
null :
formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), fullName);
var dataItem = new EvalResultDataItem(
name: name,
return new EvalResultDataItem(
ExpansionKind.ResultsView,
name,
typeDeclaringMember: null,
declaredType: proxyType,
parent: null,
value: _proxyValue,
displayValue: Resources.ResultsViewValueWarning,
expansion: _proxyMembers,
childShouldParenthesize: childShouldParenthesize,
fullName: fullName,
......@@ -177,13 +173,8 @@ private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataIt
formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "results"),
category: DkmEvaluationResultCategory.Method,
flags: DkmEvaluationResultFlags.ReadOnly,
editableValue: null);
return ResultProvider.CreateEvaluationResult(
value: _proxyValue,
name: name,
typeName: string.Empty,
display: Resources.ResultsViewValueWarning,
dataItem: dataItem);
editableValue: null,
inspectionContext: inspectionContext);
}
}
}
......@@ -30,7 +30,7 @@ internal TypeVariablesExpansion(Type declaredType)
internal override void GetRows(
ResultProvider resultProvider,
ArrayBuilder<DkmEvaluationResult> rows,
ArrayBuilder<EvalResultDataItem> rows,
DkmInspectionContext inspectionContext,
EvalResultDataItem parent,
DkmClrValue value,
......@@ -46,51 +46,34 @@ internal TypeVariablesExpansion(Type declaredType)
int offset = startIndex2 - index;
for (int i = 0; i < count2; i++)
{
rows.Add(GetRow(resultProvider, value, i + offset, parent));
rows.Add(GetRow(resultProvider, inspectionContext, value, i + offset, parent));
}
index += _typeArguments.Length;
}
private DkmEvaluationResult GetRow(ResultProvider resultProvider, DkmClrValue value, int index, EvalResultDataItem parent)
private EvalResultDataItem GetRow(ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue value, int index, EvalResultDataItem parent)
{
var inspectionContext = value.InspectionContext;
var appDomain = value.Type.AppDomain;
var typeParameter = _typeParameters[index];
var typeArgument = _typeArguments[index];
var type = DkmClrType.Create(appDomain, typeArgument);
var name = typeParameter.Name;
var dataItem = new EvalResultDataItem(
name,
var formatSpecifiers = Formatter.NoFormatSpecifiers;
return new EvalResultDataItem(
ExpansionKind.TypeVariables,
typeParameter.Name,
typeDeclaringMember: null,
declaredType: typeArgument,
value: null,
parent: parent,
value: value,
displayValue: inspectionContext.GetTypeName(DkmClrType.Create(value.Type.AppDomain, typeArgument), formatSpecifiers),
expansion: null,
childShouldParenthesize: false,
fullName: null,
childFullNamePrefixOpt: null,
formatSpecifiers: Formatter.NoFormatSpecifiers,
formatSpecifiers: formatSpecifiers,
category: DkmEvaluationResultCategory.Data,
flags: DkmEvaluationResultFlags.ReadOnly,
editableValue: null);
var typeName = inspectionContext.GetTypeName(DkmClrType.Create(appDomain, typeArgument));
return DkmSuccessEvaluationResult.Create(
inspectionContext,
value.StackFrame,
name,
dataItem.FullName,
dataItem.Flags,
Value: typeName,
EditableValue: null,
Type: typeName,
Category: dataItem.Category,
Access: value.Access,
StorageType: value.StorageType,
TypeModifierFlags: value.TypeModifierFlags,
Address: value.Address,
CustomUIVisualizers: null,
ExternalModules: null,
DataItem: dataItem);
editableValue: null,
inspectionContext: inspectionContext);
}
}
}
......@@ -22,14 +22,14 @@ internal enum GetValueFlags
// This class provides implementation for the "displaying values as strings" aspect of the default (C#) Formatter component.
internal abstract partial class Formatter
{
internal string GetValueString(DkmClrValue value, ObjectDisplayOptions options, GetValueFlags flags)
internal string GetValueString(DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options, GetValueFlags flags)
{
if (value.IsError())
{
return (string)value.HostObjectValue;
}
if (UsesHexadecimalNumbers(value))
if (UsesHexadecimalNumbers(inspectionContext))
{
options |= ObjectDisplayOptions.UseHexadecimalNumbers;
}
......@@ -96,24 +96,24 @@ internal string GetValueString(DkmClrValue value, ObjectDisplayOptions options,
// It should be impossible to nest nullables, so this recursion should introduce only a single extra stack frame.
return nullableValue == null
? _nullString
: GetValueString(nullableValue, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
: GetValueString(nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
}
// "value.EvaluateToString()" will check "Call string-conversion function on objects in variables windows"
// (Tools > Options setting) and call "value.ToString()" if appropriate.
return IncludeObjectId(
value,
string.Format(_defaultFormat, value.EvaluateToString() ?? value.InspectionContext.GetTypeName(value.Type)),
string.Format(_defaultFormat, value.EvaluateToString(inspectionContext) ?? inspectionContext.GetTypeName(value.Type, Formatter.NoFormatSpecifiers)),
flags);
}
/// <summary>
/// Gets the string representation of a character literal without including the numeric code point.
/// </summary>
internal string GetValueStringForCharacter(DkmClrValue value, ObjectDisplayOptions options)
internal string GetValueStringForCharacter(DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options)
{
Debug.Assert(value.Type.GetLmrType().IsCharacter());
if (UsesHexadecimalNumbers(value))
if (UsesHexadecimalNumbers(inspectionContext))
{
options |= ObjectDisplayOptions.UseHexadecimalNumbers;
}
......@@ -122,12 +122,12 @@ internal string GetValueStringForCharacter(DkmClrValue value, ObjectDisplayOptio
return charTemp;
}
internal bool HasUnderlyingString(DkmClrValue value)
internal bool HasUnderlyingString(DkmClrValue value, DkmInspectionContext inspectionContext)
{
return GetUnderlyingString(value) != null;
return GetUnderlyingString(value, inspectionContext) != null;
}
internal string GetUnderlyingString(DkmClrValue value)
internal string GetUnderlyingString(DkmClrValue value, DkmInspectionContext inspectionContext)
{
RawStringDataItem dataItem = value.GetDataItem<RawStringDataItem>();
if (dataItem != null)
......@@ -135,13 +135,13 @@ internal string GetUnderlyingString(DkmClrValue value)
return dataItem.RawString;
}
string underlyingString = GetUnderlyingStringImpl(value);
string underlyingString = GetUnderlyingStringImpl(value, inspectionContext);
dataItem = new RawStringDataItem(underlyingString);
value.SetDataItem(DkmDataCreationDisposition.CreateNew, dataItem);
return underlyingString;
}
private string GetUnderlyingStringImpl(DkmClrValue value)
private string GetUnderlyingStringImpl(DkmClrValue value, DkmInspectionContext inspectionContext)
{
if (value.IsNull)
{
......@@ -157,7 +157,7 @@ private string GetUnderlyingStringImpl(DkmClrValue value)
if (lmrType.IsNullable())
{
var nullableValue = value.GetNullableValue();
return nullableValue != null ? GetUnderlyingStringImpl(nullableValue) : null;
return nullableValue != null ? GetUnderlyingStringImpl(nullableValue, inspectionContext) : null;
}
if (lmrType.IsString())
......@@ -177,7 +177,7 @@ private string GetUnderlyingStringImpl(DkmClrValue value)
{
if (string.Equals(lmrType.FullName, "System.Xml.Linq.XNode", StringComparison.Ordinal))
{
return value.EvaluateToString();
return value.EvaluateToString(inspectionContext);
}
lmrType = lmrType.BaseType;
......@@ -283,11 +283,11 @@ private static bool IsFlagsEnum(Type lmrType)
return false;
}
private static bool UsesHexadecimalNumbers(DkmClrValue value)
private static bool UsesHexadecimalNumbers(DkmInspectionContext inspectionContext)
{
Debug.Assert(value.InspectionContext != null);
Debug.Assert(inspectionContext != null);
return value.InspectionContext.Radix == 16;
return inspectionContext.Radix == 16;
}
/// <summary>
......@@ -323,7 +323,7 @@ protected static ulong ConvertEnumUnderlyingTypeToUInt64(object value, TypeCode
}
}
internal string GetEditableValue(DkmClrValue value)
internal string GetEditableValue(DkmClrValue value, DkmInspectionContext inspectionContext)
{
if (value.IsError())
{
......@@ -339,11 +339,11 @@ internal string GetEditableValue(DkmClrValue value)
if (type.IsEnum)
{
return this.GetValueString(value, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
return this.GetValueString(value, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
}
else if (type.IsDecimal())
{
return this.GetValueString(value, ObjectDisplayOptions.IncludeTypeSuffix, GetValueFlags.None);
return this.GetValueString(value, inspectionContext, ObjectDisplayOptions.IncludeTypeSuffix, GetValueFlags.None);
}
// The legacy EE didn't special-case strings or chars (when ",nq" was used,
// you had to manually add quotes when editing) but it makes sense to
......@@ -352,12 +352,12 @@ internal string GetEditableValue(DkmClrValue value)
{
if (!value.IsNull)
{
return this.GetValueString(value, ObjectDisplayOptions.UseQuotes, GetValueFlags.None);
return this.GetValueString(value, inspectionContext, ObjectDisplayOptions.UseQuotes, GetValueFlags.None);
}
}
else if (type.IsCharacter())
{
return this.GetValueStringForCharacter(value, ObjectDisplayOptions.UseQuotes);
return this.GetValueStringForCharacter(value, inspectionContext, ObjectDisplayOptions.UseQuotes);
}
return null;
......
......@@ -28,30 +28,27 @@ internal Formatter(string defaultFormat, string nullString, string staticMembers
this.StaticMembersString = staticMembersString;
}
string IDkmClrFormatter.GetValueString(DkmClrValue clrValue)
string IDkmClrFormatter.GetValueString(DkmClrValue value, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers)
{
// TODO: IDkmClrFormatter.GetValueString should have
// an explicit InspectionContext parameter that is not
// inherited from the containing DkmClrValue. #1099978
var options = ((clrValue.InspectionContext.EvaluationFlags & DkmEvaluationFlags.NoQuotes) == 0) ?
var options = ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoQuotes) == 0) ?
ObjectDisplayOptions.UseQuotes :
ObjectDisplayOptions.None;
return GetValueString(clrValue, options, GetValueFlags.IncludeObjectId);
return GetValueString(value, inspectionContext, options, GetValueFlags.IncludeObjectId);
}
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType)
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, ReadOnlyCollection<string> formatSpecifiers)
{
return GetTypeName(clrType.GetLmrType());
return GetTypeName(type.GetLmrType());
}
bool IDkmClrFormatter.HasUnderlyingString(DkmClrValue clrValue)
bool IDkmClrFormatter.HasUnderlyingString(DkmClrValue value, DkmInspectionContext inspectionContext)
{
return HasUnderlyingString(clrValue);
return HasUnderlyingString(value, inspectionContext);
}
string IDkmClrFormatter.GetUnderlyingString(DkmClrValue clrValue)
string IDkmClrFormatter.GetUnderlyingString(DkmClrValue value, DkmInspectionContext inspectionContext)
{
return GetUnderlyingString(clrValue);
return GetUnderlyingString(value, inspectionContext);
}
// CONSIDER: If the number or complexity of the "language-specific syntax helpers" grows (or if
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal struct DebuggerDisplayInfo
{
public readonly DkmClrType TargetType;
public readonly DkmClrDebuggerDisplayAttribute Attribute;
public DebuggerDisplayInfo(DkmClrType targetType, DkmClrDebuggerDisplayAttribute attribute)
{
TargetType = targetType;
Attribute = attribute;
}
}
}
......@@ -9,6 +9,18 @@
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal enum ExpansionKind
{
Default,
Error,
NonPublicMembers,
PointerDereference,
RawView,
ResultsView,
StaticMembers,
TypeVariables
}
/// <summary>
/// A pair of DkmClrValue and Expansion, used to store
/// state on a DkmEvaluationResult. Also computes the
......@@ -21,13 +33,13 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator
/// </remarks>
internal sealed class EvalResultDataItem : DkmDataItem
{
/// <summary>
/// May be null for synthesized nodes like "Results View", etc.
/// </summary>
public readonly string NameOpt;
public readonly ExpansionKind Kind;
public readonly string Name;
public readonly Type TypeDeclaringMember;
public readonly Type DeclaredType;
public readonly EvalResultDataItem Parent;
public readonly DkmClrValue Value;
public readonly string DisplayValue; // overrides the "Value" text displayed for certain kinds of DataItems (errors, invalid pointer dereferences, etc)...not to be confused with DebuggerDisplayAttribute Value...
public readonly Expansion Expansion;
public readonly bool ChildShouldParenthesize;
public readonly string FullNameWithoutFormatSpecifiers;
......@@ -53,11 +65,35 @@ public string FullName
}
}
public EvalResultDataItem(string name, string errorMessage)
: this(
ExpansionKind.Error,
inspectionContext: null,
name: name,
typeDeclaringMember: null,
declaredType: null,
parent: null,
value: null,
displayValue: errorMessage,
expansion: null,
childShouldParenthesize: false,
fullName: null,
childFullNamePrefixOpt: null,
formatSpecifiers: Formatter.NoFormatSpecifiers,
category: DkmEvaluationResultCategory.Other,
flags: DkmEvaluationResultFlags.None,
editableValue: null)
{
}
public EvalResultDataItem(
ExpansionKind kind,
string name,
Type typeDeclaringMember,
Type declaredType,
EvalResultDataItem parent,
DkmClrValue value,
string displayValue,
Expansion expansion,
bool childShouldParenthesize,
string fullName,
......@@ -65,26 +101,31 @@ public string FullName
ReadOnlyCollection<string> formatSpecifiers,
DkmEvaluationResultCategory category,
DkmEvaluationResultFlags flags,
string editableValue)
string editableValue,
DkmInspectionContext inspectionContext)
{
Debug.Assert(name != null);
Debug.Assert(formatSpecifiers != null);
Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0);
this.NameOpt = name;
this.Kind = kind;
this.Name = name;
this.TypeDeclaringMember = typeDeclaringMember;
this.DeclaredType = declaredType;
this.Parent = parent;
this.Value = value;
this.DisplayValue = displayValue;
this.ChildShouldParenthesize = childShouldParenthesize;
this.FullNameWithoutFormatSpecifiers = fullName;
this.ChildFullNamePrefix = childFullNamePrefixOpt;
this.FormatSpecifiers = formatSpecifiers;
this.Category = category;
this.EditableValue = editableValue;
this.Flags = flags | GetFlags(value) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable);
this.Flags = flags | GetFlags(value, inspectionContext) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable);
this.Expansion = expansion;
}
private static DkmEvaluationResultFlags GetFlags(DkmClrValue value)
private static DkmEvaluationResultFlags GetFlags(DkmClrValue value, DkmInspectionContext inspectionContext)
{
if (value == null)
{
......@@ -103,7 +144,7 @@ private static DkmEvaluationResultFlags GetFlags(DkmClrValue value)
}
}
if (!value.IsError() && value.HasUnderlyingString())
if (!value.IsError() && value.HasUnderlyingString(inspectionContext))
{
resultFlags |= DkmEvaluationResultFlags.RawString;
}
......
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
......@@ -368,16 +369,15 @@ internal static bool TryGetEvalAttribute<T>(this DkmClrType type, out DkmClrType
/// <summary>
/// Extracts information from the first <see cref="DebuggerDisplayAttribute"/> on the runtime type of <paramref name="value"/>, if there is one.
/// </summary>
internal static void GetDebuggerDisplayStrings(this DkmClrValue value, out string nameString, out string valueString, out string typeString)
internal static bool TryGetDebuggerDisplayInfo(this DkmClrValue value, out DebuggerDisplayInfo displayInfo)
{
displayInfo = default(DebuggerDisplayInfo);
// The native EE does not consider DebuggerDisplayAttribute
// on null or error instances.
if (value.IsError() || value.IsNull)
{
nameString = null;
valueString = null;
typeString = null;
return;
return false;
}
var clrType = value.Type;
......@@ -386,16 +386,11 @@ internal static void GetDebuggerDisplayStrings(this DkmClrValue value, out strin
DkmClrDebuggerDisplayAttribute attribute;
if (clrType.TryGetEvalAttribute(out attributeTarget, out attribute)) // First, as in dev12.
{
nameString = EvaluateDebuggerDisplayString(value, attribute.Name);
valueString = EvaluateDebuggerDisplayString(value, attribute.Value);
typeString = EvaluateDebuggerDisplayString(value, attribute.TypeName);
}
else
{
nameString = null;
valueString = null;
typeString = null;
displayInfo = new DebuggerDisplayInfo(attributeTarget, attribute);
return true;
}
return false;
}
/// <summary>
......@@ -439,9 +434,16 @@ internal static DkmCustomUIVisualizerInfo[] GetDebuggerCustomUIVisualizerInfo(th
return result;
}
private static string EvaluateDebuggerDisplayString(DkmClrValue value, string str)
internal static void EvaluateDebuggerDisplayStringAndContinue(this DkmClrValue value, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string str, DkmCompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine)
{
return str == null ? null : value.EvaluateDebuggerDisplayString(str);
if (str == null)
{
completionRoutine(default(DkmEvaluateDebuggerDisplayStringAsyncResult));
}
else
{
value.EvaluateDebuggerDisplayString(workList, inspectionContext, targetType, str, completionRoutine);
}
}
internal static DkmClrType GetProxyType(this DkmClrType type)
......
......@@ -92,6 +92,7 @@
<Compile Include="Formatter.Values.cs" />
<Compile Include="Formatter.cs" />
<Compile Include="Helpers\ArrayBuilder.cs" />
<Compile Include="Helpers\DebuggerDisplayInfo.cs" />
<Compile Include="Helpers\DkmClrValueFlagsExtensions.cs" />
<Compile Include="Helpers\DkmEvaluationResultFlagsExtensions.cs" />
<Compile Include="Helpers\EnumContextDataItem.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
......@@ -29,8 +30,7 @@ public class DkmClrValue : DkmDataContainer
string alias,
IDkmClrFormatter formatter,
DkmEvaluationResultFlags evalFlags,
DkmClrValueFlags valueFlags,
DkmInspectionContext inspectionContext)
DkmClrValueFlags valueFlags)
{
Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic));
Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId));
......@@ -44,14 +44,12 @@ public class DkmClrValue : DkmDataContainer
this.Alias = alias;
this.EvalFlags = evalFlags;
this.ValueFlags = valueFlags;
this.InspectionContext = inspectionContext ?? new DkmInspectionContext(formatter, DkmEvaluationFlags.None, 10);
}
public readonly DkmEvaluationResultFlags EvalFlags;
public readonly DkmClrValueFlags ValueFlags;
public readonly DkmClrType Type;
public DkmClrType DeclaredType { get { throw new NotImplementedException(); } }
public readonly DkmInspectionContext InspectionContext;
public readonly DkmStackWalkFrame StackFrame;
public readonly DkmEvaluationResultCategory Category;
public readonly DkmEvaluationResultAccessType Access;
......@@ -64,21 +62,13 @@ public class DkmClrValue : DkmDataContainer
private readonly IDkmClrFormatter _formatter;
private readonly object _rawValue;
internal DkmClrValue WithInspectionContext(DkmInspectionContext inspectionContext)
public DkmClrValue Dereference(DkmInspectionContext inspectionContext)
{
return new DkmClrValue(
_rawValue,
this.HostObjectValue,
this.Type,
this.Alias,
_formatter,
this.EvalFlags,
this.ValueFlags,
inspectionContext);
}
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
public DkmClrValue Dereference()
{
if (_rawValue == null)
{
throw new InvalidOperationException("Cannot dereference invalid value");
......@@ -105,8 +95,7 @@ public DkmClrValue Dereference()
alias: null,
formatter: _formatter,
evalFlags: evalFlags,
valueFlags: valueFlags,
inspectionContext: this.InspectionContext);
valueFlags: valueFlags);
}
public bool IsNull
......@@ -135,24 +124,44 @@ internal static object GetHostObjectValue(Type lmrType, object rawValue)
: null;
}
public string GetValueString()
public string GetValueString(DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers)
{
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
// The real version does some sort of dynamic dispatch that ultimately calls this method.
return _formatter.GetValueString(this);
return _formatter.GetValueString(this, inspectionContext, formatSpecifiers);
}
public bool HasUnderlyingString()
public bool HasUnderlyingString(DkmInspectionContext inspectionContext)
{
return _formatter.HasUnderlyingString(this);
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
return _formatter.HasUnderlyingString(this, inspectionContext);
}
public string GetUnderlyingString()
public string GetUnderlyingString(DkmInspectionContext inspectionContext)
{
return _formatter.GetUnderlyingString(this);
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
return _formatter.GetUnderlyingString(this, inspectionContext);
}
public string EvaluateToString()
public string EvaluateToString(DkmInspectionContext inspectionContext)
{
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
// This is a rough approximation of the real functionality. Basically,
// if object.ToString is not overridden, we return null and it is the
// caller's responsibility to compute a string.
......@@ -183,10 +192,15 @@ public string EvaluateToString()
/// <remarks>
/// Very simple expression evaluation (may not support all syntax supported by Concord).
/// </remarks>
public string EvaluateDebuggerDisplayString(string formatString)
public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string formatString, DkmCompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine)
{
Debug.Assert(!this.IsNull, "Not supported by VIL");
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
var pooled = PooledStringBuilder.GetInstance();
var builder = pooled.Builder;
......@@ -237,8 +251,7 @@ public string EvaluateDebuggerDisplayString(string formatString)
alias: null,
formatter: _formatter,
evalFlags: GetEvaluationResultFlags(fieldValue),
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
else
{
......@@ -253,8 +266,7 @@ public string EvaluateDebuggerDisplayString(string formatString)
alias: null,
formatter: _formatter,
evalFlags: GetEvaluationResultFlags(propertyValue),
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
else
{
......@@ -277,8 +289,7 @@ public string EvaluateDebuggerDisplayString(string formatString)
alias: null,
formatter: _formatter,
evalFlags: GetEvaluationResultFlags(methodValue),
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
else
{
......@@ -291,13 +302,12 @@ public string EvaluateDebuggerDisplayString(string formatString)
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.Error,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.Error);
}
}
}
builder.Append(exprValue.GetValueString()); // Re-enter the formatter.
builder.Append(exprValue.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers)); // Re-enter the formatter.
}
else if (openPos < 0)
{
......@@ -309,8 +319,8 @@ public string EvaluateDebuggerDisplayString(string formatString)
{
throw new ArgumentException(string.Format("Unmatched open brace in '{0}'", formatString));
}
return pooled.ToStringAndFree();
workList.AddWork(() => completionRoutine(new DkmEvaluateDebuggerDisplayStringAsyncResult(pooled.ToStringAndFree())));
}
public DkmClrValue GetMemberValue(string MemberName, int MemberType, string ParentTypeName)
......@@ -346,8 +356,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
else if (MemberName == InternalWellKnownMemberNames.NullableValue)
{
......@@ -362,8 +371,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
}
......@@ -401,8 +409,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null,
formatter: _formatter,
evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
break;
case MemberTypes.Property:
......@@ -426,8 +433,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null,
formatter: _formatter,
evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
break;
default:
......@@ -466,12 +472,16 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null,
formatter: _formatter,
evalFlags: evalFlags,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
public DkmClrValue GetArrayElement(int[] indices)
public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext)
{
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
var array = (System.Array)_rawValue;
var element = array.GetValue(indices);
var type = DkmClrType.Create(this.Type.AppDomain, (TypeImpl)((element == null) ? array.GetType().GetElementType() : element.GetType()));
......@@ -482,8 +492,7 @@ public DkmClrValue GetArrayElement(int[] indices)
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
public ReadOnlyCollection<int> ArrayDimensions
......@@ -526,8 +535,13 @@ public ReadOnlyCollection<int> ArrayLowerBounds
}
}
public DkmClrValue InstantiateProxyType(DkmClrType proxyType)
public DkmClrValue InstantiateProxyType(DkmInspectionContext inspectionContext, DkmClrType proxyType)
{
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
var lmrType = proxyType.GetLmrType();
Debug.Assert(!lmrType.IsGenericTypeDefinition);
const BindingFlags bindingFlags =
......@@ -544,12 +558,16 @@ public DkmClrValue InstantiateProxyType(DkmClrType proxyType)
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None,
inspectionContext: this.InspectionContext);
valueFlags: DkmClrValueFlags.None);
}
public DkmClrValue InstantiateResultsViewProxy(DkmClrType enumerableType)
public DkmClrValue InstantiateResultsViewProxy(DkmInspectionContext inspectionContext, DkmClrType enumerableType)
{
if (inspectionContext == null)
{
throw new ArgumentNullException("inspectionContext");
}
var appDomain = enumerableType.AppDomain;
var module = GetModule(appDomain, "System.Core.dll");
if (module == null)
......@@ -573,7 +591,7 @@ public DkmClrValue InstantiateResultsViewProxy(DkmClrType enumerableType)
return null;
}
return this.InstantiateProxyType(proxyType);
return this.InstantiateProxyType(inspectionContext, proxyType);
}
private static DkmClrModuleInstance GetModule(DkmClrAppDomain appDomain, string moduleName)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// D:\Roslyn\Main\Open\Binaries\Debug\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
namespace Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation
{
public struct DkmEvaluateDebuggerDisplayStringAsyncResult
{
private readonly string _result;
public DkmEvaluateDebuggerDisplayStringAsyncResult(string result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
_result = result;
}
public string Result { get { return _result; } }
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// D:\Roslyn\Main\Open\Binaries\Debug\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
using System.Diagnostics;
namespace Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation
{
public struct DkmEvaluationAsyncResult
{
private readonly DkmEvaluationResult _result;
public DkmEvaluationAsyncResult(DkmEvaluationResult Result)
{
if (Result == null)
{
throw new ArgumentNullException("Result");
}
_result = Result;
}
public int ErrorCode { get { throw new NotImplementedException(); } }
public DkmEvaluationResult Result { get { return _result; } }
public static DkmEvaluationAsyncResult CreateErrorResult(Exception exception)
{
throw new NotImplementedException();
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
......@@ -33,10 +35,10 @@ internal DkmInspectionContext(IDkmClrFormatter formatter, DkmEvaluationFlags eva
// '16' and '10'.
public readonly uint Radix;
public string GetTypeName(DkmClrType clrType)
public string GetTypeName(DkmClrType clrType, ReadOnlyCollection<string> formatSpecifiers)
{
// The real version does some sort of dynamic dispatch that ultimately calls this method.
return _formatter.GetTypeName(this, clrType);
return _formatter.GetTypeName(this, clrType, formatSpecifiers);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
namespace Microsoft.VisualStudio.Debugger
{
public delegate void DkmCompletionRoutine<TResult>(TResult result);
public class DkmWorkList { }
public static class DkmComponentManager
{
public static bool ReportCurrentNonFatalException(Exception currentException, string implementationName)
{
return true;
}
}
public enum DkmDataCreationDisposition
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// D:\Roslyn\Main\Open\Binaries\Debug\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.VisualStudio.Debugger
{
/// <summary>
/// This mock of DkmWorkList doesn't really reflect the details of the *real* implementation.
/// It simply serves as a useful mechanism for testing async calls (in a way that resembles
/// the Concord dispatcher).
/// </summary>
public sealed class DkmWorkList
{
private readonly Queue<Action> _workList;
/// <summary>
/// internal helper for testing only (not available on *real* DkmWorkList)...
/// </summary>
internal DkmWorkList()
{
_workList = new Queue<Action>(1);
}
/// <summary>
/// internal helper for testing only (not available on *real* DkmWorkList)...
/// </summary>
internal void AddWork(Action item)
{
_workList.Enqueue(item);
}
public void Execute()
{
while (_workList.Count > 0)
{
var item = _workList.Dequeue();
item.Invoke();
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
......@@ -11,9 +13,9 @@ namespace Microsoft.VisualStudio.Debugger.ComponentInterfaces
{
public interface IDkmClrFormatter
{
string GetValueString(DkmClrValue clrValue);
string GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType);
bool HasUnderlyingString(DkmClrValue clrValue);
string GetUnderlyingString(DkmClrValue clrValue);
string GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, ReadOnlyCollection<string> formatSpecifiers);
string GetUnderlyingString(DkmClrValue clrValue, DkmInspectionContext inspectionContext);
string GetValueString(DkmClrValue clrValue, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers);
bool HasUnderlyingString(DkmClrValue clrValue, DkmInspectionContext inspectionContext);
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
......@@ -11,7 +13,7 @@ namespace Microsoft.VisualStudio.Debugger.ComponentInterfaces
{
public interface IDkmClrResultProvider
{
DkmEvaluationResult GetResult(DkmClrValue clrValue, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName);
void GetResult(DkmClrValue clrValue, DkmWorkList workList, DkmClrType declaredType, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine);
void GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine);
void GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine);
string GetUnderlyingString(DkmEvaluationResult result);
......
......@@ -4,8 +4,8 @@
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
using Microsoft.VisualStudio.Debugger.Evaluation;
......@@ -33,8 +33,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
Type type = null,
string alias = null,
DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None,
DkmClrValueFlags valueFlags = DkmClrValueFlags.None,
DkmInspectionContext inspectionContext = null)
DkmClrValueFlags valueFlags = DkmClrValueFlags.None)
{
if (type == null)
{
......@@ -47,8 +46,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
alias,
_formatter,
evalFlags,
valueFlags,
inspectionContext);
valueFlags);
}
internal DkmClrValue CreateDkmClrValue(
......@@ -56,8 +54,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
DkmClrType type,
string alias = null,
DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None,
DkmClrValueFlags valueFlags = DkmClrValueFlags.None,
DkmInspectionContext inspectionContext = null)
DkmClrValueFlags valueFlags = DkmClrValueFlags.None)
{
return new DkmClrValue(
value,
......@@ -66,14 +63,12 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
alias,
_formatter,
evalFlags,
valueFlags,
inspectionContext);
valueFlags);
}
internal DkmClrValue CreateErrorValue(
DkmClrType type,
string message,
DkmInspectionContext inspectionContext = null)
string message)
{
return new DkmClrValue(
value: null,
......@@ -82,8 +77,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
alias: null,
formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.Error,
inspectionContext: inspectionContext);
valueFlags: DkmClrValueFlags.Error);
}
#region Formatter Tests
......@@ -100,11 +94,9 @@ internal string FormatValue(object value, bool useHexadecimal = false)
internal string FormatValue(object value, Type type, bool useHexadecimal = false)
{
var clrValue = CreateDkmClrValue(
value,
type,
inspectionContext: CreateDkmInspectionContext(_formatter, DkmEvaluationFlags.None, radix: useHexadecimal ? 16u : 10u));
return clrValue.GetValueString();
var clrValue = CreateDkmClrValue(value, type);
var inspectionContext = CreateDkmInspectionContext(_formatter, DkmEvaluationFlags.None, radix: useHexadecimal ? 16u : 10u);
return clrValue.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers);
}
internal bool HasUnderlyingString(object value)
......@@ -115,13 +107,13 @@ internal bool HasUnderlyingString(object value)
internal bool HasUnderlyingString(object value, Type type)
{
var clrValue = GetValueForUnderlyingString(value, type);
return clrValue.HasUnderlyingString();
return clrValue.HasUnderlyingString(DefaultInspectionContext);
}
internal string GetUnderlyingString(object value)
{
var clrValue = GetValueForUnderlyingString(value, value.GetType());
return clrValue.GetUnderlyingString();
return clrValue.GetUnderlyingString(DefaultInspectionContext);
}
internal DkmClrValue GetValueForUnderlyingString(object value, Type type)
......@@ -129,8 +121,7 @@ internal DkmClrValue GetValueForUnderlyingString(object value, Type type)
return CreateDkmClrValue(
value,
type,
evalFlags: DkmEvaluationResultFlags.RawString,
inspectionContext: CreateDkmInspectionContext(_formatter, DkmEvaluationFlags.None, radix: 10));
evalFlags: DkmEvaluationResultFlags.RawString);
}
#endregion
......@@ -147,30 +138,48 @@ internal static DkmInspectionContext CreateDkmInspectionContext(IDkmClrFormatter
return new DkmInspectionContext(formatter, flags, radix);
}
internal DkmEvaluationResult FormatResult(string name, DkmClrValue value, DkmClrType declaredType = null)
internal DkmEvaluationResult FormatResult(string name, DkmClrValue value, DkmClrType declaredType = null, DkmInspectionContext inspectionContext = null)
{
return FormatResult(name, name, value, declaredType);
return FormatResult(name, name, value, declaredType, inspectionContext);
}
internal DkmEvaluationResult FormatResult(string name, string fullName, DkmClrValue value, DkmClrType declaredType = null)
internal DkmEvaluationResult FormatResult(string name, string fullName, DkmClrValue value, DkmClrType declaredType = null, DkmInspectionContext inspectionContext = null)
{
// TODO: IDkmClrResultProvider.GetResult should have
// an explicit declaredType parameter. See #1099981
return ((ResultProvider)_resultProvider).GetResult(value, declaredType ?? value.Type, formatSpecifiers: null, resultName: name, resultFullName: fullName);
DkmEvaluationResult evaluationResult = null;
var workList = new DkmWorkList();
_resultProvider.GetResult(
value,
workList,
declaredType: declaredType ?? value.Type,
inspectionContext: inspectionContext ?? DefaultInspectionContext,
formatSpecifiers: Formatter.NoFormatSpecifiers,
resultName: name,
resultFullName: null,
completionRoutine: asyncResult => evaluationResult = asyncResult.Result);
workList.Execute();
return evaluationResult;
}
internal DkmEvaluationResult[] GetChildren(DkmEvaluationResult evalResult, DkmInspectionContext inspectionContext = null)
{
DkmEvaluationResultEnumContext enumContext;
const int size = 1;
var builder = ArrayBuilder<DkmEvaluationResult>.GetInstance();
// Request 0 children.
var items = GetChildren(evalResult, 0, inspectionContext, out enumContext);
Assert.Equal(items.Length, 0);
// Request >0 children.
items = GetChildren(evalResult, size, inspectionContext, out enumContext);
// Request 0-3 children.
int size;
DkmEvaluationResult[] items;
for (size = 0; size < 3; size++)
{
items = GetChildren(evalResult, size, inspectionContext, out enumContext);
var totalChildCount = enumContext.Count;
Assert.InRange(totalChildCount, 0, int.MaxValue);
var expectedSize = (size < totalChildCount) ? size : totalChildCount;
Assert.Equal(expectedSize, items.Length);
}
// Request items (increasing the size of the request with each iteration).
size = 1;
items = GetChildren(evalResult, size, inspectionContext, out enumContext);
while (items.Length > 0)
{
builder.AddRange(items);
......@@ -181,6 +190,7 @@ internal DkmEvaluationResult[] GetChildren(DkmEvaluationResult evalResult, DkmIn
items = GetItems(enumContext, offset, 0);
Assert.Equal(items.Length, 0);
// Request >0 items.
size++;
items = GetItems(enumContext, offset, size);
}
......@@ -191,7 +201,9 @@ internal DkmEvaluationResult[] GetChildren(DkmEvaluationResult evalResult, DkmIn
internal DkmEvaluationResult[] GetChildren(DkmEvaluationResult evalResult, int initialRequestSize, DkmInspectionContext inspectionContext, out DkmEvaluationResultEnumContext enumContext)
{
DkmGetChildrenAsyncResult getChildrenResult = default(DkmGetChildrenAsyncResult);
_resultProvider.GetChildren(evalResult, null, initialRequestSize, inspectionContext ?? DefaultInspectionContext, r => { getChildrenResult = r; });
var workList = new DkmWorkList();
_resultProvider.GetChildren(evalResult, workList, initialRequestSize, inspectionContext ?? DefaultInspectionContext, r => { getChildrenResult = r; });
workList.Execute();
var exception = getChildrenResult.Exception;
if (exception != null)
{
......@@ -204,7 +216,9 @@ internal DkmEvaluationResult[] GetChildren(DkmEvaluationResult evalResult, int i
internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumContext, int startIndex, int count)
{
DkmEvaluationEnumAsyncResult getItemsResult = default(DkmEvaluationEnumAsyncResult);
_resultProvider.GetItems(enumContext, null, startIndex, count, r => { getItemsResult = r; });
var workList = new DkmWorkList();
_resultProvider.GetItems(enumContext, workList, startIndex, count, r => { getItemsResult = r; });
workList.Execute();
var exception = getItemsResult.Exception;
if (exception != null)
{
......
......@@ -111,6 +111,9 @@
<Compile Include="..\..\Source\ResultProvider\Helpers\ArrayBuilder.cs">
<Link>ResultProvider\Helpers\ArrayBuilder.cs</Link>
</Compile>
<Compile Include="..\..\Source\ResultProvider\Helpers\DebuggerDisplayInfo.cs">
<Link>ResultProvider\Helpers\DebuggerDisplayInfo.cs</Link>
</Compile>
<Compile Include="..\..\Source\ResultProvider\Helpers\DkmClrValueFlagsExtensions.cs">
<Link>ResultProvider\Helpers\DkmClrValueFlagsExtensions.cs</Link>
</Compile>
......@@ -153,6 +156,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Debugger\Engine\DkmContinueCorruptingException.cs" />
<Compile Include="Debugger\Engine\DkmEvaluateDebuggerDisplayStringAsyncResult.cs" />
<Compile Include="Debugger\Engine\DkmEvaluationAsyncResult.cs" />
<Compile Include="Debugger\Engine\DkmExceptionCode.cs" />
<Compile Include="Debugger\Engine\DkmException.cs" />
<Compile Include="Debugger\Engine\DkmClrAppDomain.cs" />
......@@ -183,6 +188,7 @@
<Compile Include="Debugger\Engine\DkmModuleInstance.cs" />
<Compile Include="Debugger\Engine\DkmReportNonFatalWatsonExceptionAttribute.cs" />
<Compile Include="Debugger\Engine\DkmSuccessEvaluationResult.cs" />
<Compile Include="Debugger\Engine\DkmWorkList.cs" />
<Compile Include="Debugger\Engine\IDkmClrFormatter.cs" />
<Compile Include="Debugger\Engine\IDkmClrResultProvider.cs" />
<Compile Include="Debugger\MemberInfo\AssemblyImpl.cs" />
......@@ -221,5 +227,4 @@
<Import Project="..\..\..\..\..\build\Roslyn.Toolsets.Xunit.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -26,26 +26,23 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
staticMembersString:=Resources.SharedMembers)
End Sub
Private Function IDkmClrFormatter_GetTypeName(inspectionContext As DkmInspectionContext, clrType As DkmClrType) As String Implements IDkmClrFormatter.GetTypeName
Private Function IDkmClrFormatter_GetTypeName(inspectionContext As DkmInspectionContext, clrType As DkmClrType, formatSpecifiers As ReadOnlyCollection(Of String)) As String Implements IDkmClrFormatter.GetTypeName
Return GetTypeName(clrType.GetLmrType())
End Function
Private Function IDkmClrFormatter_GetUnderlyingString(clrValue As DkmClrValue) As String Implements IDkmClrFormatter.GetUnderlyingString
Return GetUnderlyingString(clrValue)
Private Function IDkmClrFormatter_GetUnderlyingString(clrValue As DkmClrValue, inspectionContext As DkmInspectionContext) As String Implements IDkmClrFormatter.GetUnderlyingString
Return GetUnderlyingString(clrValue, inspectionContext)
End Function
Private Function IDkmClrFormatter_GetValueString(clrValue As DkmClrValue) As String Implements IDkmClrFormatter.GetValueString
' TODO: IDkmClrFormatter.GetValueString should have
' an explicit InspectionContext parameter that is not
' inherited from the containing DkmClrValue. #1099978.
Dim options = If((clrValue.InspectionContext.EvaluationFlags And DkmEvaluationFlags.NoQuotes) = 0,
Private Function IDkmClrFormatter_GetValueString(clrValue As DkmClrValue, inspectionContext As DkmInspectionContext, formatSpecifiers As ReadOnlyCollection(Of String)) As String Implements IDkmClrFormatter.GetValueString
Dim options = If((inspectionContext.EvaluationFlags And DkmEvaluationFlags.NoQuotes) = 0,
ObjectDisplayOptions.UseQuotes,
ObjectDisplayOptions.None)
Return GetValueString(clrValue, options, GetValueFlags.IncludeObjectId)
Return GetValueString(clrValue, inspectionContext, options, GetValueFlags.IncludeObjectId)
End Function
Private Function IDkmClrFormatter_HasUnderlyingString(clrValue As DkmClrValue) As Boolean Implements IDkmClrFormatter.HasUnderlyingString
Return HasUnderlyingString(clrValue)
Private Function IDkmClrFormatter_HasUnderlyingString(clrValue As DkmClrValue, inspectionContext As DkmInspectionContext) As Boolean Implements IDkmClrFormatter.HasUnderlyingString
Return HasUnderlyingString(clrValue, inspectionContext)
End Function
Friend Overrides Function IsIdentifierPartCharacter(c As Char) As Boolean
......
......@@ -280,8 +280,8 @@ End Class
' This Char is not printable, so we expect the EditableValue to be the "ChrW" representation.
quotedChar = "ChrW(&H7)"
value = CreateDkmClrValue(ChrW(&H0007), GetType(Char), inspectionContext:=CreateDkmInspectionContext(radix:=16))
result = FormatResult("c", value)
value = CreateDkmClrValue(ChrW(&H0007), GetType(Char))
result = FormatResult("c", value, inspectionContext:=CreateDkmInspectionContext(radix:=16))
Verify(result,
EvalResult("c", quotedChar, "Char", "c", editableValue:=quotedChar))
End Sub
......
......@@ -17,44 +17,44 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim stringType = runtime.GetType(GetType(String))
' Nothing
Dim value = CreateDkmClrValue(Nothing, type:=stringType, inspectionContext:=inspectionContext)
Dim result = FormatResult("s", value)
Dim value = CreateDkmClrValue(Nothing, type:=stringType)
Dim result = FormatResult("s", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("s", "Nothing", "String", "s", editableValue:=Nothing, flags:=DkmEvaluationResultFlags.None))
' ""
value = CreateDkmClrValue(String.Empty, type:=stringType, inspectionContext:=inspectionContext)
result = FormatResult("s", value)
value = CreateDkmClrValue(String.Empty, type:=stringType)
result = FormatResult("s", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("s", "", "String", "s", editableValue:="""""", flags:=DkmEvaluationResultFlags.RawString))
' "'"
value = CreateDkmClrValue("'", type:=stringType, inspectionContext:=inspectionContext)
result = FormatResult("s", value)
value = CreateDkmClrValue("'", type:=stringType)
result = FormatResult("s", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("s", "'", "String", "s", editableValue:="""'""", flags:=DkmEvaluationResultFlags.RawString))
' """"
value = CreateDkmClrValue("""", type:=stringType, inspectionContext:=inspectionContext)
result = FormatResult("s", value)
value = CreateDkmClrValue("""", type:=stringType)
result = FormatResult("s", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("s", """", "String", "s", editableValue:="""""""""", flags:=DkmEvaluationResultFlags.RawString))
' " " with alias
value = CreateDkmClrValue(" ", type:=stringType, [alias]:="1", evalFlags:=DkmEvaluationResultFlags.HasObjectId, inspectionContext:=inspectionContext)
result = FormatResult("s", value)
value = CreateDkmClrValue(" ", type:=stringType, [alias]:="1", evalFlags:=DkmEvaluationResultFlags.HasObjectId)
result = FormatResult("s", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("s", " {$1}", "String", "s", editableValue:=""" """, flags:=DkmEvaluationResultFlags.RawString Or DkmEvaluationResultFlags.HasObjectId))
' array
value = CreateDkmClrValue({"1"}, type:=stringType.MakeArrayType(), inspectionContext:=inspectionContext)
result = FormatResult("a", value)
value = CreateDkmClrValue({"1"}, type:=stringType.MakeArrayType())
result = FormatResult("a", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("a", "{Length=1}", "String()", "a", editableValue:=Nothing, flags:=DkmEvaluationResultFlags.Expandable))
Dim children = GetChildren(result)
' TODO: InspectionContext should not be inherited. See IDkmClrFormatter.GetValueString.
' DkmInspectionContext should not be inherited.
Verify(children,
EvalResult("(0)", "1", "String", "a(0)", editableValue:="""1""", flags:=DkmEvaluationResultFlags.RawString))
EvalResult("(0)", """1""", "String", "a(0)", editableValue:="""1""", flags:=DkmEvaluationResultFlags.RawString))
End Sub
<Fact>
......@@ -64,32 +64,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim charType = runtime.GetType(GetType(Char))
' 0
Dim value = CreateDkmClrValue(ChrW(0), type:=charType, inspectionContext:=inspectionContext)
Dim result = FormatResult("c", value)
Dim value = CreateDkmClrValue(ChrW(0), type:=charType)
Dim result = FormatResult("c", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("c", "vbNullChar", "Char", "c", editableValue:="vbNullChar", flags:=DkmEvaluationResultFlags.None))
' "'"c
value = CreateDkmClrValue("'"c, type:=charType, inspectionContext:=inspectionContext)
result = FormatResult("c", value)
value = CreateDkmClrValue("'"c, type:=charType)
result = FormatResult("c", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("c", "'", "Char", "c", editableValue:="""'""c", flags:=DkmEvaluationResultFlags.None))
' """"c
value = CreateDkmClrValue(""""c, type:=charType, inspectionContext:=inspectionContext)
result = FormatResult("c", value)
value = CreateDkmClrValue(""""c, type:=charType)
result = FormatResult("c", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("c", """"c, "Char", "c", editableValue:="""""""""c", flags:=DkmEvaluationResultFlags.None))
' array
value = CreateDkmClrValue({"1"c}, type:=charType.MakeArrayType(), inspectionContext:=inspectionContext)
result = FormatResult("a", value)
value = CreateDkmClrValue({"1"c}, type:=charType.MakeArrayType())
result = FormatResult("a", value, inspectionContext:=inspectionContext)
Verify(result,
EvalResult("a", "{Length=1}", "Char()", "a", editableValue:=Nothing, flags:=DkmEvaluationResultFlags.Expandable))
Dim children = GetChildren(result)
' TODO: InspectionContext should not be inherited. See IDkmClrFormatter.GetValueString.
' DkmInspectionContext should not be inherited.
Verify(children,
EvalResult("(0)", "1", "Char", "a(0)", editableValue:="""1""c", flags:=DkmEvaluationResultFlags.None))
EvalResult("(0)", """1""c", "Char", "a(0)", editableValue:="""1""c", flags:=DkmEvaluationResultFlags.None))
End Sub
End Class
......
......@@ -21,9 +21,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
FormatResult("i", value, objectType),
EvalResult("i", "1 {$1}", "Object {Integer}", "i", DkmEvaluationResultFlags.HasObjectId))
' Integer (hex)
value = CreateDkmClrValue(value:=2, type:=GetType(Integer), alias:="2", evalFlags:=DkmEvaluationResultFlags.HasObjectId, inspectionContext:=CreateDkmInspectionContext(radix:=16))
value = CreateDkmClrValue(value:=2, type:=GetType(Integer), alias:="2", evalFlags:=DkmEvaluationResultFlags.HasObjectId)
Verify(
FormatResult("i", value, objectType),
FormatResult("i", value, objectType, inspectionContext:=CreateDkmInspectionContext(radix:=16)),
EvalResult("i", "&H00000002 {$2}", "Object {Integer}", "i", DkmEvaluationResultFlags.HasObjectId))
' Char
value = CreateDkmClrValue(value:="c"c, type:=GetType(Char), alias:="3", evalFlags:=DkmEvaluationResultFlags.HasObjectId)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册