microsoft / cppwinrt

C++/WinRT
MIT License
1.61k stars 232 forks source link

Project attributes as structures #1378

Closed JaiganeshKumaran closed 6 months ago

JaiganeshKumaran commented 7 months ago

I am writing a reflexion API for WinRT and I want to be able to enable access to attributes as boxed structs. Unfortunately, as C++/WinRT does not project attributes as structures, I cannot really do that.

jonwis commented 6 months ago

Can you provide a source MIDL3 and a desired projection?

JaiganeshKumaran commented 6 months ago

Here's an example

attribute GuidAttribute
{
   Guid InterfaceId;
}

// should be projected as

struct GuidAttribute
{
   winrt::guid InterfaceId;
};
kennykerr commented 6 months ago

Language projections don't project attributes as structs. Some attributes, like ActivatableAttribute, don't even have a defined layout. That's why ECMA-335 encodes them as attributes rather than structs.

jonwis commented 6 months ago

Just to continue the thought experiment, though... @JaiganeshKumaran can you show a little more, like of how you'd want that to be projected onto a type? Are you imaging something like:

[attributeusage(target_runtimeclass), attributename(kittenpart)]
attribute KittenPartAttribute {
    String Name;
    Single Cuteness;
}

[kittenpart("ears", 2.1)]
runtimeclass TwitchyEars {
}

[kittenpart("toes", 129.3)]
runtimeclass PinkPads {
}

And then the C++/WinRT projection adds attributes like

struct KittenPartAttribute {
    std::wstring_view Name;
    float Cuteness;
};

And then you can find it at compile time like:

if constexpr (winrt::get_attribute<PinkPads, KittenPartAttribute>().Name == L"ears") {
}

... so somewhere there's a map of runtimeclass/member/etc -> attribute-list?

I'm looking for more of how you'd use this with reflection, not just the "MIDL3 -> C++" part.

JaiganeshKumaran commented 6 months ago

I am going to have a WinRT API for reflexion, so will return a boxed object containing the attribute data.

TypeInfo const typeInfo = ...;
KittenPartAttribute const attribute = typeInfo.Attributes().GetAt(n).as<KittenPartAttribute();
jonwis commented 6 months ago

OK, so what you really want is a way to have:

  1. A TypeInfo generated for each runtimeclass or interface
  2. The TypeInfo contains details about that type (what other than attributes?)
  3. The TypeInfo contains the attributes from metadata projected as values (structs, probably)

Do you get this "for free" with C#'s projection?

You're welcome to add a switch or flag to produce these for your use case. You could also look into writing your own generator (see the metadata tools that cppwinrt sits on) for now while you refine what you're looking for.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.