summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlfg <lfg@chromium.org>2014-08-28 20:56:28 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-29 03:58:01 +0000
commit8a1bee36d9f609ab9a98ecf89bf1dfc0bb4762dc (patch)
tree98801b1699e47204b60186ec5619e1ba9a492157
parent792dcd9ba6050f1dce72f9a7e1961e0f0ceabc2c (diff)
downloadchromium_src-8a1bee36d9f609ab9a98ecf89bf1dfc0bb4762dc.zip
chromium_src-8a1bee36d9f609ab9a98ecf89bf1dfc0bb4762dc.tar.gz
chromium_src-8a1bee36d9f609ab9a98ecf89bf1dfc0bb4762dc.tar.bz2
- Add support for references in different paths in apis.
- Move ImageDetails from chrome to extensions. BUG=352290 Review URL: https://codereview.chromium.org/487533005 Cr-Commit-Position: refs/heads/master@{#292567}
-rw-r--r--build/json_schema_bundle_compile.gypi7
-rw-r--r--build/json_schema_compile.gypi8
-rw-r--r--chrome/browser/extensions/api/capture_web_contents_function.h4
-rw-r--r--chrome/common/extensions/api/BUILD.gn3
-rw-r--r--chrome/common/extensions/api/api.gyp3
-rw-r--r--chrome/common/extensions/api/schemas.gni3
-rw-r--r--chrome/common/extensions/api/schemas.gypi11
-rw-r--r--chrome/common/extensions/api/tabs.json2
-rw-r--r--chrome/common/extensions/api/types.json20
-rw-r--r--chrome/common/extensions/api/web_view_internal.json2
-rw-r--r--extensions/common/api/extension_types.json32
-rw-r--r--extensions/common/api/schemas.gypi1
-rw-r--r--extensions/generated_extensions_api.gni26
-rw-r--r--tools/json_schema_compiler/cc_generator.py17
-rwxr-xr-xtools/json_schema_compiler/compiler.py38
-rw-r--r--tools/json_schema_compiler/cpp_generator.py6
-rw-r--r--tools/json_schema_compiler/cpp_namespace_environment.py7
-rw-r--r--tools/json_schema_compiler/cpp_type_generator.py12
-rwxr-xr-xtools/json_schema_compiler/cpp_type_generator_test.py38
-rwxr-xr-xtools/json_schema_compiler/dart_generator_test.py2
-rw-r--r--tools/json_schema_compiler/h_generator.py18
-rw-r--r--tools/json_schema_compiler/model.py16
-rw-r--r--tools/json_schema_compiler/schema_loader.py81
23 files changed, 246 insertions, 111 deletions
diff --git a/build/json_schema_bundle_compile.gypi b/build/json_schema_bundle_compile.gypi
index 7560bdc..a302013 100644
--- a/build/json_schema_bundle_compile.gypi
+++ b/build/json_schema_bundle_compile.gypi
@@ -7,6 +7,11 @@
# When including this gypi, the following variables must be set:
# schema_files:
# An array of json or idl files that comprise the api model.
+ # schema_include_rules (optional):
+ # An array of paths to include when searching for referenced objects,
+ # with the namespace separated by a :.
+ # Example:
+ # [ '/foo/bar:Foo::Bar::%(namespace)s' ]
# cc_dir:
# The directory to put the generated code in.
# root_namespace:
@@ -32,6 +37,7 @@
'<(api_gen_dir)/model.py',
'<(api_gen_dir)/util_cc_helper.py',
],
+ 'schema_include_rules': [],
},
'actions': [
{
@@ -52,6 +58,7 @@
'--destdir=<(SHARED_INTERMEDIATE_DIR)',
'--namespace=<(root_namespace)',
'--generator=cpp-bundle-schema',
+ '--include-rules=<(schema_include_rules)',
'<@(schema_files)',
'<@(non_compiled_schema_files)',
],
diff --git a/build/json_schema_compile.gypi b/build/json_schema_compile.gypi
index 9672f79..9952e20 100644
--- a/build/json_schema_compile.gypi
+++ b/build/json_schema_compile.gypi
@@ -7,6 +7,11 @@
# When including this gypi, the following variables must be set:
# schema_files:
# An array of json or idl files that comprise the api model.
+ # schema_include_rules (optional):
+ # An array of paths to include when searching for referenced objects,
+ # with the namespace separated by a :.
+ # Example:
+ # [ '/foo/bar:Foo::Bar::%(namespace)s' ]
# cc_dir:
# The directory to put the generated code in.
# root_namespace:
@@ -17,6 +22,7 @@
# Functions and namespaces can be excluded by setting "nocompile" to true.
'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler',
'api_gen': '<(api_gen_dir)/compiler.py',
+ 'schema_include_rules': [],
},
'rules': [
{
@@ -54,6 +60,7 @@
'--destdir=<(SHARED_INTERMEDIATE_DIR)',
'--namespace=<(root_namespace)',
'--generator=cpp',
+ '--include-rules=<(schema_include_rules)'
],
'message': 'Generating C++ code from <(RULE_INPUT_PATH) json files',
'process_outputs_as_sources': 1,
@@ -92,6 +99,7 @@
'--destdir=<(SHARED_INTERMEDIATE_DIR)',
'--namespace=<(root_namespace)',
'--generator=cpp',
+ '--include-rules=<(schema_include_rules)'
],
'message': 'Generating C++ code from <(RULE_INPUT_PATH) IDL files',
'process_outputs_as_sources': 1,
diff --git a/chrome/browser/extensions/api/capture_web_contents_function.h b/chrome/browser/extensions/api/capture_web_contents_function.h
index 0a1c741..0f3b9db 100644
--- a/chrome/browser/extensions/api/capture_web_contents_function.h
+++ b/chrome/browser/extensions/api/capture_web_contents_function.h
@@ -6,7 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_API_CAPTURE_WEB_CONTENTS_FUNCTION_H_
#include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chrome/common/extensions/api/types.h"
+#include "extensions/common/api/extension_types.h"
class SkBitmap;
@@ -40,7 +40,7 @@ class CaptureWebContentsFunction : public ChromeAsyncExtensionFunction {
virtual void OnCaptureFailure(FailureReason reason) = 0;
private:
- typedef api::types::ImageDetails ImageDetails;
+ typedef core_api::extension_types::ImageDetails ImageDetails;
void CopyFromBackingStoreComplete(bool succeed, const SkBitmap& bitmap);
void OnCaptureSuccess(const SkBitmap& bitmap);
diff --git a/chrome/common/extensions/api/BUILD.gn b/chrome/common/extensions/api/BUILD.gn
index 469227d..c74335f 100644
--- a/chrome/common/extensions/api/BUILD.gn
+++ b/chrome/common/extensions/api/BUILD.gn
@@ -9,6 +9,8 @@ import("schemas.gni")
generated_extensions_api("api") {
schemas = true
bundle = true
+
+ deps = schema_dependencies
}
# GYP version: chrome/browser/extensions/api/api.gyp:chrome_api_registration
@@ -32,4 +34,5 @@ generated_extensions_api("api_registration") {
if (is_chromeos) {
# deps += [ "<(DEPTH)/chrome/chrome.gyp:drive_proto" ] TODO(GYP)
}
+ deps += schema_dependencies
}
diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp
index 19b28fa..da226f7 100644
--- a/chrome/common/extensions/api/api.gyp
+++ b/chrome/common/extensions/api/api.gyp
@@ -18,6 +18,9 @@
'../../../../build/json_schema_compile.gypi',
'schemas.gypi',
],
+ 'dependencies': [
+ '<@(schema_dependencies)',
+ ],
},
],
}
diff --git a/chrome/common/extensions/api/schemas.gni b/chrome/common/extensions/api/schemas.gni
index a8a8b41..9a43246 100644
--- a/chrome/common/extensions/api/schemas.gni
+++ b/chrome/common/extensions/api/schemas.gni
@@ -29,3 +29,6 @@ if (!is_android) {
}
root_namespace = "extensions::api::%(namespace)s"
+schema_include_rules =
+ "extensions/common/api:extensions::core_api::%(namespace)s"
+schema_dependencies = [ "//extensions/common/api" ]
diff --git a/chrome/common/extensions/api/schemas.gypi b/chrome/common/extensions/api/schemas.gypi
index b7b9d17..4e7b234 100644
--- a/chrome/common/extensions/api/schemas.gypi
+++ b/chrome/common/extensions/api/schemas.gypi
@@ -116,6 +116,9 @@
'web_view_internal.json',
'windows.json',
],
+ 'main_schema_include_rules': [
+ 'extensions/common/api:extensions::core_api::%(namespace)s',
+ ],
'main_non_compiled_schema_files': [
'browsing_data.json',
'chromeos_info_private.json',
@@ -157,12 +160,20 @@
'non_compiled_schema_files': [
'<@(main_non_compiled_schema_files)',
],
+ 'schema_dependencies': [
+ '<(DEPTH)/extensions/common/api/api.gyp:extensions_api',
+ ],
'schema_files': [
'<@(main_schema_files)',
],
+ 'schema_include_rules': [
+ '<@(main_schema_include_rules)',
+ ],
}, { # enable_extensions==0
'non_compiled_schema_files': [
],
+ 'schema_dependencies': [
+ ],
'schema_files': [
# These should be eliminated. See crbug.com/305852.
'<@(android_schema_files)',
diff --git a/chrome/common/extensions/api/tabs.json b/chrome/common/extensions/api/tabs.json
index 931a293..f3c9348 100644
--- a/chrome/common/extensions/api/tabs.json
+++ b/chrome/common/extensions/api/tabs.json
@@ -654,7 +654,7 @@
"description": "The target window. Defaults to the <a href='windows#current-window'>current window</a>."
},
{
- "$ref": "types.ImageDetails",
+ "$ref": "extensionTypes.ImageDetails",
"name": "options",
"optional": true
},
diff --git a/chrome/common/extensions/api/types.json b/chrome/common/extensions/api/types.json
index 80f8c6a..1a7c306 100644
--- a/chrome/common/extensions/api/types.json
+++ b/chrome/common/extensions/api/types.json
@@ -150,26 +150,6 @@
]
}
]
- },
- {
- "id": "ImageDetails",
- "type": "object",
- "description": "Details about the format and quality of an image.",
- "properties": {
- "format": {
- "type": "string",
- "optional": true,
- "enum": ["jpeg", "png"],
- "description": "The format of the resulting image. Default is <code>\"jpeg\"</code>."
- },
- "quality": {
- "type": "integer",
- "optional": true,
- "minimum": 0,
- "maximum": 100,
- "description": "When format is <code>\"jpeg\"</code>, controls the quality of the resulting image. This value is ignored for PNG images. As quality is decreased, the resulting image will have more visual artifacts, and the number of bytes needed to store it will decrease."
- }
- }
}
]
}
diff --git a/chrome/common/extensions/api/web_view_internal.json b/chrome/common/extensions/api/web_view_internal.json
index c09c126..a05e860 100644
--- a/chrome/common/extensions/api/web_view_internal.json
+++ b/chrome/common/extensions/api/web_view_internal.json
@@ -412,7 +412,7 @@
"description": "The instance ID of the guest <webview> process."
},
{
- "$ref": "types.ImageDetails",
+ "$ref": "extensionTypes.ImageDetails",
"name": "options",
"optional": true
},
diff --git a/extensions/common/api/extension_types.json b/extensions/common/api/extension_types.json
new file mode 100644
index 0000000..f3d8782
--- /dev/null
+++ b/extensions/common/api/extension_types.json
@@ -0,0 +1,32 @@
+// Copyright 2014 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.
+
+[
+ {
+ "namespace": "extensionTypes",
+ "description": "The <code>chrome.extension_types</code> API contains type declarations for Chrome extensions.",
+ "types": [
+ {
+ "id": "ImageDetails",
+ "type": "object",
+ "description": "Details about the format and quality of an image.",
+ "properties": {
+ "format": {
+ "type": "string",
+ "optional": true,
+ "enum": ["jpeg", "png"],
+ "description": "The format of the resulting image. Default is <code>\"jpeg\"</code>."
+ },
+ "quality": {
+ "type": "integer",
+ "optional": true,
+ "minimum": 0,
+ "maximum": 100,
+ "description": "When format is <code>\"jpeg\"</code>, controls the quality of the resulting image. This value is ignored for PNG images. As quality is decreased, the resulting image will have more visual artifacts, and the number of bytes needed to store it will decrease."
+ }
+ }
+ }
+ ]
+ }
+]
diff --git a/extensions/common/api/schemas.gypi b/extensions/common/api/schemas.gypi
index e595e5d..b7fd1de 100644
--- a/extensions/common/api/schemas.gypi
+++ b/extensions/common/api/schemas.gypi
@@ -18,6 +18,7 @@
'cast_channel.idl',
'dns.idl',
'extensions_manifest_types.json',
+ 'extension_types.json',
'hid.idl',
'power.idl',
'runtime.json',
diff --git a/extensions/generated_extensions_api.gni b/extensions/generated_extensions_api.gni
index 98ddc77..0926d94 100644
--- a/extensions/generated_extensions_api.gni
+++ b/extensions/generated_extensions_api.gni
@@ -16,6 +16,12 @@
# namespace for each API. Use %(namespace)s to replace with the API
# namespace, like "toplevel::%(namespace)s_api".
#
+# schema_include_rules [optional]
+# A list of paths to include when searching for referenced objects,
+# with the namespace separated by a :.
+# Example:
+# [ '/foo/bar:Foo::Bar::%(namespace)s' ]
+#
# schemas [optional, default = false]
# Boolean indicating if the schema files should be generated.
#
@@ -54,6 +60,11 @@ template("generated_extensions_api") {
bundle_registration = defined(invoker.bundle_registration) &&
invoker.bundle_registration
+ schema_include_rules = ""
+ if (defined(invoker.schema_include_rules)) {
+ schema_include_rules = invoker.schema_include_rules
+ }
+
# Keep a copy of the target_name here since it will be trampled
# in nested targets.
target_visibility = ":$target_name"
@@ -96,7 +107,8 @@ template("generated_extensions_api") {
"--root=" + rebase_path("//", root_build_dir),
"--destdir=" + rebase_path(root_gen_dir, root_build_dir),
"--namespace=$root_namespace",
- "--generator=cpp" ]
+ "--generator=cpp",
+ "--include-rules=$schema_include_rules" ]
visibility = target_visibility
}
}
@@ -120,9 +132,9 @@ template("generated_extensions_api") {
"--destdir=" + rebase_path(root_gen_dir, root_build_dir),
"--namespace=$root_namespace",
"--generator=cpp-bundle-schema",
- ] +
- rebase_path(sources, root_build_dir) +
- rebase_path(uncompiled_sources, root_build_dir)
+ "--include-rules=$schema_include_rules" ]
+ + rebase_path(sources, root_build_dir)
+ + rebase_path(uncompiled_sources, root_build_dir)
}
}
@@ -151,9 +163,9 @@ template("generated_extensions_api") {
"--namespace=$root_namespace",
"--generator=cpp-bundle-registration",
"--impl-dir=" + rebase_path(impl_dir, "//"),
- ] +
- rebase_path(sources, root_build_dir) +
- rebase_path(uncompiled_sources, root_build_dir)
+ "--include-rules=$schema_include_rules" ]
+ + rebase_path(sources, root_build_dir)
+ + rebase_path(uncompiled_sources, root_build_dir)
}
}
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 43434b8..1d243f0 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -7,25 +7,23 @@ from model import PropertyType
import cpp_util
import schema_util
import util_cc_helper
+from cpp_namespace_environment import CppNamespaceEnvironment
class CCGenerator(object):
- def __init__(self, type_generator, cpp_namespace_pattern):
+ def __init__(self, type_generator):
self._type_generator = type_generator
- self._cpp_namespace_pattern = cpp_namespace_pattern
def Generate(self, namespace):
- return _Generator(namespace,
- self._type_generator,
- self._cpp_namespace_pattern).Generate()
+ return _Generator(namespace, self._type_generator).Generate()
class _Generator(object):
"""A .cc generator for a namespace.
"""
- def __init__(self, namespace, cpp_type_generator, cpp_namespace_pattern):
+ def __init__(self, namespace, cpp_type_generator):
+ assert type(namespace.environment) is CppNamespaceEnvironment
self._namespace = namespace
self._type_helper = cpp_type_generator
- self._cpp_namespace_pattern = cpp_namespace_pattern
self._util_cc_helper = (
util_cc_helper.UtilCCHelper(self._type_helper))
self._generate_error_messages = namespace.compiler_options.get(
@@ -34,8 +32,9 @@ class _Generator(object):
def Generate(self):
"""Generates a Code object with the .cc for a single namespace.
"""
- cpp_namespace = cpp_util.GetCppNamespace(self._cpp_namespace_pattern,
- self._namespace.unix_name)
+ cpp_namespace = cpp_util.GetCppNamespace(
+ self._namespace.environment.namespace_pattern,
+ self._namespace.unix_name)
c = Code()
(c.Append(cpp_util.CHROMIUM_LICENSE)
diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py
index 38899286..7a2e4dd 100755
--- a/tools/json_schema_compiler/compiler.py
+++ b/tools/json_schema_compiler/compiler.py
@@ -18,6 +18,7 @@ Usage example:
import optparse
import os
+import shlex
import sys
from cpp_bundle_generator import CppBundleGenerator
@@ -25,6 +26,7 @@ from cpp_generator import CppGenerator
from cpp_type_generator import CppTypeGenerator
from dart_generator import DartGenerator
import json_schema
+from cpp_namespace_environment import CppNamespaceEnvironment
from model import Model
from schema_loader import SchemaLoader
@@ -38,15 +40,18 @@ def GenerateSchema(generator_name,
destdir,
cpp_namespace_pattern,
dart_overrides_dir,
- impl_dir):
+ impl_dir,
+ include_rules):
# Merge the source files into a single list of schemas.
api_defs = []
for file_path in file_paths:
- schema = os.path.normpath(file_path)
+ schema = os.path.relpath(file_path, root)
schema_loader = SchemaLoader(
- os.path.dirname(os.path.relpath(schema, root)),
- os.path.dirname(file_path))
- api_def = schema_loader.LoadSchema(os.path.split(schema)[1])
+ root,
+ os.path.dirname(schema),
+ include_rules,
+ cpp_namespace_pattern)
+ api_def = schema_loader.LoadSchema(schema)
# If compiling the C++ model code, delete 'nocompile' nodes.
if generator_name == 'cpp':
@@ -68,7 +73,9 @@ def GenerateSchema(generator_name,
relpath = os.path.relpath(os.path.normpath(file_path), root)
namespace = api_model.AddNamespace(target_namespace,
relpath,
- include_compiler_options=True)
+ include_compiler_options=True,
+ environment=CppNamespaceEnvironment(
+ cpp_namespace_pattern))
if default_namespace is None:
default_namespace = namespace
@@ -105,7 +112,7 @@ def GenerateSchema(generator_name,
('generated_schemas.h', cpp_bundle_generator.schemas_h_generator)
]
elif generator_name == 'cpp':
- cpp_generator = CppGenerator(type_generator, cpp_namespace_pattern)
+ cpp_generator = CppGenerator(type_generator)
generators = [
('%s.h' % filename_base, cpp_generator.h_generator),
('%s.cc' % filename_base, cpp_generator.cc_generator)
@@ -156,6 +163,10 @@ if __name__ == '__main__':
help='Adds custom dart from files in the given directory (Dart only).')
parser.add_option('-i', '--impl-dir', dest='impl_dir',
help='The root path of all API implementations')
+ parser.add_option('-I', '--include-rules',
+ help='A list of paths to include when searching for referenced objects,'
+ ' with the namespace separated by a \':\'. Example: '
+ '/foo/bar:Foo::Bar::%(namespace)s')
(opts, file_paths) = parser.parse_args()
@@ -169,8 +180,19 @@ if __name__ == '__main__':
raise Exception(
"Unless in bundle mode, only one file can be specified at a time.")
+ def split_path_and_namespace(path_and_namespace):
+ if ':' not in path_and_namespace:
+ raise ValueError('Invalid include rule "%s". Rules must be of '
+ 'the form path:namespace' % path_and_namespace)
+ return path_and_namespace.split(':', 1)
+
+ include_rules = []
+ if opts.include_rules:
+ include_rules = map(split_path_and_namespace,
+ shlex.split(opts.include_rules))
+
result = GenerateSchema(opts.generator, file_paths, opts.root, opts.destdir,
opts.namespace, opts.dart_overrides_dir,
- opts.impl_dir)
+ opts.impl_dir, include_rules)
if not opts.destdir:
print result
diff --git a/tools/json_schema_compiler/cpp_generator.py b/tools/json_schema_compiler/cpp_generator.py
index 7441ac5..5521ea9 100644
--- a/tools/json_schema_compiler/cpp_generator.py
+++ b/tools/json_schema_compiler/cpp_generator.py
@@ -6,6 +6,6 @@ from cc_generator import CCGenerator
from h_generator import HGenerator
class CppGenerator(object):
- def __init__(self, type_generator, cpp_namespace_pattern):
- self.h_generator = HGenerator(type_generator, cpp_namespace_pattern)
- self.cc_generator = CCGenerator(type_generator, cpp_namespace_pattern)
+ def __init__(self, type_generator):
+ self.h_generator = HGenerator(type_generator)
+ self.cc_generator = CCGenerator(type_generator)
diff --git a/tools/json_schema_compiler/cpp_namespace_environment.py b/tools/json_schema_compiler/cpp_namespace_environment.py
new file mode 100644
index 0000000..20e77bb
--- /dev/null
+++ b/tools/json_schema_compiler/cpp_namespace_environment.py
@@ -0,0 +1,7 @@
+# Copyright 2014 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.
+
+class CppNamespaceEnvironment(object):
+ def __init__(self, namespace_pattern):
+ self.namespace_pattern = namespace_pattern
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py
index de6d130..6bec67e4 100644
--- a/tools/json_schema_compiler/cpp_type_generator.py
+++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -96,7 +96,10 @@ class CppTypeGenerator(object):
if self._default_namespace is type_.namespace:
cpp_type = cpp_util.Classname(type_.name)
else:
- cpp_type = '%s::%s' % (type_.namespace.unix_name,
+ cpp_namespace = cpp_util.GetCppNamespace(
+ type_.namespace.environment.namespace_pattern,
+ type_.namespace.unix_name)
+ cpp_type = '%s::%s' % (cpp_namespace,
cpp_util.Classname(type_.name))
elif type_.property_type == PropertyType.ANY:
cpp_type = 'base::Value'
@@ -130,7 +133,7 @@ class CppTypeGenerator(object):
PropertyType.OBJECT,
PropertyType.CHOICES))
- def GenerateForwardDeclarations(self, cpp_namespace_pattern):
+ def GenerateForwardDeclarations(self):
"""Returns the forward declarations for self._default_namespace.
"""
c = Code()
@@ -144,8 +147,9 @@ class CppTypeGenerator(object):
if not filtered_deps:
continue
- cpp_namespace = cpp_util.GetCppNamespace(cpp_namespace_pattern,
- namespace.unix_name)
+ cpp_namespace = cpp_util.GetCppNamespace(
+ namespace.environment.namespace_pattern,
+ namespace.unix_name)
c.Concat(cpp_util.OpenNamespace(cpp_namespace))
for dep in filtered_deps:
c.Append('struct %s;' % dep.type_.name)
diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py
index f3a760a..51fcfe9 100755
--- a/tools/json_schema_compiler/cpp_type_generator_test.py
+++ b/tools/json_schema_compiler/cpp_type_generator_test.py
@@ -3,6 +3,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from cpp_namespace_environment import CppNamespaceEnvironment
from cpp_type_generator import CppTypeGenerator
from json_schema import CachedLoad
import model
@@ -51,8 +52,12 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGenerateIncludesAndForwardDeclarations(self):
m = model.Model()
- m.AddNamespace(self.windows_json[0], 'path/to/windows.json')
- m.AddNamespace(self.tabs_json[0], 'path/to/tabs.json')
+ m.AddNamespace(self.windows_json[0],
+ 'path/to/windows.json',
+ environment=CppNamespaceEnvironment('%(namespace)s'))
+ m.AddNamespace(self.tabs_json[0],
+ 'path/to/tabs.json',
+ environment=CppNamespaceEnvironment('%(namespace)s'))
manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
self.assertEquals('', manager.GenerateIncludes().Render())
@@ -62,7 +67,18 @@ class CppTypeGeneratorTest(unittest.TestCase):
'namespace tabs {\n'
'struct Tab;\n'
'} // namespace tabs',
- manager.GenerateForwardDeclarations('%(namespace)s').Render())
+ manager.GenerateForwardDeclarations().Render())
+
+ m = model.Model()
+ m.AddNamespace(self.windows_json[0],
+ 'path/to/windows.json',
+ environment=CppNamespaceEnvironment(
+ 'foo::bar::%(namespace)s'))
+ m.AddNamespace(self.tabs_json[0],
+ 'path/to/tabs.json',
+ environment=CppNamespaceEnvironment(
+ 'foo::bar::%(namespace)s'))
+ manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
self.assertEquals(
'namespace foo {\n'
'namespace bar {\n'
@@ -71,13 +87,12 @@ class CppTypeGeneratorTest(unittest.TestCase):
'} // namespace tabs\n'
'} // namespace bar\n'
'} // namespace foo',
- manager.GenerateForwardDeclarations('foo::bar::%(namespace)s').Render())
+ manager.GenerateForwardDeclarations().Render())
manager = CppTypeGenerator(self.models.get('permissions'),
_FakeSchemaLoader(m))
self.assertEquals('', manager.GenerateIncludes().Render())
self.assertEquals('', manager.GenerateIncludes().Render())
- self.assertEquals(
- '', manager.GenerateForwardDeclarations('%(namespace)s').Render())
+ self.assertEquals('', manager.GenerateForwardDeclarations().Render())
manager = CppTypeGenerator(self.models.get('content_settings'),
_FakeSchemaLoader(m))
self.assertEquals('', manager.GenerateIncludes().Render())
@@ -96,8 +111,7 @@ class CppTypeGeneratorTest(unittest.TestCase):
self.assertEquals('#include "path/to/browser_action.h"\n'
'#include "path/to/font_settings.h"',
manager.GenerateIncludes().Render())
- self.assertEquals(
- '', manager.GenerateForwardDeclarations('%(namespace)s').Render())
+ self.assertEquals('', manager.GenerateForwardDeclarations().Render())
def testGetCppTypeSimple(self):
manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None))
@@ -147,8 +161,12 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGetCppTypeIncludedRef(self):
m = model.Model()
- m.AddNamespace(self.windows_json[0], 'path/to/windows.json')
- m.AddNamespace(self.tabs_json[0], 'path/to/tabs.json')
+ m.AddNamespace(self.windows_json[0],
+ 'path/to/windows.json',
+ environment=CppNamespaceEnvironment('%(namespace)s'))
+ m.AddNamespace(self.tabs_json[0],
+ 'path/to/tabs.json',
+ environment=CppNamespaceEnvironment('%(namespace)s'))
manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
self.assertEquals(
'std::vector<linked_ptr<tabs::Tab> >',
diff --git a/tools/json_schema_compiler/dart_generator_test.py b/tools/json_schema_compiler/dart_generator_test.py
index b01d467..2005e7e 100755
--- a/tools/json_schema_compiler/dart_generator_test.py
+++ b/tools/json_schema_compiler/dart_generator_test.py
@@ -32,7 +32,7 @@ class DartTest(unittest.TestCase):
if REBASE_MODE:
output_dir = TESTS_DIR
output_code = GenerateSchema('dart', ['%s.idl' % file_rel], TESTS_DIR,
- output_dir, None, None, None)
+ output_dir, '', None, None, [])
if not REBASE_MODE:
with open('%s.dart' % file_rel) as f:
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 95c8056..a6d67db 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -10,23 +10,19 @@ import cpp_util
import schema_util
class HGenerator(object):
- def __init__(self, type_generator, cpp_namespace_pattern):
+ def __init__(self, type_generator):
self._type_generator = type_generator
- self._cpp_namespace_pattern = cpp_namespace_pattern
def Generate(self, namespace):
- return _Generator(namespace,
- self._type_generator,
- self._cpp_namespace_pattern).Generate()
+ return _Generator(namespace, self._type_generator).Generate()
class _Generator(object):
"""A .h generator for a namespace.
"""
- def __init__(self, namespace, cpp_type_generator, cpp_namespace_pattern):
+ def __init__(self, namespace, cpp_type_generator):
self._namespace = namespace
self._type_helper = cpp_type_generator
- self._cpp_namespace_pattern = cpp_namespace_pattern
self._generate_error_messages = namespace.compiler_options.get(
'generate_error_messages', False)
@@ -65,11 +61,11 @@ class _Generator(object):
# $ref types from other files to be used as required params. This requires
# some detangling of windows and tabs which will currently lead to circular
# #includes.
- c.Cblock(self._type_helper.GenerateForwardDeclarations(
- self._cpp_namespace_pattern))
+ c.Cblock(self._type_helper.GenerateForwardDeclarations())
- cpp_namespace = cpp_util.GetCppNamespace(self._cpp_namespace_pattern,
- self._namespace.unix_name)
+ cpp_namespace = cpp_util.GetCppNamespace(
+ self._namespace.environment.namespace_pattern,
+ self._namespace.unix_name)
c.Concat(cpp_util.OpenNamespace(cpp_namespace))
c.Append()
if self._namespace.properties:
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py
index ed8a2ec..16530e7 100644
--- a/tools/json_schema_compiler/model.py
+++ b/tools/json_schema_compiler/model.py
@@ -27,12 +27,17 @@ class Model(object):
def __init__(self):
self.namespaces = {}
- def AddNamespace(self, json, source_file, include_compiler_options=False):
+ def AddNamespace(self,
+ json,
+ source_file,
+ include_compiler_options=False,
+ environment=None):
"""Add a namespace's json to the model and returns the namespace.
"""
namespace = Namespace(json,
source_file,
- include_compiler_options=include_compiler_options)
+ include_compiler_options=include_compiler_options,
+ environment=environment)
self.namespaces[namespace.name] = namespace
return namespace
@@ -95,7 +100,11 @@ class Namespace(object):
- |compiler_options| the compiler_options dict, only not empty if
|include_compiler_options| is True
"""
- def __init__(self, json, source_file, include_compiler_options=False):
+ def __init__(self,
+ json,
+ source_file,
+ include_compiler_options=False,
+ environment=None):
self.name = json['namespace']
if 'description' not in json:
# TODO(kalman): Go back to throwing an error here.
@@ -119,6 +128,7 @@ class Namespace(object):
self.compiler_options = json.get('compiler_options', {})
else:
self.compiler_options = {}
+ self.environment = environment
self.documentation_options = json.get('documentation_options', {})
diff --git a/tools/json_schema_compiler/schema_loader.py b/tools/json_schema_compiler/schema_loader.py
index 358381f..261e8d0 100644
--- a/tools/json_schema_compiler/schema_loader.py
+++ b/tools/json_schema_compiler/schema_loader.py
@@ -8,20 +8,48 @@ import sys
import idl_schema
import json_schema
+from cpp_namespace_environment import CppNamespaceEnvironment
from model import Model, UnixName
+def GenerateFilenames(full_namespace):
+ # Try to find the file defining the namespace. Eg. for
+ # nameSpace.sub_name_space.Type' the following heuristics looks for:
+ # 1. name_space_sub_name_space.json,
+ # 2. name_space_sub_name_space.idl,
+ # 3. sub_name_space.json,
+ # 4. sub_name_space.idl,
+ # 5. etc.
+ sub_namespaces = full_namespace.split('.')
+ filenames = [ ]
+ basename = None
+ for namespace in reversed(sub_namespaces):
+ if basename is not None:
+ basename = UnixName(namespace + '.' + basename)
+ else:
+ basename = UnixName(namespace)
+ for ext in ['json', 'idl']:
+ filenames.append('%s.%s' % (basename, ext))
+ return filenames
+
class SchemaLoader(object):
'''Resolves a type name into the namespace the type belongs to.
Properties:
- - |display_path| path to the directory with the API header files, intended for
- use with the Model.
- - |real_path| path to the directory with the API header files, used for file
- access.
+ - |root| path to the root directory.
+ - |path| path to the directory with the API header files, relative to the
+ root.
+ - |include_rules| List containing tuples with (path, cpp_namespace_pattern)
+ used when searching for types.
+ - |cpp_namespace_pattern| Default namespace pattern
'''
- def __init__(self, display_path, real_path):
- self._display_path = display_path
- self._real_path = real_path
+ def __init__(self,
+ root,
+ path,
+ include_rules,
+ cpp_namespace_pattern):
+ self._root = root
+ self._include_rules = [(path, cpp_namespace_pattern)]
+ self._include_rules.extend(include_rules)
def ResolveType(self, full_name, default_namespace):
name_parts = full_name.rsplit('.', 1)
@@ -29,35 +57,26 @@ class SchemaLoader(object):
if full_name not in default_namespace.types:
return None
return default_namespace
- namespace_name, type_name = name_parts
- real_name = None
- # Try to find the file defining the namespace. Eg. for
- # nameSpace.sub_name_space.Type' the following heuristics looks for:
- # 1. name_space_sub_name_space.json,
- # 2. name_space_sub_name_space.idl.
- for ext in ['json', 'idl']:
- basename = UnixName(namespace_name)
- filename = '%s.%s' % (basename, ext)
- filepath = os.path.join(self._real_path, filename);
- if os.path.exists(filepath):
- real_name = filename
- break
- if real_name is None:
- return None
- namespace = Model().AddNamespace(
- self.LoadSchema(real_name)[0],
- os.path.join(self._display_path, real_name))
- if type_name not in namespace.types:
- return None
- return namespace
+ full_namespace, type_name = full_name.rsplit('.', 1)
+ filenames = GenerateFilenames(full_namespace)
+ for path, namespace in self._include_rules:
+ for filename in reversed(filenames):
+ filepath = os.path.join(path, filename);
+ if os.path.exists(os.path.join(self._root, filepath)):
+ namespace = Model().AddNamespace(
+ self.LoadSchema(filepath)[0],
+ filepath,
+ environment=CppNamespaceEnvironment(namespace))
+ if type_name in namespace.types:
+ return namespace
+ return None
def LoadSchema(self, schema):
'''Load a schema definition. The schema parameter must be a file name
- without any path component - the file is loaded from the path defined by
- the real_path argument passed to the constructor.'''
+ with the full path relative to the root.'''
schema_filename, schema_extension = os.path.splitext(schema)
- schema_path = os.path.join(self._real_path, schema);
+ schema_path = os.path.join(self._root, schema)
if schema_extension == '.json':
api_defs = json_schema.Load(schema_path)
elif schema_extension == '.idl':