From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 4e10bce8898..4a19c633c07 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1893,6 +1893,9 @@ static void add_propget_method( const type_t *iface, const var_t *method ) BYTE sig[256]; char *name;
+ /* method may already have been added by add_propput_method() */ + if (method->declspec.type->md.property) return; + property = add_property_row( 0, add_string(method->name), add_blob(sig_prop, sizeof(sig_prop)) ); method->declspec.type->md.property = property; add_propertymap_row( iface->md.def, property ); @@ -1910,6 +1913,42 @@ static void add_propget_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_GETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); }
+static const var_t *find_propget_method( const type_t *iface, const char *name ) +{ + const statement_t *stmt; + + STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) + { + const var_t *method = stmt->u.var; + if (is_attr( method->attrs, ATTR_PROPGET ) && !strcmp( method->name, name )) return method; + } + return NULL; +} + +static void add_propput_method( const type_t *iface, const var_t *method ) +{ + const var_t *propget = find_propget_method( iface, method->name ); + UINT methoddef, property, sig_size, paramlist, attrs; + BYTE sig[256]; + char *name; + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_FAMANDASSEM | METHOD_ATTR_FAMILY | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT | METHOD_ATTR_SPECIALNAME; + + name = strmake( "put_%s", method->name ); + methoddef = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); + free( name ); + + /* add propget method if not already added */ + if (!propget->declspec.type->md.property) add_propget_method( iface, propget ); + property = propget->declspec.type->md.property; + + add_methodsemantics_row( METHOD_SEM_SETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; @@ -1933,6 +1972,7 @@ static void add_interface_type_step2( type_t *type ) const var_t *method = stmt->u.var;
if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( type, method ); + else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); }
add_contract_attr_step2( type );