# HG changeset patch # User Atul Varma # Date 1271724346 25200 # Node ID dc37f719de3347d89f4945bc264b38a906823a4e # Parent c17df2133c3d10afb4757bc547726a16d7b32e82 Added json output diff -r c17df2133c3d -r dc37f719de33 idlexperiment.py --- 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))