| 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
|
| index 7364800ee2437ab25445d08166d497b93397cffd..65d7baeb485f0a06026a24c2a2e02112c72f63e7 100755
|
| --- a/tools/json_schema_compiler/idl_schema.py
|
| +++ b/tools/json_schema_compiler/idl_schema.py
|
| @@ -6,6 +6,7 @@
|
| import itertools
|
| import json
|
| import os.path
|
| +import pprint
|
| import re
|
| import sys
|
|
|
| @@ -167,7 +168,7 @@ class Member(object):
|
| def __init__(self, member_node):
|
| self.node = member_node
|
|
|
| - def process(self, callbacks):
|
| + def process(self, callbacks, functions_are_properties=False):
|
| properties = OrderedDict()
|
| name = self.node.GetName()
|
| if self.node.GetProperty('deprecated'):
|
| @@ -187,34 +188,69 @@ class Member(object):
|
| properties['options'] = {}
|
| properties['options'][option_name] = sanitizer(self.node.GetProperty(
|
| option_name))
|
| - is_function = False
|
| + type_override = None
|
| parameter_comments = OrderedDict()
|
| for node in self.node.GetChildren():
|
| if node.cls == 'Comment':
|
| (parent_comment, parameter_comments) = ProcessComment(node.GetName())
|
| properties['description'] = parent_comment
|
| elif node.cls == 'Callspec':
|
| - is_function = True
|
| name, parameters, return_type = (Callspec(node, parameter_comments)
|
| .process(callbacks))
|
| - properties['parameters'] = parameters
|
| - if return_type is not None:
|
| - properties['returns'] = return_type
|
| + if functions_are_properties:
|
| + # If functions are treated as properties (which will happen if the
|
| + # interface is named Properties) then this isn't a function, it's a
|
| + # property which is encoded as a function with no arguments. The
|
| + # property type is the return type. This is an egregious hack in lieu
|
| + # of the IDL parser supporting 'const'.
|
| + assert parameters == [], (
|
| + 'Property "%s" must be no-argument functions '
|
| + 'with a non-void return type' % name)
|
| + assert return_type is not None, (
|
| + 'Property "%s" must be no-argument functions '
|
| + 'with a non-void return type' % name)
|
| + assert 'type' in return_type, (
|
| + 'Property return type "%s" from "%s" must specify a '
|
| + 'fundamental IDL type.' % (pprint.pformat(return_type), name))
|
| + type_override = return_type['type']
|
| + else:
|
| + type_override = 'function'
|
| + properties['parameters'] = parameters
|
| + if return_type is not None:
|
| + properties['returns'] = return_type
|
| properties['name'] = name
|
| - if is_function:
|
| - properties['type'] = 'function'
|
| + if type_override is not None:
|
| + properties['type'] = type_override
|
| else:
|
| properties = Typeref(self.node.GetProperty('TYPEREF'),
|
| self.node, properties).process(callbacks)
|
| + value = self.node.GetProperty('value')
|
| + if value is not None:
|
| + # IDL always returns values as strings, so cast to their real type.
|
| + properties['value'] = self.cast_from_json_type(properties['type'], value)
|
| enum_values = self.node.GetProperty('legalValues')
|
| if enum_values:
|
| - if properties['type'] == 'integer':
|
| - enum_values = map(int, enum_values)
|
| - elif properties['type'] == 'double':
|
| - enum_values = map(float, enum_values)
|
| - properties['enum'] = enum_values
|
| + # IDL always returns enum values as strings, so cast to their real type.
|
| + properties['enum'] = [self.cast_from_json_type(properties['type'], enum)
|
| + for enum in enum_values]
|
| return name, properties
|
|
|
| + def cast_from_json_type(self, json_type, string_value):
|
| + '''Casts from string |string_value| to a real Python type based on a JSON
|
| + Schema type |json_type|. For example, a string value of '42' and a JSON
|
| + Schema type 'integer' will cast to int('42') ==> 42.
|
| + '''
|
| + if json_type == 'integer':
|
| + return int(string_value)
|
| + if json_type == 'number':
|
| + return float(string_value)
|
| + # Add more as necessary.
|
| + assert json_type == 'string', (
|
| + 'No rule exists to cast JSON Schema type "%s" to its equivalent '
|
| + 'Python type for value "%s". You must add a new rule here.' %
|
| + (json_type, string_value))
|
| + return string_value
|
| +
|
|
|
| class Typeref(object):
|
| '''
|
| @@ -352,6 +388,7 @@ class Namespace(object):
|
| self.compiler_options = compiler_options
|
| self.events = []
|
| self.functions = []
|
| + self.properties = OrderedDict()
|
| self.types = []
|
| self.callbacks = OrderedDict()
|
| self.description = description
|
| @@ -369,6 +406,17 @@ class Namespace(object):
|
| self.functions = self.process_interface(node)
|
| elif node.cls == 'Interface' and node.GetName() == 'Events':
|
| self.events = self.process_interface(node)
|
| + elif node.cls == 'Interface' and node.GetName() == 'Properties':
|
| + properties_as_list = self.process_interface(
|
| + node, functions_are_properties=True)
|
| + for prop in properties_as_list:
|
| + # Properties are given as key-value pairs, but IDL will parse
|
| + # it as a list. Convert back to key-value pairs.
|
| + prop_name = prop.pop('name')
|
| + assert not self.properties.has_key(prop_name), (
|
| + 'Property "%s" cannot be specified more than once.' %
|
| + prop_name)
|
| + self.properties[prop_name] = prop
|
| elif node.cls == 'Enum':
|
| self.types.append(Enum(node).process())
|
| else:
|
| @@ -380,6 +428,7 @@ class Namespace(object):
|
| 'nodoc': self.nodoc,
|
| 'types': self.types,
|
| 'functions': self.functions,
|
| + 'properties': self.properties,
|
| 'internal': self.internal,
|
| 'events': self.events,
|
| 'platforms': self.platforms,
|
| @@ -387,11 +436,13 @@ class Namespace(object):
|
| 'deprecated': self.deprecated,
|
| 'documentation_options': documentation_options}
|
|
|
| - def process_interface(self, node):
|
| + def process_interface(self, node, functions_are_properties=False):
|
| members = []
|
| for member in node.GetChildren():
|
| if member.cls == 'Member':
|
| - _, properties = Member(member).process(self.callbacks)
|
| + _, properties = Member(member).process(
|
| + self.callbacks,
|
| + functions_are_properties=functions_are_properties)
|
| members.append(properties)
|
| return members
|
|
|
|
|