Bug 661984: Add [nostdcall] as an extended idl attribute. r=bsmedberg

This commit is contained in:
Jonas Sicking 2011-06-23 19:17:58 -07:00
parent 9e2a034567
commit 05d24287f8
4 changed files with 72 additions and 11 deletions

View File

@ -62,6 +62,13 @@ def attributeNativeName(a, getter):
binaryname = a.binaryname is not None and a.binaryname or firstCap(a.name)
return "%s%s" % (getter and 'Get' or 'Set', binaryname)
def attributeReturnType(a, macro):
"""macro should be NS_IMETHOD or NS_IMETHODIMP"""
if (a.nostdcall):
return macro == "NS_IMETHOD" and "virtual nsresult" or "nsresult"
else:
return macro
def attributeParamlist(a, getter):
return "%s%s" % (a.realtype.nativeType(getter and 'out' or 'in'),
attributeParamName(a))
@ -69,16 +76,22 @@ def attributeParamlist(a, getter):
def attributeAsNative(a, getter):
scriptable = a.isScriptable() and "NS_SCRIPTABLE " or ""
params = {'scriptable': scriptable,
'returntype': attributeReturnType(a, 'NS_IMETHOD'),
'binaryname': attributeNativeName(a, getter),
'paramlist': attributeParamlist(a, getter)}
return "%(scriptable)sNS_IMETHOD %(binaryname)s(%(paramlist)s)" % params
return "%(scriptable)s%(returntype)s %(binaryname)s(%(paramlist)s)" % params
def methodNativeName(m):
return m.binaryname is not None and m.binaryname or firstCap(m.name)
def methodReturnType(m, macro):
"""macro should be NS_IMETHOD or NS_IMETHODIMP"""
if m.notxpcom:
if m.nostdcall and m.notxpcom:
return "%s%s" % (macro == "NS_IMETHOD" and "virtual " or "",
m.realtype.nativeType('in').strip())
elif m.nostdcall:
return "%snsresult" % (macro == "NS_IMETHOD" and "virtual " or "")
elif m.notxpcom:
return "%s_(%s)" % (macro, m.realtype.nativeType('in').strip())
else:
return macro
@ -410,12 +423,12 @@ def write_interface(iface, fd):
fd.write("/* %s */\n" % member.toIDL())
if isinstance(member, xpidl.Attribute):
fd.write(example_tmpl % {'implclass': implclass,
'returntype': 'NS_IMETHODIMP',
'returntype': attributeReturnType(member, 'NS_IMETHODIMP'),
'nativeName': attributeNativeName(member, True),
'paramList': attributeParamlist(member, True)})
if not member.readonly:
fd.write(example_tmpl % {'implclass': implclass,
'returntype': 'NS_IMETHODIMP',
'returntype': attributeReturnType(member, 'NS_IMETHODIMP'),
'nativeName': attributeNativeName(member, False),
'paramList': attributeParamlist(member, False)})
elif isinstance(member, xpidl.Method):

View File

@ -648,6 +648,7 @@ class Attribute(object):
notxpcom = False
readonly = False
implicit_jscontext = False
nostdcall = False
binaryname = None
null = None
undefined = None
@ -699,8 +700,10 @@ class Attribute(object):
self.notxpcom = True
elif name == 'implicit_jscontext':
self.implicit_jscontext = True
elif name == 'nostdcall':
self.nostdcall = True
else:
raise IDLError("Unexpected attribute '%s'", aloc)
raise IDLError("Unexpected attribute '%s'" % name, aloc)
def resolve(self, iface):
self.iface = iface
@ -733,6 +736,7 @@ class Method(object):
notxpcom = False
binaryname = None
implicit_jscontext = False
nostdcall = False
optional_argc = False
def __init__(self, type, name, attlist, paramlist, location, doccomments, raises):
@ -764,8 +768,10 @@ class Method(object):
self.implicit_jscontext = True
elif name == 'optional_argc':
self.optional_argc = True
elif name == 'nostdcall':
self.nostdcall = True
else:
raise IDLError("Unexpected attribute '%s'", aloc)
raise IDLError("Unexpected attribute '%s'" % name, aloc)
self.namemap = NameMap()
for p in paramlist:

