diff options
-rw-r--r-- | build/json_schema_bundle_compile.gypi | 16 | ||||
-rw-r--r-- | chrome/chrome_common.gypi | 3 | ||||
-rw-r--r-- | chrome/common/common_resources.grd | 1 | ||||
-rw-r--r-- | chrome/common/extensions/api/experimental.dns.json | 46 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.cc | 14 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.h | 4 | ||||
-rw-r--r-- | chrome/common/extensions/docs/js/api_page_generator.js | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/json_schema_compiler/compiler.py | 34 | ||||
-rw-r--r-- | tools/json_schema_compiler/h_bundle_generator.py | 79 | ||||
-rw-r--r-- | tools/json_schema_compiler/schema_bundle_generator.py | 145 |
10 files changed, 189 insertions, 154 deletions
diff --git a/build/json_schema_bundle_compile.gypi b/build/json_schema_bundle_compile.gypi index 1f564d1..ecefe41 100644 --- a/build/json_schema_bundle_compile.gypi +++ b/build/json_schema_bundle_compile.gypi @@ -5,7 +5,7 @@ { 'variables': { # When including this gypi, the following variables must be set: - # json_schema_files: an array of json files that comprise the api model. + # idl_schema_files: an array of idl files that comprise the api model. # cc_dir: path to generated files # root_namespace: the C++ namespace that all generated files go under # Functions and namespaces can be excluded by setting "nocompile" to true. @@ -16,24 +16,23 @@ { 'action_name': 'genapi_bundle', 'inputs': [ - '<(api_gen_dir)/any.cc', - '<(api_gen_dir)/any.h', - '<(api_gen_dir)/any_helper.py', '<(api_gen_dir)/cc_generator.py', '<(api_gen_dir)/code.py', '<(api_gen_dir)/compiler.py', '<(api_gen_dir)/cpp_type_generator.py', '<(api_gen_dir)/cpp_util.py', '<(api_gen_dir)/h_generator.py', + '<(api_gen_dir)/idl_schema.py', '<(api_gen_dir)/json_schema.py', '<(api_gen_dir)/model.py', - '<(api_gen_dir)/util.cc', - '<(api_gen_dir)/util.h', + '<(api_gen_dir)/schema_bundle_generator.py', '<(api_gen_dir)/util_cc_helper.py', '<@(idl_schema_files)', ], 'outputs': [ - '<(SHARED_INTERMEDIATE_DIR)/chrome/common/extensions/api/generated_api.h', + '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/generated_api.h', + '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/generated_schemas.h', + '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/generated_schemas.cc', ], 'action': [ 'python', @@ -52,9 +51,6 @@ '<(SHARED_INTERMEDIATE_DIR)', '<(DEPTH)', ], - 'dependencies':[ - '<(DEPTH)/tools/json_schema_compiler/api_gen_util.gyp:api_gen_util', - ], 'direct_dependent_settings': { 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 5e9ac64..69f558e 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -258,9 +258,6 @@ 'common/zip_internal.h', 'common/zip_reader.cc', 'common/zip_reader.h', - - # Generated by the api.gyp:api target - '<(SHARED_INTERMEDIATE_DIR)/chrome/common/extensions/api/generated_api.h' ], 'conditions': [ ['OS=="android"', { diff --git a/chrome/common/common_resources.grd b/chrome/common/common_resources.grd index e898d36..fb47109 100644 --- a/chrome/common/common_resources.grd +++ b/chrome/common/common_resources.grd @@ -28,7 +28,6 @@ <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP" file="extensions\api\experimental.app.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER" file="extensions\api\experimental.bookmarkManager.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_DECLARATIVE" file="extensions\api\experimental.declarative.json" type="BINDATA" /> - <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_DNS" file="extensions\api\experimental.dns.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_DOWNLOADS" file="extensions\api\experimental.downloads.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_EXTENSIONS" file="extensions\api\experimental.extension.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTS" file="extensions\api\experimental.fontSettings.json" type="BINDATA" /> diff --git a/chrome/common/extensions/api/experimental.dns.json b/chrome/common/extensions/api/experimental.dns.json deleted file mode 100644 index 2e99d68..0000000 --- a/chrome/common/extensions/api/experimental.dns.json +++ /dev/null @@ -1,46 +0,0 @@ -// 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. - -[ - { - "namespace": "experimental.dns", - "nodoc": true, - "functions": [ - { - "name": "resolve", - "type": "function", - "description": "Resolves the given hostname or IP address literal.", - "parameters": [ - { - "name": "hostname", - "type": "string", - "description": "The hostname to resolve." - }, - { - "name": "callback", - "type": "function", - "description": "Called when the resolution operation completes.", - "parameters": [ - { - "type": "object", - "name": "resolveInfo", - "properties": { - "resultCode": { - "type": "integer", - "description": "The result code. Zero indicates success." - }, - "address": { - "type": "string", - "description": "A string representing the IP address literal. Supplied only if resultCode indicates success. Note that we presently return only IPv4 addresses.", - "optional": true - } - } - } - ] - } - ] - } - ] - } -] diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc index a36989d..6350d04 100644 --- a/chrome/common/extensions/api/extension_api.cc +++ b/chrome/common/extensions/api/extension_api.cc @@ -13,6 +13,7 @@ #include "base/string_split.h" #include "base/string_util.h" #include "base/values.h" +#include "chrome/common/extensions/api/generated_schemas.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_permission_set.h" #include "googleurl/src/gurl.h" @@ -66,11 +67,16 @@ static base::ListValue* LoadSchemaList(int resource_id) { } void ExtensionAPI::LoadSchemaFromResource(int resource_id) { - scoped_ptr<base::ListValue> loaded(LoadSchemaList(resource_id)); + RegisterSchema(LoadSchemaList(resource_id)); +} + +void ExtensionAPI::RegisterSchema(base::ListValue* loaded_schema) { + // We take ownership of loaded_schema, so we need to delete it. + scoped_ptr<base::ListValue> scoped_loaded_schema(loaded_schema); Value* value = NULL; std::string schema_namespace; - while (!loaded->empty()) { - loaded->Remove(loaded->GetSize() - 1, &value); + while (!loaded_schema->empty()) { + loaded_schema->Remove(loaded_schema->GetSize() - 1, &value); CHECK(value->IsType(Value::TYPE_DICTIONARY)); const DictionaryValue* schema = static_cast<const DictionaryValue*>(value); CHECK(schema->GetString("namespace", &schema_namespace)); @@ -96,7 +102,6 @@ ExtensionAPI::ExtensionAPI() { IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP, IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER, IDR_EXTENSION_API_JSON_EXPERIMENTAL_DECLARATIVE, - IDR_EXTENSION_API_JSON_EXPERIMENTAL_DNS, IDR_EXTENSION_API_JSON_EXPERIMENTAL_DOWNLOADS, IDR_EXTENSION_API_JSON_EXPERIMENTAL_EXTENSIONS, IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTS, @@ -148,6 +153,7 @@ ExtensionAPI::ExtensionAPI() { for (size_t i = 0; i < arraysize(kJsonApiResourceIds); i++) { LoadSchemaFromResource(kJsonApiResourceIds[i]); } + RegisterSchema(api::GeneratedSchemas::Get()); // Populate {completely,partially}_unprivileged_apis_. for (SchemaMap::iterator it = schemas_.begin(); it != schemas_.end(); ++it) { diff --git a/chrome/common/extensions/api/extension_api.h b/chrome/common/extensions/api/extension_api.h index 6e2c604..4907152 100644 --- a/chrome/common/extensions/api/extension_api.h +++ b/chrome/common/extensions/api/extension_api.h @@ -63,6 +63,10 @@ class ExtensionAPI { // Loads a schema from a resource. void LoadSchemaFromResource(int resource_id); + // Given a schema in ListValue form, registers it in a map. Takes ownership + // of |loaded_schema|. + void RegisterSchema(base::ListValue* loaded_schema); + // Find an item in |list| with the specified property name and value, or NULL // if no such item exists. base::DictionaryValue* FindListItem(const base::ListValue* list, diff --git a/chrome/common/extensions/docs/js/api_page_generator.js b/chrome/common/extensions/docs/js/api_page_generator.js index 9d06222..6325535 100644 --- a/chrome/common/extensions/docs/js/api_page_generator.js +++ b/chrome/common/extensions/docs/js/api_page_generator.js @@ -34,7 +34,6 @@ var MODULE_SCHEMAS = [ '../api/experimental.accessibility.json', '../api/experimental.app.json', '../api/experimental.bookmarkManager.json', - '../api/experimental.dns.json', '../api/experimental.downloads.json', '../api/experimental.extension.json', '../api/experimental.fontSettings.json', diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py index bd9805d..8b95f7f 100644..100755 --- a/tools/json_schema_compiler/compiler.py +++ b/tools/json_schema_compiler/compiler.py @@ -18,11 +18,12 @@ Usage example: import cc_generator import cpp_type_generator -import h_bundle_generator import h_generator import idl_schema import json_schema import model +import schema_bundle_generator + import optparse import os.path import sys @@ -119,19 +120,32 @@ def handle_bundle_schema(filenames, dest_dir, root, root_namespace): referenced_namespace, referenced_namespace.unix_name) - generator = h_bundle_generator.HBundleGenerator(api_model, type_generator) - h_bundle_code = generator.Generate().Render() + generator = schema_bundle_generator.SchemaBundleGenerator( + api_model, api_defs, type_generator) + api_h_code = generator.GenerateAPIHeader().Render() + schemas_h_code = generator.GenerateSchemasHeader().Render() + schemas_cc_code = generator.GenerateSchemasCC().Render() - out_file = 'generated_api' if dest_dir: - with open( - os.path.join(dest_dir, 'chrome/common/extensions/api/generated_api.h'), - 'w') as h_file: - h_file.write(h_bundle_code) + basedir = os.path.join(dest_dir, 'chrome/common/extensions/api') + with open(os.path.join(basedir, 'generated_api.h'), 'w') as h_file: + h_file.write(api_h_code) + with open(os.path.join(basedir, 'generated_schemas.h'), 'w') as h_file: + h_file.write(schemas_h_code) + with open(os.path.join(basedir, 'generated_schemas.cc'), 'w') as cc_file: + cc_file.write(schemas_cc_code) else: - print '%s.h' % out_file + print 'generated_api.h' + print + print api_h_code + print + print 'generated_schemas.h' + print + print schemas_h_code + print + print 'generated_schemas.cc' print - print h_bundle_code + print schemas_cc_code if __name__ == '__main__': parser = optparse.OptionParser( diff --git a/tools/json_schema_compiler/h_bundle_generator.py b/tools/json_schema_compiler/h_bundle_generator.py deleted file mode 100644 index 5aa22d4..0000000 --- a/tools/json_schema_compiler/h_bundle_generator.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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. - -from model import PropertyType -import code -import cpp_util -import model - -SOURCE_BASE_PATH = 'chrome/common/extensions/api' - -class HBundleGenerator(object): - """A .h generator for namespace bundle functionality. - """ - def __init__(self, model, cpp_type_generator): - self._cpp_type_generator = cpp_type_generator - self._model = model - - def Generate(self): - """Generates a code.Code object with the .h for a bundle. - """ - c = code.Code() - (c.Append(cpp_util.CHROMIUM_LICENSE) - .Append() - .Append(cpp_util.GENERATED_BUNDLE_FILE_MESSAGE % SOURCE_BASE_PATH) - .Append() - ) - - ifndef_name = cpp_util.GenerateIfndefName(SOURCE_BASE_PATH, - 'generated_api') - (c.Append('#ifndef %s' % ifndef_name) - .Append('#define %s' % ifndef_name) - .Append('#pragma once') - .Append() - .Append('#include <string>') - .Append() - .Append('#include "base/basictypes.h"')) - - for namespace in self._model.namespaces.values(): - namespace_name = namespace.name.replace( - "experimental.", "") - c.Append('#include "chrome/browser/extensions/api/%s/%s_api.h"' % ( - namespace_name, namespace_name)) - - (c.Append() - .Append("class ExtensionFunctionRegistry;") - .Append()) - - c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) - - for namespace in self._model.namespaces.values(): - c.Append("// TODO(miket): emit code for %s" % (namespace.unix_name)) - c.Append() - - c.Concat(self.GenerateFunctionRegistry()) - - (c.Concat(self._cpp_type_generator.GetRootNamespaceEnd()) - .Append() - .Append('#endif // %s' % ifndef_name) - .Append() - ) - return c - - def GenerateFunctionRegistry(self): - c = code.Code() - c.Sblock("class GeneratedFunctionRegistry {") - c.Append("public:") - c.Sblock("static void RegisterAll(ExtensionFunctionRegistry* registry) {") - for namespace in self._model.namespaces.values(): - for function in namespace.functions.values(): - namespace_name = namespace.name.replace( - "experimental.", "").capitalize() - function_name = namespace_name + function.name.capitalize() - c.Append("registry->RegisterFunction<%sFunction>();" % ( - function_name)) - c.Eblock("}") - c.Eblock("};") - c.Append() - return c diff --git a/tools/json_schema_compiler/schema_bundle_generator.py b/tools/json_schema_compiler/schema_bundle_generator.py new file mode 100644 index 0000000..c17a674 --- /dev/null +++ b/tools/json_schema_compiler/schema_bundle_generator.py @@ -0,0 +1,145 @@ +# 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 code +import cpp_util + +import json +import os + +# TODO(miket/asargent) - parameterize this. +SOURCE_BASE_PATH = 'chrome/common/extensions/api' + +class SchemaBundleGenerator(object): + """This class contains methods to generate code based on multiple schemas. + """ + + def __init__(self, model, api_defs, cpp_type_generator): + self._model = model + self._api_defs = api_defs + self._cpp_type_generator = cpp_type_generator + + def GenerateHeader(self, file_base, body_code): + """Generates a code.Code object for a header file + + Parameters: + - |file_base| - the base of the filename, e.g. 'foo' (for 'foo.h') + - |body_code| - the code to put in between the multiple inclusion guards""" + c = code.Code() + c.Append(cpp_util.CHROMIUM_LICENSE) + c.Append() + c.Append(cpp_util.GENERATED_BUNDLE_FILE_MESSAGE % SOURCE_BASE_PATH) + ifndef_name = cpp_util.GenerateIfndefName(SOURCE_BASE_PATH, file_base) + c.Append() + c.Append('#ifndef %s' % ifndef_name) + c.Append('#define %s' % ifndef_name) + c.Append('#pragma once') + c.Append() + c.Concat(body_code) + c.Append() + c.Append('#endif // %s' % ifndef_name) + c.Append() + return c + + def GenerateAPIHeader(self): + """Generates the header for API registration / declaration""" + c = code.Code() + + c.Append('#include <string>') + c.Append() + c.Append('#include "base/basictypes.h"') + + for namespace in self._model.namespaces.values(): + namespace_name = namespace.name.replace( + "experimental.", "") + c.Append('#include "chrome/browser/extensions/api/%s/%s_api.h"' % ( + namespace_name, namespace_name)) + + c.Append() + c.Append("class ExtensionFunctionRegistry;") + c.Append() + + c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) + for namespace in self._model.namespaces.values(): + c.Append("// TODO(miket): emit code for %s" % (namespace.unix_name)) + c.Append() + c.Concat(self.GenerateFunctionRegistry()) + c.Concat(self._cpp_type_generator.GetRootNamespaceEnd()) + c.Append() + return self.GenerateHeader('generated_api', c) + + def GenerateFunctionRegistry(self): + c = code.Code() + c.Sblock("class GeneratedFunctionRegistry {") + c.Append("public:") + c.Sblock("static void RegisterAll(ExtensionFunctionRegistry* registry) {") + for namespace in self._model.namespaces.values(): + for function in namespace.functions.values(): + namespace_name = namespace.name.replace( + "experimental.", "").capitalize() + function_name = namespace_name + function.name.capitalize() + c.Append("registry->RegisterFunction<%sFunction>();" % ( + function_name)) + c.Eblock("}") + c.Eblock("};") + c.Append() + return c + + def GenerateSchemasHeader(self): + """Generates a code.Code object for the generated schemas .h file""" + c = code.Code() + c.Append('namespace base {') + c.Append('class ListValue;') + c.Append('}') + c.Append() + c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) + c.Append() + c.Sblock("class GeneratedSchemas {") + c.Append("public:") + c.Append("static base::ListValue* Get();") + c.Eblock("};"); + c.Append() + c.Concat(self._cpp_type_generator.GetRootNamespaceEnd()) + c.Append() + return self.GenerateHeader('generated_schemas', c) + + def GenerateSchemasCC(self): + """Generates a code.Code object for the generated schemas .cc file""" + c = code.Code() + c.Append(cpp_util.CHROMIUM_LICENSE) + c.Append() + c.Append('#include "%s"' % (os.path.join(SOURCE_BASE_PATH, + 'generated_schemas.h'))) + c.Append() + c.Append('#include "base/json/json_reader.h"') + c.Append('#include "base/values.h"') + c.Append() + c.Append('using base::ListValue;') + c.Append() + c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) + c.Append() + c.Sblock('ListValue* GeneratedSchemas::Get() {') + c.Append('ListValue* list = new ListValue();') + for api in self._api_defs: + c.Sblock('{') + c.Sblock('const char tmp[] =') + json_content = json.dumps(api, indent=2) + json_content = json_content.replace('"', '\\"') + lines = json_content.split('\n') + for index,line in enumerate(lines): + line = '"%s"' % line + if index == len(lines) - 1: + line += ';' + c.Append(line) + c.Eblock() + c.Append('Value* val = base::JSONReader::Read(std::string(tmp), false);') + c.Append('list->Append(val);') + c.Eblock('}') + + c.Append('return list;') + c.Eblock('}') + c.Append() + c.Concat(self._cpp_type_generator.GetRootNamespaceEnd()) + c.Append() + return c |