[DevTools] Refactor CodeGenerator.
Simplified, improved up_to_date, prepared to more config params.
BUG=637032
Review-Url: https://codereview.chromium.org/2248783003
Cr-Original-Commit-Position: refs/heads/master@{#412361}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 426a8b81c5c4cb53748907d8f0b77cd85e88a0d6
diff --git a/BackendCallback_h.template b/BackendCallback_h.template
index f301ede..0eb44bf 100644
--- a/BackendCallback_h.template
+++ b/BackendCallback_h.template
@@ -7,12 +7,12 @@
//#include "ErrorSupport.h"
//#include "Platform.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
namespace blink {
namespace protocol {
-class {{export_macro}} BackendCallback {
+class {{config.class_export.macro}} BackendCallback {
public:
virtual ~BackendCallback() { }
virtual void sendFailure(const ErrorString&) = 0;
diff --git a/CodeGenerator.py b/CodeGenerator.py
index 128dde3..d6ab65e 100644
--- a/CodeGenerator.py
+++ b/CodeGenerator.py
@@ -5,6 +5,8 @@
import os.path
import sys
import optparse
+import collections
+import functools
try:
import json
except ImportError:
@@ -47,129 +49,52 @@
import jinja2
-cmdline_parser = optparse.OptionParser()
-cmdline_parser.add_option("--output_base")
-cmdline_parser.add_option("--config")
+def read_config():
+ # pylint: disable=W0703
+ def json_to_object(data, output_base, config_base):
+ def json_object_hook(object_dict):
+ items = [(k, os.path.join(config_base, v) if k == "path" else v) for (k, v) in object_dict.items()]
+ items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items]
+ keys, values = zip(*items)
+ return collections.namedtuple('X', keys)(*values)
+ return json.loads(data, object_hook=json_object_hook)
-try:
- arg_options, arg_values = cmdline_parser.parse_args()
- output_base = arg_options.output_base
- if not output_base:
- raise Exception("Base output directory must be specified")
- config_file = arg_options.config
- if not config_file:
- raise Exception("Config file name must be specified")
- config_dir = os.path.dirname(config_file)
-except Exception:
- # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
- exc = sys.exc_info()[1]
- sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
- exit(1)
+ try:
+ cmdline_parser = optparse.OptionParser()
+ cmdline_parser.add_option("--output_base")
+ cmdline_parser.add_option("--config")
+ arg_options, _ = cmdline_parser.parse_args()
+ output_base = arg_options.output_base
+ if not output_base:
+ raise Exception("Base output directory must be specified")
+ config_file = arg_options.config
+ if not config_file:
+ raise Exception("Config file name must be specified")
+ config_base = os.path.dirname(config_file)
+ except Exception:
+ # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
+ exc = sys.exc_info()[1]
+ sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
+ exit(1)
-
-try:
- config_json_string = open(config_file, "r").read()
- config = json.loads(config_json_string)
-
- protocol_file = config["protocol"]["path"]
- if not protocol_file:
- raise Exception("Config is missing protocol.path")
- protocol_file = os.path.join(config_dir, protocol_file)
- output_dirname = config["protocol"]["output"]
- if not output_dirname:
- raise Exception("Config is missing protocol.output")
- output_dirname = os.path.join(output_base, output_dirname)
- output_package = config["protocol"]["package"]
- if not output_package:
- raise Exception("Config is missing protocol.package")
-
- importing = False
- if "import" in config:
- importing = True
- imported_file = config["import"]["path"]
- if not imported_file:
- raise Exception("Config is missing import.path")
- imported_file = os.path.join(config_dir, imported_file)
- imported_package = config["import"]["package"]
- if not imported_package:
- raise Exception("Config is missing import.package")
-
- exporting = False
- if "export" in config:
- exporting = True
- exported_dirname = config["export"]["output"]
- if not exported_dirname:
- raise Exception("Config is missing export.output")
- exported_dirname = os.path.join(output_base, exported_dirname)
- exported_package = config["export"]["package"]
- if not exported_package:
- raise Exception("Config is missing export.package")
-
- lib = False
- if "lib" in config:
- lib = True
- lib_dirname = config["lib"]["output"]
- if not lib_dirname:
- raise Exception("Config is missing lib.output")
- lib_dirname = os.path.join(output_base, lib_dirname)
- lib_string16_include = config["lib"]["string16_impl_header_path"]
- if not lib_string16_include:
- raise Exception("Config is missing lib.string16_impl_header_path")
- lib_platform_include = config["lib"]["platform_impl_header_path"]
- if not lib_platform_include:
- raise Exception("Config is missing lib.platform_impl_header_path")
-
- string_type = config["string"]["class_name"]
- if not string_type:
- raise Exception("Config is missing string.class_name")
-
- export_macro = config["class_export"]["macro"]
- if not export_macro:
- raise Exception("Config is missing class_export.macro")
- export_macro_include = config["class_export"]["header_path"]
- if not export_macro_include:
- raise Exception("Config is missing class_export.header_path")
-
- lib_package = config["lib_package"]
- if not lib_package:
- raise Exception("Config is missing lib_package")
-except Exception:
- # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
- exc = sys.exc_info()[1]
- sys.stderr.write("Failed to parse config file: %s\n\n" % exc)
- exit(1)
-
-
-# Make gyp / make generatos happy, otherwise make rebuilds world.
-def up_to_date():
- template_ts = max(
- os.path.getmtime(__file__),
- os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_h.template")),
- os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template")),
- os.path.getmtime(os.path.join(templates_dir, "Exported_h.template")),
- os.path.getmtime(os.path.join(templates_dir, "Imported_h.template")),
- os.path.getmtime(config_file),
- os.path.getmtime(protocol_file))
- if importing:
- template_ts = max(template_ts, os.path.getmtime(imported_file))
-
- for domain in json_api["domains"]:
- name = domain["domain"]
- paths = []
- if name in generate_domains:
- paths = [os.path.join(output_dirname, name + ".h"), os.path.join(output_dirname, name + ".cpp")]
- if domain["has_exports"]:
- paths.append(os.path.join(exported_dirname, name + ".h"))
- if name in imported_domains and domain["has_exports"]:
- paths = [os.path.join(output_dirname, name + '.h')]
- for path in paths:
- if not os.path.exists(path):
- return False
- generated_ts = os.path.getmtime(path)
- if generated_ts < template_ts:
- return False
- return True
+ try:
+ config_json_file = open(config_file, "r")
+ config_json_string = config_json_file.read()
+ config_partial = json_to_object(config_json_string, output_base, config_base)
+ keys = list(config_partial._fields) # pylint: disable=E1101
+ values = [getattr(config_partial, k) for k in keys]
+ for optional in ["imported", "exported", "lib"]:
+ if optional not in keys:
+ keys.append(optional)
+ values.append(False)
+ config_json_file.close()
+ return (config_file, collections.namedtuple('X', keys)(*values))
+ except Exception:
+ # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
+ exc = sys.exc_info()[1]
+ sys.stderr.write("Failed to parse config file: %s\n\n" % exc)
+ exit(1)
def to_title_case(name):
@@ -198,11 +123,7 @@
return jinja_env
-def output_file(file_name):
- return open(file_name, "w")
-
-
-def patch_full_qualified_refs():
+def patch_full_qualified_refs(protocol):
def patch_full_qualified_refs_in_domain(json, domain_name):
if isinstance(json, list):
for item in json:
@@ -220,11 +141,11 @@
json["$ref"] = domain_name + "." + json["$ref"]
return
- for domain in json_api["domains"]:
+ for domain in protocol.json_api["domains"]:
patch_full_qualified_refs_in_domain(domain, domain["domain"])
-def calculate_exports():
+def calculate_exports(protocol):
def calculate_exports_in_json(json_value):
has_exports = False
if isinstance(json_value, list):
@@ -236,15 +157,11 @@
has_exports = calculate_exports_in_json(json_value[key]) or has_exports
return has_exports
- json_api["has_exports"] = False
- for domain_json in json_api["domains"]:
- domain_name = domain_json["domain"]
+ protocol.json_api["has_exports"] = False
+ for domain_json in protocol.json_api["domains"]:
domain_json["has_exports"] = calculate_exports_in_json(domain_json)
- if domain_json["has_exports"] and domain_name in generate_domains:
- if not exporting:
- sys.stderr.write("Domain %s is exported, but config is missing export entry\n\n" % domain_name)
- exit(1)
- json_api["has_exports"] = True
+ if domain_json["has_exports"] and domain_json["domain"] in protocol.generate_domains:
+ protocol.json_api["has_exports"] = True
def create_imported_type_definition(domain_name, type):
@@ -307,7 +224,7 @@
}
-def create_string_type_definition(domain):
+def create_string_type_definition(string_type):
# pylint: disable=W0622
return {
"return_type": string_type,
@@ -353,14 +270,6 @@
}
-type_definitions = {}
-type_definitions["number"] = create_primitive_type_definition("number")
-type_definitions["integer"] = create_primitive_type_definition("integer")
-type_definitions["boolean"] = create_primitive_type_definition("boolean")
-type_definitions["object"] = create_object_type_definition()
-type_definitions["any"] = create_any_type_definition()
-
-
def wrap_array_definition(type):
# pylint: disable=W0622
return {
@@ -378,36 +287,42 @@
}
-def create_type_definitions():
- for domain in json_api["domains"]:
- type_definitions[domain["domain"] + ".string"] = create_string_type_definition(domain["domain"])
+def create_type_definitions(protocol, string_type):
+ protocol.type_definitions = {}
+ protocol.type_definitions["number"] = create_primitive_type_definition("number")
+ protocol.type_definitions["integer"] = create_primitive_type_definition("integer")
+ protocol.type_definitions["boolean"] = create_primitive_type_definition("boolean")
+ protocol.type_definitions["object"] = create_object_type_definition()
+ protocol.type_definitions["any"] = create_any_type_definition()
+ for domain in protocol.json_api["domains"]:
+ protocol.type_definitions[domain["domain"] + ".string"] = create_string_type_definition(string_type)
if not ("types" in domain):
continue
for type in domain["types"]:
type_name = domain["domain"] + "." + type["id"]
- if type["type"] == "object" and domain["domain"] in imported_domains:
- type_definitions[type_name] = create_imported_type_definition(domain["domain"], type)
+ if type["type"] == "object" and domain["domain"] in protocol.imported_domains:
+ protocol.type_definitions[type_name] = create_imported_type_definition(domain["domain"], type)
elif type["type"] == "object":
- type_definitions[type_name] = create_user_type_definition(domain["domain"], type)
+ protocol.type_definitions[type_name] = create_user_type_definition(domain["domain"], type)
elif type["type"] == "array":
items_type = type["items"]["type"]
- type_definitions[type_name] = wrap_array_definition(type_definitions[items_type])
+ protocol.type_definitions[type_name] = wrap_array_definition(protocol.type_definitions[items_type])
elif type["type"] == domain["domain"] + ".string":
- type_definitions[type_name] = create_string_type_definition(domain["domain"])
+ protocol.type_definitions[type_name] = create_string_type_definition(string_type)
else:
- type_definitions[type_name] = create_primitive_type_definition(type["type"])
+ protocol.type_definitions[type_name] = create_primitive_type_definition(type["type"])
-def type_definition(name):
- return type_definitions[name]
+def type_definition(protocol, name):
+ return protocol.type_definitions[name]
-def resolve_type(property):
- if "$ref" in property:
- return type_definitions[property["$ref"]]
- if property["type"] == "array":
- return wrap_array_definition(resolve_type(property["items"]))
- return type_definitions[property["type"]]
+def resolve_type(protocol, prop):
+ if "$ref" in prop:
+ return protocol.type_definitions[prop["$ref"]]
+ if prop["type"] == "array":
+ return wrap_array_definition(resolve_type(protocol, prop["items"]))
+ return protocol.type_definitions[prop["type"]]
def join_arrays(dict, keys):
@@ -425,124 +340,144 @@
return False
-def generate(domain_object, template, file_name):
- template_context = {
- "domain": domain_object,
- "join_arrays": join_arrays,
- "resolve_type": resolve_type,
- "type_definition": type_definition,
- "has_disable": has_disable,
- "export_macro": export_macro,
- "export_macro_include": export_macro_include,
- "output_package": output_package,
- "lib_package": lib_package
- }
- if exporting:
- template_context["exported_package"] = exported_package
- if importing:
- template_context["imported_package"] = imported_package
- out_file = output_file(file_name)
- out_file.write(template.render(template_context))
- out_file.close()
-
-
-def read_protocol_file(file_name, all_domains):
+def read_protocol_file(file_name, json_api):
input_file = open(file_name, "r")
json_string = input_file.read()
+ input_file.close()
parsed_json = json.loads(json_string)
domains = []
for domain in parsed_json["domains"]:
domains.append(domain["domain"])
- all_domains["domains"] += parsed_json["domains"]
+ json_api["domains"] += parsed_json["domains"]
return domains
-def generate_lib():
- template_context = {
- "string16_impl_h_include": lib_string16_include,
- "platform_impl_h_include": lib_platform_include,
- "lib_package": lib_package,
- "export_macro": export_macro,
- "export_macro_include": export_macro_include
- }
+class Protocol(object):
+ def __init__(self):
+ self.json_api = {}
+ self.generate_domains = []
+ self.imported_domains = []
- def generate_file(file_name, template_files):
- out_file = output_file(file_name)
- for template_file in template_files:
- template = jinja_env.get_template("/" + template_file)
- out_file.write(template.render(template_context))
- out_file.write("\n\n")
+
+def main():
+ config_file, config = read_config()
+
+ protocol = Protocol()
+ protocol.json_api = {"domains": []}
+ protocol.generate_domains = read_protocol_file(config.protocol.path, protocol.json_api)
+ protocol.imported_domains = read_protocol_file(config.imported.path, protocol.json_api) if config.imported else []
+ patch_full_qualified_refs(protocol)
+ calculate_exports(protocol)
+ create_type_definitions(protocol, config.string.class_name)
+
+ if not config.exported:
+ for domain_json in protocol.json_api["domains"]:
+ if domain_json["has_exports"] and domain_json["domain"] in protocol.generate_domains:
+ sys.stderr.write("Domain %s is exported, but config is missing export entry\n\n" % domain_json["domain"])
+ exit(1)
+
+ if not os.path.exists(config.protocol.output):
+ os.mkdir(config.protocol.output)
+ if protocol.json_api["has_exports"] and not os.path.exists(config.exported.output):
+ os.mkdir(config.exported.output)
+ jinja_env = initialize_jinja_env(config.protocol.output)
+
+ inputs = []
+ inputs.append(__file__)
+ inputs.append(config_file)
+ inputs.append(config.protocol.path)
+ if config.imported:
+ inputs.append(config.imported.path)
+ inputs.append(os.path.join(templates_dir, "TypeBuilder_h.template"))
+ inputs.append(os.path.join(templates_dir, "TypeBuilder_cpp.template"))
+ inputs.append(os.path.join(templates_dir, "Exported_h.template"))
+ inputs.append(os.path.join(templates_dir, "Imported_h.template"))
+
+ h_template = jinja_env.get_template("TypeBuilder_h.template")
+ cpp_template = jinja_env.get_template("TypeBuilder_cpp.template")
+ exported_template = jinja_env.get_template("Exported_h.template")
+ imported_template = jinja_env.get_template("Imported_h.template")
+
+ outputs = dict()
+
+ for domain in protocol.json_api["domains"]:
+ class_name = domain["domain"]
+ template_context = {
+ "config": config,
+ "domain": domain,
+ "join_arrays": join_arrays,
+ "resolve_type": functools.partial(resolve_type, protocol),
+ "type_definition": functools.partial(type_definition, protocol),
+ "has_disable": has_disable
+ }
+
+ if domain["domain"] in protocol.generate_domains:
+ outputs[os.path.join(config.protocol.output, class_name + ".h")] = h_template.render(template_context)
+ outputs[os.path.join(config.protocol.output, class_name + ".cpp")] = cpp_template.render(template_context)
+ if domain["has_exports"]:
+ outputs[os.path.join(config.exported.output, class_name + ".h")] = exported_template.render(template_context)
+ if domain["domain"] in protocol.imported_domains and domain["has_exports"]:
+ outputs[os.path.join(config.protocol.output, class_name + ".h")] = imported_template.render(template_context)
+
+ if config.lib:
+ template_context = {
+ "config": config
+ }
+
+ # Note these should be sorted in the right order.
+ # TODO(dgozman): sort them programmatically based on commented includes.
+ lib_h_templates = [
+ "Allocator_h.template",
+ "Platform_h.template",
+ "Collections_h.template",
+ "String16_h.template",
+ "ErrorSupport_h.template",
+ "Values_h.template",
+ "Object_h.template",
+ "ValueConversions_h.template",
+ "Maybe_h.template",
+ "Array_h.template",
+ "FrontendChannel_h.template",
+ "BackendCallback_h.template",
+ "DispatcherBase_h.template",
+ "Parser_h.template",
+ ]
+
+ lib_cpp_templates = [
+ "InspectorProtocol_cpp.template",
+ "String16_cpp.template",
+ "ErrorSupport_cpp.template",
+ "Values_cpp.template",
+ "Object_cpp.template",
+ "DispatcherBase_cpp.template",
+ "Parser_cpp.template",
+ ]
+
+ def generate_lib_file(file_name, template_files):
+ parts = []
+ for template_file in template_files:
+ inputs.append(os.path.join(templates_dir, template_file))
+ template = jinja_env.get_template(template_file)
+ parts.append(template.render(template_context))
+ outputs[file_name] = "\n\n".join(parts)
+
+ generate_lib_file(os.path.join(config.lib.output, "InspectorProtocol.h"), lib_h_templates)
+ generate_lib_file(os.path.join(config.lib.output, "InspectorProtocol.cpp"), lib_cpp_templates)
+
+ # Make gyp / make generatos happy, otherwise make rebuilds world.
+ inputs_ts = max(map(os.path.getmtime, inputs))
+ up_to_date = True
+ for output_file in outputs.iterkeys():
+ if not os.path.exists(output_file) or os.path.getmtime(output_file) < inputs_ts:
+ up_to_date = False
+ break
+ if up_to_date:
+ sys.exit()
+
+ for file_name, content in outputs.iteritems():
+ out_file = open(file_name, "w")
+ out_file.write(content)
out_file.close()
- # Note these should be sorted in the right order.
- # TODO(dgozman): sort them programmatically based on commented includes.
- lib_h_templates = [
- "Allocator_h.template",
- "Platform_h.template",
- "Collections_h.template",
- "String16_h.template",
- "ErrorSupport_h.template",
- "Values_h.template",
- "Object_h.template",
- "ValueConversions_h.template",
- "Maybe_h.template",
- "Array_h.template",
-
- "FrontendChannel_h.template",
- "BackendCallback_h.template",
- "DispatcherBase_h.template",
-
- "Parser_h.template",
- ]
-
- lib_cpp_templates = [
- "InspectorProtocol_cpp.template",
-
- "String16_cpp.template",
-
- "ErrorSupport_cpp.template",
- "Values_cpp.template",
- "Object_cpp.template",
-
- "DispatcherBase_cpp.template",
-
- "Parser_cpp.template",
- ]
-
- generate_file(os.path.join(lib_dirname, "InspectorProtocol.h"), lib_h_templates)
- generate_file(os.path.join(lib_dirname, "InspectorProtocol.cpp"), lib_cpp_templates)
-
-
-json_api = {"domains": []}
-generate_domains = read_protocol_file(protocol_file, json_api)
-imported_domains = read_protocol_file(imported_file, json_api) if importing else []
-patch_full_qualified_refs()
-calculate_exports()
-create_type_definitions()
-
-if up_to_date():
- sys.exit()
-if not os.path.exists(output_dirname):
- os.mkdir(output_dirname)
-if json_api["has_exports"] and not os.path.exists(exported_dirname):
- os.mkdir(exported_dirname)
-
-jinja_env = initialize_jinja_env(output_dirname)
-h_template = jinja_env.get_template("/TypeBuilder_h.template")
-cpp_template = jinja_env.get_template("/TypeBuilder_cpp.template")
-exported_template = jinja_env.get_template("/Exported_h.template")
-imported_template = jinja_env.get_template("/Imported_h.template")
-
-for domain in json_api["domains"]:
- class_name = domain["domain"]
- if domain["domain"] in generate_domains:
- generate(domain, h_template, os.path.join(output_dirname, class_name + ".h"))
- generate(domain, cpp_template, os.path.join(output_dirname, class_name + ".cpp"))
- if domain["has_exports"]:
- generate(domain, exported_template, os.path.join(exported_dirname, class_name + ".h"))
- if domain["domain"] in imported_domains and domain["has_exports"]:
- generate(domain, imported_template, os.path.join(output_dirname, class_name + ".h"))
-
-if lib:
- generate_lib()
+main()
diff --git a/DispatcherBase_h.template b/DispatcherBase_h.template
index 76b7958..4402d96 100644
--- a/DispatcherBase_h.template
+++ b/DispatcherBase_h.template
@@ -11,7 +11,7 @@
//#include "Platform.h"
//#include "String16.h"
//#include "Values.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
namespace blink {
namespace protocol {
@@ -19,11 +19,11 @@
class FrontendChannel;
class WeakPtr;
-class {{export_macro}} DispatcherBase {
+class {{config.class_export.macro}} DispatcherBase {
PROTOCOL_DISALLOW_COPY(DispatcherBase);
public:
static const char kInvalidRequest[];
- class {{export_macro}} WeakPtr {
+ class {{config.class_export.macro}} WeakPtr {
public:
explicit WeakPtr(DispatcherBase*);
~WeakPtr();
@@ -34,7 +34,7 @@
DispatcherBase* m_dispatcher;
};
- class {{export_macro}} Callback : public protocol::BackendCallback {
+ class {{config.class_export.macro}} Callback : public protocol::BackendCallback {
public:
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId);
virtual ~Callback();
@@ -78,7 +78,7 @@
protocol::HashSet<WeakPtr*> m_weakPtrs;
};
-class {{export_macro}} UberDispatcher {
+class {{config.class_export.macro}} UberDispatcher {
PROTOCOL_DISALLOW_COPY(UberDispatcher);
public:
explicit UberDispatcher(FrontendChannel*);
diff --git a/ErrorSupport_h.template b/ErrorSupport_h.template
index 50557c0..f837bff 100644
--- a/ErrorSupport_h.template
+++ b/ErrorSupport_h.template
@@ -7,7 +7,7 @@
//#include "Platform.h"
//#include "String16.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
#include <vector>
@@ -16,7 +16,7 @@
using ErrorString = String16;
-class {{export_macro}} ErrorSupport {
+class {{config.class_export.macro}} ErrorSupport {
public:
ErrorSupport();
ErrorSupport(String16* errorString);
diff --git a/Exported_h.template b/Exported_h.template
index 116a441..66cf7f9 100644
--- a/Exported_h.template
+++ b/Exported_h.template
@@ -7,8 +7,8 @@
#ifndef protocol_{{domain.domain}}_api_h
#define protocol_{{domain.domain}}_api_h
-#include "{{export_macro_include}}"
-#include "{{lib_package}}/InspectorProtocol.h"
+#include "{{config.class_export.header}}"
+#include "{{config.lib_package}}/InspectorProtocol.h"
namespace blink {
namespace protocol {
@@ -21,7 +21,7 @@
namespace {{type.id}}Enum {
{% for literal in type.enum %}
-{{export_macro}} extern const char* {{ literal | dash_to_camelcase}};
+{{config.class_export.macro}} extern const char* {{ literal | dash_to_camelcase}};
{% endfor %}
} // {{type.id}}Enum
{% endif %}
@@ -33,7 +33,7 @@
namespace {{command.name | to_title_case}} {
namespace {{param.name | to_title_case}}Enum {
{% for literal in param.enum %}
-{{export_macro}} extern const char* {{ literal | dash_to_camelcase}};
+{{config.class_export.macro}} extern const char* {{ literal | dash_to_camelcase}};
{% endfor %}
} // {{param.name | to_title_case}}Enum
} // {{command.name | to_title_case }}
@@ -45,7 +45,7 @@
{% for type in domain.types %}
{% if not (type.type == "object") or not ("properties" in type) or not (type.exported) %}{% continue %}{% endif %}
-class {{export_macro}} {{type.id}} {
+class {{config.class_export.macro}} {{type.id}} {
public:
virtual String16 toJSONString() const = 0;
virtual ~{{type.id}}() { }
diff --git a/FrontendChannel_h.template b/FrontendChannel_h.template
index 0b7025f..ead1491 100644
--- a/FrontendChannel_h.template
+++ b/FrontendChannel_h.template
@@ -6,12 +6,12 @@
#define FrontendChannel_h
//#include "String16.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
namespace blink {
namespace protocol {
-class {{export_macro}} FrontendChannel {
+class {{config.class_export.macro}} FrontendChannel {
public:
virtual ~FrontendChannel() { }
virtual void sendProtocolResponse(int callId, const String16& message) = 0;
diff --git a/Imported_h.template b/Imported_h.template
index 2dd30bc..2d4e11a 100644
--- a/Imported_h.template
+++ b/Imported_h.template
@@ -7,8 +7,8 @@
#ifndef protocol_{{domain.domain}}_imported_h
#define protocol_{{domain.domain}}_imported_h
-#include "{{lib_package}}/InspectorProtocol.h"
-#include "{{imported_package}}/{{domain.domain}}.h"
+#include "{{config.lib_package}}/InspectorProtocol.h"
+#include "{{config.imported.package}}/{{domain.domain}}.h"
namespace blink {
namespace protocol {
diff --git a/InspectorProtocol_cpp.template b/InspectorProtocol_cpp.template
index 153dbf0..e7c49fd 100644
--- a/InspectorProtocol_cpp.template
+++ b/InspectorProtocol_cpp.template
@@ -2,4 +2,4 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "{{lib_package}}/InspectorProtocol.h"
+#include "{{config.lib_package}}/InspectorProtocol.h"
diff --git a/Object_h.template b/Object_h.template
index 8b3e3ec..dc7f44b 100644
--- a/Object_h.template
+++ b/Object_h.template
@@ -8,12 +8,12 @@
//#include "ErrorSupport.h"
//#include "Platform.h"
//#include "Values.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
namespace blink {
namespace protocol {
-class {{export_macro}} Object {
+class {{config.class_export.macro}} Object {
public:
static std::unique_ptr<Object> parse(protocol::Value*, ErrorSupport*);
~Object();
diff --git a/Parser_h.template b/Parser_h.template
index eab025f..1f3a1b6 100644
--- a/Parser_h.template
+++ b/Parser_h.template
@@ -7,14 +7,14 @@
//#include "Platform.h"
//#include "String16.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
namespace blink {
namespace protocol {
class Value;
-{{export_macro}} std::unique_ptr<Value> parseJSON(const String16& json);
+{{config.class_export.macro}} std::unique_ptr<Value> parseJSON(const String16& json);
} // namespace platform
} // namespace blink
diff --git a/Platform_h.template b/Platform_h.template
index f09f192..41b8ef2 100644
--- a/Platform_h.template
+++ b/Platform_h.template
@@ -5,6 +5,6 @@
#ifndef protocol_Platform_h
#define protocol_Platform_h
-#include "{{platform_impl_h_include}}"
+#include "{{config.lib.platform_header}}"
#endif // !defined(protocol_Platform_h)
diff --git a/String16_h.template b/String16_h.template
index 005f349..e6f8f0c 100644
--- a/String16_h.template
+++ b/String16_h.template
@@ -7,7 +7,7 @@
//#include "Collections.h"
//#include "Platform.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
#include <vector>
@@ -15,16 +15,16 @@
namespace protocol {
namespace internal {
-{{export_macro}} void intToStr(int, char*, size_t);
-{{export_macro}} void doubleToStr(double, char*, size_t);
-{{export_macro}} void doubleToStr3(double, char*, size_t);
-{{export_macro}} void doubleToStr6(double, char*, size_t);
-{{export_macro}} double strToDouble(const char*, bool*);
-{{export_macro}} int strToInt(const char*, bool*);
+{{config.class_export.macro}} void intToStr(int, char*, size_t);
+{{config.class_export.macro}} void doubleToStr(double, char*, size_t);
+{{config.class_export.macro}} void doubleToStr3(double, char*, size_t);
+{{config.class_export.macro}} void doubleToStr6(double, char*, size_t);
+{{config.class_export.macro}} double strToDouble(const char*, bool*);
+{{config.class_export.macro}} int strToInt(const char*, bool*);
} // namespace internal
template <typename T, typename C>
-class {{export_macro}} String16Base {
+class {{config.class_export.macro}} String16Base {
public:
static bool isASCII(C c)
{
@@ -152,12 +152,12 @@
} // namespace protocol
} // namespace blink
-#include "{{string16_impl_h_include}}"
+#include "{{config.lib.string16_header}}"
namespace blink {
namespace protocol {
-class {{export_macro}} String16Builder {
+class {{config.class_export.macro}} String16Builder {
public:
String16Builder();
void append(const String16&);
diff --git a/TypeBuilder_cpp.template b/TypeBuilder_cpp.template
index 1e76823..8f0412a 100644
--- a/TypeBuilder_cpp.template
+++ b/TypeBuilder_cpp.template
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "{{output_package}}/{{domain.domain}}.h"
+#include "{{config.protocol.package}}/{{domain.domain}}.h"
namespace blink {
namespace protocol {
@@ -37,7 +37,7 @@
{% if "enum" in property %}
{% for literal in property.enum %}
-const char* {{type.id}}::{{property.name | to_title_case}}Enum::{{ literal | dash_to_camelcase}} = "{{literal}}";
+const char* {{type.id}}::{{property.name | to_title_case}}Enum::{{literal | dash_to_camelcase}} = "{{literal}}";
{% endfor %}
{% endif %}
{% endfor %}
diff --git a/TypeBuilder_h.template b/TypeBuilder_h.template
index eb7fe2f..1b421d6 100644
--- a/TypeBuilder_h.template
+++ b/TypeBuilder_h.template
@@ -7,15 +7,15 @@
#ifndef protocol_{{domain.domain}}_h
#define protocol_{{domain.domain}}_h
-#include "{{export_macro_include}}"
-#include "{{lib_package}}/InspectorProtocol.h"
+#include "{{config.class_export.header}}"
+#include "{{config.lib_package}}/InspectorProtocol.h"
// For each imported domain we generate a ValueConversions struct instead of a full domain definition
// and include Domain::API version from there.
{% for name in domain.dependencies %}
-#include "{{output_package}}/{{name}}.h"
+#include "{{config.protocol.package}}/{{name}}.h"
{% endfor %}
{% if domain["has_exports"] %}
-#include "{{exported_package}}/{{domain.domain}}.h"
+#include "{{config.exported.package}}/{{domain.domain}}.h"
{% endif %}
namespace blink {
@@ -42,7 +42,7 @@
namespace {{type.id}}Enum {
{% for literal in type.enum %}
-{{export_macro}} extern const char* {{ literal | dash_to_camelcase}};
+{{config.class_export.macro}} extern const char* {{ literal | dash_to_camelcase}};
{% endfor %}
} // namespace {{type.id}}Enum
{% endif %}
@@ -54,7 +54,7 @@
namespace {{command.name | to_title_case}} {
namespace {{param.name | to_title_case}}Enum {
{% for literal in param.enum %}
-{{export_macro}} extern const char* {{ literal | dash_to_camelcase}};
+{{config.class_export.macro}} extern const char* {{literal | dash_to_camelcase}};
{% endfor %}
} // {{param.name | to_title_case}}Enum
} // {{command.name | to_title_case }}
@@ -68,7 +68,7 @@
{% set type_def = type_definition(domain.domain + "." + type.id)%}
// {{type.description}}
-class {{export_macro}} {{type.id}} {% if type.exported %}: public API::{{type.id}} {% endif %}{
+class {{config.class_export.macro}} {{type.id}} {% if type.exported %}: public API::{{type.id}} {% endif %}{
PROTOCOL_DISALLOW_COPY({{type.id}});
public:
static std::unique_ptr<{{type.id}}> parse(protocol::Value* value, ErrorSupport* errors);
@@ -77,9 +77,9 @@
{% for property in type.properties %}
{% if "enum" in property %}
- struct {{export_macro}} {{property.name | to_title_case}}Enum {
+ struct {{config.class_export.macro}} {{property.name | to_title_case}}Enum {
{% for literal in property.enum %}
- static const char* {{ literal | dash_to_camelcase}};
+ static const char* {{literal | dash_to_camelcase}};
{% endfor %}
}; // {{property.name | to_title_case}}Enum
{% endif %}
@@ -180,13 +180,13 @@
// ------------- Backend interface.
-class {{export_macro}} Backend {
+class {{config.class_export.macro}} Backend {
public:
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if ("handlers" in command) and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if "async" in command %}
- class {{export_macro}} {{command.name | to_title_case}}Callback : public BackendCallback {
+ class {{config.class_export.macro}} {{command.name | to_title_case}}Callback : public BackendCallback {
public:
virtual void sendSuccess(
{%- for parameter in command.returns -%}
@@ -237,7 +237,7 @@
// ------------- Frontend interface.
-class {{export_macro}} Frontend {
+class {{config.class_export.macro}} Frontend {
public:
Frontend(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
{% for event in domain.events %}
@@ -260,7 +260,7 @@
// ------------- Dispatcher.
-class {{export_macro}} Dispatcher {
+class {{config.class_export.macro}} Dispatcher {
public:
static void wire(UberDispatcher*, blink::protocol::{{domain.domain}}::Backend*);
@@ -270,7 +270,7 @@
// ------------- Metainfo.
-class {{export_macro}} Metainfo {
+class {{config.class_export.macro}} Metainfo {
public:
using BackendClass = Backend;
using FrontendClass = Frontend;
diff --git a/Values_h.template b/Values_h.template
index 840d119..9874183 100644
--- a/Values_h.template
+++ b/Values_h.template
@@ -9,7 +9,7 @@
//#include "Collections.h"
//#include "Platform.h"
//#include "String16.h"
-#include "{{export_macro_include}}"
+#include "{{config.class_export.header}}"
#include <vector>
@@ -20,7 +20,7 @@
class DictionaryValue;
class Value;
-class {{export_macro}} Value {
+class {{config.class_export.macro}} Value {
PROTOCOL_DISALLOW_COPY(Value);
public:
static const int maxDepth = 1000;
@@ -68,7 +68,7 @@
ValueType m_type;
};
-class {{export_macro}} FundamentalValue : public Value {
+class {{config.class_export.macro}} FundamentalValue : public Value {
public:
static std::unique_ptr<FundamentalValue> create(bool value)
{
@@ -103,7 +103,7 @@
};
};
-class {{export_macro}} StringValue : public Value {
+class {{config.class_export.macro}} StringValue : public Value {
public:
static std::unique_ptr<StringValue> create(const String16& value)
{
@@ -126,7 +126,7 @@
String16 m_stringValue;
};
-class {{export_macro}} SerializedValue : public Value {
+class {{config.class_export.macro}} SerializedValue : public Value {
public:
static std::unique_ptr<SerializedValue> create(const String16& value)
{
@@ -144,7 +144,7 @@
String16 m_serializedValue;
};
-class {{export_macro}} DictionaryValue : public Value {
+class {{config.class_export.macro}} DictionaryValue : public Value {
public:
using Entry = std::pair<String16, Value*>;
static std::unique_ptr<DictionaryValue> create()
@@ -211,7 +211,7 @@
std::vector<String16> m_order;
};
-class {{export_macro}} ListValue : public Value {
+class {{config.class_export.macro}} ListValue : public Value {
public:
static std::unique_ptr<ListValue> create()
{
diff --git a/sample_config.json b/sample_config.json
index 48cad2e..5ad6722 100644
--- a/sample_config.json
+++ b/sample_config.json
@@ -5,12 +5,12 @@
"output": "place/generated/files/here"
},
- "import": {
+ "imported": {
"path": "../relative/path/imported_protocol.json",
"package": "include/imported/files/like/this"
},
- "export": {
+ "exported": {
"package": "include/exported/files/like/this",
"output": "place/exported/files/here"
},
@@ -21,14 +21,14 @@
"lib": {
"output": "place/generated/lib/files/here",
- "string16_impl_header_path": "sting16/implementation.h",
- "platform_impl_header_path": "platform/implementation.h"
+ "string16_header": "sting16/implementation.h",
+ "platform_header": "platform/implementation.h"
},
"lib_package": "include/lib/files/like/this",
"class_export": {
"macro": "LIB_EXPORT",
- "header_path": "lib/export.h"
+ "header": "lib/export.h"
}
}