Bug 676649 - Include jspubtd.h automagically when necessary in IDL files; r=khuey
authorMs2ger <ms2ger@gmail.com>
Mon, 08 Aug 2011 17:14:34 +0200
changeset 74001 e0ae0b46f4f546b0041f962cff9076c46d6d0901
parent 74000 ac18ea6e0b37630c4e1ba0ceedae250e320dd639
child 74002 36989c74b287e7f7d132e3ecb80c02b54a88c6bd
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewerskhuey
bugs676649
milestone8.0a1
Bug 676649 - Include jspubtd.h automagically when necessary in IDL files; r=khuey
xpcom/idl-parser/header.py
xpcom/idl-parser/xpidl.py
--- a/xpcom/idl-parser/header.py
+++ b/xpcom/idl-parser/header.py
@@ -173,16 +173,20 @@ header = """/*
 """
 
 include = """
 #ifndef __gen_%(basename)s_h__
 #include "%(basename)s.h"
 #endif
 """
 
+jspubtd_include = """
+#include "jspubtd.h"
+"""
+
 header_end = """/* For IDL files that don't want to include root IDL files. */
 #ifndef NS_NO_VTABLE
 #define NS_NO_VTABLE
 #endif
 """
 
 footer = """
 #endif /* __gen_%(basename)s_h__ */
@@ -202,16 +206,19 @@ def print_header(idl, fd, filename):
 
     foundinc = False
     for inc in idl.includes():
         if not foundinc:
             foundinc = True
             fd.write('\n')
         fd.write(include % {'basename': idl_basename(inc.filename)})
 
+    if idl.needsJSTypes():
+        fd.write(jspubtd_include)
+
     fd.write('\n')
     fd.write(header_end)
 
     for p in idl.productions:
         if p.kind == 'include': continue
         if p.kind == 'cdata':
             fd.write(p.data)
             continue
--- a/xpcom/idl-parser/xpidl.py
+++ b/xpcom/idl-parser/xpidl.py
@@ -317,16 +317,22 @@ class IDL(object):
         for p in self.productions:
             p.resolve(self)
 
     def includes(self):
         for p in self.productions:
             if p.kind == 'include':
                 yield p
 
+    def needsJSTypes(self):
+        for p in self.productions:
+            if p.kind == 'interface' and p.needsJSTypes():
+                return True
+        return False
+
 class CDATA(object):
     kind = 'cdata'
     _re = re.compile(r'\n+')
 
     def __init__(self, data, location):
         self.data = self._re.sub('\n', data)
         self.location = location
 
@@ -547,16 +553,24 @@ class Interface(object):
 
     def getConst(self, name, location):
         c = self.namemap.get(name, location)
         if c.kind != 'const':
             raise IDLError("symbol '%s' is not a constant", c.location)
 
         return c.getValue()
 
+    def needsJSTypes(self):
+        for m in self.members:
+            if m.kind == "attribute" and m.type == "jsval":
+                return True
+            if m.kind == "method" and m.needsJSTypes():
+                return True
+        return False
+
 class InterfaceAttributes(object):
     uuid = None
     scriptable = False
     builtinclass = False
     function = False
     deprecated = False
     noscript = False
 
@@ -810,16 +824,25 @@ class Method(object):
 
         return "%s%s %s (%s)%s;" % (attlistToIDL(self.attlist),
                                     self.type,
                                     self.name,
                                     ", ".join([p.toIDL()
                                                for p in self.params]),
                                     raises)
 
+    def needsJSTypes(self):
+        if self.implicit_jscontext:
+            return True
+        for p in self.params:
+            t = p.realtype
+            if isinstance(t, Native) and t.specialtype == "jsval":
+                return True
+        return False
+
 class Param(object):
     size_is = None
     iid_is = None
     const = False
     array = False
     retval = False
     shared = False
     optional = False