| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import code | 5 import code |
| 6 import cpp_util | 6 import cpp_util |
| 7 from model import Platforms | 7 from model import Platforms |
| 8 from schema_util import CapitalizeFirstLetter | 8 from schema_util import CapitalizeFirstLetter |
| 9 from schema_util import JsFunctionNameToClassName | 9 from schema_util import JsFunctionNameToClassName |
| 10 | 10 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 class CppBundleGenerator(object): | 33 class CppBundleGenerator(object): |
| 34 """This class contains methods to generate code based on multiple schemas. | 34 """This class contains methods to generate code based on multiple schemas. |
| 35 """ | 35 """ |
| 36 | 36 |
| 37 def __init__(self, | 37 def __init__(self, |
| 38 root, | 38 root, |
| 39 model, | 39 model, |
| 40 api_defs, | 40 api_defs, |
| 41 cpp_type_generator, | 41 cpp_type_generator, |
| 42 cpp_namespace_pattern, | 42 cpp_namespace_pattern, |
| 43 bundle_name, |
| 43 source_file_dir, | 44 source_file_dir, |
| 44 impl_dir): | 45 impl_dir): |
| 45 self._root = root | 46 self._root = root |
| 46 self._model = model | 47 self._model = model |
| 47 self._api_defs = api_defs | 48 self._api_defs = api_defs |
| 48 self._cpp_type_generator = cpp_type_generator | 49 self._cpp_type_generator = cpp_type_generator |
| 50 self._bundle_name = bundle_name |
| 49 self._source_file_dir = source_file_dir | 51 self._source_file_dir = source_file_dir |
| 50 self._impl_dir = impl_dir | 52 self._impl_dir = impl_dir |
| 51 | 53 |
| 52 # Hack: assume that the C++ namespace for the bundle is the namespace of the | 54 # Hack: assume that the C++ namespace for the bundle is the namespace of the |
| 53 # files without the last component of the namespace. A cleaner way to do | 55 # files without the last component of the namespace. A cleaner way to do |
| 54 # this would be to make it a separate variable in the gyp file. | 56 # this would be to make it a separate variable in the gyp file. |
| 55 self._cpp_namespace = cpp_namespace_pattern.rsplit('::', 1)[0] | 57 self._cpp_namespace = cpp_namespace_pattern.rsplit('::', 1)[0] |
| 56 | 58 |
| 57 self.api_cc_generator = _APICCGenerator(self) | 59 self.api_cc_generator = _APICCGenerator(self) |
| 58 self.api_h_generator = _APIHGenerator(self) | 60 self.api_h_generator = _APIHGenerator(self) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 c.Append("registry->RegisterFunction<%sFunction>();" % ( | 113 c.Append("registry->RegisterFunction<%sFunction>();" % ( |
| 112 function_name)) | 114 function_name)) |
| 113 | 115 |
| 114 if function_ifdefs is not None: | 116 if function_ifdefs is not None: |
| 115 c.Append("#endif // %s" % function_ifdefs, indent_level=0) | 117 c.Append("#endif // %s" % function_ifdefs, indent_level=0) |
| 116 return c | 118 return c |
| 117 | 119 |
| 118 def _GenerateFunctionRegistryRegisterAll(self): | 120 def _GenerateFunctionRegistryRegisterAll(self): |
| 119 c = code.Code() | 121 c = code.Code() |
| 120 c.Append('// static') | 122 c.Append('// static') |
| 121 c.Sblock('void GeneratedFunctionRegistry::RegisterAll(' | 123 c.Sblock('void %s::RegisterAll(ExtensionFunctionRegistry* registry) {' % |
| 122 'ExtensionFunctionRegistry* registry) {') | 124 self._GenerateBundleClass('GeneratedFunctionRegistry')) |
| 123 for namespace in self._model.namespaces.values(): | 125 for namespace in self._model.namespaces.values(): |
| 124 namespace_ifdefs = self._GetPlatformIfdefs(namespace) | 126 namespace_ifdefs = self._GetPlatformIfdefs(namespace) |
| 125 if namespace_ifdefs is not None: | 127 if namespace_ifdefs is not None: |
| 126 c.Append("#if %s" % namespace_ifdefs, indent_level=0) | 128 c.Append("#if %s" % namespace_ifdefs, indent_level=0) |
| 127 | 129 |
| 128 for function in namespace.functions.values(): | 130 for function in namespace.functions.values(): |
| 129 if function.nocompile: | 131 if function.nocompile: |
| 130 continue | 132 continue |
| 131 c.Concat(self._GenerateRegisterFunctions(namespace.name, function)) | 133 c.Concat(self._GenerateRegisterFunctions(namespace.name, function)) |
| 132 | 134 |
| 133 for type_ in namespace.types.values(): | 135 for type_ in namespace.types.values(): |
| 134 for function in type_.functions.values(): | 136 for function in type_.functions.values(): |
| 135 if function.nocompile: | 137 if function.nocompile: |
| 136 continue | 138 continue |
| 137 namespace_types_name = JsFunctionNameToClassName( | 139 namespace_types_name = JsFunctionNameToClassName( |
| 138 namespace.name, type_.name) | 140 namespace.name, type_.name) |
| 139 c.Concat(self._GenerateRegisterFunctions(namespace_types_name, | 141 c.Concat(self._GenerateRegisterFunctions(namespace_types_name, |
| 140 function)) | 142 function)) |
| 141 | 143 |
| 142 if namespace_ifdefs is not None: | 144 if namespace_ifdefs is not None: |
| 143 c.Append("#endif // %s" % namespace_ifdefs, indent_level=0) | 145 c.Append("#endif // %s" % namespace_ifdefs, indent_level=0) |
| 144 c.Eblock("}") | 146 c.Eblock("}") |
| 145 return c | 147 return c |
| 146 | 148 |
| 149 def _GenerateBundleClass(self, class_name): |
| 150 '''Generates the C++ class name to use for a bundle class, taking into |
| 151 account the bundle's name. |
| 152 ''' |
| 153 return self._bundle_name + class_name |
| 154 |
| 147 | 155 |
| 148 class _APIHGenerator(object): | 156 class _APIHGenerator(object): |
| 149 """Generates the header for API registration / declaration""" | 157 """Generates the header for API registration / declaration""" |
| 150 def __init__(self, cpp_bundle): | 158 def __init__(self, cpp_bundle): |
| 151 self._bundle = cpp_bundle | 159 self._bundle = cpp_bundle |
| 152 | 160 |
| 153 def Generate(self, _): # namespace not relevant, this is a bundle | 161 def Generate(self, _): # namespace not relevant, this is a bundle |
| 154 c = code.Code() | 162 c = code.Code() |
| 155 | 163 |
| 156 c.Append('#include <string>') | 164 c.Append('#include <string>') |
| 157 c.Append() | 165 c.Append() |
| 158 c.Append('#include "base/basictypes.h"') | 166 c.Append('#include "base/basictypes.h"') |
| 159 c.Append() | 167 c.Append() |
| 160 c.Append("class ExtensionFunctionRegistry;") | 168 c.Append("class ExtensionFunctionRegistry;") |
| 161 c.Append() | 169 c.Append() |
| 162 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) | 170 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) |
| 163 c.Append() | 171 c.Append() |
| 164 c.Append('class GeneratedFunctionRegistry {') | 172 c.Append('class %s {' % |
| 173 self._bundle._GenerateBundleClass('GeneratedFunctionRegistry')) |
| 165 c.Sblock(' public:') | 174 c.Sblock(' public:') |
| 166 c.Append('static void RegisterAll(' | 175 c.Append('static void RegisterAll(' |
| 167 'ExtensionFunctionRegistry* registry);') | 176 'ExtensionFunctionRegistry* registry);') |
| 168 c.Eblock('};') | 177 c.Eblock('};') |
| 169 c.Append() | 178 c.Append() |
| 170 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) | 179 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) |
| 171 return self._bundle._GenerateHeader('generated_api', c) | 180 return self._bundle._GenerateHeader('generated_api', c) |
| 172 | 181 |
| 173 | 182 |
| 174 class _APICCGenerator(object): | 183 class _APICCGenerator(object): |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 | 237 |
| 229 def Generate(self, _): # namespace not relevant, this is a bundle | 238 def Generate(self, _): # namespace not relevant, this is a bundle |
| 230 c = code.Code() | 239 c = code.Code() |
| 231 c.Append('#include <map>') | 240 c.Append('#include <map>') |
| 232 c.Append('#include <string>') | 241 c.Append('#include <string>') |
| 233 c.Append() | 242 c.Append() |
| 234 c.Append('#include "base/strings/string_piece.h"') | 243 c.Append('#include "base/strings/string_piece.h"') |
| 235 c.Append() | 244 c.Append() |
| 236 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) | 245 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) |
| 237 c.Append() | 246 c.Append() |
| 238 c.Append('class GeneratedSchemas {') | 247 c.Append('class %s {' % |
| 248 self._bundle._GenerateBundleClass('GeneratedSchemas')) |
| 239 c.Sblock(' public:') | 249 c.Sblock(' public:') |
| 240 c.Append('// Determines if schema named |name| is generated.') | 250 c.Append('// Determines if schema named |name| is generated.') |
| 241 c.Append('static bool IsGenerated(std::string name);') | 251 c.Append('static bool IsGenerated(std::string name);') |
| 242 c.Append() | 252 c.Append() |
| 243 c.Append('// Gets the API schema named |name|.') | 253 c.Append('// Gets the API schema named |name|.') |
| 244 c.Append('static base::StringPiece Get(const std::string& name);') | 254 c.Append('static base::StringPiece Get(const std::string& name);') |
| 245 c.Eblock('};') | 255 c.Eblock('};') |
| 246 c.Append() | 256 c.Append() |
| 247 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) | 257 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) |
| 248 return self._bundle._GenerateHeader('generated_schemas', c) | 258 return self._bundle._GenerateHeader('generated_schemas', c) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 # Escape all double-quotes and backslashes. For this to output a valid | 290 # Escape all double-quotes and backslashes. For this to output a valid |
| 281 # JSON C string, we need to escape \ and ". Note that some schemas are | 291 # JSON C string, we need to escape \ and ". Note that some schemas are |
| 282 # too large to compile on windows. Split the JSON up into several | 292 # too large to compile on windows. Split the JSON up into several |
| 283 # strings, since apparently that helps. | 293 # strings, since apparently that helps. |
| 284 max_length = 8192 | 294 max_length = 8192 |
| 285 segments = [json_content[i:i + max_length].replace('\\', '\\\\') | 295 segments = [json_content[i:i + max_length].replace('\\', '\\\\') |
| 286 .replace('"', '\\"') | 296 .replace('"', '\\"') |
| 287 for i in xrange(0, len(json_content), max_length)] | 297 for i in xrange(0, len(json_content), max_length)] |
| 288 c.Append('const char %s[] = "%s";' % | 298 c.Append('const char %s[] = "%s";' % |
| 289 (_FormatNameAsConstant(namespace.name), '" "'.join(segments))) | 299 (_FormatNameAsConstant(namespace.name), '" "'.join(segments))) |
| 290 c.Append('}') | |
| 291 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) | |
| 292 c.Append() | 300 c.Append() |
| 293 c.Sblock('struct Static {') | 301 c.Sblock('struct Static {') |
| 294 c.Sblock('Static() {') | 302 c.Sblock('Static() {') |
| 295 for api in self._bundle._api_defs: | 303 for api in self._bundle._api_defs: |
| 296 namespace = self._bundle._model.namespaces[api.get('namespace')] | 304 namespace = self._bundle._model.namespaces[api.get('namespace')] |
| 297 c.Append('schemas["%s"] = %s;' % (namespace.name, | 305 c.Append('schemas["%s"] = %s;' % (namespace.name, |
| 298 _FormatNameAsConstant(namespace.name))) | 306 _FormatNameAsConstant(namespace.name))) |
| 299 c.Eblock('}') | 307 c.Eblock('}') |
| 300 c.Append() | 308 c.Append() |
| 301 c.Append('std::map<std::string, const char*> schemas;') | 309 c.Append('std::map<std::string, const char*> schemas;') |
| 302 c.Eblock('};') | 310 c.Eblock('};') |
| 303 c.Append() | 311 c.Append() |
| 304 c.Append('base::LazyInstance<Static> g_lazy_instance;') | 312 c.Append('base::LazyInstance<Static> g_lazy_instance;') |
| 305 c.Append() | 313 c.Append() |
| 314 c.Append('} // namespace') |
| 315 c.Append() |
| 316 c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) |
| 317 c.Append() |
| 306 c.Append('// static') | 318 c.Append('// static') |
| 307 c.Sblock('base::StringPiece GeneratedSchemas::Get(' | 319 c.Sblock('base::StringPiece %s::Get(const std::string& name) {' % |
| 308 'const std::string& name) {') | 320 self._bundle._GenerateBundleClass('GeneratedSchemas')) |
| 309 c.Append('return IsGenerated(name) ? ' | 321 c.Append('return IsGenerated(name) ? ' |
| 310 'g_lazy_instance.Get().schemas[name] : "";') | 322 'g_lazy_instance.Get().schemas[name] : "";') |
| 311 c.Eblock('}') | 323 c.Eblock('}') |
| 312 c.Append() | 324 c.Append() |
| 313 c.Append('// static') | 325 c.Append('// static') |
| 314 c.Sblock('bool GeneratedSchemas::IsGenerated(std::string name) {') | 326 c.Sblock('bool %s::IsGenerated(std::string name) {' % |
| 327 self._bundle._GenerateBundleClass('GeneratedSchemas')) |
| 315 c.Append('return g_lazy_instance.Get().schemas.count(name) > 0;') | 328 c.Append('return g_lazy_instance.Get().schemas.count(name) > 0;') |
| 316 c.Eblock('}') | 329 c.Eblock('}') |
| 317 c.Append() | 330 c.Append() |
| 318 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) | 331 c.Concat(cpp_util.CloseNamespace(self._bundle._cpp_namespace)) |
| 319 c.Append() | 332 c.Append() |
| 320 return c | 333 return c |
| OLD | NEW |