View File

@ -789,6 +789,8 @@ write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
char *attrname = ATTR_IDENT(attr_tree).str;
const char *binaryname;
IDL_tree ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data;
gboolean nostdcall =
(IDL_tree_property_get(ATTR_DECLS(attr_tree), "nostdcall") != NULL);
if (mode == AS_DECL) {
if (IDL_tree_property_get(ident, "deprecated"))
@ -796,9 +798,15 @@ write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
if (is_method_scriptable(attr_tree, ident))
fputs("NS_SCRIPTABLE ", outfile);
fputs("NS_IMETHOD ", outfile);
if (nostdcall)
fputs("virtual nsresult ", outfile);
else
fputs("NS_IMETHOD ", outfile);
} else if (mode == AS_IMPL) {
fprintf(outfile, "NS_IMETHODIMP %s::", className);
if (nostdcall)
fprintf(outfile, "nsresult %s::", className);
else
fprintf(outfile, "NS_IMETHODIMP %s::", className);
}
fprintf(outfile, "%cet",
getter ? 'G' : 'S');
@ -1040,6 +1048,8 @@ write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
(IDL_tree_property_get(op->ident, "optional_argc") != NULL);
gboolean op_context =
(IDL_tree_property_get(op->ident, "implicit_jscontext") != NULL);
gboolean op_nostdcall =
(IDL_tree_property_get(op->ident, "nostdcall") != NULL);
const char *name;
const char *binaryname;
IDL_tree iter;
@ -1050,7 +1060,17 @@ write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
if (is_method_scriptable(method_tree, op->ident))
fputs("NS_SCRIPTABLE ", outfile);
if (op_notxpcom) {
if (op_nostdcall) {
fputs("virtual ", outfile);
if (op_notxpcom) {
if (!write_type(op->op_type_spec, WT_PLAIN, FALSE, outfile))
return FALSE;
}
else {
fputs("nsresult", outfile);
}
}
else if (op_notxpcom) {
fputs("NS_IMETHOD_(", outfile);
if (!write_type(op->op_type_spec, WT_PLAIN, FALSE, outfile))
return FALSE;
@ -1061,7 +1081,16 @@ write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
fputc(' ', outfile);
}
else if (mode == AS_IMPL) {
if (op_notxpcom) {
if (op_nostdcall) {
if (op_notxpcom) {
if (!write_type(op->op_type_spec, WT_PLAIN, FALSE, outfile))
return FALSE;
}
else {
fputs("nsresult", outfile);
}
}
else if (op_notxpcom) {
fputs("NS_IMETHODIMP_(", outfile);
if (!write_type(op->op_type_spec, WT_PLAIN, FALSE, outfile))
return FALSE;

View File

@ -360,6 +360,12 @@ verify_attribute_declaration(IDL_tree attr_tree)
if (!is_method_scriptable(attr_tree, ident))
return TRUE;
if (IDL_tree_property_get(ident, "nostdcall") != NULL) {
IDL_tree_error(attr_tree,
"[nostdcall] attribute must not be scriptable");
return FALSE;
}
/*
* If it should be scriptable, check that the type is non-native. nsid,
* domstring, utf8string, cstring, astring are exempted.
@ -779,7 +785,14 @@ verify_method_declaration(IDL_tree method_tree)
"arguments");
return FALSE;
}
if (IDL_tree_property_get(op->ident, "nostdcall") != NULL &&
scriptable_method) {
IDL_tree_error(method_tree,
"[nostdcall] method must not be scriptable");
return FALSE;
}
/* XXX q: can return type be nsid? */
/* Native return type? */
if (scriptable_method &&