summaryrefslogtreecommitdiffstats
path: root/tools/json_schema_compiler
diff options
context:
space:
mode:
Diffstat (limited to 'tools/json_schema_compiler')
-rw-r--r--tools/json_schema_compiler/cc_generator.py101
-rw-r--r--tools/json_schema_compiler/cpp_type_generator.py8
-rwxr-xr-xtools/json_schema_compiler/cpp_type_generator_test.py16
-rw-r--r--tools/json_schema_compiler/h_generator.py30
-rw-r--r--tools/json_schema_compiler/idl_schema.py120
-rwxr-xr-xtools/json_schema_compiler/idl_schema_test.py11
-rw-r--r--tools/json_schema_compiler/model.py4
-rw-r--r--tools/json_schema_compiler/schema_util.py4
-rw-r--r--tools/json_schema_compiler/test/idl_basics.idl4
9 files changed, 168 insertions, 130 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 1a7f80c..99e0eb3 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -42,12 +42,6 @@ class CCGenerator(object):
)
(c.Append()
- .Append('using base::Value;')
- .Append('using base::DictionaryValue;')
- .Append('using base::ListValue;')
- .Append('using base::BinaryValue;')
- .Append('using %s;' % any_helper.ANY_CLASS)
- .Append()
.Concat(self._cpp_type_generator.GetRootNamespaceStart())
.Concat(self._cpp_type_generator.GetNamespaceStart())
.Append()
@@ -173,13 +167,13 @@ class CCGenerator(object):
c = Code()
(c.Append('// static')
.Sblock('bool %(namespace)s::Populate'
- '(const Value& value, %(name)s* out) {')
- .Append('if (!value.IsType(Value::TYPE_DICTIONARY))')
+ '(const base::Value& value, %(name)s* out) {')
+ .Append('if (!value.IsType(base::Value::TYPE_DICTIONARY))')
.Append(' return false;')
)
if type_.properties:
- (c.Append('const DictionaryValue* dict = '
- 'static_cast<const DictionaryValue*>(&value);')
+ (c.Append('const base::DictionaryValue* dict = '
+ 'static_cast<const base::DictionaryValue*>(&value);')
.Append()
)
for prop in type_.properties.values():
@@ -204,12 +198,12 @@ class CCGenerator(object):
def _GenerateTypePopulateProperty(self, prop, src, dst):
"""Generate the code to populate a single property in a type.
- src: DictionaryValue*
+ src: base::DictionaryValue*
dst: Type*
"""
c = Code()
value_var = prop.unix_name + '_value'
- c.Append('Value* %(value_var)s = NULL;')
+ c.Append('base::Value* %(value_var)s = NULL;')
if prop.optional:
(c.Sblock(
'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {'
@@ -230,14 +224,16 @@ class CCGenerator(object):
return c
def _GenerateTypeToValue(self, cpp_namespace, type_):
- """Generates a function that serializes the type into a |DictionaryValue|.
+ """Generates a function that serializes the type into a
+ |base::DictionaryValue|.
E.g. for type "Foo" generates Foo::ToValue()
"""
c = Code()
- (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' %
+ (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' %
cpp_namespace)
- .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());')
+ .Append('scoped_ptr<base::DictionaryValue> value('
+ 'new base::DictionaryValue());')
.Append()
)
for prop in type_.properties.values():
@@ -287,27 +283,29 @@ class CCGenerator(object):
return c
def _GenerateCreateEnumValue(self, cpp_namespace, prop):
- """Generates CreateEnumValue() that returns the |StringValue|
+ """Generates CreateEnumValue() that returns the |base::StringValue|
representation of an enum.
"""
c = Code()
c.Append('// static')
- c.Sblock('scoped_ptr<Value> %(cpp_namespace)s::CreateEnumValue(%(arg)s) {')
+ c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue('
+ '%(arg)s) {')
c.Sblock('switch (%s) {' % prop.unix_name)
if prop.optional:
(c.Append('case %s: {' % self._cpp_type_generator.GetEnumNoneValue(prop))
- .Append(' return scoped_ptr<Value>();')
+ .Append(' return scoped_ptr<base::Value>();')
.Append('}')
)
for enum_value in prop.enum_values:
(c.Append('case %s: {' %
self._cpp_type_generator.GetEnumValue(prop, enum_value))
- .Append(' return scoped_ptr<Value>(Value::CreateStringValue("%s"));' %
- enum_value)
+ .Append(' return scoped_ptr<base::Value>('
+ 'base::Value::CreateStringValue("%s"));' %
+ enum_value)
.Append('}')
)
(c.Append('default: {')
- .Append(' return scoped_ptr<Value>();')
+ .Append(' return scoped_ptr<base::Value>();')
.Append('}')
)
c.Eblock('}')
@@ -320,20 +318,20 @@ class CCGenerator(object):
return c
def _CreateValueFromProperty(self, prop, var):
- """Creates a Value given a property. Generated code passes ownership
+ """Creates a base::Value given a property. Generated code passes ownership
to caller.
var: variable or variable*
- E.g for std::string, generate Value::CreateStringValue(var)
+ E.g for std::string, generate base::Value::CreateStringValue(var)
"""
if prop.type_ == PropertyType.CHOICES:
# CHOICES conversion not implemented. If needed, write something to
- # generate a function that returns a scoped_ptr<Value> and put it in
+ # generate a function that returns a scoped_ptr<base::Value> and put it in
# _GeneratePropertyFunctions, then use it here. Look at CreateEnumValue()
# for reference.
raise NotImplementedError(
- 'Conversion of CHOICES to Value not implemented')
+ 'Conversion of CHOICES to base::Value not implemented')
if self._IsObjectOrObjectRef(prop):
if prop.optional:
return '%s->ToValue().release()' % var
@@ -356,13 +354,13 @@ class CCGenerator(object):
var = '*' + var
prop = self._cpp_type_generator.GetReferencedProperty(prop);
return {
- PropertyType.STRING: 'Value::CreateStringValue(%s)',
- PropertyType.BOOLEAN: 'Value::CreateBooleanValue(%s)',
- PropertyType.INTEGER: 'Value::CreateIntegerValue(%s)',
- PropertyType.DOUBLE: 'Value::CreateDoubleValue(%s)',
+ PropertyType.STRING: 'base::Value::CreateStringValue(%s)',
+ PropertyType.BOOLEAN: 'base::Value::CreateBooleanValue(%s)',
+ PropertyType.INTEGER: 'base::Value::CreateIntegerValue(%s)',
+ PropertyType.DOUBLE: 'base::Value::CreateDoubleValue(%s)',
}[prop.type_] % var
else:
- raise NotImplementedError('Conversion of %s to Value not '
+ raise NotImplementedError('Conversion of %s to base::Value not '
'implemented' % repr(prop.type_))
def _GenerateParamsCheck(self, function, var):
@@ -391,14 +389,14 @@ class CCGenerator(object):
def _GenerateFunctionParamsCreate(self, cpp_namespace, function):
"""Generate function to create an instance of Params. The generated
- function takes a ListValue of arguments.
+ function takes a base::ListValue of arguments.
E.g for function "Bar", generate Bar::Params::Create()
"""
c = Code()
(c.Append('// static')
.Sblock('scoped_ptr<%(cpp_namespace)s::Params> '
- '%(cpp_namespace)s::Params::Create(const ListValue& args) {')
+ '%(cpp_namespace)s::Params::Create(const base::ListValue& args) {')
.Concat(self._GenerateParamsCheck(function, 'args'))
.Append('scoped_ptr<Params> params(new Params());')
)
@@ -415,9 +413,9 @@ class CCGenerator(object):
failure_value = 'scoped_ptr<Params>()'
c.Append()
value_var = param.unix_name + '_value'
- (c.Append('Value* %(value_var)s = NULL;')
- .Append('if (args.Get(%(i)s, &%(value_var)s) && '
- '!%(value_var)s->IsType(Value::TYPE_NULL))')
+ (c.Append('base::Value* %(value_var)s = NULL;')
+ .Append('if (args.Get(%(i)s, &%(value_var)s) &&\n'
+ ' !%(value_var)s->IsType(base::Value::TYPE_NULL))')
.Sblock('{')
.Concat(self._GeneratePopulatePropertyFromValue(
param, value_var, 'params', failure_value))
@@ -439,16 +437,17 @@ class CCGenerator(object):
def _GeneratePopulatePropertyFromValue(
self, prop, value_var, dst, failure_value, check_type=True):
- """Generates code to populate a model.Property given a Value*. The
- existence of data inside the Value* is assumed so checks for existence
+ """Generates code to populate a model.Property given a base::Value*. The
+ existence of data inside the base::Value* is assumed so checks for existence
should be performed before the code this generates.
prop: the property the code is populating.
- value_var: a Value* that should represent |prop|.
+ value_var: a base::Value* that should represent |prop|.
dst: the object with |prop| as a member.
failure_value: the value to return if |prop| cannot be extracted from
|value_var|
- check_type: if true, will check if |value_var| is the correct Value::Type
+ check_type: if true, will check if |value_var| is the correct
+ base::Value::Type
"""
c = Code()
c.Sblock('{')
@@ -474,7 +473,7 @@ class CCGenerator(object):
)
elif self._IsObjectOrObjectRef(prop):
if prop.optional:
- (c.Append('DictionaryValue* dictionary = NULL;')
+ (c.Append('base::DictionaryValue* dictionary = NULL;')
.Append('if (!%(value_var)s->GetAsDictionary(&dictionary))')
.Append(' return %(failure_value)s;')
.Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());')
@@ -483,7 +482,7 @@ class CCGenerator(object):
.Append('%(dst)s->%(name)s = temp.Pass();')
)
else:
- (c.Append('DictionaryValue* dictionary = NULL;')
+ (c.Append('base::DictionaryValue* dictionary = NULL;')
.Append('if (!%(value_var)s->GetAsDictionary(&dictionary))')
.Append(' return %(failure_value)s;')
.Append(
@@ -492,11 +491,11 @@ class CCGenerator(object):
)
elif prop.type_ == PropertyType.ANY:
if prop.optional:
- c.Append('%(dst)s->%(name)s.reset(new Any());')
+ c.Append('%(dst)s->%(name)s.reset(new ' + any_helper.ANY_CLASS + '());')
c.Append(self._any_helper.Init(prop, value_var, dst) + ';')
elif self._IsArrayOrArrayRef(prop):
# util_cc_helper deals with optional and required arrays
- (c.Append('ListValue* list = NULL;')
+ (c.Append('base::ListValue* list = NULL;')
.Append('if (!%(value_var)s->GetAsList(&list))')
.Append(' return %(failure_value)s;'))
if prop.item_type.type_ == PropertyType.ENUM:
@@ -533,12 +532,13 @@ class CCGenerator(object):
c.Eblock('}')
elif prop.type_ == PropertyType.BINARY:
# This is the same if the property is optional or not. We need a pointer
- # to the BinaryValue to be able to populate it, so a scoped_ptr is used
- # whether it is optional or required.
+ # to the base::BinaryValue to be able to populate it, so a scoped_ptr is
+ # used whether it is optional or required.
(c.Append('if (!%(value_var)s->IsType(%(value_type)s))')
.Append(' return %(failure_value)s;')
.Append('%(dst)s->%(name)s.reset(')
- .Append(' static_cast<BinaryValue*>(%(value_var)s)->DeepCopy());')
+ .Append(' static_cast<base::BinaryValue*>(%(value_var)s)'
+ '->DeepCopy());')
)
else:
raise NotImplementedError(prop.type_)
@@ -632,8 +632,8 @@ class CCGenerator(object):
params = function.callback.params
if not params:
- (c.Append('Value* %s::Result::Create() {' % cpp_namespace)
- .Append(' return Value::CreateNullValue();')
+ (c.Append('base::Value* %s::Result::Create() {' % cpp_namespace)
+ .Append(' return base::Value::CreateNullValue();')
.Append('}')
)
else:
@@ -648,13 +648,14 @@ class CCGenerator(object):
# time.
for param in expanded_params:
if param.type_ == PropertyType.ANY:
- # Generation of Value* Create(Value*) is redundant.
+ # Generation of base::Value* Create(base::Value*) is redundant.
continue
# We treat this argument as 'required' to avoid wrapping it in a
# scoped_ptr if it's optional.
param_copy = param.Copy()
param_copy.optional = False
- c.Sblock('Value* %(cpp_namespace)s::Result::Create(const %(arg)s) {')
+ c.Sblock('base::Value* %(cpp_namespace)s::Result::Create('
+ 'const %(arg)s) {')
c.Append('return %s;' %
self._CreateValueFromProperty(param_copy, param_copy.unix_name))
c.Eblock('}')
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py
index 55cb36e..28967b0 100644
--- a/tools/json_schema_compiler/cpp_type_generator.py
+++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -7,7 +7,6 @@ from model import PropertyType
import any_helper
import cpp_util
import schema_util
-import string
class CppTypeGenerator(object):
"""Manages the types of properties and provides utilities for getting the
@@ -191,9 +190,10 @@ class CppTypeGenerator(object):
c.Append('typedef std::string %s;' % type_name)
elif namespace.types[type_].type_ == PropertyType.ARRAY:
c.Append('typedef std::vector<%(item_type)s> %(name)s;')
- c.Substitute({'name': type_name, 'item_type':
- self.GetType(namespace.types[type_].item_type,
- wrap_optional=True)})
+ c.Substitute({
+ 'name': type_name,
+ 'item_type': self.GetType(namespace.types[type_].item_type,
+ wrap_optional=True)})
else:
c.Append('struct %s;' % type_name)
c.Append('}')
diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py
index b22c430..7c74fad 100755
--- a/tools/json_schema_compiler/cpp_type_generator_test.py
+++ b/tools/json_schema_compiler/cpp_type_generator_test.py
@@ -59,12 +59,14 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGenerateIncludesAndForwardDeclarationsMultipleTypes(self):
m = model.Model()
self.tabs_json[0]['types'].append(self.permissions_json[0]['types'][0])
- tabs_namespace = m.AddNamespace(self.tabs_json[0],
- 'path/to/tabs.json')
self.windows_json[0]['functions'].append(
self.permissions_json[0]['functions'][1])
+ # Insert 'windows' before 'tabs' in order to test that they are sorted
+ # properly.
windows = m.AddNamespace(self.windows_json[0],
'path/to/windows.json')
+ tabs_namespace = m.AddNamespace(self.tabs_json[0],
+ 'path/to/tabs.json')
manager = CppTypeGenerator('', windows, self.windows.unix_name)
manager.AddNamespace(tabs_namespace, self.tabs.unix_name)
self.assertEquals('#include "path/to/tabs.h"',
@@ -81,16 +83,18 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGenerateIncludesAndForwardDeclarationsDependencies(self):
m = model.Model()
- browser_action_namespace = m.AddNamespace(self.browser_action_json[0],
- 'path/to/browser_action.json')
+ # Insert 'font_settings' before 'browser_action' in order to test that
+ # CppTypeGenerator sorts them properly.
font_settings_namespace = m.AddNamespace(self.font_settings_json[0],
'path/to/font_settings.json')
+ browser_action_namespace = m.AddNamespace(self.browser_action_json[0],
+ 'path/to/browser_action.json')
manager = CppTypeGenerator('', self.dependency_tester,
self.dependency_tester.unix_name)
- manager.AddNamespace(browser_action_namespace,
- self.browser_action.unix_name)
manager.AddNamespace(font_settings_namespace,
self.font_settings.unix_name)
+ manager.AddNamespace(browser_action_namespace,
+ self.browser_action.unix_name)
self.assertEquals('#include "path/to/browser_action.h"\n'
'#include "path/to/font_settings.h"',
manager.GenerateIncludes().Render())
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index b5801ef..30a357d 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -5,8 +5,6 @@
from code import Code
from model import PropertyType
import cpp_util
-import model
-import os
import schema_util
class HGenerator(object):
@@ -110,7 +108,8 @@ class HGenerator(object):
raise ValueError("Illegal circular dependency via cycle " +
", ".join(map(lambda x: x.name, path + [type_])))
for prop in type_.properties.values():
- if not prop.optional and prop.type_ == PropertyType.REF:
+ if (prop.type_ == PropertyType.REF and
+ schema_util.GetNamespace(prop.ref_type) == self._namespace.name):
ExpandType(path + [type_], self._namespace.types[prop.ref_type])
if not type_ in dependency_order:
dependency_order.append(type_)
@@ -177,7 +176,6 @@ class HGenerator(object):
if type_.description:
c.Comment(type_.description)
c.Append('typedef std::string %(classname)s;')
- c.Substitute({'classname': classname})
else:
if type_.description:
c.Comment(type_.description)
@@ -189,18 +187,18 @@ class HGenerator(object):
.Concat(self._GenerateFields(type_.properties.values()))
)
if type_.from_json:
- (c.Comment('Populates a %s object from a Value. Returns'
+ (c.Comment('Populates a %s object from a base::Value. Returns'
' whether |out| was successfully populated.' % classname)
- .Append(
- 'static bool Populate(const Value& value, %(classname)s* out);')
+ .Append('static bool Populate(const base::Value& value, '
+ '%(classname)s* out);')
.Append()
)
if type_.from_client:
- (c.Comment('Returns a new DictionaryValue representing the'
+ (c.Comment('Returns a new base::DictionaryValue representing the'
' serialized form of this %s object. Passes '
'ownership to caller.' % classname)
- .Append('scoped_ptr<DictionaryValue> ToValue() const;')
+ .Append('scoped_ptr<base::DictionaryValue> ToValue() const;')
)
(c.Eblock()
@@ -238,7 +236,8 @@ class HGenerator(object):
.Concat(self._GenerateFields(function.params))
.Append('~Params();')
.Append()
- .Append('static scoped_ptr<Params> Create(const ListValue& args);')
+ .Append('static scoped_ptr<Params> Create('
+ 'const base::ListValue& args);')
.Eblock()
.Sblock(' private:')
.Append('Params();')
@@ -273,7 +272,7 @@ class HGenerator(object):
enum_name,
prop,
prop.enum_values))
- c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' %
+ c.Append('static scoped_ptr<base::Value> CreateEnumValue(%s %s);' %
(enum_name, prop.unix_name))
return c
@@ -285,7 +284,7 @@ class HGenerator(object):
c.Sblock('namespace Result {')
params = function.callback.params
if not params:
- c.Append('Value* Create();')
+ c.Append('base::Value* Create();')
else:
c.Concat(self._GeneratePropertyStructures(params))
@@ -297,11 +296,12 @@ class HGenerator(object):
if param.description:
c.Comment(param.description)
if param.type_ == PropertyType.ANY:
- c.Comment("Value* Result::Create(Value*) not generated "
+ c.Comment("base::Value* Result::Create(base::Value*) not generated "
"because it's redundant.")
continue
- c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration(
- param, self._cpp_type_generator.GetType(param)))
+ c.Append('base::Value* Create(const %s);' %
+ cpp_util.GetParameterDeclaration(
+ param, self._cpp_type_generator.GetType(param)))
c.Eblock('};')
return c
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py
index 09b75a2..d59103b 100644
--- a/tools/json_schema_compiler/idl_schema.py
+++ b/tools/json_schema_compiler/idl_schema.py
@@ -55,7 +55,7 @@ def ProcessComment(comment):
# Escape double quotes.
comment = comment.replace('"', '\\"');
- # Find all the parameter comments of the form "|name|: comment".
+ # Find all the parameter comments of the form '|name|: comment'.
parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment))
# Get the parent comment (everything before the first parameter comment.
@@ -104,9 +104,9 @@ class Param(object):
self.node = param_node
def process(self, callbacks):
- return Typeref(self.node.GetProperty( 'TYPEREF'),
+ return Typeref(self.node.GetProperty('TYPEREF'),
self.node,
- { 'name': self.node.GetName() }).process(callbacks)
+ {'name': self.node.GetName()}).process(callbacks)
class Dictionary(object):
'''
@@ -122,30 +122,12 @@ class Dictionary(object):
if node.cls == 'Member':
k, v = Member(node).process(callbacks)
properties[k] = v
- return { 'id': self.node.GetName(),
- 'properties': properties,
- 'type': 'object' }
-
-class Enum(object):
- '''
- Given an IDL Enum node, converts into a Python dictionary that the JSON
- schema compiler expects to see.
- '''
- def __init__(self, enum_node):
- self.node = enum_node
-
- def process(self, callbacks):
- enum = []
- for node in self.node.children:
- if node.cls == 'EnumItem':
- name = node.GetName()
- enum.append(name)
- else:
- sys.exit("Did not process %s %s" % (node.cls, node))
- return { "id" : self.node.GetName(),
- 'enum': enum,
- 'type': 'string' }
-
+ result = {'id': self.node.GetName(),
+ 'properties': properties,
+ 'type': 'object'}
+ if self.node.GetProperty('inline_doc'):
+ result['inline_doc'] = True
+ return result
class Member(object):
@@ -169,8 +151,7 @@ class Member(object):
if node.cls == 'Comment':
(parent_comment, parameter_comments) = ProcessComment(node.GetName())
properties['description'] = parent_comment
- for node in self.node.children:
- if node.cls == 'Callspec':
+ elif node.cls == 'Callspec':
is_function = True
name, parameters = Callspec(node, parameter_comments).process(callbacks)
properties['parameters'] = parameters
@@ -180,6 +161,13 @@ class Member(object):
else:
properties = Typeref(self.node.GetProperty('TYPEREF'),
self.node, properties).process(callbacks)
+ 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
return name, properties
class Typeref(object):
@@ -240,42 +228,70 @@ class Typeref(object):
return result
+
+class Enum(object):
+ '''
+ Given an IDL Enum node, converts into a Python dictionary that the JSON
+ schema compiler expects to see.
+ '''
+ def __init__(self, enum_node):
+ self.node = enum_node
+ self.description = ''
+
+ def process(self, callbacks):
+ enum = []
+ for node in self.node.children:
+ if node.cls == 'EnumItem':
+ enum.append(node.GetName())
+ elif node.cls == 'Comment':
+ self.description = ProcessComment(node.GetName())[0]
+ else:
+ sys.exit('Did not process %s %s' % (node.cls, node))
+ result = {'id' : self.node.GetName(),
+ 'description': self.description,
+ 'type': 'string',
+ 'enum': enum}
+ if self.node.GetProperty('inline_doc'):
+ result['inline_doc'] = True
+ return result
+
+
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, nodoc=False):
+ def __init__(self, namespace_node, nodoc=False, permissions=None):
self.namespace = namespace_node
self.nodoc = nodoc
self.events = []
self.functions = []
self.types = []
self.callbacks = {}
+ self.permissions = permissions or []
def process(self):
for node in self.namespace.children:
- cls = node.cls
- if cls == "Dictionary":
+ if node.cls == 'Dictionary':
self.types.append(Dictionary(node).process(self.callbacks))
- elif cls == "Callback":
+ elif node.cls == 'Callback':
k, v = Member(node).process(self.callbacks)
self.callbacks[k] = v
- elif cls == "Interface" and node.GetName() == "Functions":
+ elif node.cls == 'Interface' and node.GetName() == 'Functions':
self.functions = self.process_interface(node)
- elif cls == "Interface" and node.GetName() == "Events":
+ elif node.cls == 'Interface' and node.GetName() == 'Events':
self.events = self.process_interface(node)
- elif cls == "Enum":
+ elif node.cls == 'Enum':
self.types.append(Enum(node).process(self.callbacks))
else:
- sys.exit("Did not process %s %s" % (node.cls, node))
-
- return { 'events': self.events,
- 'functions': self.functions,
- 'types': self.types,
- 'namespace': self.namespace.GetName(),
- 'nodoc': self.nodoc }
+ sys.exit('Did not process %s %s' % (node.cls, node))
+ return {'namespace': self.namespace.GetName(),
+ 'nodoc': self.nodoc,
+ 'documentation_permissions_required': self.permissions,
+ 'types': self.types,
+ 'functions': self.functions,
+ 'events': self.events}
def process_interface(self, node):
members = []
@@ -296,23 +312,25 @@ class IDLSchema(object):
def process(self):
namespaces = []
+ nodoc = False
+ permissions = None
for node in self.idl:
- nodoc = False
- cls = node.cls
- if cls == 'Namespace':
- namespace = Namespace(node, nodoc)
+ if node.cls == 'Namespace':
+ namespace = Namespace(node, nodoc, permissions)
namespaces.append(namespace.process())
- elif cls == 'Copyright':
+ elif node.cls == 'Copyright':
continue
- elif cls == 'Comment':
+ elif node.cls == 'Comment':
continue
- elif cls == 'ExtAttribute':
+ elif node.cls == 'ExtAttribute':
if node.name == 'nodoc':
nodoc = bool(node.value)
+ elif node.name == 'permissions':
+ permission = node.value.split(',')
else:
continue
else:
- sys.exit("Did not process %s %s" % (node.cls, node))
+ sys.exit('Did not process %s %s' % (node.cls, node))
schema_util.PrefixSchemasWithNamespace(namespaces)
return namespaces
diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py
index f83d616..71bf987 100755
--- a/tools/json_schema_compiler/idl_schema_test.py
+++ b/tools/json_schema_compiler/idl_schema_test.py
@@ -56,11 +56,18 @@ class IdlSchemaTest(unittest.TestCase):
'parameters':[{'type':'integer', 'name':'x'}]}}]
self.assertEquals(expected, getParams(schema, 'whatever'))
+ def testLegalValues(self):
+ self.assertEquals({
+ 'x': {'name': 'x', 'type': 'integer', 'enum': [1,2],
+ 'description': 'This comment tests \\\"double-quotes\\\".'},
+ 'y': {'name': 'y', 'type': 'string'}},
+ getType(self.idl_basics, 'idl_basics.MyType1')['properties'])
+
def testEnum(self):
schema = self.idl_basics
- expected = {'enum': ['name1', 'name2'],
+ expected = {'enum': ['name1', 'name2'], 'description': 'Enum description',
'type': 'string', 'id': 'idl_basics.EnumType'}
- self.assertEquals(expected, getType(schema, 'idl_basics.EnumType'))
+ self.assertEquals(expected, getType(schema, expected['id']))
expected = [{'name':'type', '$ref':'idl_basics.EnumType'},
{'type':'function', 'name':'Callback5',
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py
index 63973d4..bb3fe0e 100644
--- a/tools/json_schema_compiler/model.py
+++ b/tools/json_schema_compiler/model.py
@@ -193,7 +193,9 @@ class Property(object):
elif '$ref' in json:
self.ref_type = json['$ref']
self.type_ = PropertyType.REF
- elif 'enum' in json:
+ elif 'enum' in json and json.get('type') == 'string':
+ # Non-string enums (as in the case of [legalValues=(1,2)]) should fall
+ # through to the next elif.
self.enum_values = []
for value in json['enum']:
self.enum_values.append(value)
diff --git a/tools/json_schema_compiler/schema_util.py b/tools/json_schema_compiler/schema_util.py
index 289d24d..177e77f 100644
--- a/tools/json_schema_compiler/schema_util.py
+++ b/tools/json_schema_compiler/schema_util.py
@@ -4,6 +4,10 @@
"""Utilies for the processing of schema python structures.
"""
+def GetNamespace(ref_type):
+ if '.' in ref_type:
+ return ref_type[:ref_type.rindex('.')]
+
def StripSchemaNamespace(s):
last_dot = s.rfind('.')
if not last_dot == -1:
diff --git a/tools/json_schema_compiler/test/idl_basics.idl b/tools/json_schema_compiler/test/idl_basics.idl
index af5442e..39298ec 100644
--- a/tools/json_schema_compiler/test/idl_basics.idl
+++ b/tools/json_schema_compiler/test/idl_basics.idl
@@ -5,13 +5,15 @@
// Tests a variety of basic API definition features.
namespace idl_basics {
+ // Enum description
enum EnumType {
name1,
name2
};
dictionary MyType1 {
- long x; // This comment tests "double-quotes".
+ // This comment tests "double-quotes".
+ [legalValues=(1,2)] long x;
DOMString y;
};