| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 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 os.path | 5 import os.path |
| 6 import sys | 6 import sys |
| 7 import optparse | 7 import optparse |
| 8 import collections | 8 import collections |
| 9 import functools | 9 import functools |
| 10 import re | 10 import re |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 config_partial = json_to_object(config_json_string, output_base, config_
base) | 81 config_partial = json_to_object(config_json_string, output_base, config_
base) |
| 82 config_json_file.close() | 82 config_json_file.close() |
| 83 defaults = { | 83 defaults = { |
| 84 ".use_snake_file_names": False, | 84 ".use_snake_file_names": False, |
| 85 ".use_title_case_methods": False, | 85 ".use_title_case_methods": False, |
| 86 ".imported": False, | 86 ".imported": False, |
| 87 ".imported.export_macro": "", | 87 ".imported.export_macro": "", |
| 88 ".imported.export_header": False, | 88 ".imported.export_header": False, |
| 89 ".imported.header": False, | 89 ".imported.header": False, |
| 90 ".imported.package": False, | 90 ".imported.package": False, |
| 91 ".imported.options": False, |
| 91 ".protocol.export_macro": "", | 92 ".protocol.export_macro": "", |
| 92 ".protocol.export_header": False, | 93 ".protocol.export_header": False, |
| 93 ".protocol.options": False, | 94 ".protocol.options": False, |
| 94 ".exported": False, | 95 ".exported": False, |
| 95 ".exported.export_macro": "", | 96 ".exported.export_macro": "", |
| 96 ".exported.export_header": False, | 97 ".exported.export_header": False, |
| 97 ".lib": False, | 98 ".lib": False, |
| 98 ".lib.export_macro": "", | 99 ".lib.export_macro": "", |
| 99 ".lib.export_header": False, | 100 ".lib.export_header": False, |
| 100 } | 101 } |
| 101 for key_value in config_values: | 102 for key_value in config_values: |
| 102 parts = key_value.split("=") | 103 parts = key_value.split("=") |
| 103 if len(parts) == 2: | 104 if len(parts) == 2: |
| 104 defaults["." + parts[0]] = parts[1] | 105 defaults["." + parts[0]] = parts[1] |
| 105 return (jinja_dir, config_file, init_defaults(config_partial, "", defaul
ts)) | 106 return (jinja_dir, config_file, init_defaults(config_partial, "", defaul
ts)) |
| 106 except Exception: | 107 except Exception: |
| 107 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.h
tml | 108 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.h
tml |
| 108 exc = sys.exc_info()[1] | 109 exc = sys.exc_info()[1] |
| 109 sys.stderr.write("Failed to parse config file: %s\n\n" % exc) | 110 sys.stderr.write("Failed to parse config file: %s\n\n" % exc) |
| 110 exit(1) | 111 exit(1) |
| 111 | 112 |
| 112 | 113 |
| 114 # ---- Begin of utilities exposed to generator ---- |
| 115 |
| 116 |
| 113 def to_title_case(name): | 117 def to_title_case(name): |
| 114 return name[:1].upper() + name[1:] | 118 return name[:1].upper() + name[1:] |
| 115 | 119 |
| 116 | 120 |
| 117 def dash_to_camelcase(word): | 121 def dash_to_camelcase(word): |
| 118 prefix = "" | 122 prefix = "" |
| 119 if word[0] == "-": | 123 if word[0] == "-": |
| 120 prefix = "Negative" | 124 prefix = "Negative" |
| 121 word = word[1:] | 125 word = word[1:] |
| 122 return prefix + "".join(to_title_case(x) or "-" for x in word.split("-")) | 126 return prefix + "".join(to_title_case(x) or "-" for x in word.split("-")) |
| 123 | 127 |
| 124 | 128 |
| 125 def to_snake_case(name): | 129 def to_snake_case(name): |
| 126 return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxint).lower() | 130 return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxint).lower() |
| 127 | 131 |
| 128 | 132 |
| 129 def to_method_case(config, name): | 133 def to_method_case(config, name): |
| 130 if config.use_title_case_methods: | 134 if config.use_title_case_methods: |
| 131 return to_title_case(name) | 135 return to_title_case(name) |
| 132 return name | 136 return name |
| 133 | 137 |
| 134 | 138 |
| 139 def join_arrays(dict, keys): |
| 140 result = [] |
| 141 for key in keys: |
| 142 if key in dict: |
| 143 result += dict[key] |
| 144 return result |
| 145 |
| 146 |
| 147 def format_include(config, header, file_name=None): |
| 148 if file_name is not None: |
| 149 header = header + "/" + file_name + ".h" |
| 150 header = "\"" + header + "\"" if header[0] not in "<\"" else header |
| 151 if config.use_snake_file_names: |
| 152 header = to_snake_case(header) |
| 153 return header |
| 154 |
| 155 |
| 156 def to_file_name(config, file_name): |
| 157 if config.use_snake_file_names: |
| 158 return to_snake_case(file_name).replace(".cpp", ".cc") |
| 159 return file_name |
| 160 |
| 161 |
| 162 # ---- End of utilities exposed to generator ---- |
| 163 |
| 164 |
| 135 def initialize_jinja_env(jinja_dir, cache_dir, config): | 165 def initialize_jinja_env(jinja_dir, cache_dir, config): |
| 136 # pylint: disable=F0401 | 166 # pylint: disable=F0401 |
| 137 sys.path.insert(1, os.path.abspath(jinja_dir)) | 167 sys.path.insert(1, os.path.abspath(jinja_dir)) |
| 138 import jinja2 | 168 import jinja2 |
| 139 | 169 |
| 140 jinja_env = jinja2.Environment( | 170 jinja_env = jinja2.Environment( |
| 141 loader=jinja2.FileSystemLoader(module_path), | 171 loader=jinja2.FileSystemLoader(module_path), |
| 142 # Bytecode cache is not concurrency-safe unless pre-cached: | 172 # Bytecode cache is not concurrency-safe unless pre-cached: |
| 143 # if pre-cached this is read-only, but writing creates a race condition. | 173 # if pre-cached this is read-only, but writing creates a race condition. |
| 144 bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir), | 174 bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir), |
| 145 keep_trailing_newline=True, # newline-terminate generated files | 175 keep_trailing_newline=True, # newline-terminate generated files |
| 146 lstrip_blocks=True, # so can indent control flow tags | 176 lstrip_blocks=True, # so can indent control flow tags |
| 147 trim_blocks=True) | 177 trim_blocks=True) |
| 148 jinja_env.filters.update({"to_title_case": to_title_case, "dash_to_camelcase
": dash_to_camelcase, "to_method_case": functools.partial(to_method_case, config
)}) | 178 jinja_env.filters.update({"to_title_case": to_title_case, "dash_to_camelcase
": dash_to_camelcase, "to_method_case": functools.partial(to_method_case, config
)}) |
| 149 jinja_env.add_extension("jinja2.ext.loopcontrols") | 179 jinja_env.add_extension("jinja2.ext.loopcontrols") |
| 150 return jinja_env | 180 return jinja_env |
| 151 | 181 |
| 152 | 182 |
| 153 def patch_full_qualified_refs(protocol): | |
| 154 def patch_full_qualified_refs_in_domain(json, domain_name): | |
| 155 if isinstance(json, list): | |
| 156 for item in json: | |
| 157 patch_full_qualified_refs_in_domain(item, domain_name) | |
| 158 | |
| 159 if not isinstance(json, dict): | |
| 160 return | |
| 161 for key in json: | |
| 162 if key == "type" and json[key] == "string": | |
| 163 json[key] = domain_name + ".string" | |
| 164 if key != "$ref": | |
| 165 patch_full_qualified_refs_in_domain(json[key], domain_name) | |
| 166 continue | |
| 167 if json["$ref"].find(".") == -1: | |
| 168 json["$ref"] = domain_name + "." + json["$ref"] | |
| 169 return | |
| 170 | |
| 171 for domain in protocol.json_api["domains"]: | |
| 172 patch_full_qualified_refs_in_domain(domain, domain["domain"]) | |
| 173 | |
| 174 | |
| 175 def calculate_imports_and_exports(config, protocol): | |
| 176 def has_exports(json_value, clear): | |
| 177 result = False | |
| 178 if isinstance(json_value, list): | |
| 179 for item in json_value: | |
| 180 result = has_exports(item, clear) or result | |
| 181 if isinstance(json_value, dict): | |
| 182 if "exported" in json_value and json_value["exported"]: | |
| 183 result = True | |
| 184 if "exported" in json_value and clear: | |
| 185 del json_value["exported"] | |
| 186 for key in json_value: | |
| 187 result = has_exports(json_value[key], clear) or result | |
| 188 return result | |
| 189 | |
| 190 imported_domains = protocol.imported_domains | |
| 191 if config.protocol.options: | |
| 192 protocol.generate_domains = [rule.domain for rule in config.protocol.opt
ions] | |
| 193 imported_domains = list(set(protocol.imported_domains) - set(protocol.ge
nerate_domains)) | |
| 194 exported_domains = protocol.generate_domains | |
| 195 | |
| 196 protocol.imported_domains = [] | |
| 197 protocol.exported_domains = [] | |
| 198 for domain_json in protocol.json_api["domains"]: | |
| 199 domain = domain_json["domain"] | |
| 200 clear = domain not in exported_domains and domain not in imported_domain
s | |
| 201 if not has_exports(domain_json, clear): | |
| 202 continue | |
| 203 if domain in exported_domains: | |
| 204 domain_json["has_exports"] = True | |
| 205 protocol.exported_domains.append(domain) | |
| 206 if domain in imported_domains: | |
| 207 protocol.imported_domains.append(domain) | |
| 208 | |
| 209 | |
| 210 def create_imported_type_definition(domain_name, type, imported_namespace): | 183 def create_imported_type_definition(domain_name, type, imported_namespace): |
| 211 # pylint: disable=W0622 | 184 # pylint: disable=W0622 |
| 212 return { | 185 return { |
| 213 "return_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace,
domain_name, type["id"]), | 186 "return_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace,
domain_name, type["id"]), |
| 214 "pass_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, d
omain_name, type["id"]), | 187 "pass_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, d
omain_name, type["id"]), |
| 215 "to_raw_type": "%s.get()", | 188 "to_raw_type": "%s.get()", |
| 216 "to_pass_type": "std::move(%s)", | 189 "to_pass_type": "std::move(%s)", |
| 217 "to_rvalue": "std::move(%s)", | 190 "to_rvalue": "std::move(%s)", |
| 218 "type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, domain
_name, type["id"]), | 191 "type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, domain
_name, type["id"]), |
| 219 "raw_type": "%s::%s::API::%s" % (imported_namespace, domain_name, type["
id"]), | 192 "raw_type": "%s::%s::API::%s" % (imported_namespace, domain_name, type["
id"]), |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 "to_pass_type": "std::move(%s)", | 295 "to_pass_type": "std::move(%s)", |
| 323 "to_rvalue": "std::move(%s)", | 296 "to_rvalue": "std::move(%s)", |
| 324 "type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], | 297 "type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], |
| 325 "raw_type": "protocol::Array<%s>" % type["raw_type"], | 298 "raw_type": "protocol::Array<%s>" % type["raw_type"], |
| 326 "raw_pass_type": "protocol::Array<%s>*" % type["raw_type"], | 299 "raw_pass_type": "protocol::Array<%s>*" % type["raw_type"], |
| 327 "raw_return_type": "protocol::Array<%s>*" % type["raw_type"], | 300 "raw_return_type": "protocol::Array<%s>*" % type["raw_type"], |
| 328 "out_type": "protocol::Array<%s>&" % type["raw_type"], | 301 "out_type": "protocol::Array<%s>&" % type["raw_type"], |
| 329 } | 302 } |
| 330 | 303 |
| 331 | 304 |
| 332 def create_type_definitions(protocol, imported_namespace): | 305 class Protocol(object): |
| 333 protocol.type_definitions = {} | 306 def __init__(self, config): |
| 334 protocol.type_definitions["number"] = create_primitive_type_definition("numb
er") | 307 self.config = config |
| 335 protocol.type_definitions["integer"] = create_primitive_type_definition("int
eger") | 308 self.json_api = {"domains": []} |
| 336 protocol.type_definitions["boolean"] = create_primitive_type_definition("boo
lean") | 309 self.imported_domains = [] |
| 337 protocol.type_definitions["object"] = create_object_type_definition() | 310 self.exported_domains = [] |
| 338 protocol.type_definitions["any"] = create_any_type_definition() | 311 self.generate_domains = self.read_protocol_file(config.protocol.path) |
| 339 for domain in protocol.json_api["domains"]: | 312 |
| 340 protocol.type_definitions[domain["domain"] + ".string"] = create_string_
type_definition() | 313 if config.protocol.options: |
| 341 if not ("types" in domain): | 314 self.generate_domains = [rule.domain for rule in config.protocol.opt
ions] |
| 342 continue | 315 self.exported_domains = [rule.domain for rule in config.protocol.opt
ions if hasattr(rule, "exported")] |
| 343 for type in domain["types"]: | 316 |
| 344 type_name = domain["domain"] + "." + type["id"] | 317 if config.imported: |
| 345 if type["type"] == "object" and domain["domain"] in protocol.importe
d_domains: | 318 self.imported_domains = self.read_protocol_file(config.imported.path
) |
| 346 protocol.type_definitions[type_name] = create_imported_type_defi
nition(domain["domain"], type, imported_namespace) | 319 if config.imported.options: |
| 347 elif type["type"] == "object": | 320 self.imported_domains = [rule.domain for rule in config.imported
.options] |
| 348 protocol.type_definitions[type_name] = create_user_type_definiti
on(domain["domain"], type) | 321 |
| 349 elif type["type"] == "array": | 322 self.patch_full_qualified_refs() |
| 350 items_type = type["items"]["type"] | 323 self.create_notification_types() |
| 351 protocol.type_definitions[type_name] = wrap_array_definition(pro
tocol.type_definitions[items_type]) | 324 self.create_type_definitions() |
| 352 elif type["type"] == domain["domain"] + ".string": | |
| 353 protocol.type_definitions[type_name] = create_string_type_defini
tion() | |
| 354 else: | |
| 355 protocol.type_definitions[type_name] = create_primitive_type_def
inition(type["type"]) | |
| 356 | 325 |
| 357 | 326 |
| 358 def type_definition(protocol, name): | 327 def read_protocol_file(self, file_name): |
| 359 return protocol.type_definitions[name] | 328 input_file = open(file_name, "r") |
| 329 json_string = input_file.read() |
| 330 input_file.close() |
| 331 parsed_json = json.loads(json_string) |
| 332 version = parsed_json["version"]["major"] + "." + parsed_json["version"]
["minor"] |
| 333 domains = [] |
| 334 for domain in parsed_json["domains"]: |
| 335 domains.append(domain["domain"]) |
| 336 domain["version"] = version |
| 337 self.json_api["domains"] += parsed_json["domains"] |
| 338 return domains |
| 360 | 339 |
| 361 | 340 |
| 362 def resolve_type(protocol, prop): | 341 def patch_full_qualified_refs(self): |
| 363 if "$ref" in prop: | 342 def patch_full_qualified_refs_in_domain(json, domain_name): |
| 364 return protocol.type_definitions[prop["$ref"]] | 343 if isinstance(json, list): |
| 365 if prop["type"] == "array": | 344 for item in json: |
| 366 return wrap_array_definition(resolve_type(protocol, prop["items"])) | 345 patch_full_qualified_refs_in_domain(item, domain_name) |
| 367 return protocol.type_definitions[prop["type"]] | 346 if not isinstance(json, dict): |
| 347 return |
| 348 for key in json: |
| 349 if key == "type" and json[key] == "string": |
| 350 json[key] = domain_name + ".string" |
| 351 if key != "$ref": |
| 352 patch_full_qualified_refs_in_domain(json[key], domain_name) |
| 353 continue |
| 354 if json["$ref"].find(".") == -1: |
| 355 json["$ref"] = domain_name + "." + json["$ref"] |
| 356 return |
| 357 |
| 358 for domain in self.json_api["domains"]: |
| 359 patch_full_qualified_refs_in_domain(domain, domain["domain"]) |
| 368 | 360 |
| 369 | 361 |
| 370 def join_arrays(dict, keys): | 362 def create_notification_types(self): |
| 371 result = [] | 363 for domain in self.json_api["domains"]: |
| 372 for key in keys: | 364 if "events" in domain: |
| 373 if key in dict: | 365 for event in domain["events"]: |
| 374 result += dict[key] | 366 event_type = dict() |
| 375 return result | 367 event_type["description"] = "Wrapper for notification params
" |
| 368 event_type["type"] = "object" |
| 369 event_type["id"] = to_title_case(event["name"]) + "Notificat
ion" |
| 370 if "parameters" in event: |
| 371 event_type["properties"] = copy.deepcopy(event["paramete
rs"]) |
| 372 if "types" not in domain: |
| 373 domain["types"] = list() |
| 374 domain["types"].append(event_type) |
| 376 | 375 |
| 377 | 376 |
| 378 def generate_command(protocol, config, domain, command): | 377 def create_type_definitions(self): |
| 379 if not config.protocol.options: | 378 imported_namespace = "::".join(self.config.imported.namespace) if self.c
onfig.imported else "" |
| 380 return domain in protocol.generate_domains | 379 self.type_definitions = {} |
| 381 for rule in config.protocol.options: | 380 self.type_definitions["number"] = create_primitive_type_definition("numb
er") |
| 382 if rule.domain != domain: | 381 self.type_definitions["integer"] = create_primitive_type_definition("int
eger") |
| 383 continue | 382 self.type_definitions["boolean"] = create_primitive_type_definition("boo
lean") |
| 384 if hasattr(rule, "include"): | 383 self.type_definitions["object"] = create_object_type_definition() |
| 385 return command in rule.include | 384 self.type_definitions["any"] = create_any_type_definition() |
| 386 if hasattr(rule, "exclude"): | 385 for domain in self.json_api["domains"]: |
| 387 return command not in rule.exclude | 386 self.type_definitions[domain["domain"] + ".string"] = create_string_
type_definition() |
| 388 return True | 387 if not ("types" in domain): |
| 389 return False | 388 continue |
| 389 for type in domain["types"]: |
| 390 type_name = domain["domain"] + "." + type["id"] |
| 391 if type["type"] == "object" and domain["domain"] in self.importe
d_domains: |
| 392 self.type_definitions[type_name] = create_imported_type_defi
nition(domain["domain"], type, imported_namespace) |
| 393 elif type["type"] == "object": |
| 394 self.type_definitions[type_name] = create_user_type_definiti
on(domain["domain"], type) |
| 395 elif type["type"] == "array": |
| 396 items_type = type["items"]["type"] |
| 397 self.type_definitions[type_name] = wrap_array_definition(sel
f.type_definitions[items_type]) |
| 398 elif type["type"] == domain["domain"] + ".string": |
| 399 self.type_definitions[type_name] = create_string_type_defini
tion() |
| 400 else: |
| 401 self.type_definitions[type_name] = create_primitive_type_def
inition(type["type"]) |
| 390 | 402 |
| 391 | 403 |
| 392 def generate_event(protocol, config, domain, event): | 404 def check_options(self, options, domain, name, include_attr, exclude_attr, d
efault): |
| 393 if not config.protocol.options: | 405 for rule in options: |
| 394 return domain in protocol.generate_domains | 406 if rule.domain != domain: |
| 395 for rule in config.protocol.options: | 407 continue |
| 396 if rule.domain != domain: | 408 if include_attr and hasattr(rule, include_attr): |
| 397 continue | 409 return name in getattr(rule, include_attr) |
| 398 if hasattr(rule, "include_events"): | 410 if exclude_attr and hasattr(rule, exclude_attr): |
| 399 return event in rule.include_events | 411 return name not in getattr(rule, exclude_attr) |
| 400 if hasattr(rule, "exclude_events"): | 412 return default |
| 401 return event not in rule.exclude_events | 413 return False |
| 402 return True | |
| 403 return False | |
| 404 | 414 |
| 405 | 415 |
| 406 def is_async_command(protocol, config, domain, command): | 416 # ---- Begin of methods exposed to generator |
| 407 if not config.protocol.options: | |
| 408 return False | |
| 409 for rule in config.protocol.options: | |
| 410 if rule.domain != domain: | |
| 411 continue | |
| 412 if hasattr(rule, "async"): | |
| 413 return command in rule.async | |
| 414 return False | |
| 415 return False | |
| 416 | 417 |
| 417 | 418 |
| 418 def generate_disable(protocol, config, domain): | 419 def type_definition(self, name): |
| 419 if "commands" not in domain: | 420 return self.type_definitions[name] |
| 420 return True | |
| 421 for command in domain["commands"]: | |
| 422 if command["name"] == "disable" and generate_command(protocol, config, d
omain["domain"], "disable"): | |
| 423 return False | |
| 424 return True | |
| 425 | 421 |
| 426 | 422 |
| 427 def format_include(config, header, file_name=None): | 423 def resolve_type(self, prop): |
| 428 if file_name is not None: | 424 if "$ref" in prop: |
| 429 header = header + "/" + file_name + ".h" | 425 return self.type_definitions[prop["$ref"]] |
| 430 header = "\"" + header + "\"" if header[0] not in "<\"" else header | 426 if prop["type"] == "array": |
| 431 if config.use_snake_file_names: | 427 return wrap_array_definition(self.resolve_type(prop["items"])) |
| 432 header = to_snake_case(header) | 428 return self.type_definitions[prop["type"]] |
| 433 return header | |
| 434 | 429 |
| 435 | 430 |
| 436 def to_file_name(config, file_name): | 431 def generate_command(self, domain, command): |
| 437 if config.use_snake_file_names: | 432 if not self.config.protocol.options: |
| 438 return to_snake_case(file_name).replace(".cpp", ".cc") | 433 return domain in self.generate_domains |
| 439 return file_name | 434 return self.check_options(self.config.protocol.options, domain, command,
"include", "exclude", True) |
| 440 | 435 |
| 441 | 436 |
| 442 def read_protocol_file(file_name, json_api): | 437 def generate_event(self, domain, event): |
| 443 input_file = open(file_name, "r") | 438 if not self.config.protocol.options: |
| 444 json_string = input_file.read() | 439 return domain in self.generate_domains |
| 445 input_file.close() | 440 return self.check_options(self.config.protocol.options, domain, event, "
include_events", "exclude_events", True) |
| 446 parsed_json = json.loads(json_string) | |
| 447 version = parsed_json["version"]["major"] + "." + parsed_json["version"]["mi
nor"] | |
| 448 domains = [] | |
| 449 for domain in parsed_json["domains"]: | |
| 450 domains.append(domain["domain"]) | |
| 451 domain["version"] = version | |
| 452 json_api["domains"] += parsed_json["domains"] | |
| 453 return domains | |
| 454 | 441 |
| 455 | 442 |
| 456 class Protocol(object): | 443 def is_async_command(self, domain, command): |
| 457 def __init__(self): | 444 if not self.config.protocol.options: |
| 458 self.json_api = {} | 445 return False |
| 459 self.generate_domains = [] | 446 return self.check_options(self.config.protocol.options, domain, command,
"async", None, False) |
| 460 self.imported_domains = [] | 447 |
| 461 self.exported_domains = [] | 448 |
| 449 def is_exported(self, domain, name): |
| 450 if not self.config.protocol.options: |
| 451 return False |
| 452 return self.check_options(self.config.protocol.options, domain, name, "e
xported", None, False) |
| 453 |
| 454 |
| 455 def is_imported(self, domain, name): |
| 456 if not self.config.imported: |
| 457 return False |
| 458 if not self.config.imported.options: |
| 459 return domain in self.imported_domains |
| 460 return self.check_options(self.config.imported.options, domain, name, "i
mported", None, False) |
| 461 |
| 462 |
| 463 def is_exported_domain(self, domain): |
| 464 return domain in self.exported_domains |
| 465 |
| 466 |
| 467 def generate_disable(self, domain): |
| 468 if "commands" not in domain: |
| 469 return True |
| 470 for command in domain["commands"]: |
| 471 if command["name"] == "disable" and self.generate_command(domain["do
main"], "disable"): |
| 472 return False |
| 473 return True |
| 462 | 474 |
| 463 | 475 |
| 464 def main(): | 476 def main(): |
| 465 jinja_dir, config_file, config = read_config() | 477 jinja_dir, config_file, config = read_config() |
| 466 | 478 |
| 467 protocol = Protocol() | 479 protocol = Protocol(config) |
| 468 protocol.json_api = {"domains": []} | |
| 469 protocol.generate_domains = read_protocol_file(config.protocol.path, protoco
l.json_api) | |
| 470 protocol.imported_domains = read_protocol_file(config.imported.path, protoco
l.json_api) if config.imported else [] | |
| 471 patch_full_qualified_refs(protocol) | |
| 472 calculate_imports_and_exports(config, protocol) | |
| 473 | |
| 474 for domain in protocol.json_api["domains"]: | |
| 475 if "events" in domain: | |
| 476 for event in domain["events"]: | |
| 477 event_type = dict() | |
| 478 event_type["description"] = "Wrapper for notification params" | |
| 479 event_type["type"] = "object" | |
| 480 event_type["id"] = to_title_case(event["name"]) + "Notification" | |
| 481 if "parameters" in event: | |
| 482 event_type["properties"] = copy.deepcopy(event["parameters"]
) | |
| 483 if "types" not in domain: | |
| 484 domain["types"] = list() | |
| 485 domain["types"].append(event_type) | |
| 486 | |
| 487 create_type_definitions(protocol, "::".join(config.imported.namespace) if co
nfig.imported else "") | |
| 488 | 480 |
| 489 if not config.exported and len(protocol.exported_domains): | 481 if not config.exported and len(protocol.exported_domains): |
| 490 sys.stderr.write("Domains [%s] are exported, but config is missing expor
t entry\n\n" % ", ".join(protocol.exported_domains)) | 482 sys.stderr.write("Domains [%s] are exported, but config is missing expor
t entry\n\n" % ", ".join(protocol.exported_domains)) |
| 491 exit(1) | 483 exit(1) |
| 492 | 484 |
| 493 if not os.path.exists(config.protocol.output): | 485 if not os.path.exists(config.protocol.output): |
| 494 os.mkdir(config.protocol.output) | 486 os.mkdir(config.protocol.output) |
| 495 if len(protocol.exported_domains) and not os.path.exists(config.exported.out
put): | 487 if len(protocol.exported_domains) and not os.path.exists(config.exported.out
put): |
| 496 os.mkdir(config.exported.output) | 488 os.mkdir(config.exported.output) |
| 497 jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output, config) | 489 jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output, config) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 511 h_template = jinja_env.get_template("templates/TypeBuilder_h.template") | 503 h_template = jinja_env.get_template("templates/TypeBuilder_h.template") |
| 512 cpp_template = jinja_env.get_template("templates/TypeBuilder_cpp.template") | 504 cpp_template = jinja_env.get_template("templates/TypeBuilder_cpp.template") |
| 513 exported_template = jinja_env.get_template("templates/Exported_h.template") | 505 exported_template = jinja_env.get_template("templates/Exported_h.template") |
| 514 imported_template = jinja_env.get_template("templates/Imported_h.template") | 506 imported_template = jinja_env.get_template("templates/Imported_h.template") |
| 515 | 507 |
| 516 outputs = dict() | 508 outputs = dict() |
| 517 | 509 |
| 518 for domain in protocol.json_api["domains"]: | 510 for domain in protocol.json_api["domains"]: |
| 519 class_name = domain["domain"] | 511 class_name = domain["domain"] |
| 520 template_context = { | 512 template_context = { |
| 513 "protocol": protocol, |
| 521 "config": config, | 514 "config": config, |
| 522 "domain": domain, | 515 "domain": domain, |
| 523 "join_arrays": join_arrays, | 516 "join_arrays": join_arrays, |
| 524 "resolve_type": functools.partial(resolve_type, protocol), | |
| 525 "type_definition": functools.partial(type_definition, protocol), | |
| 526 "generate_command": functools.partial(generate_command, protocol, co
nfig), | |
| 527 "generate_event": functools.partial(generate_event, protocol, config
), | |
| 528 "is_async_command": functools.partial(is_async_command, protocol, co
nfig), | |
| 529 "generate_disable": functools.partial(generate_disable, protocol, co
nfig), | |
| 530 "format_include": functools.partial(format_include, config), | 517 "format_include": functools.partial(format_include, config), |
| 531 } | 518 } |
| 532 | 519 |
| 533 if domain["domain"] in protocol.generate_domains: | 520 if domain["domain"] in protocol.generate_domains: |
| 534 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".h"))] = h_template.render(template_context) | 521 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".h"))] = h_template.render(template_context) |
| 535 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".cpp"))] = cpp_template.render(template_context) | 522 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".cpp"))] = cpp_template.render(template_context) |
| 536 if domain["domain"] in protocol.exported_domains: | 523 if domain["domain"] in protocol.exported_domains: |
| 537 outputs[os.path.join(config.exported.output, to_file_name(config
, class_name + ".h"))] = exported_template.render(template_context) | 524 outputs[os.path.join(config.exported.output, to_file_name(config
, class_name + ".h"))] = exported_template.render(template_context) |
| 538 if domain["domain"] in protocol.imported_domains: | 525 if domain["domain"] in protocol.imported_domains: |
| 539 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".h"))] = imported_template.render(template_context) | 526 outputs[os.path.join(config.protocol.output, to_file_name(config, cl
ass_name + ".h"))] = imported_template.render(template_context) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 if up_to_date: | 583 if up_to_date: |
| 597 sys.exit() | 584 sys.exit() |
| 598 | 585 |
| 599 for file_name, content in outputs.iteritems(): | 586 for file_name, content in outputs.iteritems(): |
| 600 out_file = open(file_name, "w") | 587 out_file = open(file_name, "w") |
| 601 out_file.write(content) | 588 out_file.write(content) |
| 602 out_file.close() | 589 out_file.close() |
| 603 | 590 |
| 604 | 591 |
| 605 main() | 592 main() |
| OLD | NEW |