Needed to build windows.ui.composition.idl.
Example:
` [ composable(Windows.UI.Composition.ICompositionEasingFunctionFactory, public, Windows.Foundation.UniversalApiContract, 2.0), contract(Windows.Foundation.UniversalApiContract, 2.0), marshaling_behavior(agile), static(Windows.UI.Composition.ICompositionEasingFunctionStatics, Windows.Foundation.UniversalApiContract, 12.0), threading(both) ] runtimeclass CompositionEasingFunction : Windows.UI.Composition.CompositionObject { [default] interface Windows.UI.Composition.ICompositionEasingFunction; } `
Some WinRT headers use `protected` rather than `public` for the composable attribute like windows.ui.xaml.media.idl:2304
`[composable(Windows.UI.Xaml.Media.ICacheModeFactory, protected, Windows.Foundation.UniversalApiContract, 1.0)]`
-- v2: widl: Add support for composable attribute. widl: Add support for protected attribute.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- tools/widl/attribute.c | 1 + tools/widl/parser.l | 1 + tools/widl/parser.y | 2 ++ tools/widl/widltypes.h | 1 + 4 files changed, 5 insertions(+)
diff --git a/tools/widl/attribute.c b/tools/widl/attribute.c index 92c6f1a44fa..c5bfbce716d 100644 --- a/tools/widl/attribute.c +++ b/tools/widl/attribute.c @@ -215,6 +215,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" }, /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" }, /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" }, + /* ATTR_PROTECTED */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "protected" }, /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" }, /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" }, /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" }, diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 3ea03a7a26f..4f24929d5a4 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -319,6 +319,7 @@ static void winrt_enable( int ns_prefix ) propget { return tPROPGET; } propput { return tPROPPUT; } propputref { return tPROPPUTREF; } + protected { return tPROTECTED; } proxy { return tPROXY; } ptr { return tPTR; } public { return tPUBLIC; } diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 5567d94559e..ef37d74e5fb 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -249,6 +249,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %token tPRAGMA_WARNING %token tPROGID tPROPERTIES %token tPROPGET tPROPPUT tPROPPUTREF +%token tPROTECTED %token tPROXY tPTR %token tPUBLIC %token tRANGE @@ -703,6 +704,7 @@ attribute | tPROPGET { $$ = attr_int( @$, ATTR_PROPGET, 0 ); } | tPROPPUT { $$ = attr_int( @$, ATTR_PROPPUT, 0 ); } | tPROPPUTREF { $$ = attr_int( @$, ATTR_PROPPUTREF, 0 ); } + | tPROTECTED { $$ = attr_int( @$, ATTR_PROTECTED, 0 ); } | tPROXY { $$ = attr_int( @$, ATTR_PROXY, 0 ); } | tPUBLIC { $$ = attr_int( @$, ATTR_PUBLIC, 0 ); } | tRANGE '(' expr_int_const ',' expr_int_const ')' diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 652c0d822ee..7b68b684c0b 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -154,6 +154,7 @@ enum attr_type ATTR_PROPGET, ATTR_PROPPUT, ATTR_PROPPUTREF, + ATTR_PROTECTED, ATTR_PROXY, ATTR_PUBLIC, ATTR_RANGE,
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed to build windows.ui.composition.idl. --- tools/widl/attribute.c | 1 + tools/widl/parser.l | 1 + tools/widl/parser.y | 17 +++++++++++++++++ tools/widl/register.c | 2 +- tools/widl/widltypes.h | 1 + 5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/tools/widl/attribute.c b/tools/widl/attribute.c index c5bfbce716d..b9aa99c9228 100644 --- a/tools/widl/attribute.c +++ b/tools/widl/attribute.c @@ -145,6 +145,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" }, /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" }, /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" }, + /* ATTR_COMPOSABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "composable" }, /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, /* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" }, /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" }, diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 4f24929d5a4..445efd2d458 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -245,6 +245,7 @@ static void winrt_enable( int ns_prefix ) callback { return tCALLBACK; } code { return tCODE; } comm_status { return tCOMMSTATUS; } + composable { return token_winrt( tCOMPOSABLE, yytext, yylval ); } context_handle { return tCONTEXTHANDLE; } context_handle_noserialize { return tCONTEXTHANDLENOSERIALIZE; } context_handle_serialize { return tCONTEXTHANDLENOSERIALIZE; } diff --git a/tools/widl/parser.y b/tools/widl/parser.y index ef37d74e5fb..15ced04cda2 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -186,6 +186,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %token tAPPOBJECT tASYNC tASYNCUUID %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT %token tCALLAS tCALLBACK tCASE tCHAR tCOCLASS tCODE tCOMMSTATUS +%token tCOMPOSABLE %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE %token tCONTEXTHANDLESERIALIZE %token tCONTRACT @@ -285,6 +286,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %token tWCHAR tWIREMARSHAL %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
+%type <attr> access_attr %type <attr> attribute acf_attribute %type <attr_list> m_attributes attributes attrib_list %type <attr_list> acf_attributes acf_attribute_list @@ -295,6 +297,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %type <expr> contract_req %type <expr> static_attr %type <expr> activatable_attr +%type <expr> composable_attr %type <type> delegatedef %type <stgclass> storage_cls_spec %type <type_qualifier> type_qualifier m_type_qual_list @@ -612,6 +615,19 @@ activatable_attr: | contract_req { $$ = $1; } /* activatable on the default activation factory */ ;
+access_attr + : tPUBLIC { $$ = attr_int( @$, ATTR_PUBLIC, 0 ); } + | tPROTECTED { $$ = attr_int( @$, ATTR_PROTECTED, 0 ); } + ; + +composable_attr + : decl_spec ',' access_attr ',' contract_req + { if ($1->type->type_type != TYPE_INTERFACE) + error_loc( "type %s is not an interface\n", $1->type->name ); + $$ = make_exprt( EXPR_MEMBER, declare_var( append_attr( NULL, $3 ), $1, make_declarator( NULL ), 0 ), $5 ); + } + ; + attribute : %empty { $$ = NULL; } | tACTIVATABLE '(' activatable_attr ')' { $$ = attr_ptr( @$, ATTR_ACTIVATABLE, $3 ); } @@ -625,6 +641,7 @@ attribute | tCALLAS '(' ident ')' { $$ = attr_ptr( @$, ATTR_CALLAS, $3 ); } | tCASE '(' expr_list_int_const ')' { $$ = attr_ptr( @$, ATTR_CASE, $3 ); } | tCODE { $$ = attr_int( @$, ATTR_CODE, 0 ); } + | tCOMPOSABLE '(' composable_attr ')' { $$ = attr_ptr( @$, ATTR_COMPOSABLE, $3 ); } | tCOMMSTATUS { $$ = attr_int( @$, ATTR_COMMSTATUS, 0 ); } | tCONTEXTHANDLE { $$ = attr_int( @$, ATTR_CONTEXTHANDLE, 0 ); } | tCONTEXTHANDLENOSERIALIZE { $$ = attr_int( @$, ATTR_CONTEXTHANDLE, 0 ); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } diff --git a/tools/widl/register.c b/tools/widl/register.c index 6c00dfaf5a2..65d30a5c91c 100644 --- a/tools/widl/register.c +++ b/tools/widl/register.c @@ -190,7 +190,7 @@ static void write_runtimeclasses_registry( const statement_list_t *stmts ) { if (stmt->type != STMT_TYPE) continue; if (type_get_type((type = stmt->u.type)) != TYPE_RUNTIMECLASS) continue; - if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC)) continue; + if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC) && !get_attrp(type->attrs, ATTR_COMPOSABLE)) continue; put_str( indent, "ForceRemove %s\n", format_namespace( type->namespace, "", ".", type->name, NULL ) ); put_str( indent++, "{\n" ); put_str( indent, "val 'DllPath' = s '%%MODULE%%'\n" ); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 7b68b684c0b..ad6a4e0b7ec 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -84,6 +84,7 @@ enum attr_type ATTR_CASE, ATTR_CODE, ATTR_COMMSTATUS, + ATTR_COMPOSABLE, ATTR_CONTEXTHANDLE, ATTR_CONTRACT, ATTR_CONTRACTVERSION,
On Mon Apr 3 07:38:07 2023 +0000, Rémi Bernon wrote:
Would you mind splitting this, adding `protected` attribute parsing first and then `composable` attribute?
Sure, no problem.
Using an expression is probably fine for now, especially for consistency as other attributes are parsed the same, but I think that at some point we should instead have specific structs to describe attributes in a less obfuscated way.
This is a good idea, but perhaps it would be better to add it after moving to IDL 3.0, well if we move to it anyway.
Note also that I've started to progressively convert this file to using spaces only, and to use julliard style spacing too for readability. Tabs alignment gets often messed up and will look differently depending on the editor settings.
The editor I use converts tabs to spaces. I'm not really sure what constitutes julliard style spacing, but if it's like the style in the WinRT DLLs then that's something I appreciate. It definitely makes readability a lot better.
Anyway, I hope this was the formatting you wanted.
Thanks for the reviews!
Rémi Bernon (@rbernon) commented about tools/widl/register.c:
{ if (stmt->type != STMT_TYPE) continue; if (type_get_type((type = stmt->u.type)) != TYPE_RUNTIMECLASS) continue;
if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC)) continue;
if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC) && !get_attrp(type->attrs, ATTR_COMPOSABLE)) continue;
It doesn't look like the `composable` attribute creates an entry for the class in the `ActivatableClassId` registry key on windows.
(Actually it looks like the `static` attribute also doesn't, for instance I cannot find `Windows.UI.Composition.DelegatedInkTrailVisual`, but `Windows.Gaming.Input.Gamepad` is and we need it.)