changeset 2:dc37f719de33 default tip

Added json output
author Atul Varma <avarma@mozilla.com>
date Mon, 19 Apr 2010 17:45:46 -0700
parents c17df2133c3d
children
files idlexperiment.py
diffstat 1 files changed, 102 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/idlexperiment.py	Fri Apr 16 18:47:29 2010 -0700
+++ b/idlexperiment.py	Mon Apr 19 17:45:46 2010 -0700
@@ -1,31 +1,106 @@
+import os
+import sys
+import json
+
 import xpidl
 
+ROOT_SRC_DIR = os.path.expanduser("~/Documents/firefox-3.6.3-source")
+
+DOM_DIR = "dom/interfaces"
+
+IDL_PATHS = ["xpcom/base",
+             "content/base/public"]
+
+IDL_PATHS.extend([os.path.join(DOM_DIR, path)
+                  for path in os.listdir(os.path.join(ROOT_SRC_DIR,
+                                                      DOM_DIR))])
+
+def get_idl(class_name, search_paths):
+    parser = xpidl.IDLParser()
+    basename = "%s.idl" % class_name
+    for path in search_paths:
+        fullpath = os.path.join(path, basename)
+        if os.path.exists(fullpath):
+            idl = parser.parse(open(fullpath, "r").read(),
+                               filename=basename)
+            idl.resolve(search_paths, parser)
+            return idl
+    raise Exception('class not found: %s' % class_name)
+
+PRIMITIVES = [
+    "void",
+    "long",
+    "DOMString",
+    "unsigned long",
+    "nsQIResult",
+    "nsIIDRef",
+    "nsrefcnt",
+    "boolean",
+    "unsigned short",
+    "short",
+    "wstring",
+    "float"
+    ]
+
 if __name__ == '__main__':
-    parser = xpidl.IDLParser()
-    filename = "idl/nsIDOMNode.idl"
-    idl = parser.parse(open(filename, "r").read(),
-                       filename=filename)
-    idl.resolve(["idl"], parser)
-    for thing in idl.getNames():
-        if isinstance(thing, xpidl.Interface):
-            print "Interface %s" % thing.name
-            for prop in thing.namemap:
-                if isinstance(prop, xpidl.Method):
-                    args = []
-                    for param in prop.params:
-                        args.append("%s %s" % (param.type, param.name))
-                    arglist = "(%s)" % (", ".join(args))
-                    print "  %s %s.%s%s" % (prop.type,
-                                            thing.name, prop.name,
-                                            arglist)
-                elif isinstance(prop, xpidl.Attribute):
-                    print "  attribute %s %s readonly=%s" % (prop.type,
-                                                             prop.name,
-                                                             prop.readonly)
-                elif isinstance(prop, xpidl.ConstMember):
-                    print "  %s %s = %s" % (prop.type,
-                                            prop.name,
-                                            prop.getValue())
-                else:
-                    print "TODO: %s" % prop.__class__.__name__
+    to_resolve = ['nsIDOMWindow']
+
+    interfaces = {}
+
+    search_paths = [os.path.join(ROOT_SRC_DIR, path)
+                    for path in IDL_PATHS]
+
+    def maybe_add(class_name):
+        if class_name not in interfaces and class_name not in PRIMITIVES:
+            to_resolve.append(class_name)
 
+    while to_resolve:
+        class_name = to_resolve.pop()
+        idl = get_idl(class_name, search_paths)
+        for thing in idl.getNames():
+            if isinstance(thing, xpidl.Interface):
+                if thing.name in interfaces:
+                    continue
+                attrs = {}
+                iface = {'name': thing.name,
+                         'base': thing.base,
+                         'attrs': attrs}
+                #print "Interface %s (%s)" % (thing.name, thing.base)
+                interfaces[thing.name] = iface
+                for prop in thing.namemap:
+                    info = {}
+                    attrs[prop.name] = info
+                    if isinstance(prop, xpidl.Method):
+                        args = []
+                        for param in prop.params:
+                            maybe_add(param.type)
+                            args.append({'name': param.name,
+                                         'type': param.type})
+                            #args.append("%s %s" % (param.type, param.name))
+                        maybe_add(prop.type)
+                        info['type'] = 'method'
+                        info['args'] = args
+                        info['returns'] = {'type': prop.type}
+                        #arglist = "(%s)" % (", ".join(args))
+                        #print "  %s %s.%s%s" % (prop.type,
+                        #                        thing.name, prop.name,
+                        #                        arglist)
+                    elif isinstance(prop, xpidl.Attribute):
+                        maybe_add(prop.type)
+                        info['type'] = 'attribute'
+                        info['readOnly'] = prop.readonly
+                        info['value'] = {'type': prop.type}
+                        #print "  attribute %s %s readonly=%s" % (prop.type,
+                        #                                         prop.name,
+                        #                                         prop.readonly)
+                    elif isinstance(prop, xpidl.ConstMember):
+                        maybe_add(prop.type)
+                        info['type'] = 'constant'
+                        info['value'] = prop.getValue()
+                        #print "  %s %s = %s" % (prop.type,
+                        #                        prop.name,
+                        #                        prop.getValue())
+                    else:
+                        raise Exception("Don't know what to do with "
+                                        "type: %s" % prop.__class__.__name__)
+    sys.stdout.write(json.dumps(interfaces))