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 |