Signed-off-by: Bernhard Kölbl besentv@gmail.com
-- v4: include: Add VoiceCommandSet runtimeclass with it's dependencies. include: Add Windows.Phone.PhoneContract api contract. widl: Add basic support for the [deprecated] attribute.
From: Bernhard Kölbl bkoelbl@codeweavers.com
--- tools/widl/attribute.c | 1 + tools/widl/header.c | 40 +++++++++++++++++++++++++++++++++++++++- tools/widl/parser.l | 1 + tools/widl/parser.y | 8 ++++++++ tools/widl/widltypes.h | 1 + 5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/tools/widl/attribute.c b/tools/widl/attribute.c index b9aa99c9228..5ea13a01175 100644 --- a/tools/widl/attribute.c +++ b/tools/widl/attribute.c @@ -157,6 +157,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" }, /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" }, /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" }, + /* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "deprecated" }, /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" }, /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL }, /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" }, diff --git a/tools/widl/header.c b/tools/widl/header.c index b7497e215d5..2b617c3ace1 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -158,6 +158,22 @@ const char *get_name(const var_t *v) return v->name; }
+static void write_deprecated(FILE *h, const expr_t *deprecated_attr) +{ + const expr_t *deprecated_msg = deprecated_attr->ref; + const expr_t *contract_req = deprecated_attr->ext2; + if (deprecated_msg->type == EXPR_STRLIT && contract_req->type == EXPR_GTREQL) { + const char *deprecated_text = deprecated_msg->u.sval; + + write_apicontract_guard_start( h, contract_req ); + indent( h, 0 ); + fprintf( h, "DEPRECATED("%s")\n", deprecated_text ); + write_apicontract_guard_end( h, contract_req ); + } + else + warning( "Deprecation attributes without explicit contract declaration are not supported, yet.\n" ); +} + static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) { unsigned nameless_struct_cnt = 0, nameless_struct_i = 0, nameless_union_cnt = 0, nameless_union_i = 0; @@ -1174,6 +1190,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) const decl_spec_t *ret = type_function_get_ret(func->declspec.type); const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV); const var_list_t *args = type_function_get_args(func->declspec.type); + const expr_t *deprecated = get_attrp(func->attrs, ATTR_DEPRECATED); const var_t *arg;
if (!callconv) callconv = "STDMETHODCALLTYPE"; @@ -1220,6 +1237,8 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) fprintf(header, "#else\n"); }
+ if (deprecated) + write_deprecated(header, deprecated); indent(header, 0); fprintf(header, "virtual "); write_type_decl_left(header, ret); @@ -1304,6 +1323,9 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char } if (!is_callas(func->attrs)) { const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV); + const expr_t *deprecated = get_attrp(func->attrs, ATTR_DEPRECATED); + if (deprecated) + write_deprecated(header, deprecated); if (!callconv) callconv = "STDMETHODCALLTYPE"; indent(header, 0); write_type_decl_left(header, type_function_get_ret(func->declspec.type)); @@ -1657,6 +1679,7 @@ static void write_widl_using_macros(FILE *header, type_t *iface)
static void write_com_interface_end(FILE *header, type_t *iface) { + const expr_t *deprecated = get_attrp(iface->attrs, ATTR_DEPRECATED); int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); const struct uuid *uuid = get_attrp(iface->attrs, ATTR_UUID); expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT); @@ -1674,6 +1697,7 @@ static void write_com_interface_end(FILE *header, type_t *iface) if (uuid) { if (strchr(iface->name, '<')) write_line(header, 0, "template<>"); write_line(header, 0, "MIDL_INTERFACE("%s")", uuid_string(uuid)); + if (deprecated) write_deprecated(header, deprecated); indent(header, 0); }else { indent(header, 0); @@ -1712,7 +1736,16 @@ static void write_com_interface_end(FILE *header, type_t *iface) write_uuid_decl(header, iface, uuid); fprintf(header, "#else\n"); /* C interface */ - write_line(header, 1, "typedef struct %sVtbl {", iface->c_name); + indent(header, 1); + fprintf(header, "typedef struct"); + if (deprecated) + { + fprintf(header, "\n"); + write_deprecated(header, deprecated); + } + else + fprintf(header, " "); + fprintf(header, "%sVtbl {\n", iface->c_name); write_line(header, 0, "BEGIN_INTERFACE\n"); if (dispinterface) write_c_disp_method_def(header, iface); @@ -1836,7 +1869,9 @@ static void write_apicontract(FILE *header, type_t *apicontract)
static void write_runtimeclass(FILE *header, type_t *runtimeclass) { + const expr_t *deprecated = get_attrp(runtimeclass->attrs, ATTR_DEPRECATED); expr_t *contract = get_attrp(runtimeclass->attrs, ATTR_CONTRACT); + char *name, *c_name; size_t i, len; name = format_namespace(runtimeclass->namespace, "", ".", runtimeclass->name, NULL); @@ -1852,6 +1887,7 @@ static void write_runtimeclass(FILE *header, type_t *runtimeclass) for (i = 0, len = strlen(name); i < len; ++i) fprintf(header, "'%c',", name[i]); fprintf(header, "0};\n"); fprintf(header, "#elif defined(__GNUC__) && !defined(__cplusplus)\n"); + if (deprecated) write_deprecated(header, deprecated); /* FIXME: MIDL generates extern const here but GCC warns if extern is initialized */ fprintf(header, "const DECLSPEC_SELECTANY WCHAR RuntimeClass_%s[] = L"%s";\n", c_name, name); fprintf(header, "#else\n"); @@ -2098,6 +2134,8 @@ void write_header(const statement_list_t *stmts) fprintf(header, "#ifndef __%s__\n", header_token); fprintf(header, "#define __%s__\n\n", header_token);
+ fprintf(header, "#define DEPRECATED(x)\n\n"); + fprintf(header, "#ifndef __WIDL_INLINE\n"); fprintf(header, "#if defined(__cplusplus) || defined(_MSC_VER)\n"); fprintf(header, "#define __WIDL_INLINE inline\n"); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 445efd2d458..afbdf7151f0 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -258,6 +258,7 @@ static void winrt_enable( int ns_prefix ) defaultcollelem { return tDEFAULTCOLLELEM; } defaultvalue { return tDEFAULTVALUE; } defaultvtable { return tDEFAULTVTABLE; } + deprecated { return token_winrt( tDEPRECATED, yytext, yylval ); } disable_consistency_check { return tDISABLECONSISTENCYCHECK; } displaybind { return tDISPLAYBIND; } dllname { return tDLLNAME; } diff --git a/tools/widl/parser.y b/tools/widl/parser.y index b802f75874d..d449a29c725 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -199,6 +199,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %token tDEFAULTCOLLELEM %token tDEFAULTVALUE %token tDEFAULTVTABLE +%token tDEPRECATED %token tDISABLECONSISTENCYCHECK tDISPLAYBIND %token tDISPINTERFACE %token tDLLNAME tDONTFREE tDOUBLE tDUAL @@ -298,6 +299,7 @@ void pop_import( PARSER_LTYPE *yylloc ); %type <expr> static_attr %type <expr> activatable_attr %type <expr> composable_attr +%type <expr> deprecated_attr %type <type> delegatedef %type <stgclass> storage_cls_spec %type <type_qualifier> type_qualifier m_type_qual_list @@ -628,6 +630,11 @@ composable_attr } ;
+deprecated_attr + : aSTRING ',' aIDENTIFIER ',' contract_req + { $$ = make_expr3( EXPR_MEMBER, make_exprs( EXPR_STRLIT, $1 ), make_exprs( EXPR_IDENTIFIER, $1 ), $5 ); } + ; + attribute : %empty { $$ = NULL; } | tACTIVATABLE '(' activatable_attr ')' { $$ = attr_ptr( @$, ATTR_ACTIVATABLE, $3 ); } @@ -659,6 +666,7 @@ attribute | tDEFAULTCOLLELEM { $$ = attr_int( @$, ATTR_DEFAULTCOLLELEM, 0 ); } | tDEFAULTVALUE '(' expr_const ')' { $$ = attr_ptr( @$, ATTR_DEFAULTVALUE, $3 ); } | tDEFAULTVTABLE { $$ = attr_int( @$, ATTR_DEFAULTVTABLE, 0 ); } + | tDEPRECATED '(' deprecated_attr ')' { $$ = attr_ptr( @$, ATTR_DEPRECATED, $3 ); } | tDISABLECONSISTENCYCHECK { $$ = attr_int( @$, ATTR_DISABLECONSISTENCYCHECK, 0 ); } | tDISPLAYBIND { $$ = attr_int( @$, ATTR_DISPLAYBIND, 0 ); } | tDLLNAME '(' aSTRING ')' { $$ = attr_ptr( @$, ATTR_DLLNAME, $3 ); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index ad6a4e0b7ec..b92c8c15e68 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -96,6 +96,7 @@ enum attr_type ATTR_DEFAULTCOLLELEM, ATTR_DEFAULTVALUE, ATTR_DEFAULTVTABLE, + ATTR_DEPRECATED, ATTR_DISABLECONSISTENCYCHECK, ATTR_DISPINTERFACE, ATTR_DISPLAYBIND,
From: Bernhard Kölbl bkoelbl@codeweavers.com
--- include/windowscontracts.idl | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/include/windowscontracts.idl b/include/windowscontracts.idl index 5bcae48a5b5..46e1e3d0e1b 100644 --- a/include/windowscontracts.idl +++ b/include/windowscontracts.idl @@ -30,4 +30,9 @@ namespace Windows { apicontract UniversalApiContract {}; } + namespace Phone { + [contractversion(1)] + apicontract PhoneContract + {}; + } }
From: Bernhard Kölbl bkoelbl@codeweavers.com
--- include/windows.media.speechrecognition.idl | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/include/windows.media.speechrecognition.idl b/include/windows.media.speechrecognition.idl index 79107aab1bf..2d64854264e 100644 --- a/include/windows.media.speechrecognition.idl +++ b/include/windows.media.speechrecognition.idl @@ -60,6 +60,7 @@ namespace Windows { interface ISpeechRecognizerStatics2; interface ISpeechRecognizerTimeouts; interface ISpeechRecognizerUIOptions; + interface IVoiceCommandSet; runtimeclass SpeechContinuousRecognitionCompletedEventArgs; runtimeclass SpeechContinuousRecognitionResultGeneratedEventArgs; runtimeclass SpeechContinuousRecognitionSession; @@ -74,6 +75,7 @@ namespace Windows { runtimeclass SpeechRecognizerStateChangedEventArgs; runtimeclass SpeechRecognizerTimeouts; runtimeclass SpeechRecognizerUIOptions; + runtimeclass VoiceCommandSet; } } } @@ -471,6 +473,19 @@ namespace Windows { [propput] HRESULT ShowConfirmation([in] boolean value); }
+ [ + contract(Windows.Phone.PhoneContract, 1.0), + deprecated("Use Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition instead of Windows.Media.SpeechRecognition.VoiceComandSet. For more info, see MSDN.", deprecate, Windows.Phone.PhoneContract, 1.0), + exclusiveto(Windows.Media.SpeechRecognition.VoiceCommandSet), + uuid(0BEDDA75-46E6-4B11-A088-5C68632899B5) + ] + interface IVoiceCommandSet : IInspectable + { + [deprecated("Use Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition instead of Windows.Media.SpeechRecognition.VoiceComandSet. For more info, see MSDN.", deprecate, Windows.Phone.PhoneContract, 1.0), propget] HRESULT Language([out, retval] HSTRING* value); + [deprecated("Use Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition instead of Windows.Media.SpeechRecognition.VoiceComandSet. For more info, see MSDN.", deprecate, Windows.Phone.PhoneContract, 1.0), propget] HRESULT Name([out, retval] HSTRING* value); + [deprecated("Use Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition instead of Windows.Media.SpeechRecognition.VoiceComandSet. For more info, see MSDN.", deprecate, Windows.Phone.PhoneContract, 1.0)] HRESULT SetPhraseListAsync([in] HSTRING phraseListName, [in] Windows.Foundation.Collections.IIterable<HSTRING>* phraseList, [out, retval] Windows.Foundation.IAsyncAction** updateAction); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), marshaling_behavior(agile), @@ -610,6 +625,16 @@ namespace Windows { { [default] interface Windows.Media.SpeechRecognition.ISpeechRecognizerUIOptions; } + + [ + contract(Windows.Phone.PhoneContract, 1.0), + deprecated("Use Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition instead of Windows.Media.SpeechRecognition.VoiceComandSet. For more info, see MSDN.", deprecate, Windows.Phone.PhoneContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass VoiceCommandSet + { + [default] interface Windows.Media.SpeechRecognition.IVoiceCommandSet; + } } } }
v2: - Rebase - Parsing rework - Write attribute for runtimeclasses and interfaces as well - Add example IDL.
On Wed Jul 5 10:35:13 2023 +0000, Bernhard Kölbl wrote:
I did it like this because idk if we support `__declspec(deprecated(x))` .
I think for now you should just add the parsing support, which is what we want to complete the IDLs.
Adding generated code to end up with it doing nothing feels a bit pointless. I'm not sure we want to generate matching deprecated attributes, but if we find it useful it could always be added later.