diff options
author | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-10 14:38:07 +0000 |
---|---|---|
committer | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-10 14:38:07 +0000 |
commit | 120513402d3216eb2302af40f3efc4092b00ecaa (patch) | |
tree | 163b182fb867621be80dea6023ee700bfb59e8bb /tools/json_schema_compiler | |
parent | 1a3a98614c89db39832dcbb1620775002f5ef12b (diff) | |
download | chromium_src-120513402d3216eb2302af40f3efc4092b00ecaa.zip chromium_src-120513402d3216eb2302af40f3efc4092b00ecaa.tar.gz chromium_src-120513402d3216eb2302af40f3efc4092b00ecaa.tar.bz2 |
Make all extension api types fully qualified.
BUG=123073
TEST= (unit_tests --gtest_filter=ExtensionAPI) && (browser_tests --gtest_filter=ExtensionApiTest)
Review URL: https://chromiumcodereview.appspot.com/10367002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136296 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/json_schema_compiler')
-rw-r--r-- | tools/json_schema_compiler/cc_generator.py | 9 | ||||
-rw-r--r-- | tools/json_schema_compiler/cpp_type_generator.py | 44 | ||||
-rwxr-xr-x | tools/json_schema_compiler/cpp_type_generator_test.py | 23 | ||||
-rw-r--r-- | tools/json_schema_compiler/h_generator.py | 3 | ||||
-rw-r--r-- | tools/json_schema_compiler/idl_schema.py | 5 | ||||
-rwxr-xr-x | tools/json_schema_compiler/idl_schema_test.py | 4 | ||||
-rw-r--r-- | tools/json_schema_compiler/json_schema.py | 6 | ||||
-rwxr-xr-x | tools/json_schema_compiler/model_test.py | 17 | ||||
-rw-r--r-- | tools/json_schema_compiler/schema_util.py | 37 | ||||
-rwxr-xr-x | tools/json_schema_compiler/schema_util_test.py | 67 | ||||
-rw-r--r-- | tools/json_schema_compiler/test/crossref.json | 8 | ||||
-rw-r--r-- | tools/json_schema_compiler/test/dependencyTester.json | 4 | ||||
-rw-r--r-- | tools/json_schema_compiler/test/windows.json | 2 |
13 files changed, 164 insertions, 65 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 3efad84..508e0f2 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py @@ -7,6 +7,7 @@ from model import PropertyType import any_helper import cpp_util import model +import schema_util import sys import util_cc_helper @@ -71,8 +72,8 @@ class CCGenerator(object): .Append() ) for type_ in self._namespace.types.values(): - (c.Concat(self._GenerateType(type_.name, type_)) - .Append() + (c.Concat(self._GenerateType( + schema_util.StripSchemaNamespace(type_.name), type_)).Append() ) if self._namespace.functions: (c.Append('//') @@ -95,7 +96,7 @@ class CCGenerator(object): def _GenerateType(self, cpp_namespace, type_): """Generates the function definitions for a type. """ - classname = cpp_util.Classname(type_.name) + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name)) c = Code() if type_.functions: @@ -174,7 +175,7 @@ class CCGenerator(object): E.g for type "Foo", generates Foo::Populate() """ - classname = cpp_util.Classname(type_.name) + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name)) c = Code() (c.Append('// static') .Sblock('bool %(namespace)s::Populate' diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py index 5afc915..1d3ac303 100644 --- a/tools/json_schema_compiler/cpp_type_generator.py +++ b/tools/json_schema_compiler/cpp_type_generator.py @@ -6,6 +6,8 @@ from code import Code 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 @@ -28,12 +30,10 @@ class CppTypeGenerator(object): beneath the root namespace. """ for type_ in namespace.types: - qualified_name = self._QualifyName(namespace, type_) - if qualified_name in self._type_namespaces: + if type_ in self._type_namespaces: raise ValueError('Type %s is declared in both %s and %s' % - (qualified_name, namespace.name, - self._type_namespaces[qualified_name].name)) - self._type_namespaces[qualified_name] = namespace + (type_, namespace.name, self._type_namespaces[type_].name)) + self._type_namespaces[type_] = namespace self._cpp_namespaces[namespace] = cpp_namespace def GetExpandedChoicesInParams(self, params): @@ -125,9 +125,9 @@ class CppTypeGenerator(object): raise KeyError('Cannot find referenced type: %s' % prop.ref_type) if self._namespace != dependency_namespace: cpp_type = '%s::%s' % (self._cpp_namespaces[dependency_namespace], - prop.ref_type) + schema_util.StripSchemaNamespace(prop.ref_type)) else: - cpp_type = prop.ref_type + cpp_type = schema_util.StripSchemaNamespace(prop.ref_type) elif prop.type_ == PropertyType.BOOLEAN: cpp_type = 'bool' elif prop.type_ == PropertyType.INTEGER: @@ -175,20 +175,21 @@ class CppTypeGenerator(object): for namespace, types in sorted(self._NamespaceTypeDependencies().items()): c.Append('namespace %s {' % namespace.name) for type_ in types: + type_name = schema_util.StripSchemaNamespace(type_) if namespace.types[type_].type_ == PropertyType.STRING: - c.Append('typedef std::string %s;' % type_) + 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_, 'item_type': + c.Substitute({'name': type_name, 'item_type': self.GetType(namespace.types[type_].item_type, wrap_optional=True)}) else: - c.Append('struct %s;' % type_) + c.Append('struct %s;' % type_name) c.Append('}') c.Concat(self.GetNamespaceStart()) for (name, type_) in self._namespace.types.items(): if not type_.functions and type_.type_ == PropertyType.OBJECT: - c.Append('struct %s;' % name) + c.Append('struct %s;' % schema_util.StripSchemaNamespace(name)) c.Concat(self.GetNamespaceEnd()) return c @@ -203,23 +204,13 @@ class CppTypeGenerator(object): return c def _ResolveTypeNamespace(self, ref_type): - """Resolves a type name to its enclosing namespace. - - Searches for the ref_type first as an explicitly qualified name, then within - the enclosing namespace, then within other namespaces that the current - namespace depends upon. + """Resolves a type, which must be explicitly qualified, to its enclosing + namespace. """ if ref_type in self._type_namespaces: return self._type_namespaces[ref_type] - - qualified_name = self._QualifyName(self._namespace, ref_type) - if qualified_name in self._type_namespaces: - return self._type_namespaces[qualified_name] - - for (type_name, namespace) in self._type_namespaces.items(): - if type_name == self._QualifyName(namespace, ref_type): - return namespace - + raise KeyError(('Cannot resolve type: %s.' % ref_type) + + 'Maybe it needs a namespace prefix if it comes from another namespace?') return None def GetReferencedProperty(self, prop): @@ -233,9 +224,6 @@ class CppTypeGenerator(object): return self._ResolveTypeNamespace(prop.ref_type).types.get(prop.ref_type, None) - def _QualifyName(self, namespace, name): - return '.'.join([namespace.name, name]) - def _NamespaceTypeDependencies(self): """Returns a dict containing a mapping of model.Namespace to the C++ type of type dependencies for self._namespace. diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py index 708bd46..46b10a2 100755 --- a/tools/json_schema_compiler/cpp_type_generator_test.py +++ b/tools/json_schema_compiler/cpp_type_generator_test.py @@ -119,27 +119,27 @@ class CppTypeGeneratorTest(unittest.TestCase): manager = CppTypeGenerator('', self.tabs, self.tabs.unix_name) self.assertEquals('int', manager.GetType( - self.tabs.types['Tab'].properties['id'])) + self.tabs.types['tabs.Tab'].properties['id'])) self.assertEquals('std::string', manager.GetType( - self.tabs.types['Tab'].properties['status'])) + self.tabs.types['tabs.Tab'].properties['status'])) self.assertEquals('bool', manager.GetType( - self.tabs.types['Tab'].properties['selected'])) + self.tabs.types['tabs.Tab'].properties['selected'])) def testStringAsType(self): manager = CppTypeGenerator('', self.font_settings, self.font_settings.unix_name) self.assertEquals('std::string', manager.GetType( - self.font_settings.types['ScriptCode'])) + self.font_settings.types['fontSettings.ScriptCode'])) def testArrayAsType(self): manager = CppTypeGenerator('', self.browser_action, self.browser_action.unix_name) self.assertEquals('std::vector<int>', manager.GetType( - self.browser_action.types['ColorArray'])) + self.browser_action.types['browserAction.ColorArray'])) def testGetTypeArray(self): manager = CppTypeGenerator('', self.windows, self.windows.unix_name) @@ -147,9 +147,8 @@ class CppTypeGeneratorTest(unittest.TestCase): manager.GetType( self.windows.functions['getAll'].callback.params[0])) manager = CppTypeGenerator('', self.permissions, self.permissions.unix_name) - self.assertEquals('std::vector<std::string>', - manager.GetType( - self.permissions.types['Permissions'].properties['origins'])) + self.assertEquals('std::vector<std::string>', manager.GetType( + self.permissions.types['permissions.Permissions'].properties['origins'])) def testGetTypeLocalRef(self): manager = CppTypeGenerator('', self.tabs, self.tabs.unix_name) @@ -162,16 +161,16 @@ class CppTypeGeneratorTest(unittest.TestCase): manager.AddNamespace(self.tabs, self.tabs.unix_name) self.assertEquals('std::vector<linked_ptr<tabs::Tab> >', manager.GetType( - self.windows.types['Window'].properties['tabs'])) + self.windows.types['windows.Window'].properties['tabs'])) def testGetTypeNotfound(self): - prop = self.windows.types['Window'].properties['tabs'].item_type + prop = self.windows.types['windows.Window'].properties['tabs'].item_type prop.ref_type = 'Something' manager = CppTypeGenerator('', self.windows, self.windows.unix_name) self.assertRaises(KeyError, manager.GetType, prop) def testGetTypeNotimplemented(self): - prop = self.windows.types['Window'].properties['tabs'].item_type + prop = self.windows.types['windows.Window'].properties['tabs'].item_type prop.type_ = 10 manager = CppTypeGenerator('', self.windows, self.windows.unix_name) self.assertRaises(NotImplementedError, manager.GetType, prop) @@ -180,7 +179,7 @@ class CppTypeGeneratorTest(unittest.TestCase): manager = CppTypeGenerator('', self.permissions, self.permissions.unix_name) self.assertEquals('std::vector<std::string> ', manager.GetType( - self.permissions.types['Permissions'].properties['origins'], + self.permissions.types['permissions.Permissions'].properties['origins'], pad_for_generics=True)) self.assertEquals('bool', manager.GetType( diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py index 9ce2868..a028813 100644 --- a/tools/json_schema_compiler/h_generator.py +++ b/tools/json_schema_compiler/h_generator.py @@ -7,6 +7,7 @@ from model import PropertyType import cpp_util import model import os +import schema_util class HGenerator(object): """A .h generator for a namespace. @@ -156,7 +157,7 @@ class HGenerator(object): def _GenerateType(self, type_): """Generates a struct for a type. """ - classname = cpp_util.Classname(type_.name) + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name)) c = Code() if type_.functions: diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index 087b2f4..bdaa2ca 100644 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py @@ -5,8 +5,10 @@ import json import os.path -import sys import re +import sys + +import schema_util # This file is a peer to json_schema.py. Each of these files understands a # certain format describing APIs (either JSON or IDL), reads files written @@ -256,6 +258,7 @@ class IDLSchema(object): continue else: sys.exit("Did not process %s %s" % (node.cls, node)) + schema_util.PrefixSchemasWithNamespace(namespaces) return namespaces def Load(filename): diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py index d045f62..024f408 100755 --- a/tools/json_schema_compiler/idl_schema_test.py +++ b/tools/json_schema_compiler/idl_schema_test.py @@ -33,14 +33,14 @@ class IdlSchemaTest(unittest.TestCase): self.assertEquals(expected, getParams(schema, 'function5')) expected = [{'type':'function', 'name':'Callback3', - 'parameters':[{'name':'arg', '$ref':'MyType1'}]}] + 'parameters':[{'name':'arg', '$ref':'idl_basics.MyType1'}]}] self.assertEquals(expected, getParams(schema, 'function6')) def testCallbackWithArrayArgument(self): schema = self.idl_basics expected = [{'type':'function', 'name':'Callback4', 'parameters':[{'name':'arg', 'type':'array', - 'items':{'$ref':'MyType2'}}]}] + 'items':{'$ref':'idl_basics.MyType2'}}]}] self.assertEquals(expected, getParams(schema, 'function12')) diff --git a/tools/json_schema_compiler/json_schema.py b/tools/json_schema_compiler/json_schema.py index f51cece..636f837 100644 --- a/tools/json_schema_compiler/json_schema.py +++ b/tools/json_schema_compiler/json_schema.py @@ -10,6 +10,7 @@ import sys _script_path = os.path.realpath(__file__) sys.path.insert(0, os.path.normpath(_script_path + "/../../")) import json_comment_eater +import schema_util def DeleteNocompileNodes(item): def HasNocompile(thing): @@ -32,9 +33,10 @@ def DeleteNocompileNodes(item): def Load(filename): with open(filename, 'r') as handle: - return DeleteNocompileNodes( + schemas = DeleteNocompileNodes( json.loads(json_comment_eater.Nom(handle.read()))) - + schema_util.PrefixSchemasWithNamespace(schemas) + return schemas # A dictionary mapping |filename| to the object resulting from loading the JSON # at |filename|. diff --git a/tools/json_schema_compiler/model_test.py b/tools/json_schema_compiler/model_test.py index 577b3ca..0a15187 100755 --- a/tools/json_schema_compiler/model_test.py +++ b/tools/json_schema_compiler/model_test.py @@ -32,25 +32,26 @@ class ModelTest(unittest.TestCase): sorted(self.permissions.functions.keys())) def testHasTypes(self): - self.assertEquals(['Tab'], self.tabs.types.keys()) - self.assertEquals(['Permissions'], self.permissions.types.keys()) - self.assertEquals(['Window'], self.windows.types.keys()) + self.assertEquals(['tabs.Tab'], self.tabs.types.keys()) + self.assertEquals(['permissions.Permissions'], + self.permissions.types.keys()) + self.assertEquals(['windows.Window'], self.windows.types.keys()) def testHasProperties(self): self.assertEquals(["active", "favIconUrl", "highlighted", "id", "incognito", "index", "pinned", "selected", "status", "title", "url", "windowId"], - sorted(self.tabs.types['Tab'].properties.keys())) + sorted(self.tabs.types['tabs.Tab'].properties.keys())) def testProperties(self): - string_prop = self.tabs.types['Tab'].properties['status'] + string_prop = self.tabs.types['tabs.Tab'].properties['status'] self.assertEquals(model.PropertyType.STRING, string_prop.type_) - integer_prop = self.tabs.types['Tab'].properties['id'] + integer_prop = self.tabs.types['tabs.Tab'].properties['id'] self.assertEquals(model.PropertyType.INTEGER, integer_prop.type_) - array_prop = self.windows.types['Window'].properties['tabs'] + array_prop = self.windows.types['windows.Window'].properties['tabs'] self.assertEquals(model.PropertyType.ARRAY, array_prop.type_) self.assertEquals(model.PropertyType.REF, array_prop.item_type.type_) - self.assertEquals('Tab', array_prop.item_type.ref_type) + self.assertEquals('tabs.Tab', array_prop.item_type.ref_type) object_prop = self.tabs.functions['query'].params[0] self.assertEquals(model.PropertyType.OBJECT, object_prop.type_) self.assertEquals( diff --git a/tools/json_schema_compiler/schema_util.py b/tools/json_schema_compiler/schema_util.py new file mode 100644 index 0000000..289d24d --- /dev/null +++ b/tools/json_schema_compiler/schema_util.py @@ -0,0 +1,37 @@ +# 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. +"""Utilies for the processing of schema python structures. +""" + +def StripSchemaNamespace(s): + last_dot = s.rfind('.') + if not last_dot == -1: + return s[last_dot + 1:] + return s + +def PrefixSchemasWithNamespace(schemas): + for s in schemas: + _PrefixWithNamespace(s.get("namespace"), s) + +def _MaybePrefixFieldWithNamespace(namespace, schema, key): + if type(schema) == dict and key in schema: + old_value = schema[key] + if not "." in old_value: + schema[key] = namespace + "." + old_value + +def _PrefixTypesWithNamespace(namespace, types): + for t in types: + _MaybePrefixFieldWithNamespace(namespace, t, "id") + _MaybePrefixFieldWithNamespace(namespace, t, "customBindings") + +def _PrefixWithNamespace(namespace, schema): + if type(schema) == dict: + if "types" in schema: + _PrefixTypesWithNamespace(namespace, schema.get("types")) + _MaybePrefixFieldWithNamespace(namespace, schema, "$ref") + for s in schema: + _PrefixWithNamespace(namespace, schema[s]) + elif type(schema) == list: + for s in schema: + _PrefixWithNamespace(namespace, s) diff --git a/tools/json_schema_compiler/schema_util_test.py b/tools/json_schema_compiler/schema_util_test.py new file mode 100755 index 0000000..ecdd17c --- /dev/null +++ b/tools/json_schema_compiler/schema_util_test.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# 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. + +import schema_util +import unittest + +class SchemaUtilTest(unittest.TestCase): + def testStripSchemaNamespace(self): + self.assertEquals('Bar', schema_util.StripSchemaNamespace('foo.Bar')) + self.assertEquals('Baz', schema_util.StripSchemaNamespace('Baz')) + + def testPrefixSchemasWithNamespace(self): + schemas = [ + { 'namespace': 'n1', + 'types': [ + { + 'id': 'T1', + 'customBindings': 'T1', + 'properties': { + 'p1': {'$ref': 'T1'}, + 'p2': {'$ref': 'fully.qualified.T'}, + } + } + ], + 'functions': [ + { + 'parameters': [ + { '$ref': 'T1' }, + { '$ref': 'fully.qualified.T' }, + ], + 'returns': { '$ref': 'T1' } + }, + ], + 'events': [ + { + 'parameters': [ + { '$ref': 'T1' }, + { '$ref': 'fully.qualified.T' }, + ], + }, + ], + }, + ] + schema_util.PrefixSchemasWithNamespace(schemas) + self.assertEquals('n1.T1', schemas[0]['types'][0]['id']) + self.assertEquals('n1.T1', schemas[0]['types'][0]['customBindings']) + self.assertEquals('n1.T1', + schemas[0]['types'][0]['properties']['p1']['$ref']) + self.assertEquals('fully.qualified.T', + schemas[0]['types'][0]['properties']['p2']['$ref']) + + self.assertEquals('n1.T1', + schemas[0]['functions'][0]['parameters'][0]['$ref']) + self.assertEquals('fully.qualified.T', + schemas[0]['functions'][0]['parameters'][1]['$ref']) + self.assertEquals('n1.T1', + schemas[0]['functions'][0]['returns']['$ref']) + + self.assertEquals('n1.T1', + schemas[0]['events'][0]['parameters'][0]['$ref']) + self.assertEquals('fully.qualified.T', + schemas[0]['events'][0]['parameters'][1]['$ref']) + +if __name__ == '__main__': + unittest.main() diff --git a/tools/json_schema_compiler/test/crossref.json b/tools/json_schema_compiler/test/crossref.json index 02e5c94..9d3f905 100644 --- a/tools/json_schema_compiler/test/crossref.json +++ b/tools/json_schema_compiler/test/crossref.json @@ -8,7 +8,7 @@ "type": "object", "properties": { "testType": { - "$ref": "TestType", + "$ref": "simple_api.TestType", "optional": true } } @@ -22,7 +22,7 @@ "parameters": [ { "name": "testType", - "$ref": "TestType", + "$ref": "simple_api.TestType", "optional": true }, { @@ -43,7 +43,7 @@ "parameters": [ { "name": "result", - "$ref": "TestType", + "$ref": "simple_api.TestType", "description": "A TestType." } ] @@ -59,7 +59,7 @@ "name": "paramObject", "type": "object", "properties": { - "testType": {"$ref": "TestType", "optional": true}, + "testType": {"$ref": "simple_api.TestType", "optional": true}, "boolean": {"type": "boolean"} } }, diff --git a/tools/json_schema_compiler/test/dependencyTester.json b/tools/json_schema_compiler/test/dependencyTester.json index 43b145a..aec4c15 100644 --- a/tools/json_schema_compiler/test/dependencyTester.json +++ b/tools/json_schema_compiler/test/dependencyTester.json @@ -18,10 +18,10 @@ "type": "object", "properties": { "color": { - "$ref": "ColorArray" + "$ref": "browserAction.ColorArray" }, "scriptCode": { - "$ref": "ScriptCode" + "$ref": "fontSettings.ScriptCode" } } } diff --git a/tools/json_schema_compiler/test/windows.json b/tools/json_schema_compiler/test/windows.json index 52fc683d..f6062d4 100644 --- a/tools/json_schema_compiler/test/windows.json +++ b/tools/json_schema_compiler/test/windows.json @@ -12,7 +12,7 @@ "left": {"type": "integer", "description": "The offset of the window from the left edge of the screen in pixels."}, "width": {"type": "integer", "description": "The width of the window in pixels."}, "height": {"type": "integer", "description": "The height of the window in pixels."}, - "tabs": {"type": "array", "items": { "$ref": "Tab" }, "optional": true, "description": "Array of $ref:Tab objects representing the current tabs in the window."}, + "tabs": {"type": "array", "items": { "$ref": "tabs.Tab" }, "optional": true, "description": "Array of $ref:Tab objects representing the current tabs in the window."}, "incognito": {"type": "boolean", "description": "Whether the window is incognito."}, "type": { "type": "string", |