void GetInterfaceData()

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 });
        }
    }
}