提交 87c1a611 编写于 作者: C Charles Stoner

Merge pull request #1957 from cston/1028624

EE: "Static members", etc. should not inherit Access, StorageType, TypeModifierFlags from parent item
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
using Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator; using Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.ExpressionEvaluator; using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Debugger; using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr; using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
using Microsoft.VisualStudio.Debugger.Evaluation; using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Symbols;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Xunit; using Xunit;
...@@ -2124,52 +2126,68 @@ class D : C ...@@ -2124,52 +2126,68 @@ class D : C
} }
/// <summary> /// <summary>
/// Do not copy state from parent for base or derived items. /// Do not copy state from parent.
/// </summary> /// </summary>
[WorkItem(1028624)] [WorkItem(1028624)]
[Fact(Skip = "1028624")] [Fact]
public void DoNotCopyParentState() public void DoNotCopyParentState()
{ {
var source = var sourceA =
@"class E : System.Exception @"public class A
{ {
} public static object F = 1;
public class A internal object G = 2;
{ }";
} var sourceB =
class B : A @"class B
{ {
protected class C : B private A _1 = new A();
{ protected A _2 = new A();
private B F = new B(); internal A _3 = new A();
protected A G = new B(); public A _4 = new A();
internal virtual B P { get { return new B(); } }
protected object Q { get { throw new E(); } }
}
}"; }";
var assembly = GetAssembly(source); var compilationA = CSharpTestBase.CreateCompilationWithMscorlib(sourceA, options: TestOptions.ReleaseDll);
var type = assembly.GetType("B+C"); var bytesA = compilationA.EmitToArray();
var value = CreateDkmClrValue( var referenceA = MetadataReference.CreateFromImage(bytesA);
Activator.CreateInstance(type),
alias: "1", var compilationB = CSharpTestBase.CreateCompilationWithMscorlib(sourceB, options: TestOptions.DebugDll, references: new MetadataReference[] { referenceA });
evalFlags: DkmEvaluationResultFlags.UnflushedSideEffects | DkmEvaluationResultFlags.HasObjectId | DkmEvaluationResultFlags.CanHaveObjectId); var bytesB = compilationB.EmitToArray();
var evalResult = FormatResult("o", value, new DkmClrType((TypeImpl)type.BaseType)); var assemblyA = ReflectionUtilities.Load(bytesA);
Verify(evalResult, var assemblyB = ReflectionUtilities.Load(bytesB);
EvalResult("o", "{B.C} {$1}", "B {B.C}", "o", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.UnflushedSideEffects | DkmEvaluationResultFlags.HasObjectId | DkmEvaluationResultFlags.CanHaveObjectId));
var children = GetChildren(evalResult); DkmClrRuntimeInstance runtime = null;
Verify(children, GetModuleDelegate getModule = (r, a) => (a == assemblyB) ? new DkmClrModuleInstance(r, a, new DkmModule(a.GetName().Name + ".dll")) : null;
EvalResult("[B.C]", "{B.C} {$1}", "B.C", "(B.C)o", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.HasObjectId, DkmEvaluationResultCategory.Data), runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(assemblyA, assemblyB), getModule: getModule);
EvalResult("base", "{B.C} {$1}", "A {B.C}", "(A)o", DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.HasObjectId, DkmEvaluationResultCategory.Data)); using (runtime.Load())
children = GetChildren(children[0]); {
Verify(children, var type = runtime.GetType("B");
EvalResult("base", "{B.C} {$1}", "B {B.C}", "(B)o", DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.HasObjectId, DkmEvaluationResultCategory.Data), var value = CreateDkmClrValue(type.Instantiate(), type: type);
EvalResult("F", "{B}", "B", "((B.C)o).F", DkmEvaluationResultFlags.Expandable), // Format with "Just my code".
EvalResult("G", "{B}", "A {B}", "((B.C)o).G", DkmEvaluationResultFlags.Expandable), var inspectionContext = CreateDkmInspectionContext(DkmEvaluationFlags.HideNonPublicMembers, runtimeInstance: runtime);
EvalResult("P", "{B}", "B", "((B.C)o).P", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly), var evalResult = FormatResult("o", value, inspectionContext: inspectionContext);
EvalResult("Q", "'((B.C)o).Q' threw an exception of type 'E'", "object {E}", "((B.C)o).Q", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.ExceptionThrown)); var children = GetChildren(evalResult, inspectionContext: inspectionContext);
Verify(children,
// Also need to check Access, StorageType, and TypeModifierFlags fields. EvalResult("_1", "{A}", "A", "o._1", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Private),
// ... EvalResult("_2", "{A}", "A", "o._2", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Protected),
EvalResult("_3", "{A}", "A", "o._3", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Internal),
EvalResult("_4", "{A}", "A", "o._4", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Public));
var moreChildren = GetChildren(children[0], inspectionContext: inspectionContext);
Verify(moreChildren,
EvalResult("Static members", null, "", "A", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class, DkmEvaluationResultAccessType.None),
EvalResult("Non-Public members", null, "", "o._1, hidden", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.None));
moreChildren = GetChildren(children[1], inspectionContext: inspectionContext);
Verify(moreChildren,
EvalResult("Static members", null, "", "A", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class, DkmEvaluationResultAccessType.None),
EvalResult("Non-Public members", null, "", "o._2, hidden", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.None));
moreChildren = GetChildren(children[2], inspectionContext: inspectionContext);
Verify(moreChildren,
EvalResult("Static members", null, "", "A", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class, DkmEvaluationResultAccessType.None),
EvalResult("Non-Public members", null, "", "o._3, hidden", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.None));
moreChildren = GetChildren(children[3], inspectionContext: inspectionContext);
Verify(moreChildren,
EvalResult("Static members", null, "", "A", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class, DkmEvaluationResultAccessType.None),
EvalResult("Non-Public members", null, "", "o._4, hidden", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.None));
}
} }
[WorkItem(1130978)] [WorkItem(1130978)]
......
...@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests ...@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
public class NativeViewTests : CSharpResultProviderTestBase public class NativeViewTests : CSharpResultProviderTestBase
{ {
[Fact] [Fact]
public void NativeView1() public void NativeView()
{ {
TestNativeView(true); TestNativeView(true);
} }
...@@ -25,8 +25,7 @@ public void NativeViewManagedOnly() ...@@ -25,8 +25,7 @@ public void NativeViewManagedOnly()
private void TestNativeView(bool enableNativeDebugging) private void TestNativeView(bool enableNativeDebugging)
{ {
var source = var source =
@"using System.Collections; @"class C
class C
{ {
}"; }";
using (new EnsureEnglishUICulture()) using (new EnsureEnglishUICulture())
...@@ -41,7 +40,7 @@ class C ...@@ -41,7 +40,7 @@ class C
var value = CreateDkmClrValue( var value = CreateDkmClrValue(
value: type.Instantiate(), value: type.Instantiate(),
type: runtime.GetType((TypeImpl)type), type: runtime.GetType((TypeImpl)type),
isComObject: true); nativeComPointer: 0xfe);
var evalResult = FormatResult("o", value, inspectionContext: inspectionContext); var evalResult = FormatResult("o", value, inspectionContext: inspectionContext);
Verify(evalResult, Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable)); EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable));
...@@ -50,7 +49,7 @@ class C ...@@ -50,7 +49,7 @@ class C
{ {
DkmLanguage language = new DkmLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); DkmLanguage language = new DkmLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
Verify(children, Verify(children,
EvalIntermediateResult("Native View", "{C++}(IUnknown*)0x00000001", "(IUnknown*)0x00000001", language)); EvalIntermediateResult("Native View", "{C++}(IUnknown*)0x000000FE", "(IUnknown*)0x000000FE", language));
} }
else else
{ {
......
...@@ -1460,8 +1460,7 @@ internal IEnumerable Q ...@@ -1460,8 +1460,7 @@ internal IEnumerable Q
"\"Exception of type 'E' was thrown.\"", "\"Exception of type 'E' was thrown.\"",
"string", "string",
null, null,
DkmEvaluationResultFlags.RawString | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultFlags.RawString | DkmEvaluationResultFlags.ReadOnly));
DkmEvaluationResultCategory.Other));
} }
} }
...@@ -1615,7 +1614,7 @@ class C ...@@ -1615,7 +1614,7 @@ class C
"S", "S",
DkmEvaluationResultFlags.RawString, DkmEvaluationResultFlags.RawString,
DkmEvaluationResultCategory.Other, DkmEvaluationResultCategory.Other,
"\"\"")); editableValue: "\"\""));
// array (unchanged) // array (unchanged)
evalResult = FormatPropertyValue(runtime, value, "T"); evalResult = FormatPropertyValue(runtime, value, "T");
......
...@@ -110,7 +110,7 @@ internal sealed class MemberExpansion : Expansion ...@@ -110,7 +110,7 @@ internal sealed class MemberExpansion : Expansion
if (value.NativeComPointer != 0) if (value.NativeComPointer != 0)
{ {
expansions.Add(new NativeViewExpansion()); expansions.Add(NativeViewExpansion.Instance);
} }
if (nonPublicInstanceExpansion != null) if (nonPublicInstanceExpansion != null)
......
...@@ -9,6 +9,12 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator ...@@ -9,6 +9,12 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{ {
internal sealed class NativeViewExpansion : Expansion internal sealed class NativeViewExpansion : Expansion
{ {
internal static readonly NativeViewExpansion Instance = new NativeViewExpansion();
private NativeViewExpansion()
{
}
internal override void GetRows( internal override void GetRows(
ResultProvider resultProvider, ResultProvider resultProvider,
ArrayBuilder<EvalResultDataItem> rows, ArrayBuilder<EvalResultDataItem> rows,
......
...@@ -58,7 +58,7 @@ private EvalResultDataItem GetRow(ResultProvider resultProvider, DkmInspectionCo ...@@ -58,7 +58,7 @@ private EvalResultDataItem GetRow(ResultProvider resultProvider, DkmInspectionCo
var typeArgument = _typeArguments[index]; var typeArgument = _typeArguments[index];
var formatSpecifiers = Formatter.NoFormatSpecifiers; var formatSpecifiers = Formatter.NoFormatSpecifiers;
return new EvalResultDataItem( return new EvalResultDataItem(
ExpansionKind.TypeVariables, ExpansionKind.TypeVariable,
typeParameter.Name, typeParameter.Name,
typeDeclaringMember: null, typeDeclaringMember: null,
declaredType: typeArgument, declaredType: typeArgument,
......
...@@ -19,7 +19,7 @@ internal enum ExpansionKind ...@@ -19,7 +19,7 @@ internal enum ExpansionKind
RawView, RawView,
ResultsView, ResultsView,
StaticMembers, StaticMembers,
TypeVariables TypeVariable
} }
/// <summary> /// <summary>
......
...@@ -133,36 +133,120 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work ...@@ -133,36 +133,120 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work
DataItem: null)); DataItem: null));
break; break;
case ExpansionKind.NativeView: case ExpansionKind.NativeView:
{
var value = dataItem.Value;
var name = Resources.NativeView;
var fullName = dataItem.FullName;
var display = dataItem.Name;
DkmEvaluationResult evalResult;
if (value.IsError())
{
evalResult = DkmFailedEvaluationResult.Create(
inspectionContext,
stackFrame,
Name: name,
FullName: fullName,
ErrorMessage: display,
Flags: dataItem.Flags,
Type: null,
DataItem: dataItem);
}
else
{
// For Native View, create a DkmIntermediateEvaluationResult.
// This will allow the C++ EE to take over expansion.
var process = inspectionContext.RuntimeInstance.Process;
var cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
evalResult = DkmIntermediateEvaluationResult.Create(
inspectionContext,
stackFrame,
Name: name,
FullName: fullName,
Expression: display,
IntermediateLanguage: cpp,
TargetRuntime: process.GetNativeRuntimeInstance(),
DataItem: dataItem);
}
completionRoutine(evalResult);
}
break;
case ExpansionKind.NonPublicMembers: case ExpansionKind.NonPublicMembers:
completionRoutine(DkmSuccessEvaluationResult.Create(
inspectionContext,
stackFrame,
Name: Resources.NonPublicMembers,
FullName: dataItem.FullName,
Flags: dataItem.Flags,
Value: null,
EditableValue: null,
Type: string.Empty,
Category: DkmEvaluationResultCategory.Data,
Access: DkmEvaluationResultAccessType.None,
StorageType: DkmEvaluationResultStorageType.None,
TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
Address: dataItem.Value.Address,
CustomUIVisualizers: null,
ExternalModules: null,
DataItem: dataItem));
break;
case ExpansionKind.StaticMembers: case ExpansionKind.StaticMembers:
completionRoutine(CreateEvaluationResult( completionRoutine(DkmSuccessEvaluationResult.Create(
inspectionContext, inspectionContext,
dataItem.Value, stackFrame,
dataItem.Name, Name: Formatter.StaticMembersString,
typeName: string.Empty, FullName: dataItem.FullName,
display: null, Flags: dataItem.Flags,
dataItem: dataItem)); Value: null,
EditableValue: null,
Type: string.Empty,
Category: DkmEvaluationResultCategory.Class,
Access: DkmEvaluationResultAccessType.None,
StorageType: DkmEvaluationResultStorageType.None,
TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
Address: dataItem.Value.Address,
CustomUIVisualizers: null,
ExternalModules: null,
DataItem: dataItem));
break; break;
case ExpansionKind.RawView: case ExpansionKind.RawView:
completionRoutine(CreateEvaluationResult( completionRoutine(DkmSuccessEvaluationResult.Create(
inspectionContext, inspectionContext,
dataItem.Value, stackFrame,
Resources.RawView, Name: Resources.RawView,
typeName: string.Empty, FullName: dataItem.FullName,
display: null, Flags: dataItem.Flags,
dataItem: dataItem)); Value: null,
EditableValue: dataItem.EditableValue,
Type: string.Empty,
Category: DkmEvaluationResultCategory.Data,
Access: DkmEvaluationResultAccessType.None,
StorageType: DkmEvaluationResultStorageType.None,
TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
Address: dataItem.Value.Address,
CustomUIVisualizers: null,
ExternalModules: null,
DataItem: dataItem));
break; break;
case ExpansionKind.ResultsView: case ExpansionKind.ResultsView:
completionRoutine(CreateEvaluationResult( completionRoutine(DkmSuccessEvaluationResult.Create(
inspectionContext, inspectionContext,
dataItem.Value, stackFrame,
dataItem.Name, Name: dataItem.Name,
typeName: string.Empty, FullName: dataItem.FullName,
display: Resources.ResultsViewValueWarning, Flags: dataItem.Flags,
dataItem: dataItem)); Value: Resources.ResultsViewValueWarning,
EditableValue: null,
Type: string.Empty,
Category: DkmEvaluationResultCategory.Method,
Access: DkmEvaluationResultAccessType.None,
StorageType: DkmEvaluationResultStorageType.None,
TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
Address: dataItem.Value.Address,
CustomUIVisualizers: null,
ExternalModules: null,
DataItem: dataItem));
break; break;
case ExpansionKind.TypeVariables: case ExpansionKind.TypeVariable:
var value = dataItem.Value;
completionRoutine(DkmSuccessEvaluationResult.Create( completionRoutine(DkmSuccessEvaluationResult.Create(
inspectionContext, inspectionContext,
stackFrame, stackFrame,
...@@ -172,17 +256,17 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work ...@@ -172,17 +256,17 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work
dataItem.DisplayValue, dataItem.DisplayValue,
EditableValue: null, EditableValue: null,
Type: dataItem.DisplayValue, Type: dataItem.DisplayValue,
Category: dataItem.Category, Category: DkmEvaluationResultCategory.Data,
Access: value.Access, Access: DkmEvaluationResultAccessType.None,
StorageType: value.StorageType, StorageType: DkmEvaluationResultStorageType.None,
TypeModifierFlags: value.TypeModifierFlags, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
Address: value.Address, Address: dataItem.Value.Address,
CustomUIVisualizers: null, CustomUIVisualizers: null,
ExternalModules: null, ExternalModules: null,
DataItem: dataItem)); DataItem: dataItem));
break; break;
default: case ExpansionKind.PointerDereference:
Debug.Assert((dataItem.Kind == ExpansionKind.Default) || (dataItem.Kind == ExpansionKind.PointerDereference)); case ExpansionKind.Default:
// This call will evaluate DebuggerDisplayAttributes. // This call will evaluate DebuggerDisplayAttributes.
GetResultAndContinue( GetResultAndContinue(
dataItem, dataItem,
...@@ -192,6 +276,8 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work ...@@ -192,6 +276,8 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work
parent: dataItem.Parent, parent: dataItem.Parent,
completionRoutine: completionRoutine); completionRoutine: completionRoutine);
break; break;
default:
throw ExceptionUtilities.UnexpectedValue(dataItem.Kind);
} }
} }
...@@ -216,22 +302,6 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work ...@@ -216,22 +302,6 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work
Type: typeName, Type: typeName,
DataItem: dataItem); DataItem: dataItem);
} }
else if (dataItem.Kind == ExpansionKind.NativeView)
{
// For Native View, create a DkmIntermediateEvaluationResult. This will allow the C++ EE
// to take over expansion.
DkmProcess process = inspectionContext.RuntimeInstance.Process;
DkmLanguage cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
return DkmIntermediateEvaluationResult.Create(
InspectionContext: inspectionContext,
StackFrame: value.StackFrame,
Name: Resources.NativeView,
FullName: dataItem.FullName,
Expression: dataItem.Name,
IntermediateLanguage: cpp,
TargetRuntime: process.GetNativeRuntimeInstance(),
DataItem: dataItem);
}
else else
{ {
ReadOnlyCollection<DkmCustomUIVisualizerInfo> customUIVisualizers = null; ReadOnlyCollection<DkmCustomUIVisualizerInfo> customUIVisualizers = null;
...@@ -245,7 +315,7 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work ...@@ -245,7 +315,7 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work
} }
} }
// If the EvalResultData item doesn't specify a particular category, we'll just propagate DkmClrValue.Category, // If the EvalResultDataItem doesn't specify a particular category, we'll just propagate DkmClrValue.Category,
// which typically appears to be set to the default value ("Other"). // which typically appears to be set to the default value ("Other").
var category = (dataItem.Category != DkmEvaluationResultCategory.Other) ? dataItem.Category : value.Category; var category = (dataItem.Category != DkmEvaluationResultCategory.Other) ? dataItem.Category : value.Category;
......
...@@ -25,7 +25,7 @@ public class DkmClrRuntimeInstance : DkmRuntimeInstance ...@@ -25,7 +25,7 @@ public class DkmClrRuntimeInstance : DkmRuntimeInstance
internal readonly DkmClrModuleInstance[] Modules; internal readonly DkmClrModuleInstance[] Modules;
private readonly DkmClrModuleInstance _defaultModule; private readonly DkmClrModuleInstance _defaultModule;
private readonly DkmClrAppDomain _appDomain; // exactly one for now private readonly DkmClrAppDomain _appDomain; // exactly one for now
private readonly GetMemberValueDelegate _getMemberValue; internal readonly GetMemberValueDelegate GetMemberValue;
internal DkmClrRuntimeInstance( internal DkmClrRuntimeInstance(
Assembly[] assemblies, Assembly[] assemblies,
...@@ -42,7 +42,7 @@ public class DkmClrRuntimeInstance : DkmRuntimeInstance ...@@ -42,7 +42,7 @@ public class DkmClrRuntimeInstance : DkmRuntimeInstance
this.Modules = assemblies.Select(a => getModule(this, a)).Where(m => m != null).ToArray(); this.Modules = assemblies.Select(a => getModule(this, a)).Where(m => m != null).ToArray();
_defaultModule = getModule(this, null); _defaultModule = getModule(this, null);
_appDomain = new DkmClrAppDomain(this); _appDomain = new DkmClrAppDomain(this);
_getMemberValue = getMemberValue; this.GetMemberValue = getMemberValue;
} }
internal DkmClrModuleInstance DefaultModule internal DkmClrModuleInstance DefaultModule
...@@ -87,14 +87,5 @@ internal DkmClrModuleInstance FindClrModuleInstance(Guid mvid) ...@@ -87,14 +87,5 @@ internal DkmClrModuleInstance FindClrModuleInstance(Guid mvid)
{ {
return this.Modules.FirstOrDefault(m => m.Mvid == mvid) ?? _defaultModule; return this.Modules.FirstOrDefault(m => m.Mvid == mvid) ?? _defaultModule;
} }
internal DkmClrValue GetMemberValue(DkmClrValue value, string memberName)
{
if (_getMemberValue != null)
{
return _getMemberValue(value, memberName);
}
return null;
}
} }
} }
...@@ -32,21 +32,25 @@ public class DkmClrValue : DkmDataContainer ...@@ -32,21 +32,25 @@ public class DkmClrValue : DkmDataContainer
IDkmClrFormatter formatter, IDkmClrFormatter formatter,
DkmEvaluationResultFlags evalFlags, DkmEvaluationResultFlags evalFlags,
DkmClrValueFlags valueFlags, DkmClrValueFlags valueFlags,
bool isComObject = false) DkmEvaluationResultCategory category = default(DkmEvaluationResultCategory),
DkmEvaluationResultAccessType access = default(DkmEvaluationResultAccessType),
ulong nativeComPointer = 0)
{ {
Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic)); Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic));
Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId)); Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId));
// The "real" DkmClrValue will always have a value of zero for null pointers. // The "real" DkmClrValue will always have a value of zero for null pointers.
Debug.Assert(!type.GetLmrType().IsPointer || (value != null)); Debug.Assert(!type.GetLmrType().IsPointer || (value != null));
_rawValue = value; this.RawValue = value;
this.HostObjectValue = hostObjectValue; this.HostObjectValue = hostObjectValue;
this.Type = type; this.Type = type;
_formatter = formatter; _formatter = formatter;
this.Alias = alias; this.Alias = alias;
this.EvalFlags = evalFlags; this.EvalFlags = evalFlags;
this.ValueFlags = valueFlags; this.ValueFlags = valueFlags;
this.NativeComPointer = isComObject ? 1UL : 0; this.Category = category;
this.Access = access;
this.NativeComPointer = nativeComPointer;
} }
public readonly DkmEvaluationResultFlags EvalFlags; public readonly DkmEvaluationResultFlags EvalFlags;
...@@ -63,7 +67,11 @@ public class DkmClrValue : DkmDataContainer ...@@ -63,7 +67,11 @@ public class DkmClrValue : DkmDataContainer
public readonly ulong NativeComPointer; public readonly ulong NativeComPointer;
private readonly IDkmClrFormatter _formatter; private readonly IDkmClrFormatter _formatter;
private readonly object _rawValue; internal readonly object RawValue;
public void Close()
{
}
public DkmClrValue Dereference(DkmInspectionContext inspectionContext) public DkmClrValue Dereference(DkmInspectionContext inspectionContext)
{ {
...@@ -72,7 +80,7 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext) ...@@ -72,7 +80,7 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext)
throw new ArgumentNullException("inspectionContext"); throw new ArgumentNullException("inspectionContext");
} }
if (_rawValue == null) if (RawValue == null)
{ {
throw new InvalidOperationException("Cannot dereference invalid value"); throw new InvalidOperationException("Cannot dereference invalid value");
} }
...@@ -82,7 +90,7 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext) ...@@ -82,7 +90,7 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext)
object value; object value;
try try
{ {
var intPtr = Environment.Is64BitProcess ? new IntPtr((long)_rawValue) : new IntPtr((int)_rawValue); var intPtr = Environment.Is64BitProcess ? new IntPtr((long)RawValue) : new IntPtr((int)RawValue);
value = Dereference(intPtr, elementType); value = Dereference(intPtr, elementType);
} }
catch (Exception e) catch (Exception e)
...@@ -98,7 +106,9 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext) ...@@ -98,7 +106,9 @@ public DkmClrValue Dereference(DkmInspectionContext inspectionContext)
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: evalFlags, evalFlags: evalFlags,
valueFlags: valueFlags); valueFlags: valueFlags,
category: DkmEvaluationResultCategory.Other,
access: DkmEvaluationResultAccessType.None);
} }
public bool IsNull public bool IsNull
...@@ -112,7 +122,7 @@ public bool IsNull ...@@ -112,7 +122,7 @@ public bool IsNull
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
var lmrType = Type.GetLmrType(); var lmrType = Type.GetLmrType();
return ((_rawValue == null) && !lmrType.IsValueType) || (lmrType.IsPointer && (Convert.ToInt64(_rawValue) == 0)); return ((RawValue == null) && !lmrType.IsValueType) || (lmrType.IsPointer && (Convert.ToInt64(RawValue) == 0));
} }
} }
...@@ -187,7 +197,7 @@ public string EvaluateToString(DkmInspectionContext inspectionContext) ...@@ -187,7 +197,7 @@ public string EvaluateToString(DkmInspectionContext inspectionContext)
type = type.BaseType; type = type.BaseType;
} }
var rawValue = _rawValue; var rawValue = RawValue;
Debug.Assert(rawValue != null || this.Type.GetLmrType().IsVoid(), "In our mock system, this should only happen for void."); Debug.Assert(rawValue != null || this.Type.GetLmrType().IsVoid(), "In our mock system, this should only happen for void.");
return rawValue == null ? null : rawValue.ToString(); return rawValue == null ? null : rawValue.ToString();
} }
...@@ -250,7 +260,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon ...@@ -250,7 +260,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon
var field = type.GetField(name, bindingFlags); var field = type.GetField(name, bindingFlags);
if (field != null) if (field != null)
{ {
var fieldValue = field.GetValue(_rawValue); var fieldValue = field.GetValue(RawValue);
exprValue = new DkmClrValue( exprValue = new DkmClrValue(
fieldValue, fieldValue,
fieldValue, fieldValue,
...@@ -265,7 +275,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon ...@@ -265,7 +275,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon
var property = type.GetProperty(name, bindingFlags); var property = type.GetProperty(name, bindingFlags);
if (property != null) if (property != null)
{ {
var propertyValue = property.GetValue(_rawValue); var propertyValue = property.GetValue(RawValue);
exprValue = new DkmClrValue( exprValue = new DkmClrValue(
propertyValue, propertyValue,
propertyValue, propertyValue,
...@@ -288,7 +298,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon ...@@ -288,7 +298,7 @@ public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionCon
// we'll return error if there wasn't at least an open paren... // we'll return error if there wasn't at least an open paren...
if ((openParenIndex >= 0) && method != null) if ((openParenIndex >= 0) && method != null)
{ {
var methodValue = method.Invoke(_rawValue, new object[] { }); var methodValue = method.Invoke(RawValue, new object[] { });
exprValue = new DkmClrValue( exprValue = new DkmClrValue(
methodValue, methodValue,
methodValue, methodValue,
...@@ -343,11 +353,14 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -343,11 +353,14 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
} }
var runtime = this.Type.RuntimeInstance; var runtime = this.Type.RuntimeInstance;
var getMemberValue = runtime.GetMemberValue;
var memberValue = runtime.GetMemberValue(this, MemberName); if (getMemberValue != null)
if (memberValue != null)
{ {
return memberValue; var memberValue = getMemberValue(this, MemberName);
if (memberValue != null)
{
return memberValue;
}
} }
var declaringType = this.Type.GetLmrType(); var declaringType = this.Type.GetLmrType();
...@@ -364,7 +377,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -364,7 +377,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
{ {
// In our mock implementation, RawValue is null for null nullables, // In our mock implementation, RawValue is null for null nullables,
// so we have to compute HasValue some other way. // so we have to compute HasValue some other way.
var boolValue = _rawValue != null; var boolValue = RawValue != null;
var boolType = runtime.GetType((TypeImpl)typeof(bool)); var boolType = runtime.GetType((TypeImpl)typeof(bool));
return new DkmClrValue( return new DkmClrValue(
boolValue, boolValue,
...@@ -373,28 +386,34 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -373,28 +386,34 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None, evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None); valueFlags: DkmClrValueFlags.None,
category: DkmEvaluationResultCategory.Property,
access: DkmEvaluationResultAccessType.Public);
} }
else if (MemberName == InternalWellKnownMemberNames.NullableValue) else if (MemberName == InternalWellKnownMemberNames.NullableValue)
{ {
// In our mock implementation, RawValue is of type T rather than // In our mock implementation, RawValue is of type T rather than
// Nullable<T> for nullables, so we'll just return that value // Nullable<T> for nullables, so we'll just return that value
// (no need to unwrap by getting "value" field). // (no need to unwrap by getting "value" field).
var valueType = runtime.GetType((TypeImpl)_rawValue.GetType()); var valueType = runtime.GetType((TypeImpl)RawValue.GetType());
return new DkmClrValue( return new DkmClrValue(
_rawValue, RawValue,
_rawValue, RawValue,
type: valueType, type: valueType,
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: DkmEvaluationResultFlags.None, evalFlags: DkmEvaluationResultFlags.None,
valueFlags: DkmClrValueFlags.None); valueFlags: DkmClrValueFlags.None,
category: DkmEvaluationResultCategory.Property,
access: DkmEvaluationResultAccessType.Public);
} }
} }
Type declaredType; Type declaredType;
object value; object value;
var evalFlags = DkmEvaluationResultFlags.None; var evalFlags = DkmEvaluationResultFlags.None;
var category = DkmEvaluationResultCategory.Other;
var access = DkmEvaluationResultAccessType.None;
const BindingFlags bindingFlags = const BindingFlags bindingFlags =
BindingFlags.DeclaredOnly | BindingFlags.DeclaredOnly |
...@@ -408,13 +427,15 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -408,13 +427,15 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
case MemberTypes.Field: case MemberTypes.Field:
var field = declaringType.GetField(MemberName, bindingFlags); var field = declaringType.GetField(MemberName, bindingFlags);
declaredType = field.FieldType; declaredType = field.FieldType;
category = DkmEvaluationResultCategory.Data;
access = GetFieldAccess(field);
if (field.Attributes.HasFlag(System.Reflection.FieldAttributes.Literal) || field.Attributes.HasFlag(System.Reflection.FieldAttributes.InitOnly)) if (field.Attributes.HasFlag(System.Reflection.FieldAttributes.Literal) || field.Attributes.HasFlag(System.Reflection.FieldAttributes.InitOnly))
{ {
evalFlags |= DkmEvaluationResultFlags.ReadOnly; evalFlags |= DkmEvaluationResultFlags.ReadOnly;
} }
try try
{ {
value = field.GetValue(_rawValue); value = field.GetValue(RawValue);
} }
catch (System.Reflection.TargetInvocationException e) catch (System.Reflection.TargetInvocationException e)
{ {
...@@ -426,19 +447,23 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -426,19 +447,23 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown, evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown,
valueFlags: DkmClrValueFlags.None); valueFlags: DkmClrValueFlags.None,
category: category,
access: access);
} }
break; break;
case MemberTypes.Property: case MemberTypes.Property:
var property = declaringType.GetProperty(MemberName, bindingFlags); var property = declaringType.GetProperty(MemberName, bindingFlags);
declaredType = property.PropertyType; declaredType = property.PropertyType;
category = DkmEvaluationResultCategory.Property;
access = GetPropertyAccess(property);
if (property.GetSetMethod(nonPublic: true) == null) if (property.GetSetMethod(nonPublic: true) == null)
{ {
evalFlags |= DkmEvaluationResultFlags.ReadOnly; evalFlags |= DkmEvaluationResultFlags.ReadOnly;
} }
try try
{ {
value = property.GetValue(_rawValue, bindingFlags, null, null, null); value = property.GetValue(RawValue, bindingFlags, null, null, null);
} }
catch (System.Reflection.TargetInvocationException e) catch (System.Reflection.TargetInvocationException e)
{ {
...@@ -450,7 +475,9 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -450,7 +475,9 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown, evalFlags: evalFlags | DkmEvaluationResultFlags.ExceptionThrown,
valueFlags: DkmClrValueFlags.None); valueFlags: DkmClrValueFlags.None,
category: category,
access: access);
} }
break; break;
default: default:
...@@ -489,7 +516,9 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -489,7 +516,9 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
alias: null, alias: null,
formatter: _formatter, formatter: _formatter,
evalFlags: evalFlags, evalFlags: evalFlags,
valueFlags: DkmClrValueFlags.None); valueFlags: DkmClrValueFlags.None,
category: category,
access: access);
} }
public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext) public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext)
...@@ -499,7 +528,7 @@ public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectio ...@@ -499,7 +528,7 @@ public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectio
throw new ArgumentNullException("inspectionContext"); throw new ArgumentNullException("inspectionContext");
} }
var array = (System.Array)_rawValue; var array = (System.Array)RawValue;
var element = array.GetValue(indices); var element = array.GetValue(indices);
var type = DkmClrType.Create(this.Type.AppDomain, (TypeImpl)((element == null) ? array.GetType().GetElementType() : element.GetType())); var type = DkmClrType.Create(this.Type.AppDomain, (TypeImpl)((element == null) ? array.GetType().GetElementType() : element.GetType()));
return new DkmClrValue( return new DkmClrValue(
...@@ -516,7 +545,7 @@ public ReadOnlyCollection<int> ArrayDimensions ...@@ -516,7 +545,7 @@ public ReadOnlyCollection<int> ArrayDimensions
{ {
get get
{ {
var array = (Array)_rawValue; var array = (Array)RawValue;
if (array == null) if (array == null)
{ {
return null; return null;
...@@ -536,7 +565,7 @@ public ReadOnlyCollection<int> ArrayLowerBounds ...@@ -536,7 +565,7 @@ public ReadOnlyCollection<int> ArrayLowerBounds
{ {
get get
{ {
var array = (Array)_rawValue; var array = (Array)RawValue;
if (array == null) if (array == null)
{ {
return null; return null;
...@@ -567,7 +596,7 @@ public DkmClrValue InstantiateProxyType(DkmInspectionContext inspectionContext, ...@@ -567,7 +596,7 @@ public DkmClrValue InstantiateProxyType(DkmInspectionContext inspectionContext,
BindingFlags.NonPublic | BindingFlags.NonPublic |
BindingFlags.Public; BindingFlags.Public;
var constructor = lmrType.GetConstructors(bindingFlags).Single(); var constructor = lmrType.GetConstructors(bindingFlags).Single();
var value = constructor.Invoke(bindingFlags, null, new[] { _rawValue }, null); var value = constructor.Invoke(bindingFlags, null, new[] { RawValue }, null);
return new DkmClrValue( return new DkmClrValue(
value, value,
value, value,
...@@ -688,8 +717,49 @@ private unsafe static object Dereference(IntPtr ptr, Type elementType) ...@@ -688,8 +717,49 @@ private unsafe static object Dereference(IntPtr ptr, Type elementType)
} }
} }
public void Close() private static DkmEvaluationResultAccessType GetFieldAccess(Microsoft.VisualStudio.Debugger.Metadata.FieldInfo field)
{ {
if (field.IsPrivate)
{
return DkmEvaluationResultAccessType.Private;
}
else if (field.IsFamily)
{
return DkmEvaluationResultAccessType.Protected;
}
else if (field.IsAssembly)
{
return DkmEvaluationResultAccessType.Internal;
}
else
{
return DkmEvaluationResultAccessType.Public;
}
}
private static DkmEvaluationResultAccessType GetPropertyAccess(Microsoft.VisualStudio.Debugger.Metadata.PropertyInfo property)
{
return GetMethodAccess(property.GetGetMethod(nonPublic: true));
}
private static DkmEvaluationResultAccessType GetMethodAccess(Microsoft.VisualStudio.Debugger.Metadata.MethodBase method)
{
if (method.IsPrivate)
{
return DkmEvaluationResultAccessType.Private;
}
else if (method.IsFamily)
{
return DkmEvaluationResultAccessType.Protected;
}
else if (method.IsAssembly)
{
return DkmEvaluationResultAccessType.Internal;
}
else
{
return DkmEvaluationResultAccessType.Public;
}
} }
} }
} }
...@@ -10,10 +10,34 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation ...@@ -10,10 +10,34 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation
{ {
public abstract class DkmEvaluationResult : DkmDataContainer public abstract class DkmEvaluationResult : DkmDataContainer
{ {
public string FullName { get; internal set; } public readonly DkmInspectionContext InspectionContext;
public string Name { get; internal set; } public readonly DkmStackWalkFrame StackFrame;
public DkmInspectionContext InspectionContext { get; internal set; } public readonly string Name;
public DkmStackWalkFrame StackFrame { get; internal set; } public readonly string FullName;
public readonly DkmEvaluationResultFlags Flags;
public readonly string Type;
internal DkmEvaluationResult(
DkmInspectionContext InspectionContext,
DkmStackWalkFrame StackFrame,
string Name,
string FullName,
DkmEvaluationResultFlags Flags,
string Type,
DkmDataItem DataItem)
{
this.InspectionContext = InspectionContext;
this.StackFrame = StackFrame;
this.Name = Name;
this.FullName = FullName;
this.Flags = Flags;
this.Type = Type;
if (DataItem != null)
{
this.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
}
}
public virtual void GetChildren(DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) public virtual void GetChildren(DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
{ {
......
...@@ -9,28 +9,41 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation ...@@ -9,28 +9,41 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation
{ {
public class DkmFailedEvaluationResult : DkmEvaluationResult public class DkmFailedEvaluationResult : DkmEvaluationResult
{ {
public string ErrorMessage { get; private set; } public readonly string ErrorMessage;
public DkmEvaluationResultFlags Flags { get; private set; }
public string Type { get; private set; }
public static DkmFailedEvaluationResult Create(DkmInspectionContext InspectionContext, DkmStackWalkFrame StackFrame, string Name, string FullName, string ErrorMessage, DkmEvaluationResultFlags Flags, string Type, DkmDataItem DataItem) private DkmFailedEvaluationResult(
DkmInspectionContext inspectionContext,
DkmStackWalkFrame stackFrame,
string name,
string fullName,
string errorMessage,
DkmEvaluationResultFlags flags,
string type,
DkmDataItem dataItem) :
base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
{ {
DkmFailedEvaluationResult result = new DkmFailedEvaluationResult this.ErrorMessage = errorMessage;
{ }
InspectionContext = InspectionContext,
Name = Name,
FullName = FullName,
ErrorMessage = ErrorMessage,
Flags = Flags,
Type = Type
};
if (DataItem != null)
{
result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
}
return result; public static DkmFailedEvaluationResult Create(
DkmInspectionContext InspectionContext,
DkmStackWalkFrame StackFrame,
string Name,
string FullName,
string ErrorMessage,
DkmEvaluationResultFlags Flags,
string Type,
DkmDataItem DataItem)
{
return new DkmFailedEvaluationResult(
InspectionContext,
StackFrame,
Name,
FullName,
ErrorMessage,
Flags,
Type,
DataItem);
} }
} }
} }
...@@ -9,28 +9,45 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation ...@@ -9,28 +9,45 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation
{ {
public class DkmIntermediateEvaluationResult : DkmEvaluationResult public class DkmIntermediateEvaluationResult : DkmEvaluationResult
{ {
public string Expression { get; private set; } public readonly string Expression;
public DkmLanguage IntermediateLanguage { get; private set; } public readonly DkmLanguage IntermediateLanguage;
public DkmRuntimeInstance TargetRuntime { get; private set; } public readonly DkmRuntimeInstance TargetRuntime;
public static DkmIntermediateEvaluationResult Create(DkmInspectionContext InspectionContext, DkmStackWalkFrame StackFrame, string Name, string FullName, string Expression, DkmLanguage IntermediateLanguage, DkmRuntimeInstance TargetRuntime, DkmDataItem DataItem)
{
DkmIntermediateEvaluationResult result = new DkmIntermediateEvaluationResult
{
InspectionContext = InspectionContext,
Name = Name,
FullName = FullName,
Expression = Expression,
IntermediateLanguage = IntermediateLanguage,
TargetRuntime = TargetRuntime
};
if (DataItem != null) private DkmIntermediateEvaluationResult(
{ DkmInspectionContext inspectionContext,
result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem); DkmStackWalkFrame stackFrame,
} string name,
string fullName,
string expression,
DkmLanguage intermediateLanguage,
DkmRuntimeInstance targetRuntime,
DkmDataItem dataItem) :
base(inspectionContext, stackFrame, name, fullName, DkmEvaluationResultFlags.None, null, dataItem)
{
this.Expression = expression;
this.IntermediateLanguage = intermediateLanguage;
this.TargetRuntime = targetRuntime;
}
return result; public static DkmIntermediateEvaluationResult Create(
DkmInspectionContext InspectionContext,
DkmStackWalkFrame StackFrame,
string Name,
string FullName,
string Expression,
DkmLanguage IntermediateLanguage,
DkmRuntimeInstance TargetRuntime,
DkmDataItem DataItem)
{
return new DkmIntermediateEvaluationResult(
InspectionContext,
StackFrame,
Name,
FullName,
Expression,
IntermediateLanguage,
TargetRuntime,
DataItem);
} }
} }
} }
...@@ -27,9 +27,17 @@ public enum DkmDataCreationDisposition ...@@ -27,9 +27,17 @@ public enum DkmDataCreationDisposition
namespace Microsoft.VisualStudio.Debugger.Evaluation namespace Microsoft.VisualStudio.Debugger.Evaluation
{ {
public enum DkmEvaluationResultAccessType { } public enum DkmEvaluationResultAccessType
public enum DkmEvaluationResultStorageType { } {
public enum DkmEvaluationResultTypeModifierFlags { } None = 0,
Public,
Private,
Protected,
Internal,
}
public enum DkmEvaluationResultStorageType { None = 0 }
public enum DkmEvaluationResultTypeModifierFlags { None = 0 }
public class DkmDataAddress { } public class DkmDataAddress { }
} }
......
...@@ -10,34 +10,77 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation ...@@ -10,34 +10,77 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation
{ {
public class DkmSuccessEvaluationResult : DkmEvaluationResult public class DkmSuccessEvaluationResult : DkmEvaluationResult
{ {
public DkmEvaluationResultCategory Category { get; private set; } public readonly string Value;
public string EditableValue { get; private set; } public readonly string EditableValue;
public DkmEvaluationResultFlags Flags { get; private set; } public readonly DkmEvaluationResultCategory Category;
public string Type { get; private set; } public readonly DkmEvaluationResultAccessType Access;
public string Value { get; private set; } public readonly DkmEvaluationResultStorageType StorageType;
public ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers { get; private set; } public readonly DkmEvaluationResultTypeModifierFlags TypeModifierFlags;
public readonly ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers;
public static DkmSuccessEvaluationResult Create(DkmInspectionContext InspectionContext, DkmStackWalkFrame StackFrame, string Name, string FullName, DkmEvaluationResultFlags Flags, string Value, string EditableValue, string Type, DkmEvaluationResultCategory Category, DkmEvaluationResultAccessType Access, DkmEvaluationResultStorageType StorageType, DkmEvaluationResultTypeModifierFlags TypeModifierFlags, DkmDataAddress Address, ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers, ReadOnlyCollection<DkmModuleInstance> ExternalModules, DkmDataItem DataItem) private DkmSuccessEvaluationResult(
DkmInspectionContext inspectionContext,
DkmStackWalkFrame stackFrame,
string name,
string fullName,
DkmEvaluationResultFlags flags,
string value,
string editableValue,
string type,
DkmEvaluationResultCategory category,
DkmEvaluationResultAccessType access,
DkmEvaluationResultStorageType storageType,
DkmEvaluationResultTypeModifierFlags typeModifierFlags,
DkmDataAddress address,
ReadOnlyCollection<DkmCustomUIVisualizerInfo> customUIVisualizers,
ReadOnlyCollection<DkmModuleInstance> externalModules,
DkmDataItem dataItem) :
base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
{ {
DkmSuccessEvaluationResult result = new DkmSuccessEvaluationResult this.Value = value;
{ this.EditableValue = editableValue;
InspectionContext = InspectionContext, this.Category = category;
Name = Name, this.Access = access;
FullName = FullName, this.StorageType = storageType;
Flags = Flags, this.TypeModifierFlags = typeModifierFlags;
Value = Value, this.CustomUIVisualizers = customUIVisualizers;
Type = Type, }
Category = Category,
EditableValue = EditableValue,
CustomUIVisualizers = CustomUIVisualizers
};
if (DataItem != null)
{
result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
}
return result; public static DkmSuccessEvaluationResult Create(
DkmInspectionContext InspectionContext,
DkmStackWalkFrame StackFrame,
string Name,
string FullName,
DkmEvaluationResultFlags Flags,
string Value,
string EditableValue,
string Type,
DkmEvaluationResultCategory Category,
DkmEvaluationResultAccessType Access,
DkmEvaluationResultStorageType StorageType,
DkmEvaluationResultTypeModifierFlags TypeModifierFlags,
DkmDataAddress Address,
ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers,
ReadOnlyCollection<DkmModuleInstance> ExternalModules,
DkmDataItem DataItem)
{
return new DkmSuccessEvaluationResult(
InspectionContext,
StackFrame,
Name,
FullName,
Flags,
Value,
EditableValue,
Type,
Category,
Access,
StorageType,
TypeModifierFlags,
Address,
CustomUIVisualizers,
ExternalModules,
DataItem);
} }
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.VisualStudio.Debugger; using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr; using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
...@@ -55,7 +56,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont ...@@ -55,7 +56,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
string alias = null, string alias = null,
DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None, DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None,
DkmClrValueFlags valueFlags = DkmClrValueFlags.None, DkmClrValueFlags valueFlags = DkmClrValueFlags.None,
bool isComObject = false) ulong nativeComPointer = 0)
{ {
return new DkmClrValue( return new DkmClrValue(
value, value,
...@@ -65,7 +66,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont ...@@ -65,7 +66,7 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont
_formatter, _formatter,
evalFlags, evalFlags,
valueFlags, valueFlags,
isComObject); nativeComPointer: nativeComPointer);
} }
internal DkmClrValue CreateErrorValue( internal DkmClrValue CreateErrorValue(
...@@ -237,13 +238,17 @@ internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumConte ...@@ -237,13 +238,17 @@ internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumConte
return getItemsResult.Items; return getItemsResult.Items;
} }
private const DkmEvaluationResultCategory UnspecifiedCategory = (DkmEvaluationResultCategory)(-1);
private const DkmEvaluationResultAccessType UnspecifiedAccessType = (DkmEvaluationResultAccessType)(-1);
internal static DkmEvaluationResult EvalResult( internal static DkmEvaluationResult EvalResult(
string name, string name,
string value, string value,
string type, string type,
string fullName, string fullName,
DkmEvaluationResultFlags flags = DkmEvaluationResultFlags.None, DkmEvaluationResultFlags flags = DkmEvaluationResultFlags.None,
DkmEvaluationResultCategory category = DkmEvaluationResultCategory.Other, DkmEvaluationResultCategory category = UnspecifiedCategory,
DkmEvaluationResultAccessType access = UnspecifiedAccessType,
string editableValue = null, string editableValue = null,
DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = null) DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = null)
{ {
...@@ -257,7 +262,7 @@ internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumConte ...@@ -257,7 +262,7 @@ internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumConte
editableValue, editableValue,
type, type,
category, category,
default(DkmEvaluationResultAccessType), access,
default(DkmEvaluationResultStorageType), default(DkmEvaluationResultStorageType),
default(DkmEvaluationResultTypeModifierFlags), default(DkmEvaluationResultTypeModifierFlags),
null, null,
...@@ -314,36 +319,83 @@ internal static void Verify(IReadOnlyList<DkmEvaluationResult> actual, params Dk ...@@ -314,36 +319,83 @@ internal static void Verify(IReadOnlyList<DkmEvaluationResult> actual, params Dk
} }
catch catch
{ {
foreach (DkmSuccessEvaluationResult result in actual) foreach (var result in actual)
{ {
var optionalArgumentsTemplate = string.Empty; Console.WriteLine("{0}, ", ToString(result));
if (result.Flags != DkmEvaluationResultFlags.None)
{
optionalArgumentsTemplate += ", {4}";
}
if (result.Category != DkmEvaluationResultCategory.Other)
{
optionalArgumentsTemplate += ", {5}";
}
if (result.EditableValue != null)
{
optionalArgumentsTemplate += ", editableValue: {6}";
}
var evalResultTemplate = "EvalResult({0}, {1}, {2}, {3}" + optionalArgumentsTemplate + "),";
var resultValue = (result.Value == null) ? "null" : Quote(Escape(result.Value));
Console.WriteLine(evalResultTemplate,
Quote(result.Name),
resultValue, Quote(result.Type),
(result.FullName != null) ? Quote(Escape(result.FullName)) : "null",
FormatEnumValue(result.Flags),
FormatEnumValue(result.Category),
Quote(result.EditableValue));
} }
throw; throw;
} }
} }
private static string ToString(DkmEvaluationResult result)
{
var success = result as DkmSuccessEvaluationResult;
return (success != null) ? ToString(success) : ToString((DkmFailedEvaluationResult)result);
}
private static string ToString(DkmSuccessEvaluationResult result)
{
var pooledBuilder = PooledStringBuilder.GetInstance();
var builder = pooledBuilder.Builder;
builder.Append("EvalResult(");
builder.Append(Quote(result.Name));
builder.Append(", ");
builder.Append((result.Value == null) ? "null" : Quote(Escape(result.Value)));
builder.Append(", ");
builder.Append(Quote(result.Type));
builder.Append(", ");
builder.Append((result.FullName != null) ? Quote(Escape(result.FullName)) : "null");
if (result.Flags != DkmEvaluationResultFlags.None)
{
builder.Append(", ");
builder.Append(FormatEnumValue(result.Flags));
}
if (result.Category != DkmEvaluationResultCategory.Other)
{
builder.Append(", ");
builder.Append(FormatEnumValue(result.Category));
}
if (result.Access != DkmEvaluationResultAccessType.None)
{
builder.Append(", ");
builder.Append(FormatEnumValue(result.Access));
}
if (result.EditableValue != null)
{
builder.Append(", ");
builder.Append(Quote(result.EditableValue));
}
builder.Append(")");
return pooledBuilder.ToStringAndFree();
}
private static string ToString(DkmFailedEvaluationResult result)
{
var pooledBuilder = PooledStringBuilder.GetInstance();
var builder = pooledBuilder.Builder;
builder.Append("EvalFailedResult(");
builder.Append(Quote(result.Name));
builder.Append(", ");
builder.Append(Quote(result.ErrorMessage));
if (result.Type != null)
{
builder.Append(", ");
builder.Append(Quote(result.Type));
}
if (result.FullName != null)
{
builder.Append(", ");
builder.Append(Quote(Escape(result.FullName)));
}
if (result.Flags != DkmEvaluationResultFlags.None)
{
builder.Append(", ");
builder.Append(FormatEnumValue(result.Flags));
}
builder.Append(")");
return pooledBuilder.ToStringAndFree();
}
private static string Escape(string str) private static string Escape(string str)
{ {
return str.Replace("\"", "\\\""); return str.Replace("\"", "\\\"");
...@@ -373,9 +425,15 @@ internal static void Verify(DkmEvaluationResult actual, DkmEvaluationResult expe ...@@ -373,9 +425,15 @@ internal static void Verify(DkmEvaluationResult actual, DkmEvaluationResult expe
Assert.Equal(expectedSuccess.Value, actualSuccess.Value); Assert.Equal(expectedSuccess.Value, actualSuccess.Value);
Assert.Equal(expectedSuccess.Type, actualSuccess.Type); Assert.Equal(expectedSuccess.Type, actualSuccess.Type);
Assert.Equal(expectedSuccess.Flags, actualSuccess.Flags); Assert.Equal(expectedSuccess.Flags, actualSuccess.Flags);
Assert.Equal(expectedSuccess.Category, actualSuccess.Category); if (expectedSuccess.Category != UnspecifiedCategory)
{
Assert.Equal(expectedSuccess.Category, actualSuccess.Category);
}
if (expectedSuccess.Access != UnspecifiedAccessType)
{
Assert.Equal(expectedSuccess.Access, actualSuccess.Access);
}
Assert.Equal(expectedSuccess.EditableValue, actualSuccess.EditableValue); Assert.Equal(expectedSuccess.EditableValue, actualSuccess.EditableValue);
// Verify the DebuggerVisualizerAttribute
Assert.True( Assert.True(
(expectedSuccess.CustomUIVisualizers == actualSuccess.CustomUIVisualizers) || (expectedSuccess.CustomUIVisualizers == actualSuccess.CustomUIVisualizers) ||
(expectedSuccess.CustomUIVisualizers != null && actualSuccess.CustomUIVisualizers != null && (expectedSuccess.CustomUIVisualizers != null && actualSuccess.CustomUIVisualizers != null &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册