Commit 9d31ff5d authored by asargent@chromium.org's avatar asargent@chromium.org

Fix a bug in IDL parsing related to arrays of callbacks.

Also rename the 'refs' parameter to 'callbacks' to make the code a little bit
more clear, since 'refs' was only used to store callback information.

Matt noticed this bug after I landed 
https://chromiumcodereview.appspot.com/10054039/

It turns out the the rest of the JSON compiler infrastructure doesn't actually
support arrays of functions, but at least the IDL will generate the right JSON
in this case. 

BUG=none
TEST=included unit test should pass

Review URL: http://codereview.chromium.org/10080014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132430 0039d316-1c4b-4281-b951-d872f2087c98
parent 5e84138d
#! /usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import json
import os.path import os.path
import sys import sys
...@@ -28,10 +30,10 @@ class Callspec(object): ...@@ -28,10 +30,10 @@ class Callspec(object):
def __init__(self, callspec_node): def __init__(self, callspec_node):
self.node = callspec_node self.node = callspec_node
def process(self, refs): def process(self, callbacks):
parameters = [] parameters = []
for node in self.node.children: for node in self.node.children:
parameters.append(Param(node).process(refs)) parameters.append(Param(node).process(callbacks))
return self.node.GetName(), parameters return self.node.GetName(), parameters
class Param(object): class Param(object):
...@@ -42,10 +44,10 @@ class Param(object): ...@@ -42,10 +44,10 @@ class Param(object):
def __init__(self, param_node): def __init__(self, param_node):
self.node = param_node self.node = param_node
def process(self, refs): def process(self, callbacks):
return Typeref(self.node.GetProperty( 'TYPEREF'), return Typeref(self.node.GetProperty( 'TYPEREF'),
self.node, self.node,
{ 'name': self.node.GetName() }).process(refs) { 'name': self.node.GetName() }).process(callbacks)
class Dictionary(object): class Dictionary(object):
''' '''
...@@ -55,11 +57,11 @@ class Dictionary(object): ...@@ -55,11 +57,11 @@ class Dictionary(object):
def __init__(self, dictionary_node): def __init__(self, dictionary_node):
self.node = dictionary_node self.node = dictionary_node
def process(self, refs): def process(self, callbacks):
properties = {} properties = {}
for node in self.node.children: for node in self.node.children:
if node.cls == 'Member': if node.cls == 'Member':
k, v = Member(node).process(refs) k, v = Member(node).process(callbacks)
properties[k] = v properties[k] = v
return { 'id': self.node.GetName(), return { 'id': self.node.GetName(),
'properties': properties, 'properties': properties,
...@@ -74,7 +76,7 @@ class Member(object): ...@@ -74,7 +76,7 @@ class Member(object):
def __init__(self, member_node): def __init__(self, member_node):
self.node = member_node self.node = member_node
def process(self, refs): def process(self, callbacks):
properties = {} properties = {}
name = self.node.GetName() name = self.node.GetName()
if self.node.GetProperty('OPTIONAL'): if self.node.GetProperty('OPTIONAL'):
...@@ -85,14 +87,14 @@ class Member(object): ...@@ -85,14 +87,14 @@ class Member(object):
for node in self.node.children: for node in self.node.children:
if node.cls == 'Callspec': if node.cls == 'Callspec':
is_function = True is_function = True
name, parameters = Callspec(node).process(refs) name, parameters = Callspec(node).process(callbacks)
properties['parameters'] = parameters properties['parameters'] = parameters
properties['name'] = name properties['name'] = name
if is_function: if is_function:
properties['type'] = 'function' properties['type'] = 'function'
else: else:
properties = Typeref(self.node.GetProperty('TYPEREF'), properties = Typeref(self.node.GetProperty('TYPEREF'),
self.node, properties).process(refs) self.node, properties).process(callbacks)
return name, properties return name, properties
class Typeref(object): class Typeref(object):
...@@ -106,7 +108,7 @@ class Typeref(object): ...@@ -106,7 +108,7 @@ class Typeref(object):
self.parent = parent self.parent = parent
self.additional_properties = additional_properties self.additional_properties = additional_properties
def process(self, refs): def process(self, callbacks):
properties = self.additional_properties properties = self.additional_properties
result = properties result = properties
...@@ -141,9 +143,9 @@ class Typeref(object): ...@@ -141,9 +143,9 @@ class Typeref(object):
elif self.typeref is None: elif self.typeref is None:
properties['type'] = 'function' properties['type'] = 'function'
else: else:
try: if self.typeref in callbacks:
result = refs[self.typeref] properties.update(callbacks[self.typeref])
except KeyError, e: else:
properties['$ref'] = self.typeref properties['$ref'] = self.typeref
return result return result
...@@ -160,16 +162,16 @@ class Namespace(object): ...@@ -160,16 +162,16 @@ class Namespace(object):
self.events = [] self.events = []
self.functions = [] self.functions = []
self.types = [] self.types = []
self.refs = {} self.callbacks = {}
def process(self): def process(self):
for node in self.namespace.children: for node in self.namespace.children:
cls = node.cls cls = node.cls
if cls == "Dictionary": if cls == "Dictionary":
self.types.append(Dictionary(node).process(self.refs)) self.types.append(Dictionary(node).process(self.callbacks))
elif cls == "Callback": elif cls == "Callback":
k, v = Member(node).process(self.refs) k, v = Member(node).process(self.callbacks)
self.refs[k] = v self.callbacks[k] = v
elif cls == "Interface" and node.GetName() == "Functions": elif cls == "Interface" and node.GetName() == "Functions":
self.functions = self.process_interface(node) self.functions = self.process_interface(node)
elif cls == "Interface" and node.GetName() == "Events": elif cls == "Interface" and node.GetName() == "Events":
...@@ -187,7 +189,7 @@ class Namespace(object): ...@@ -187,7 +189,7 @@ class Namespace(object):
members = [] members = []
for member in node.children: for member in node.children:
if member.cls == 'Member': if member.cls == 'Member':
name, properties = Member(member).process(self.refs) name, properties = Member(member).process(self.callbacks)
members.append(properties) members.append(properties)
return members return members
...@@ -234,3 +236,15 @@ def Load(filename): ...@@ -234,3 +236,15 @@ def Load(filename):
idl = idl_parser.IDLParser().ParseData(contents, filename) idl = idl_parser.IDLParser().ParseData(contents, filename)
idl_schema = IDLSchema(idl) idl_schema = IDLSchema(idl)
return idl_schema.process() return idl_schema.process()
def Main():
'''
Dump a json serialization of parse result for the IDL files whose names
were passed in on the command line.
'''
for filename in sys.argv[1:]:
schema = Load(filename)
print json.dumps(schema, indent=2)
if __name__ == '__main__':
Main()
...@@ -43,5 +43,13 @@ class IdlSchemaTest(unittest.TestCase): ...@@ -43,5 +43,13 @@ class IdlSchemaTest(unittest.TestCase):
'items':{'$ref':'MyType2'}}]}] 'items':{'$ref':'MyType2'}}]}]
self.assertEquals(expected, getParams(schema, 'function12')) self.assertEquals(expected, getParams(schema, 'function12'))
def testArrayOfCallbacks(self):
schema = idl_schema.Load('test/idl_callback_arrays.idl')[0]
expected = [{'type':'array', 'name':'callbacks',
'items':{'type':'function', 'name':'MyCallback',
'parameters':[{'type':'integer', 'name':'x'}]}}]
self.assertEquals(expected, getParams(schema, 'whatever'))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
// 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.
// Tests the case of an array of callbacks as an a argument
namespace idl_callback_arrays {
callback MyCallback = void(long x);
interface Functions {
static void whatever(MyCallback[] callbacks);
};
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment