in natvis/object_visualizer.cpp [358:489]
void GetInterfaceData(
Microsoft::VisualStudio::Debugger::DkmProcess* process,
coded_index<TypeDefOrRef> index,
_Inout_ std::vector<PropertyData>& propertyData,
_Out_ bool& isStringable
){
auto [type, propIid] = ResolveTypeInterface(process, index);
if (!type)
{
return;
}
if (propIid == IID_IStringable)
{
isStringable = true;
return;
}
int32_t propIndex = -1;
for (auto&& method : type.MethodList())
{
propIndex++;
auto isGetter = method.Flags().SpecialName() && starts_with(method.Name(), "get_");
if (!isGetter)
{
continue;
}
std::optional<PropertyCategory> propCategory;
std::wstring propAbiType;
std::wstring propDisplayType;
auto retType = method.Signature().ReturnType();
std::visit(overloaded{
[&](ElementType type)
{
if ((ElementType::Boolean <= type) && (type <= ElementType::String))
{
propCategory = (PropertyCategory)(static_cast<std::underlying_type<ElementType>::type>(type) -
static_cast<std::underlying_type<ElementType>::type>(ElementType::Boolean));
}
else if (type == ElementType::Object)
{
//propDisplayType = L"winrt::Windows::Foundation::IInspectable";
//propCategory = PropertyCategory::Class;
//propAbiType = L"winrt::impl::inspectable_abi*";
}
},
[&](coded_index<TypeDefOrRef> const& index)
{
auto type = ResolveType(process, index);
if (!type)
{
return;
}
auto typeName = type.TypeName();
if (typeName == "GUID"sv)
{
propCategory = PropertyCategory::Guid;
}
else
{
auto ns = std::string(type.TypeNamespace());
auto name = std::string(type.TypeName());
// Map numeric type names
if (ns == "Windows.Foundation.Numerics")
{
if (name == "Matrix3x2") { name = "float3x2"; }
else if (name == "Matrix4x4") { name = "float4x4"; }
else if (name == "Plane") { name = "plane"; }
else if (name == "Quaternion") { name = "quaternion"; }
else if (name == "Vector2") { name = "float2"; }
else if (name == "Vector3") { name = "float3"; }
else if (name == "Vector4") { name = "float4"; }
}
// Types come back from winmd files with '.', need to be '::'
// Ex. Windows.Foundation.Uri needs to be Windows::Foundation::Uri
auto fullTypeName = ns + "::" + name;
wchar_t cppTypename[500];
size_t i, j;
for (i = 0, j = 0; i < (fullTypeName.length() + 1); i++, j++)
{
if (fullTypeName[i] == L'.')
{
cppTypename[j++] = L':';
cppTypename[j] = L':';
}
else
{
cppTypename[j] = fullTypeName[i];
}
}
propDisplayType = std::wstring(L"winrt::") + cppTypename;
if(get_category(type) == category::class_type)
{
propCategory = PropertyCategory::Class;
propAbiType = L"winrt::impl::inspectable_abi*";
}
else
{
propCategory = PropertyCategory::Value;
propAbiType = propDisplayType;
}
}
},
[&](GenericTypeIndex /*var*/)
{
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
},
[&](GenericMethodTypeIndex /*var*/)
{
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
},
[&](GenericTypeInstSig const& /*type*/)
{
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
}
}, retType.Type().Type());
if (propCategory)
{
auto propName = method.Name().substr(4);
std::wstring propDisplayName(propName.cbegin(), propName.cend());
propertyData.push_back({ propIid, propIndex, *propCategory, propAbiType, propDisplayType, propDisplayName });
}
}
}