summaryrefslogtreecommitdiffstats
path: root/tools/json_schema_compiler
diff options
context:
space:
mode:
authorricow@chromium.org <ricow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 11:14:37 +0000
committerricow@chromium.org <ricow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 11:14:37 +0000
commit78acaf6d0ac35af3081e20511afdd9565520d067 (patch)
tree5ba4004249e535cf12d624a66aedce51aebaa874 /tools/json_schema_compiler
parent85db26ae55f5b20a32884e38ce39b8ba449238b1 (diff)
downloadchromium_src-78acaf6d0ac35af3081e20511afdd9565520d067.zip
chromium_src-78acaf6d0ac35af3081e20511afdd9565520d067.tar.gz
chromium_src-78acaf6d0ac35af3081e20511afdd9565520d067.tar.bz2
Revert 176047
> Revert 176015 > > Run the JSON Schema Compiler's bundle compilation on JSON files. Previously it > > was only run on IDL files. Clean up all the code which that simplifies. > > > > TBR=isherman@chromium.org,battre@chromium.org,akalin@chromium.org > > BUG=141318 > > > > Review URL: https://chromiumcodereview.appspot.com/11747025 > > This seems to be causing complation failures on release win builders: > http://chromegw/i/chromium.chrome/builders/Google%20Chrome%20Win/builds/15702 > > TBR=kalman@chromium.org > Review URL: https://codereview.chromium.org/11826048 Drover messed up this revert, reverting it TBR=ricow@chromium.org Review URL: https://codereview.chromium.org/11778096 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176051 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/json_schema_compiler')
-rw-r--r--tools/json_schema_compiler/code.py8
-rwxr-xr-xtools/json_schema_compiler/compiler.py11
-rw-r--r--tools/json_schema_compiler/model.py76
-rw-r--r--tools/json_schema_compiler/schema_bundle_generator.py56
-rw-r--r--tools/json_schema_compiler/test/json_schema_compiler_tests.gyp15
5 files changed, 133 insertions, 33 deletions
diff --git a/tools/json_schema_compiler/code.py b/tools/json_schema_compiler/code.py
index 07f6574..e4326d4 100644
--- a/tools/json_schema_compiler/code.py
+++ b/tools/json_schema_compiler/code.py
@@ -14,15 +14,17 @@ class Code(object):
self._indent_size = indent_size
self._comment_length = comment_length
- def Append(self, line='', substitute=True):
+ def Append(self, line='', substitute=True, indent_level=None):
"""Appends a line of code at the current indent level or just a newline if
line is not specified. Trailing whitespace is stripped.
substitute: indicated whether this line should be affected by
code.Substitute().
"""
- self._code.append(Line(((' ' * self._indent_level) + line).rstrip(),
- substitute=substitute))
+ if indent_level is None:
+ indent_level = self._indent_level
+ self._code.append(Line(((' ' * indent_level) + line).rstrip(),
+ substitute=substitute))
return self
def IsEmpty(self):
diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py
index ae92373..a347541 100755
--- a/tools/json_schema_compiler/compiler.py
+++ b/tools/json_schema_compiler/compiler.py
@@ -69,13 +69,16 @@ def handle_single_schema(filename, dest_dir, root, root_namespace):
referenced_api_defs = json_schema.Load(referenced_schema_path)
for namespace in referenced_api_defs:
- api_model.AddNamespace(namespace,
+ api_model.AddNamespace(
+ namespace,
os.path.relpath(referenced_schema_path, opts.root))
# Gets the relative path from opts.root to the schema to correctly determine
# the include path.
relpath = os.path.relpath(schema, opts.root)
- namespace = api_model.AddNamespace(target_namespace, relpath)
+ namespace = api_model.AddNamespace(target_namespace,
+ relpath,
+ include_compiler_options=True)
if not namespace:
continue
@@ -130,7 +133,9 @@ def handle_bundle_schema(filenames, dest_dir, root, root_namespace):
relpath = os.path.relpath(os.path.normpath(filenames[0]), root)
for target_namespace, schema_filename in zip(api_defs, filenames):
- namespace = api_model.AddNamespace(target_namespace, relpath)
+ namespace = api_model.AddNamespace(target_namespace,
+ relpath,
+ include_compiler_options=True)
path, filename = os.path.split(schema_filename)
short_filename, extension = os.path.splitext(filename)
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py
index b583712..36be5a3 100644
--- a/tools/json_schema_compiler/model.py
+++ b/tools/json_schema_compiler/model.py
@@ -26,10 +26,12 @@ class Model(object):
def __init__(self):
self.namespaces = {}
- def AddNamespace(self, json, source_file):
+ def AddNamespace(self, json, source_file, include_compiler_options=False):
"""Add a namespace's json to the model and returns the namespace.
"""
- namespace = Namespace(json, source_file)
+ namespace = Namespace(json,
+ source_file,
+ include_compiler_options=include_compiler_options)
self.namespaces[namespace.name] = namespace
return namespace
@@ -42,21 +44,28 @@ class Namespace(object):
- |source_file| the file that contained the namespace definition
- |source_file_dir| the directory component of |source_file|
- |source_file_filename| the filename component of |source_file|
+ - |platforms| if not None, the list of platforms that the namespace is
+ available to
- |types| a map of type names to their model.Type
- |functions| a map of function names to their model.Function
- |events| a map of event names to their model.Function
- |properties| a map of property names to their model.Property
+ - |compiler_options| the compiler_options dict, only present if
+ |include_compiler_options| is True
"""
- def __init__(self, json, source_file):
+ def __init__(self, json, source_file, include_compiler_options=False):
self.name = json['namespace']
self.unix_name = UnixName(self.name)
self.source_file = source_file
self.source_file_dir, self.source_file_filename = os.path.split(source_file)
self.parent = None
+ self.platforms = _GetPlatforms(json)
_AddTypes(self, json, self)
_AddFunctions(self, json, self)
_AddEvents(self, json, self)
_AddProperties(self, json, self)
+ if include_compiler_options:
+ self.compiler_options = json.get('compiler_options', {})
class Type(object):
"""A Type defined in the json.
@@ -127,13 +136,15 @@ class Function(object):
Properties:
- |name| the function name
+ - |platforms| if not None, the list of platforms that the function is
+ available to
- |params| a list of parameters to the function (order matters). A separate
- parameter is used for each choice of a 'choices' parameter.
+ parameter is used for each choice of a 'choices' parameter
- |description| a description of the function (if provided)
- |callback| the callback parameter to the function. There should be exactly
- one
+ one
- |optional| whether the Function is "optional"; this only makes sense to be
- present when the Function is representing a callback property.
+ present when the Function is representing a callback property
- |simple_name| the name of this Function without a namespace
"""
def __init__(self,
@@ -144,6 +155,7 @@ class Function(object):
from_client=False):
self.name = json['name']
self.simple_name = _StripNamespace(self.name, namespace)
+ self.platforms = _GetPlatforms(json)
self.params = []
self.description = json.get('description')
self.callback = None
@@ -357,23 +369,37 @@ class Property(object):
unix_name = property(GetUnixName, SetUnixName)
-class _PropertyTypeInfo(object):
- """This class is not an inner class of |PropertyType| so it can be pickled.
+class _Enum(object):
+ """Superclass for enum types with a "name" field, setting up repr/eq/ne.
+ Enums need to do this so that equality/non-equality work over pickling.
"""
- def __init__(self, is_fundamental, name):
- self.is_fundamental = is_fundamental
+
+ @staticmethod
+ def GetAll(cls):
+ """Yields all _Enum objects declared in |cls|.
+ """
+ for prop_key in dir(cls):
+ prop_value = getattr(cls, prop_key)
+ if isinstance(prop_value, _Enum):
+ yield prop_value
+
+ def __init__(self, name):
self.name = name
- def __repr__(self):
+ def __repr(self):
return self.name
def __eq__(self, other):
- return isinstance(other, _PropertyTypeInfo) and self.name == other.name
+ return type(other) == type(self) and other.name == self.name
def __ne__(self, other):
- # Yes. You seriously do need this.
return not (self == other)
+class _PropertyTypeInfo(_Enum):
+ def __init__(self, is_fundamental, name):
+ _Enum.__init__(self, name)
+ self.is_fundamental = is_fundamental
+
class PropertyType(object):
"""Enum of different types of properties/parameters.
"""
@@ -461,3 +487,27 @@ def _AddProperties(model,
namespace,
from_json=from_json,
from_client=from_client)
+
+class _PlatformInfo(_Enum):
+ def __init__(self, name):
+ _Enum.__init__(self, name)
+
+class Platforms(object):
+ """Enum of the possible platforms.
+ """
+ CHROMEOS = _PlatformInfo("chromeos")
+ CHROMEOS_TOUCH = _PlatformInfo("chromeos_touch")
+ LINUX = _PlatformInfo("linux")
+ MAC = _PlatformInfo("mac")
+ WIN = _PlatformInfo("win")
+
+def _GetPlatforms(json):
+ if 'platforms' not in json:
+ return None
+ platforms = []
+ for platform_name in json['platforms']:
+ for platform_enum in _Enum.GetAll(Platforms):
+ if platform_name == platform_enum.name:
+ platforms.append(platform_enum)
+ break
+ return platforms
diff --git a/tools/json_schema_compiler/schema_bundle_generator.py b/tools/json_schema_compiler/schema_bundle_generator.py
index d391ea7..3272be1 100644
--- a/tools/json_schema_compiler/schema_bundle_generator.py
+++ b/tools/json_schema_compiler/schema_bundle_generator.py
@@ -4,6 +4,7 @@
import code
import cpp_util
+from model import Platforms
from schema_util import CapitalizeFirstLetter
from schema_util import JsFunctionNameToClassName
@@ -44,6 +45,20 @@ class SchemaBundleGenerator(object):
c.Append()
return c
+ def _GetPlatformIfdefs(self, model_object):
+ """Generates the "defined" conditional for an #if check if |model_object|
+ has platform restrictions. Returns None if there are no restrictions.
+ """
+ if model_object.platforms is None:
+ return None
+ ifdefs = []
+ for platform in model_object.platforms:
+ if platform == Platforms.CHROMEOS:
+ ifdefs.append('defined(OS_CHROMEOS)')
+ else:
+ raise ValueError("Unsupported platform ifdef: %s" % platform.name)
+ return ' and '.join(ifdefs)
+
def GenerateAPIHeader(self):
"""Generates the header for API registration / declaration"""
c = code.Code()
@@ -53,9 +68,19 @@ class SchemaBundleGenerator(object):
c.Append('#include "base/basictypes.h"')
for namespace in self._model.namespaces.values():
+ ifdefs = self._GetPlatformIfdefs(namespace)
+ if ifdefs is not None:
+ c.Append("#if %s" % ifdefs, indent_level=0)
+
namespace_name = namespace.unix_name.replace("experimental_", "")
- c.Append('#include "chrome/browser/extensions/api/%s/%s_api.h"' % (
- namespace_name, namespace_name))
+ implementation_header = namespace.compiler_options.get(
+ "implemented_in",
+ "chrome/browser/extensions/api/%s/%s_api.h" % (namespace_name,
+ namespace_name))
+ c.Append('#include "%s"' % implementation_header)
+
+ if ifdefs is not None:
+ c.Append("#endif // %s" % ifdefs, indent_level=0)
c.Append()
c.Append("class ExtensionFunctionRegistry;")
@@ -70,20 +95,41 @@ class SchemaBundleGenerator(object):
c.Append()
return self.GenerateHeader('generated_api', c)
+ def _GetNamespaceFunctions(self, namespace):
+ functions = list(namespace.functions.values())
+ if namespace.compiler_options.get("generate_type_functions", False):
+ for type_ in namespace.types.values():
+ functions += list(type_.functions.values())
+ return functions
+
def GenerateFunctionRegistry(self):
c = code.Code()
c.Sblock("class GeneratedFunctionRegistry {")
- c.Append("public:")
+ c.Append(" public:")
c.Sblock("static void RegisterAll(ExtensionFunctionRegistry* registry) {")
for namespace in self._model.namespaces.values():
+ namespace_ifdefs = self._GetPlatformIfdefs(namespace)
+ if namespace_ifdefs is not None:
+ c.Append("#if %s" % namespace_ifdefs, indent_level=0)
+
namespace_name = CapitalizeFirstLetter(namespace.name.replace(
"experimental.", ""))
- for function in namespace.functions.values():
+ for function in self._GetNamespaceFunctions(namespace):
if function.nocompile:
continue
+ function_ifdefs = self._GetPlatformIfdefs(function)
+ if function_ifdefs is not None:
+ c.Append("#if %s" % function_ifdefs, indent_level=0)
+
function_name = JsFunctionNameToClassName(namespace.name, function.name)
c.Append("registry->RegisterFunction<%sFunction>();" % (
function_name))
+
+ if function_ifdefs is not None:
+ c.Append("#endif // %s" % function_ifdefs, indent_level=0)
+
+ if namespace_ifdefs is not None:
+ c.Append("#endif // %s" % namespace_ifdefs, indent_level=0)
c.Eblock("}")
c.Eblock("};")
c.Append()
@@ -100,7 +146,7 @@ class SchemaBundleGenerator(object):
c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
c.Append()
c.Sblock('class GeneratedSchemas {')
- c.Append('public:')
+ c.Append(' public:')
c.Append('// Puts all API schemas in |schemas|.')
c.Append('static void Get('
'std::map<std::string, base::StringPiece>* schemas);')
diff --git a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
index f8e5dc3..43ec909 100644
--- a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
+++ b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
@@ -9,9 +9,9 @@
'type': 'static_library',
'variables': {
'chromium_code': 1,
- 'json_schema_files': [
- 'any.json',
+ 'schema_files': [
'additional_properties.json',
+ 'any.json',
'arrays.json',
'callbacks.json',
'choices.json',
@@ -19,22 +19,19 @@
'enums.json',
'functions_as_parameters.json',
'functions_on_types.json',
+ 'idl_basics.idl',
+ 'idl_object_types.idl',
'objects.json',
'simple_api.json',
],
- 'idl_schema_files': [
- 'idl_basics.idl',
- 'idl_object_types.idl'
- ],
'cc_dir': 'tools/json_schema_compiler/test',
'root_namespace': 'test::api',
},
'inputs': [
- '<@(idl_schema_files)',
+ '<@(schema_files)',
],
'sources': [
- '<@(json_schema_files)',
- '<@(idl_schema_files)',
+ '<@(schema_files)',
],
'includes': ['../../../build/json_schema_compile.gypi'],
},