diff options
author | ricow@chromium.org <ricow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 11:14:37 +0000 |
---|---|---|
committer | ricow@chromium.org <ricow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-10 11:14:37 +0000 |
commit | 78acaf6d0ac35af3081e20511afdd9565520d067 (patch) | |
tree | 5ba4004249e535cf12d624a66aedce51aebaa874 /tools | |
parent | 85db26ae55f5b20a32884e38ce39b8ba449238b1 (diff) | |
download | chromium_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')
-rw-r--r-- | tools/json_schema_compiler/code.py | 8 | ||||
-rwxr-xr-x | tools/json_schema_compiler/compiler.py | 11 | ||||
-rw-r--r-- | tools/json_schema_compiler/model.py | 76 | ||||
-rw-r--r-- | tools/json_schema_compiler/schema_bundle_generator.py | 56 | ||||
-rw-r--r-- | tools/json_schema_compiler/test/json_schema_compiler_tests.gyp | 15 |
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'], }, |