From 827cd20623e942636005efe79f135b2d991e078e Mon Sep 17 00:00:00 2001 From: Patrick Nelson Date: Fri, 6 Mar 2015 13:51:43 -0800 Subject: [PATCH] Implement support for inspecting native COM objects in the new EE. The native view of the COM object now shows up under a "Native View" node. --- .../Test/ResultProvider/NativeViewTests.cs | 64 +++++++++++++++++ .../Expansion/NativeViewExpansion.cs | 69 +++++++++++++++++++ .../Debugger/Engine/DkmCompilerId.cs | 21 ++++++ .../Debugger/Engine/DkmEngineSettings.cs | 17 +++++ .../Engine/DkmIntermediateEvaluationResult.cs | 36 ++++++++++ .../Debugger/Engine/DkmLanguage.cs | 17 +++++ .../Debugger/Engine/DkmLanguageId.cs | 20 ++++++ .../Debugger/Engine/DkmProcess.cs | 34 +++++++++ .../Debugger/Engine/DkmRuntimeInstance.cs | 23 +++++++ .../Debugger/Engine/DkmVendorId.cs | 20 ++++++ .../CSharpResultProviderTest.csproj | 1 + .../Expansion/MemberExpansion.cs | 5 ++ .../Helpers/EvalResultDataItem.cs | 1 + .../ResultProvider/Resources.Designer.cs | 18 +++++ .../Core/Source/ResultProvider/Resources.resx | 8 +++ .../Source/ResultProvider/ResultProvider.cs | 17 +++++ .../ResultProvider/ResultProvider.projitems | 1 + .../Debugger/Engine/DkmClrRuntimeInstance.cs | 6 +- .../Debugger/Engine/DkmClrValue.cs | 5 +- .../Debugger/Engine/DkmInspectionContext.cs | 4 +- .../ResultProvider/ResultProviderTestBase.cs | 46 +++++++++++-- .../ResultProviderTestUtilities.csproj | 9 +++ 22 files changed, 432 insertions(+), 10 deletions(-) create mode 100644 Src/ExpressionEvaluator/CSharp/Test/ResultProvider/NativeViewTests.cs create mode 100644 Src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/NativeViewExpansion.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmCompilerId.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmEngineSettings.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmIntermediateEvaluationResult.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguage.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguageId.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmProcess.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmRuntimeInstance.cs create mode 100644 Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmVendorId.cs diff --git a/Src/ExpressionEvaluator/CSharp/Test/ResultProvider/NativeViewTests.cs b/Src/ExpressionEvaluator/CSharp/Test/ResultProvider/NativeViewTests.cs new file mode 100644 index 00000000000..42cffc0a007 --- /dev/null +++ b/Src/ExpressionEvaluator/CSharp/Test/ResultProvider/NativeViewTests.cs @@ -0,0 +1,64 @@ +// 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.CodeAnalysis.ExpressionEvaluator; +using Microsoft.VisualStudio.Debugger.Clr; +using Microsoft.VisualStudio.Debugger.Evaluation; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public class NativeViewTests : CSharpResultProviderTestBase + { + [Fact] + public void NativeView1() + { + TestNativeView(true); + } + + [Fact] + public void NativeViewManagedOnly() + { + TestNativeView(false); + } + + private void TestNativeView(bool enableNativeDebugging) + { + var source = +@"using System.Collections; +class C +{ +}"; + using (new EnsureEnglishUICulture()) + { + var assembly = GetAssembly(source); + var assemblies = ReflectionUtilities.GetMscorlibAndSystemCore(assembly); + using (ReflectionUtilities.LoadAssemblies(assemblies)) + { + var runtime = new DkmClrRuntimeInstance(assemblies, enableNativeDebugging: enableNativeDebugging); + var inspectionContext = CreateDkmInspectionContext(runtimeInstance: runtime); + var type = assembly.GetType("C"); + var value = CreateDkmClrValue( + value: type.Instantiate(), + type: runtime.GetType((TypeImpl)type), + isComObject: true); + var evalResult = FormatResult("o", value, inspectionContext: inspectionContext); + Verify(evalResult, + EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable)); + var children = GetChildren(evalResult, inspectionContext); + if (enableNativeDebugging) + { + DkmLanguage language = new DkmLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); + Verify(children, + EvalIntermediateResult("Native View", "{C++}(IUnknown*)0x00000001", "(IUnknown*)0x00000001", language)); + } + else + { + Verify(children, + EvalFailedResult("Native View", "To inspect the native object, enable native code debugging.")); + } + } + } + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/NativeViewExpansion.cs b/Src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/NativeViewExpansion.cs new file mode 100644 index 00000000000..0b4eb18e132 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/NativeViewExpansion.cs @@ -0,0 +1,69 @@ +// 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; + +namespace Microsoft.CodeAnalysis.ExpressionEvaluator +{ + internal sealed class NativeViewExpansion : Expansion + { + internal override void GetRows( + ResultProvider resultProvider, + ArrayBuilder rows, + DkmInspectionContext inspectionContext, + EvalResultDataItem parent, + DkmClrValue value, + int startIndex, + int count, + bool visitAll, + ref int index) + { + if (InRange(startIndex, count, index)) + { + rows.Add(GetRow(resultProvider, inspectionContext, value, parent)); + } + + index++; + } + + private EvalResultDataItem GetRow( + ResultProvider resultProvider, + DkmInspectionContext inspectionContext, + DkmClrValue comObject, + EvalResultDataItem parent) + { + try + { + inspectionContext.RuntimeInstance.Process.GetNativeRuntimeInstance(); + } + catch (DkmException) + { + // Native View requires native debugging to be enabled. + return new EvalResultDataItem(Resources.NativeView, Resources.NativeViewNotNativeDebugging); + } + + var name = "(IUnknown*)0x" + string.Format(IntPtr.Size == 4 ? "{0:X8}" : "{0:X16}", comObject.NativeComPointer); + var fullName = "{C++}" + name; + + return new EvalResultDataItem( + ExpansionKind.NativeView, + name: name, + typeDeclaringMember: null, + declaredType: comObject.Type.GetLmrType(), + parent: null, + value: comObject, + displayValue: null, + expansion: this, + childShouldParenthesize: false, + fullName: fullName, + childFullNamePrefixOpt: fullName, + formatSpecifiers: Formatter.NoFormatSpecifiers, + category: DkmEvaluationResultCategory.Data, + flags: DkmEvaluationResultFlags.ReadOnly, + editableValue: null, + inspectionContext: inspectionContext); + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmCompilerId.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmCompilerId.cs new file mode 100644 index 00000000000..1067f7cccf9 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmCompilerId.cs @@ -0,0 +1,21 @@ +// 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.Evaluation +{ + public struct DkmCompilerId + { + public readonly Guid LanguageId; + public readonly Guid VendorId; + + public DkmCompilerId(Guid vendorId, Guid languageId) + { + VendorId = vendorId; + LanguageId = languageId; + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmEngineSettings.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmEngineSettings.cs new file mode 100644 index 00000000000..1c6fde51a87 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmEngineSettings.cs @@ -0,0 +1,17 @@ +// 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 Microsoft.VisualStudio.Debugger.Evaluation; + +namespace Microsoft.VisualStudio.Debugger +{ + public class DkmEngineSettings + { + public DkmLanguage GetLanguage(DkmCompilerId compilerId) + { + return new DkmLanguage(compilerId); + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmIntermediateEvaluationResult.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmIntermediateEvaluationResult.cs new file mode 100644 index 00000000000..b106ac78a18 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmIntermediateEvaluationResult.cs @@ -0,0 +1,36 @@ +// 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 Microsoft.VisualStudio.Debugger.CallStack; + +namespace Microsoft.VisualStudio.Debugger.Evaluation +{ + public class DkmIntermediateEvaluationResult : DkmEvaluationResult + { + public string Expression { get; private set; } + public DkmLanguage IntermediateLanguage { get; private set; } + public DkmRuntimeInstance TargetRuntime { get; private set; } + + 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) + { + result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem); + } + + return result; + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguage.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguage.cs new file mode 100644 index 00000000000..84487eea05b --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguage.cs @@ -0,0 +1,17 @@ +// 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 +namespace Microsoft.VisualStudio.Debugger.Evaluation +{ + public class DkmLanguage + { + public readonly DkmCompilerId Id; + + internal DkmLanguage(DkmCompilerId compilerId) + { + Id = compilerId; + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguageId.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguageId.cs new file mode 100644 index 00000000000..015fc078026 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmLanguageId.cs @@ -0,0 +1,20 @@ +// 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.Evaluation +{ + public static class DkmLanguageId + { + public static Guid Cpp + { + get + { + return new Guid("3A12D0B7-C26C-11D0-B442-00A0244A1DD2"); + } + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmProcess.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmProcess.cs new file mode 100644 index 00000000000..87d714878b9 --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmProcess.cs @@ -0,0 +1,34 @@ +// 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 + +namespace Microsoft.VisualStudio.Debugger +{ + public class DkmProcess + { + public readonly DkmEngineSettings EngineSettings = new DkmEngineSettings(); + + private readonly bool _nativeDebuggingEnabled; + + public DkmProcess() + { + } + + public DkmProcess(bool enableNativeDebugging) + { + _nativeDebuggingEnabled = enableNativeDebugging; + } + + public DkmRuntimeInstance GetNativeRuntimeInstance() + { + if (!_nativeDebuggingEnabled) + { + throw new DkmException(DkmExceptionCode.E_XAPI_DATA_ITEM_NOT_FOUND); + } + + return null; // Value isn't required for testing + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmRuntimeInstance.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmRuntimeInstance.cs new file mode 100644 index 00000000000..c16fbb1cdfb --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmRuntimeInstance.cs @@ -0,0 +1,23 @@ +// 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 + +namespace Microsoft.VisualStudio.Debugger +{ + public class DkmRuntimeInstance + { + internal static readonly DkmProcess DefaultProcess = new DkmProcess(); + internal static readonly DkmProcess ProcessWithNativeDebugging = new DkmProcess(enableNativeDebugging: true); + + public readonly DkmProcess Process; + + public DkmRuntimeInstance(bool enableNativeDebugging) + { + Process = enableNativeDebugging ? + ProcessWithNativeDebugging : + DefaultProcess; + } + } +} diff --git a/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmVendorId.cs b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmVendorId.cs new file mode 100644 index 00000000000..047d07524aa --- /dev/null +++ b/Src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmVendorId.cs @@ -0,0 +1,20 @@ +// 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.Evaluation +{ + public static class DkmVendorId + { + public static Guid Microsoft + { + get + { + return new Guid("994B45C4-E6E9-11D2-903F-00C04FA302A1"); + } + } + } +} diff --git a/src/ExpressionEvaluator/CSharp/Test/ResultProvider/CSharpResultProviderTest.csproj b/src/ExpressionEvaluator/CSharp/Test/ResultProvider/CSharpResultProviderTest.csproj index 6b768e2f981..60d981fc6cc 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ResultProvider/CSharpResultProviderTest.csproj +++ b/src/ExpressionEvaluator/CSharp/Test/ResultProvider/CSharpResultProviderTest.csproj @@ -103,6 +103,7 @@ + diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/MemberExpansion.cs b/src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/MemberExpansion.cs index 12100f7b60a..0641224f149 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/MemberExpansion.cs +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/MemberExpansion.cs @@ -108,6 +108,11 @@ internal sealed class MemberExpansion : Expansion expansions.Add(staticMembersExpansion); } + if (value.NativeComPointer != 0) + { + expansions.Add(new NativeViewExpansion()); + } + if (nonPublicInstanceExpansion != null) { expansions.Add(nonPublicInstanceExpansion); diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/Helpers/EvalResultDataItem.cs b/src/ExpressionEvaluator/Core/Source/ResultProvider/Helpers/EvalResultDataItem.cs index 3886d9a975b..61dec591d2e 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/Helpers/EvalResultDataItem.cs +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/Helpers/EvalResultDataItem.cs @@ -13,6 +13,7 @@ internal enum ExpansionKind { Default, Error, + NativeView, NonPublicMembers, PointerDereference, RawView, diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.Designer.cs b/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.Designer.cs index 97bfccc8f77..371b34603fe 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.Designer.cs +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.Designer.cs @@ -87,6 +87,24 @@ internal class Resources { } } + /// + /// Looks up a localized string similar to Native View. + /// + internal static string NativeView { + get { + return ResourceManager.GetString("NativeView", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to To inspect the native object, enable native code debugging.. + /// + internal static string NativeViewNotNativeDebugging { + get { + return ResourceManager.GetString("NativeViewNotNativeDebugging", resourceCulture); + } + } + /// /// Looks up a localized string similar to Non-Public members. /// diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.resx b/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.resx index e380fdbdad9..b24f03a0018 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.resx +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/Resources.resx @@ -129,6 +129,14 @@ Cannot dereference '{0}'. The pointer is not valid. Invalid pointer dereference + + Native View + Native COM object expansion + + + To inspect the native object, enable native code debugging. + Display value of Native View node when native debugging is not enabled + Non-Public members Non-public type members diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.cs b/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.cs index 37fa6910771..53f1cfe0595 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.cs +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.cs @@ -132,6 +132,7 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work Type: null, DataItem: null)); break; + case ExpansionKind.NativeView: case ExpansionKind.NonPublicMembers: case ExpansionKind.StaticMembers: completionRoutine(CreateEvaluationResult( @@ -215,6 +216,22 @@ private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, Work Type: typeName, 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 { ReadOnlyCollection customUIVisualizers = null; diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.projitems b/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.projitems index af4c39acc23..433b8517f9b 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.projitems +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/ResultProvider.projitems @@ -18,6 +18,7 @@ + diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrRuntimeInstance.cs b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrRuntimeInstance.cs index 4abea4fd4dd..2e98b073bde 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrRuntimeInstance.cs +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrRuntimeInstance.cs @@ -17,7 +17,7 @@ namespace Microsoft.VisualStudio.Debugger.Clr internal delegate DkmClrModuleInstance GetModuleDelegate(DkmClrRuntimeInstance runtime, Assembly assembly); - public class DkmClrRuntimeInstance + public class DkmClrRuntimeInstance : DkmRuntimeInstance { internal static readonly DkmClrRuntimeInstance DefaultRuntime = new DkmClrRuntimeInstance(new Assembly[0]); @@ -30,7 +30,9 @@ public class DkmClrRuntimeInstance internal DkmClrRuntimeInstance( Assembly[] assemblies, GetModuleDelegate getModule = null, - GetMemberValueDelegate getMemberValue = null) + GetMemberValueDelegate getMemberValue = null, + bool enableNativeDebugging = false) + : base(enableNativeDebugging) { if (getModule == null) { diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrValue.cs b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrValue.cs index ee69eee2f55..3e5107d6e8a 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrValue.cs +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmClrValue.cs @@ -30,7 +30,8 @@ public class DkmClrValue : DkmDataContainer string alias, IDkmClrFormatter formatter, DkmEvaluationResultFlags evalFlags, - DkmClrValueFlags valueFlags) + DkmClrValueFlags valueFlags, + bool isComObject = false) { Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic)); Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId)); @@ -44,6 +45,7 @@ public class DkmClrValue : DkmDataContainer this.Alias = alias; this.EvalFlags = evalFlags; this.ValueFlags = valueFlags; + this.NativeComPointer = isComObject ? 1UL : 0; } public readonly DkmEvaluationResultFlags EvalFlags; @@ -57,6 +59,7 @@ public class DkmClrValue : DkmDataContainer public readonly DkmDataAddress Address; public readonly object HostObjectValue; public readonly string Alias; + public readonly ulong NativeComPointer; private readonly IDkmClrFormatter _formatter; private readonly object _rawValue; diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmInspectionContext.cs b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmInspectionContext.cs index 31bff8281f3..489ed6c1c01 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmInspectionContext.cs +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/Debugger/Engine/DkmInspectionContext.cs @@ -18,16 +18,18 @@ namespace Microsoft.VisualStudio.Debugger.Evaluation [Guid("0807c826-3338-dd99-2f3a-202ba8fb9da7")] public class DkmInspectionContext { - internal DkmInspectionContext(IDkmClrFormatter formatter, DkmEvaluationFlags evaluationFlags, uint radix) + internal DkmInspectionContext(IDkmClrFormatter formatter, DkmEvaluationFlags evaluationFlags, uint radix, DkmRuntimeInstance runtimeInstance = null) { _formatter = formatter; this.EvaluationFlags = evaluationFlags; this.Radix = radix; + this.RuntimeInstance = runtimeInstance ?? DkmClrRuntimeInstance.DefaultRuntime; } private readonly IDkmClrFormatter _formatter; public readonly DkmEvaluationFlags EvaluationFlags; + public readonly DkmRuntimeInstance RuntimeInstance; // // Summary: diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestBase.cs b/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestBase.cs index c9b0ba177e8..4487356e50c 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestBase.cs +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestBase.cs @@ -54,7 +54,8 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont DkmClrType type, string alias = null, DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None, - DkmClrValueFlags valueFlags = DkmClrValueFlags.None) + DkmClrValueFlags valueFlags = DkmClrValueFlags.None, + bool isComObject = false) { return new DkmClrValue( value, @@ -63,7 +64,8 @@ internal ResultProviderTestBase(ResultProvider resultProvider, DkmInspectionCont alias, _formatter, evalFlags, - valueFlags); + valueFlags, + isComObject); } internal DkmClrValue CreateErrorValue( @@ -128,14 +130,21 @@ internal DkmClrValue GetValueForUnderlyingString(object value, Type type) #region ResultProvider Tests - internal DkmInspectionContext CreateDkmInspectionContext(DkmEvaluationFlags flags = DkmEvaluationFlags.None, uint radix = 10) + internal DkmInspectionContext CreateDkmInspectionContext( + DkmEvaluationFlags flags = DkmEvaluationFlags.None, + uint radix = 10, + DkmRuntimeInstance runtimeInstance = null) { - return CreateDkmInspectionContext(_formatter, flags, radix); + return CreateDkmInspectionContext(_formatter, flags, radix, runtimeInstance); } - internal static DkmInspectionContext CreateDkmInspectionContext(IDkmClrFormatter formatter, DkmEvaluationFlags flags, uint radix) + internal static DkmInspectionContext CreateDkmInspectionContext( + IDkmClrFormatter formatter, + DkmEvaluationFlags flags, + uint radix, + DkmRuntimeInstance runtimeInstance = null) { - return new DkmInspectionContext(formatter, flags, radix); + return new DkmInspectionContext(formatter, flags, radix, runtimeInstance); } internal DkmEvaluationResult FormatResult(string name, DkmClrValue value, DkmClrType declaredType = null, DkmInspectionContext inspectionContext = null) @@ -256,6 +265,23 @@ internal DkmEvaluationResult[] GetItems(DkmEvaluationResultEnumContext enumConte null); } + internal static DkmIntermediateEvaluationResult EvalIntermediateResult( + string name, + string fullName, + string expression, + DkmLanguage language) + { + return DkmIntermediateEvaluationResult.Create( + InspectionContext: null, + StackFrame: null, + Name: name, + FullName: fullName, + Expression: expression, + IntermediateLanguage: language, + TargetRuntime: null, + DataItem: null); + } + internal static DkmEvaluationResult EvalFailedResult( string name, string message, @@ -339,6 +365,7 @@ internal static void Verify(DkmEvaluationResult actual, DkmEvaluationResult expe Assert.Equal(expected.Name, actual.Name); Assert.Equal(expected.FullName, actual.FullName); var expectedSuccess = expected as DkmSuccessEvaluationResult; + var expectedIntermediate = expected as DkmIntermediateEvaluationResult; if (expectedSuccess != null) { var actualSuccess = (DkmSuccessEvaluationResult)actual; @@ -353,6 +380,13 @@ internal static void Verify(DkmEvaluationResult actual, DkmEvaluationResult expe (expectedSuccess.CustomUIVisualizers != null && actualSuccess.CustomUIVisualizers != null && expectedSuccess.CustomUIVisualizers.SequenceEqual(actualSuccess.CustomUIVisualizers, CustomUIVisualizerInfoComparer.Instance))); } + else if (expectedIntermediate != null) + { + var actualIntermediate = (DkmIntermediateEvaluationResult)actual; + Assert.Equal(expectedIntermediate.Expression, actualIntermediate.Expression); + Assert.Equal(expectedIntermediate.IntermediateLanguage.Id.LanguageId, actualIntermediate.IntermediateLanguage.Id.LanguageId); + Assert.Equal(expectedIntermediate.IntermediateLanguage.Id.VendorId, actualIntermediate.IntermediateLanguage.Id.VendorId); + } else { var actualFailed = (DkmFailedEvaluationResult)actual; diff --git a/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestUtilities.csproj b/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestUtilities.csproj index e002ad2216d..5a1a8ff4ab8 100644 --- a/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestUtilities.csproj +++ b/src/ExpressionEvaluator/Core/Test/ResultProvider/ResultProviderTestUtilities.csproj @@ -1,4 +1,5 @@  + @@ -83,7 +84,9 @@ + + @@ -111,11 +114,17 @@ + + + + + + -- GitLab