Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Unified Diff: tools/json_schema_compiler/idl_schema.py

Issue 9600050: Add IDL capability to json_schema_compiler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Patch Set 1 Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/json_schema_compiler/idl_schema.py
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py
new file mode 100644
index 0000000000000000000000000000000000000000..540ba2bc105c4197cb04bb120e3b95f4d9ba42ab
--- /dev/null
+++ b/tools/json_schema_compiler/idl_schema.py
@@ -0,0 +1,182 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
asargent_no_longer_on_chrome 2012/03/06 22:27:57 nit: might be worth having an overview comment her
+import os.path
+import sys
+
+idl_generators_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+ os.pardir, os.pardir, 'ppapi', 'generators')
+if idl_generators_path not in sys.path:
+ sys.path.insert(0, idl_generators_path)
+import idl_parser
+
+class Callspec(object):
+ '''
+ Given a Callspec node representing an IDL namespace, converts into a Python
asargent_no_longer_on_chrome 2012/03/06 22:27:57 "an IDL namespace" -> "an IDL function declaration
+ dictionary that the JSON schema compiler expects to see.
+ '''
+ def __init__(self, callspec_node):
+ self.node = callspec_node
+
+ def process(self, refs):
+ parameters = []
+ for node in self.node.children:
+ parameters.append(Param(node).process(refs))
+ return self.node.GetName(), parameters
+
+class Param(object):
+ '''
+ Given a Param node representing an IDL namespace, converts into a Python
asargent_no_longer_on_chrome 2012/03/06 22:27:57 "an IDL namespace" -> "a function parameter"
+ dictionary that the JSON schema compiler expects to see.
+ '''
+ def __init__(self, param_node):
+ self.node = param_node
+
+ def process(self, refs):
+ properties = { 'name': self.node.GetName() }
+ return dict(properties.items() +
+ Typeref(self.node.GetProperty(
+ 'TYPEREF'), self.node).process(refs).items())
+
+class Dictionary(object):
+ '''
+ Given a Dictionary node representing an IDL namespace, converts into a Python
asargent_no_longer_on_chrome 2012/03/06 22:27:57 "an IDL namespace" -> "an IDL dictionary"
+ dictionary that the JSON schema compiler expects to see.
+ '''
+ def __init__(self, dictionary_node):
+ self.node = dictionary_node
+
+ def process(self, refs):
+ properties = {}
+ for node in self.node.children:
+ if node.cls == 'Member':
+ k, v = Member(node).process(refs)
+ properties[k] = v
+ return { 'id': self.node.GetName(),
+ 'properties': properties,
+ 'type': 'object' }
+
+class Member(object):
+ '''
+ Given a Member node representing an IDL namespace, converts into a Python
asargent_no_longer_on_chrome 2012/03/06 22:27:57 "an IDL namespace" -> "an IDL dictionary or interf
+ dictionary that the JSON schema compiler expects to see.
+ '''
+ def __init__(self, member_node):
+ self.node = member_node
+
+ def process(self, refs):
+ properties = {}
+ name = self.node.GetName()
+ if self.node.GetProperty('OPTIONAL'):
+ properties['optional'] = True
+ if self.node.GetProperty('nodoc'):
+ properties['nodoc'] = True
+ for node in self.node.children:
+ if node.cls == 'Callspec':
+ name, parameters = Callspec(node).process(refs)
asargent_no_longer_on_chrome 2012/03/06 22:27:57 It would be nice to enforce somewhere that this ca
+ properties['parameters'] = parameters
+ properties['name'] = name
+ typeref = self.node.GetProperty('TYPEREF')
+ if typeref == 'void':
asargent_no_longer_on_chrome 2012/03/06 22:27:57 Instead of looking for typeref==void to tell if th
miket_OOO 2012/03/07 00:23:01 Done.
+ properties['type'] = 'function'
+ else:
+ properties = dict(properties.items() +
+ Typeref(typeref, self.node).process(refs).items())
asargent_no_longer_on_chrome 2012/03/06 22:27:57 would it be clearer if instead of merging dict's h
miket_OOO 2012/03/07 00:23:01 Yes, great idea! Done.
+ return name, properties
+
+class Typeref(object):
+ '''
+ Given a TYPEREF property representing an IDL namespace, converts into a
asargent_no_longer_on_chrome 2012/03/06 22:27:57 "an IDL namespace" -> "the type of a dictionary me
+ Python dictionary that the JSON schema compiler expects to see.
+ '''
+ def __init__(self, typeref, parent):
+ self.typeref = typeref
+ self.parent = parent
+
+ def process(self, refs):
+ properties = {}
+ if self.typeref == 'DOMString':
+ properties['type'] = 'string'
+ elif self.typeref == 'boolean':
+ properties['type'] = 'boolean'
+ elif self.typeref == 'long':
+ properties['type'] = 'integer'
+ elif self.typeref is None:
+ properties['type'] = 'function'
+ else:
+ try:
+ properties = refs[self.typeref]
+ except KeyError, e:
+ properties['$ref'] = self.typeref
asargent_no_longer_on_chrome 2012/03/06 22:27:57 Someday it would be cool to take note of not-yet-d
miket_OOO 2012/03/07 00:23:01 Agreed -- though at present, it's caught loudly an
asargent_no_longer_on_chrome 2012/03/07 00:42:09 Good point!
+ return properties
+
+class Namespace(object):
+ '''
+ Given an IDLNode representing an IDL namespace, converts into a Python
+ dictionary that the JSON schema compiler expects to see.
+ '''
+
+ def __init__(self, namespace_node):
+ self.namespace = namespace_node
+ self.events = []
+ self.functions = []
+ self.types = []
+ self.refs = {}
+
+ def process(self):
+ for node in self.namespace.children:
+ cls = node.cls
+ if cls == "Dictionary":
+ self.types.append(Dictionary(node).process(self.refs))
+ elif cls == "Callback":
+ k, v = Member(node).process(self.refs)
+ self.refs[k] = v
+ elif cls == "Interface" and node.GetName() == "Functions":
+ self.functions = self.process_interface(node)
+ elif cls == "Interface" and node.GetName() == "Events":
+ self.events = self.process_interface(node)
+
+ return { 'events': self.events,
+ 'functions': self.functions,
+ 'types': self.types,
+ 'namespace': self.namespace.GetName() }
asargent_no_longer_on_chrome 2012/03/06 22:27:57 looks like you're missing the 'nodoc' attribute if
miket_OOO 2012/03/07 00:23:01 Fixed. I know I'm being inconsistent here because
asargent_no_longer_on_chrome 2012/03/07 00:42:09 Good point. (It was actually seeing the code elsew
+
+ def process_interface(self, node):
+ members = []
+ for member in node.children:
+ if member.cls == 'Member':
+ name, properties = Member(member).process(self.refs)
+ members.append(properties)
+ return members
+
+class IDLSchema(object):
+ '''
+ Given a list of IDLNodes and IDLAttributes, converts into a Python list
+ of api_defs that the JSON schema compiler expects to see.
+ '''
+
+ def __init__(self, idl):
+ self.idl = idl
+
+ def process(self):
+ namespaces = []
+ for node in self.idl:
+ if node.cls == 'Namespace':
+ namespace = Namespace(node)
+ namespaces.append(namespace.process())
+ return namespaces
+
+def Load(filename):
+ '''
+ Given the filename of an IDL file, parses it and returns an equivalent
+ Python dictionary in a format that the JSON schema compiler expects to see.
+ '''
+
+ f = open(filename, 'r')
+ contents = f.read()
+ f.close()
+
+ idl = idl_parser.IDLParser().ParseData(contents, filename)
+ idl_schema = IDLSchema(idl)
+ return idl_schema.process()

Powered by Google App Engine
This is Rietveld 408576698