зеркало из https://github.com/microsoft/cppwinrt.git
per request, provide implementation-side visualizations. and always show raw data. (#1128)
This commit is contained in:
Родитель
27adc6b382
Коммит
b69f40d6ec
|
@ -14,6 +14,11 @@
|
|||
<CustomVisualizer Condition="this != 0" VisualizerId="2ec1a02f-997c-4693-840e-88ffa1e21b56"/>
|
||||
<DisplayString Condition="this == 0">null</DisplayString>
|
||||
</Type>
|
||||
<!-- Visualize C++/WinRT object implementations -->
|
||||
<Type Name="winrt::impl::producer<*>">
|
||||
<CustomVisualizer Condition="this != 0" VisualizerId="2ec1a02f-997c-4693-840e-88ffa1e21b56"/>
|
||||
<DisplayString Condition="this == 0">null</DisplayString>
|
||||
</Type>
|
||||
<!--Visualize all raw IInspectable pointers-->
|
||||
<Type Name="IInspectable">
|
||||
<CustomVisualizer Condition="this != 0" VisualizerId="2ec1a02f-997c-4693-840e-88ffa1e21b56"/>
|
||||
|
|
|
@ -207,21 +207,26 @@ HRESULT cppwinrt_visualizer::EvaluateVisualizedExpression(
|
|||
IF_FAIL_RET(pTypeSymbol->get_name(&bstrTypeName));
|
||||
|
||||
// Visualize top-level C++/WinRT objects containing ABI pointers
|
||||
bool isAbiObject;
|
||||
ObjectType objectType;
|
||||
if (wcscmp(bstrTypeName, L"winrt::Windows::Foundation::IInspectable") == 0)
|
||||
{
|
||||
isAbiObject = false;
|
||||
objectType = ObjectType::Projection;
|
||||
}
|
||||
// Visualize nested object properties via raw ABI pointers
|
||||
else if ((wcscmp(bstrTypeName, L"winrt::impl::IInspectable") == 0) ||
|
||||
(wcscmp(bstrTypeName, L"winrt::impl::inspectable_abi") == 0))
|
||||
{
|
||||
isAbiObject = true;
|
||||
objectType = ObjectType::Abi;
|
||||
}
|
||||
// Visualize C++/WinRT object implementations
|
||||
else if (wcsncmp(bstrTypeName, L"winrt::impl::producer<", wcslen(L"winrt::impl::producer<")) == 0)
|
||||
{
|
||||
objectType = ObjectType::Abi;
|
||||
}
|
||||
// Visualize all raw IInspectable pointers
|
||||
else if (wcscmp(bstrTypeName, L"IInspectable") == 0)
|
||||
{
|
||||
isAbiObject = true;
|
||||
objectType = ObjectType::Abi;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -231,7 +236,7 @@ HRESULT cppwinrt_visualizer::EvaluateVisualizedExpression(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
IF_FAIL_RET(object_visualizer::CreateEvaluationResult(pVisualizedExpression, isAbiObject, ppResultObject));
|
||||
IF_FAIL_RET(object_visualizer::CreateEvaluationResult(pVisualizedExpression, objectType, ppResultObject));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -99,14 +99,14 @@ static HRESULT EvaluatePropertyExpression(
|
|||
_In_ PropertyData const& prop,
|
||||
_In_ DkmVisualizedExpression* pExpression,
|
||||
_In_ DkmPointerValueHome* pObject,
|
||||
bool isAbiObject,
|
||||
ObjectType objectType,
|
||||
_Out_ com_ptr<DkmEvaluationResult>& pEvaluationResult
|
||||
)
|
||||
{
|
||||
wchar_t abiAddress[40];
|
||||
auto process = pExpression->RuntimeInstance()->Process();
|
||||
bool is64Bit = ((process->SystemInformation()->Flags() & DefaultPort::DkmSystemInformationFlags::Is64Bit) != 0);
|
||||
swprintf_s(abiAddress, is64Bit ? L"%s0x%I64x" : L"%s0x%08x", isAbiObject ? L"(::IUnknown*)" : L"*(::IUnknown**)", pObject->Address());
|
||||
swprintf_s(abiAddress, is64Bit ? L"%s0x%I64x" : L"%s0x%08x", objectType == ObjectType::Abi ? L"(::IUnknown*)" : L"*(::IUnknown**)", pObject->Address());
|
||||
wchar_t wszEvalText[500];
|
||||
std::wstring propCast;
|
||||
PCWSTR propField;
|
||||
|
@ -174,12 +174,12 @@ static HRESULT EvaluatePropertyString(
|
|||
_In_ PropertyData const& prop,
|
||||
_In_ DkmVisualizedExpression* pExpression,
|
||||
_In_ DkmPointerValueHome* pObject,
|
||||
bool isAbiObject,
|
||||
ObjectType objectType,
|
||||
_Out_ com_ptr<DkmString>& pValue
|
||||
)
|
||||
{
|
||||
com_ptr<DkmEvaluationResult> pEvaluationResult;
|
||||
IF_FAIL_RET(EvaluatePropertyExpression(prop, pExpression, pObject, isAbiObject, pEvaluationResult));
|
||||
IF_FAIL_RET(EvaluatePropertyExpression(prop, pExpression, pObject, objectType, pEvaluationResult));
|
||||
if (pEvaluationResult->TagValue() != DkmEvaluationResult::Tag::SuccessResult)
|
||||
{
|
||||
return E_FAIL;
|
||||
|
@ -195,11 +195,11 @@ static HRESULT EvaluatePropertyString(
|
|||
static std::string GetRuntimeClass(
|
||||
_In_ DkmVisualizedExpression* pExpression,
|
||||
_In_ DkmPointerValueHome* pObject,
|
||||
bool isAbiObject
|
||||
ObjectType objectType
|
||||
)
|
||||
{
|
||||
com_ptr<DkmString> pValue;
|
||||
EvaluatePropertyString({ IID_IInspectable, -2, PropertyCategory::String }, pExpression, pObject, isAbiObject, pValue);
|
||||
EvaluatePropertyString({ IID_IInspectable, -2, PropertyCategory::String }, pExpression, pObject, objectType, pValue);
|
||||
if (!pValue || pValue->Length() == 0)
|
||||
{
|
||||
return "";
|
||||
|
@ -210,16 +210,11 @@ static std::string GetRuntimeClass(
|
|||
static HRESULT ObjectToString(
|
||||
_In_ DkmVisualizedExpression* pExpression,
|
||||
_In_ DkmPointerValueHome* pObject,
|
||||
bool isAbiObject,
|
||||
_Out_ com_ptr<DkmString>& pValue,
|
||||
bool* unavailable = nullptr
|
||||
ObjectType objectType,
|
||||
_Out_ com_ptr<DkmString>& pValue
|
||||
)
|
||||
{
|
||||
if (unavailable)
|
||||
{
|
||||
*unavailable = false;
|
||||
}
|
||||
if (SUCCEEDED(EvaluatePropertyString({ IID_IStringable, 0, PropertyCategory::String }, pExpression, pObject, isAbiObject, pValue)))
|
||||
if (SUCCEEDED(EvaluatePropertyString({ IID_IStringable, 0, PropertyCategory::String }, pExpression, pObject, objectType, pValue)))
|
||||
{
|
||||
if (pValue && pValue->Length() > 0)
|
||||
{
|
||||
|
@ -229,7 +224,7 @@ static HRESULT ObjectToString(
|
|||
|
||||
// WINRT_abi_val returned 0, which may be success or failure (due to VirtualQuery validation)
|
||||
// Call back for the runtime class name to determine which it was
|
||||
if (!GetRuntimeClass(pExpression, pObject, isAbiObject).empty())
|
||||
if (!GetRuntimeClass(pExpression, pObject, objectType).empty())
|
||||
{
|
||||
return DkmString::Create(L"<Expand object to view properties>", pValue.put());
|
||||
}
|
||||
|
@ -237,17 +232,13 @@ static HRESULT ObjectToString(
|
|||
|
||||
// VirtualQuery validation failed (as determined by no runtime class name) or an
|
||||
// exception escaped WINRT_abi_val (e.g, bad pointer, which we try to avoid via VirtualQuery)
|
||||
if (unavailable)
|
||||
{
|
||||
*unavailable = true;
|
||||
}
|
||||
return DkmString::Create(L"<Object uninitialized or information unavailable>", pValue.put());
|
||||
}
|
||||
|
||||
static HRESULT CreateChildVisualizedExpression(
|
||||
_In_ PropertyData const& prop,
|
||||
_In_ DkmVisualizedExpression* pParent,
|
||||
bool isAbiObject,
|
||||
ObjectType objectType,
|
||||
_Deref_out_ DkmChildVisualizedExpression** ppResult
|
||||
)
|
||||
{
|
||||
|
@ -256,7 +247,7 @@ static HRESULT CreateChildVisualizedExpression(
|
|||
com_ptr<DkmEvaluationResult> pEvaluationResult;
|
||||
auto valueHome = make_com_ptr(pParent->ValueHome());
|
||||
com_ptr<DkmPointerValueHome> pParentPointer = valueHome.as<DkmPointerValueHome>();
|
||||
IF_FAIL_RET(EvaluatePropertyExpression(prop, pParent, pParentPointer.get(), isAbiObject, pEvaluationResult));
|
||||
IF_FAIL_RET(EvaluatePropertyExpression(prop, pParent, pParentPointer.get(), objectType, pEvaluationResult));
|
||||
if (pEvaluationResult->TagValue() != DkmEvaluationResult::Tag::SuccessResult)
|
||||
{
|
||||
return E_FAIL;
|
||||
|
@ -273,7 +264,7 @@ static HRESULT CreateChildVisualizedExpression(
|
|||
{
|
||||
isNonNullObject = true;
|
||||
IF_FAIL_RET(DkmPointerValueHome::Create(childObjectAddress, pChildPointer.put()));
|
||||
IF_FAIL_RET(ObjectToString(pParent, pChildPointer.get(), true, pValue));
|
||||
IF_FAIL_RET(ObjectToString(pParent, pChildPointer.get(), ObjectType::Abi, pValue));
|
||||
}
|
||||
}
|
||||
if(!isNonNullObject)
|
||||
|
@ -335,7 +326,7 @@ static HRESULT CreateChildVisualizedExpression(
|
|||
|
||||
if (isNonNullObject)
|
||||
{
|
||||
com_ptr<object_visualizer> pObjectVisualizer = make_self<object_visualizer>(pChildVisualizedExpression.get(), true);
|
||||
com_ptr<object_visualizer> pObjectVisualizer = make_self<object_visualizer>(pChildVisualizedExpression.get(), ObjectType::Abi);
|
||||
IF_FAIL_RET(pChildVisualizedExpression->SetDataItem(DkmDataCreationDisposition::CreateNew, pObjectVisualizer.get()));
|
||||
}
|
||||
else
|
||||
|
@ -492,7 +483,7 @@ void object_visualizer::GetPropertyData()
|
|||
{
|
||||
auto valueHome = make_com_ptr(m_pVisualizedExpression->ValueHome());
|
||||
com_ptr<DkmPointerValueHome> pObject = valueHome.as<DkmPointerValueHome>();
|
||||
auto rc = GetRuntimeClass(m_pVisualizedExpression.get(), pObject.get(), m_isAbiObject);
|
||||
auto rc = GetRuntimeClass(m_pVisualizedExpression.get(), pObject.get(), m_objectType);
|
||||
if (rc.empty())
|
||||
{
|
||||
return;
|
||||
|
@ -539,9 +530,9 @@ void object_visualizer::GetTypeProperties(Microsoft::VisualStudio::Debugger::Dkm
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT object_visualizer::CreateEvaluationResult(_In_ DkmVisualizedExpression* pVisualizedExpression, _In_ bool isAbiObject, _Deref_out_ DkmEvaluationResult** ppResultObject)
|
||||
HRESULT object_visualizer::CreateEvaluationResult(_In_ DkmVisualizedExpression* pVisualizedExpression, _In_ ObjectType objectType, _Deref_out_ DkmEvaluationResult** ppResultObject)
|
||||
{
|
||||
com_ptr<object_visualizer> pObjectVisualizer = make_self<object_visualizer>(pVisualizedExpression, isAbiObject);
|
||||
com_ptr<object_visualizer> pObjectVisualizer = make_self<object_visualizer>(pVisualizedExpression, objectType);
|
||||
|
||||
IF_FAIL_RET(pVisualizedExpression->SetDataItem(DkmDataCreationDisposition::CreateNew, pObjectVisualizer.get()));
|
||||
|
||||
|
@ -582,7 +573,7 @@ HRESULT object_visualizer::CreateEvaluationResult(_Deref_out_ DkmEvaluationResul
|
|||
auto address = pPointerValueHome->Address();
|
||||
|
||||
com_ptr<DkmString> pValue;
|
||||
DkmEvaluationResultFlags_t evalResultFlags = DkmEvaluationResultFlags::ReadOnly;
|
||||
DkmEvaluationResultFlags_t evalResultFlags = DkmEvaluationResultFlags::ReadOnly | DkmEvaluationResultFlags::Expandable;;
|
||||
if (requires_refresh(address, m_pVisualizedExpression->InspectionContext()->EvaluationFlags()))
|
||||
{
|
||||
IF_FAIL_RET(DkmString::Create(L"<Refresh to view properties>", pValue.put()));
|
||||
|
@ -591,12 +582,7 @@ HRESULT object_visualizer::CreateEvaluationResult(_Deref_out_ DkmEvaluationResul
|
|||
else
|
||||
{
|
||||
cache_refresh(address);
|
||||
bool unavailable;
|
||||
IF_FAIL_RET(ObjectToString(m_pVisualizedExpression.get(), pPointerValueHome.get(), m_isAbiObject, pValue, &unavailable));
|
||||
if (!unavailable)
|
||||
{
|
||||
evalResultFlags |= DkmEvaluationResultFlags::Expandable;
|
||||
}
|
||||
IF_FAIL_RET(ObjectToString(m_pVisualizedExpression.get(), pPointerValueHome.get(), m_objectType, pValue));
|
||||
}
|
||||
|
||||
com_ptr<DkmDataAddress> pAddress;
|
||||
|
@ -689,7 +675,7 @@ HRESULT object_visualizer::GetItems(
|
|||
{
|
||||
auto& prop = m_propertyData[i + (size_t)StartIndex];
|
||||
com_ptr<DkmChildVisualizedExpression> pPropertyVisualized;
|
||||
if (FAILED(CreateChildVisualizedExpression(prop, pParent, m_isAbiObject, pPropertyVisualized.put())))
|
||||
if(FAILED(CreateChildVisualizedExpression(prop, pParent, m_objectType, pPropertyVisualized.put())))
|
||||
{
|
||||
com_ptr<DkmString> pErrorMessage;
|
||||
IF_FAIL_RET(DkmString::Create(L"<Property evaluation failed>", pErrorMessage.put()));
|
||||
|
|
|
@ -20,6 +20,12 @@ enum class PropertyCategory
|
|||
Class,
|
||||
};
|
||||
|
||||
enum class ObjectType
|
||||
{
|
||||
Abi,
|
||||
Projection,
|
||||
};
|
||||
|
||||
// Metatdata for resolving a runtime class property value
|
||||
struct PropertyData
|
||||
{
|
||||
|
@ -36,17 +42,17 @@ struct PropertyData
|
|||
struct __declspec(uuid("c7da92da-3bc9-4312-8a93-46f480663980"))
|
||||
object_visualizer : winrt::implements<object_visualizer, ::IUnknown>
|
||||
{
|
||||
object_visualizer(Microsoft::VisualStudio::Debugger::Evaluation::DkmVisualizedExpression* pVisualizedExpression, bool isAbiObject)
|
||||
object_visualizer(Microsoft::VisualStudio::Debugger::Evaluation::DkmVisualizedExpression* pVisualizedExpression, ObjectType objectType)
|
||||
{
|
||||
m_pVisualizedExpression = make_com_ptr(pVisualizedExpression);
|
||||
m_isAbiObject = isAbiObject;
|
||||
m_objectType = objectType;
|
||||
}
|
||||
|
||||
~object_visualizer()
|
||||
{
|
||||
}
|
||||
|
||||
static HRESULT CreateEvaluationResult(_In_ Microsoft::VisualStudio::Debugger::Evaluation::DkmVisualizedExpression* pVisualizedExpression, _In_ bool isAbiObject, _Deref_out_ Microsoft::VisualStudio::Debugger::Evaluation::DkmEvaluationResult** ppResultObject);
|
||||
static HRESULT CreateEvaluationResult(_In_ Microsoft::VisualStudio::Debugger::Evaluation::DkmVisualizedExpression* pVisualizedExpression, _In_ ObjectType objectType, _Deref_out_ Microsoft::VisualStudio::Debugger::Evaluation::DkmEvaluationResult** ppResultObject);
|
||||
|
||||
HRESULT CreateEvaluationResult(_Deref_out_ Microsoft::VisualStudio::Debugger::Evaluation::DkmEvaluationResult** ppResultObject);
|
||||
|
||||
|
@ -69,7 +75,7 @@ private:
|
|||
void GetPropertyData();
|
||||
void GetTypeProperties(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& type_name);
|
||||
winrt::com_ptr<Microsoft::VisualStudio::Debugger::Evaluation::DkmVisualizedExpression> m_pVisualizedExpression;
|
||||
bool m_isAbiObject;
|
||||
ObjectType m_objectType;
|
||||
std::vector<PropertyData> m_propertyData;
|
||||
bool m_isStringable{ false };
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче