Bug 578478 - Make header.py process the following new attributes: deprecated, optional_argc, implicit_jscontext, r=jorendorff
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 09 Aug 2010 14:38:44 -0400
changeset 49225 81344fe5f7a0eddd4d94c2c59fc97df54ea1d3e1
parent 49224 6f169212eec6b756a3161b15e82dda7cbe0df304
child 49226 6291e3e408ec9824c0bac04b98f62625c6d8e7f0
push id14952
push userbsmedberg@mozilla.com
push dateMon, 09 Aug 2010 18:39:03 +0000
treeherderautoland@33939a23c4b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs578478
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 578478 - Make header.py process the following new attributes: deprecated, optional_argc, implicit_jscontext, r=jorendorff
config/rules.mk
js/src/config/rules.mk
xpcom/idl-parser/header.py
xpcom/idl-parser/xpidl.py
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1754,19 +1754,27 @@ endif
 # warn against overriding existing .h file. 
 $(XPIDL_GEN_DIR)/.done:
 	@if test ! -d $(XPIDL_GEN_DIR); then echo Creating $(XPIDL_GEN_DIR)/.done; rm -rf $(XPIDL_GEN_DIR); mkdir $(XPIDL_GEN_DIR); fi
 	@touch $@
 
 # don't depend on $(XPIDL_GEN_DIR), because the modification date changes
 # with any addition to the directory, regenerating all .h files -> everything.
 
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_COMPILE) $(XPIDL_GEN_DIR)/.done
+XPIDL_DEPS = \
+  $(topsrcdir)/xpcom/idl-parser/header.py \
+  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
+  $(NULL)
+
+$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
 	$(REPORT_BUILD)
-	$(ELOG) $(XPIDL_COMPILE) -m header -w $(XPIDL_FLAGS) -o $(XPIDL_GEN_DIR)/$* $(_VPATH_SRCS)
+	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/other-licenses/ply \
+	  -I$(topsrcdir)/xpcom/idl-parser \
+	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser -I $(DIST)/idl $(_VPATH_SRCS) > $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_COMPILE) $(XPIDL_GEN_DIR)/.done
 	$(REPORT_BUILD)
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -1754,19 +1754,27 @@ endif
 # warn against overriding existing .h file. 
 $(XPIDL_GEN_DIR)/.done:
 	@if test ! -d $(XPIDL_GEN_DIR); then echo Creating $(XPIDL_GEN_DIR)/.done; rm -rf $(XPIDL_GEN_DIR); mkdir $(XPIDL_GEN_DIR); fi
 	@touch $@
 
 # don't depend on $(XPIDL_GEN_DIR), because the modification date changes
 # with any addition to the directory, regenerating all .h files -> everything.
 
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_COMPILE) $(XPIDL_GEN_DIR)/.done
+XPIDL_DEPS = \
+  $(topsrcdir)/xpcom/idl-parser/header.py \
+  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
+  $(NULL)
+
+$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
 	$(REPORT_BUILD)
-	$(ELOG) $(XPIDL_COMPILE) -m header -w $(XPIDL_FLAGS) -o $(XPIDL_GEN_DIR)/$* $(_VPATH_SRCS)
+	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/other-licenses/ply \
+	  -I$(topsrcdir)/xpcom/idl-parser \
+	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser -I $(DIST)/idl $(_VPATH_SRCS) > $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_COMPILE) $(XPIDL_GEN_DIR)/.done
 	$(REPORT_BUILD)
--- a/xpcom/idl-parser/header.py
+++ b/xpcom/idl-parser/header.py
@@ -53,30 +53,42 @@ else:
         pass
 
 def firstCap(str):
     return str[0].upper() + str[1:]
 
 def attributeParamName(a):
     return "a" + firstCap(a.name)
 
+def attributeParamNames(a):
+    l = [attributeParamName(a)]
+    if a.implicit_jscontext:
+        l.insert(0, "cx")
+    return ", ".join(l)
+
 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 attributeParamlist(a, getter):
-    return "%s%s" % (a.realtype.nativeType(getter and 'out' or 'in'),
-                     attributeParamName(a))
+    l = ["%s%s" % (a.realtype.nativeType(getter and 'out' or 'in'),
+                   attributeParamName(a))]
+    if a.implicit_jscontext:
+        l.insert(0, "JSContext* cx")
+
+    return ", ".join(l)
 
 def attributeAsNative(a, getter):
         scriptable = a.isScriptable() and "NS_SCRIPTABLE " or ""
+        deprecated = a.deprecated and "NS_DEPRECATED " or ""
         params = {'scriptable': scriptable,
+                  'deprecated': deprecated,
                   'binaryname': attributeNativeName(a, getter),
                   'paramlist': attributeParamlist(a, getter)}
-        return "%(scriptable)sNS_IMETHOD %(binaryname)s(%(paramlist)s)" % params
+        return "%(deprecated)s%(scriptable)sNS_IMETHOD %(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:
         return "%s_(%s)" % (macro, m.realtype.nativeType('in').strip())
@@ -84,49 +96,62 @@ def methodReturnType(m, macro):
         return macro
 
 def methodAsNative(m):
     scriptable = m.isScriptable() and "NS_SCRIPTABLE " or ""
 
     return "%s%s %s(%s)" % (scriptable,
                             methodReturnType(m, 'NS_IMETHOD'),
                             methodNativeName(m),
-                            paramlistAsNative(m.params,
-                                              m.realtype,
-                                              notxpcom=m.notxpcom))
+                            paramlistAsNative(m))
+
+def paramlistAsNative(m, empty='void'):
+    l = [paramAsNative(p) for p in m.params]
+
+    if m.implicit_jscontext:
+        l.append("JSContext* cx")
 
-def paramlistAsNative(l, rettype, notxpcom, empty='void'):
-    l = list(l)
-    if not notxpcom and rettype.name != 'void':
-        l.append(xpidl.Param(paramtype='out',
-                             type=None,
-                             name='_retval',
-                             attlist=[],
-                             location=None,
-                             realtype=rettype))
+    if m.optional_argc:
+        l.append('PRUint8 _argc')
+
+    if not m.notxpcom and m.realtype.name != 'void':
+        l.append(paramAsNative(xpidl.Param(paramtype='out',
+                                           type=None,
+                                           name='_retval',
+                                           attlist=[],
+                                           location=None,
+                                           realtype=m.realtype)))
 
     if len(l) == 0:
         return empty
 
-    return ", ".join([paramAsNative(p) for p in l])
+    return ", ".join(l)
 
 def paramAsNative(p):
     if p.paramtype == 'in':
         typeannotate = ''
     else:
         typeannotate = ' NS_%sPARAM' % p.paramtype.upper()
 
     return "%s%s%s" % (p.nativeType(),
                        p.name,
                        typeannotate)
 
-def paramlistNames(l, rettype, notxpcom):
-    names = [p.name for p in l]
-    if not notxpcom and rettype.name != 'void':
+def paramlistNames(m):
+    names = [p.name for p in m.params]
+
+    if m.implicit_jscontext:
+        names.append('cx')
+
+    if m.optional_argc:
+        names.append('_argc')
+
+    if not m.notxpcom and m.realtype.name != 'void':
         names.append('_retval')
+
     if len(names) == 0:
         return ''
     return ', '.join(names)
 
 header = """/*
  * DO NOT EDIT.  THIS FILE IS GENERATED FROM %(filename)s
  */
 
@@ -378,25 +403,25 @@ def write_interface(iface, fd):
 
     fd.write(iface_forward % names)
 
     def emitTemplate(tmpl):
         for member in iface.members:
             if isinstance(member, xpidl.Attribute):
                 fd.write(tmpl % {'asNative': attributeAsNative(member, True),
                                  'nativeName': attributeNativeName(member, True),
-                                 'paramList': attributeParamName(member)})
+                                 'paramList': attributeParamNames(member)})
                 if not member.readonly:
                     fd.write(tmpl % {'asNative': attributeAsNative(member, False),
                                      'nativeName': attributeNativeName(member, False),
-                                     'paramList': attributeParamName(member)})
+                                     'paramList': attributeParamNames(member)})
             elif isinstance(member, xpidl.Method):
                 fd.write(tmpl % {'asNative': methodAsNative(member),
                                  'nativeName': methodNativeName(member),
-                                 'paramList': paramlistNames(member.params, member.realtype, member.notxpcom)})
+                                 'paramList': paramlistNames(member)})
         if len(iface.members) == 0:
             fd.write('\\\n  /* no methods! */')
         elif not member.kind in ('attribute', 'method'):
             fd.write('\\')
 
     emitTemplate("\\\n  %(asNative)s { return _to %(nativeName)s(%(paramList)s); } ")
 
     fd.write(iface_forward_safe % names)
@@ -417,17 +442,17 @@ def write_interface(iface, fd):
                 fd.write(example_tmpl % {'implclass': implclass,
                                          'returntype': 'NS_IMETHODIMP',
                                          'nativeName': attributeNativeName(member, False),
                                          'paramList': attributeParamlist(member, False)})
         elif isinstance(member, xpidl.Method):
             fd.write(example_tmpl % {'implclass': implclass,
                                      'returntype': methodReturnType(member, 'NS_IMETHODIMP'),
                                      'nativeName': methodNativeName(member),
-                                     'paramList': paramlistAsNative(member.params, member.realtype, notxpcom=member.notxpcom, empty='')})
+                                     'paramList': paramlistAsNative(member, empty='')})
         fd.write('\n')
 
     fd.write(iface_template_epilog)
 
 if __name__ == '__main__':
     from optparse import OptionParser
     o = OptionParser()
     o.add_option('-I', action='append', dest='incdirs', help="Directory to search for imported files", default=[])
--- a/xpcom/idl-parser/xpidl.py
+++ b/xpcom/idl-parser/xpidl.py
@@ -639,16 +639,17 @@ class Attribute(object):
     kind = 'attribute'
     noscript = False
     notxpcom = False
     readonly = False
     implicit_jscontext = False
     binaryname = None
     null = None
     undefined = None
+    deprecated = False
 
     def __init__(self, type, name, attlist, readonly, location, doccomments):
         self.type = type
         self.name = name
         self.attlist = attlist
         self.readonly = readonly
         self.location = location
         self.doccomments = doccomments
@@ -687,16 +688,18 @@ class Attribute(object):
                     raise IDLError("Unexpected attribute value", aloc)
 
                 if name == 'noscript':
                     self.noscript = True
                 elif name == 'notxpcom':
                     self.notxpcom = True
                 elif name == 'implicit_jscontext':
                     self.implicit_jscontext = True
+                elif name == 'deprecated':
+                    self.deprecated = True
                 else:
                     raise IDLError("Unexpected attribute '%s'", aloc)
 
     def resolve(self, iface):
         self.iface = iface
         self.realtype = iface.idl.getName(self.type, self.location)
         if (self.null is not None and
             getBuiltinOrNativeTypeName(self.realtype) != '[domstring]'):
@@ -722,16 +725,17 @@ class Attribute(object):
 
 class Method(object):
     kind = 'method'
     noscript = False
     notxpcom = False
     binaryname = None
     implicit_jscontext = False
     optional_argc = False
+    deprecated = False
 
     def __init__(self, type, name, attlist, paramlist, location, doccomments, raises):
         self.type = type
         self.name = name
         self.attlist = attlist
         self.params = paramlist
         self.location = location
         self.doccomments = doccomments
@@ -752,16 +756,18 @@ class Method(object):
             if name == 'noscript':
                 self.noscript = True
             elif name == 'notxpcom':
                 self.notxpcom = True
             elif name == 'implicit_jscontext':
                 self.implicit_jscontext = True
             elif name == 'optional_argc':
                 self.optional_argc = True
+            elif name == 'deprecated':
+                self.deprecated = True
             else:
                 raise IDLError("Unexpected attribute '%s'", aloc)
 
         self.namemap = NameMap()
         for p in paramlist:
             self.namemap.set(p)
 
     def resolve(self, iface):