Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py

Issue 2240663003: [DevTools] Introduce config file for inspector_protocol. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2226863003
Patch Set: rebased Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 try: 8 try:
9 import json 9 import json
10 except ImportError: 10 except ImportError:
(...skipping 30 matching lines...) Expand all
41 deps_dir = os.path.normpath(os.path.join( 41 deps_dir = os.path.normpath(os.path.join(
42 module_path, os.pardir, os.pardir, os.pardir, os.pardir, "third_party")) 42 module_path, os.pardir, os.pardir, os.pardir, os.pardir, "third_party"))
43 43
44 if os.path.isdir(deps_dir): 44 if os.path.isdir(deps_dir):
45 sys.path.insert(1, os.path.join(deps_dir, "jinja2")) 45 sys.path.insert(1, os.path.join(deps_dir, "jinja2"))
46 sys.path.insert(1, os.path.join(deps_dir, "markupsafe")) 46 sys.path.insert(1, os.path.join(deps_dir, "markupsafe"))
47 47
48 import jinja2 48 import jinja2
49 49
50 cmdline_parser = optparse.OptionParser() 50 cmdline_parser = optparse.OptionParser()
51 cmdline_parser.add_option("--protocol") 51 cmdline_parser.add_option("--output_base")
52 cmdline_parser.add_option("--include") 52 cmdline_parser.add_option("--config")
53 cmdline_parser.add_option("--include_package") 53
54 cmdline_parser.add_option("--string_type")
55 cmdline_parser.add_option("--export_macro")
56 cmdline_parser.add_option("--output_dir")
57 cmdline_parser.add_option("--output_package")
58 cmdline_parser.add_option("--exported_dir")
59 cmdline_parser.add_option("--exported_package")
60 54
61 try: 55 try:
62 arg_options, arg_values = cmdline_parser.parse_args() 56 arg_options, arg_values = cmdline_parser.parse_args()
63 protocol_file = arg_options.protocol 57 output_base = arg_options.output_base
64 if not protocol_file: 58 if not output_base:
65 raise Exception("Protocol directory must be specified") 59 raise Exception("Base output directory must be specified")
66 include_file = arg_options.include 60 config_file = arg_options.config
67 include_package = arg_options.include_package 61 if not config_file:
68 if include_file and not include_package: 62 raise Exception("Config file name must be specified")
69 raise Exception("Include package must be specified when using include fi le") 63 config_dir = os.path.dirname(config_file)
70 if include_package and not include_file:
71 raise Exception("Include file must be specified when using include packa ge")
72 output_dirname = arg_options.output_dir
73 if not output_dirname:
74 raise Exception("Output directory must be specified")
75 output_package = arg_options.output_package
76 if not output_package:
77 raise Exception("Output package must be specified")
78 exported_dirname = arg_options.exported_dir
79 if not exported_dirname:
80 exported_dirname = os.path.join(output_dirname, "exported")
81 exported_package = arg_options.exported_package
82 if not exported_package:
83 exported_package = os.path.join(output_package, "exported")
84 string_type = arg_options.string_type
85 if not string_type:
86 raise Exception("String type must be specified")
87 export_macro = arg_options.export_macro
88 if not export_macro:
89 raise Exception("Export macro must be specified")
90 except Exception: 64 except Exception:
91 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html 65 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
92 exc = sys.exc_info()[1] 66 exc = sys.exc_info()[1]
93 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) 67 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
94 exit(1) 68 exit(1)
95 69
96 70
97 input_file = open(protocol_file, "r") 71 try:
98 json_string = input_file.read() 72 config_json_string = open(config_file, "r").read()
99 parsed_json = json.loads(json_string) 73 config = json.loads(config_json_string)
74
75 protocol_file = config["protocol"]["path"]
76 if not protocol_file:
77 raise Exception("Config is missing protocol.path")
78 protocol_file = os.path.join(config_dir, protocol_file)
79 output_dirname = config["protocol"]["output"]
80 if not output_dirname:
81 raise Exception("Config is missing protocol.output")
82 output_dirname = os.path.join(output_base, output_dirname)
83 output_package = config["protocol"]["package"]
84 if not output_package:
85 raise Exception("Config is missing protocol.package")
86
87 importing = False
88 if "import" in config:
89 importing = True
90 imported_file = config["import"]["path"]
91 if not imported_file:
92 raise Exception("Config is missing import.path")
93 imported_file = os.path.join(config_dir, imported_file)
94 imported_package = config["import"]["package"]
95 if not imported_package:
96 raise Exception("Config is missing import.package")
97
98 exporting = False
99 if "export" in config:
100 exporting = True
101 exported_dirname = config["export"]["output"]
102 if not exported_dirname:
103 raise Exception("Config is missing export.output")
104 exported_dirname = os.path.join(output_base, exported_dirname)
105 exported_package = config["export"]["package"]
106 if not exported_package:
107 raise Exception("Config is missing export.package")
108
109 string_type = config["string"]["class_name"]
110 if not string_type:
111 raise Exception("Config is missing string.class_name")
112
113 export_macro = config["export_macro"]
114 if not export_macro:
115 raise Exception("Config is missing export_macro")
116 except Exception:
117 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
118 exc = sys.exc_info()[1]
119 sys.stderr.write("Failed to parse config file: %s\n\n" % exc)
120 exit(1)
100 121
101 122
102 # Make gyp / make generatos happy, otherwise make rebuilds world. 123 # Make gyp / make generatos happy, otherwise make rebuilds world.
103 def up_to_date(): 124 def up_to_date():
104 template_ts = max( 125 template_ts = max(
105 os.path.getmtime(__file__), 126 os.path.getmtime(__file__),
106 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_h.template")), 127 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_h.template")),
107 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template") ), 128 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template") ),
108 os.path.getmtime(os.path.join(templates_dir, "Exported_h.template")), 129 os.path.getmtime(os.path.join(templates_dir, "Exported_h.template")),
109 os.path.getmtime(os.path.join(templates_dir, "Imported_h.template")), 130 os.path.getmtime(os.path.join(templates_dir, "Imported_h.template")),
131 os.path.getmtime(config_file),
110 os.path.getmtime(protocol_file)) 132 os.path.getmtime(protocol_file))
133 if importing:
134 template_ts = max(template_ts, os.path.getmtime(imported_file))
111 135
112 for domain in parsed_json["domains"]: 136 for domain in json_api["domains"]:
113 name = domain["domain"] 137 name = domain["domain"]
114 paths = [] 138 paths = []
115 if name in generate_domains: 139 if name in generate_domains:
116 paths = [os.path.join(output_dirname, name + ".h"), os.path.join(out put_dirname, name + ".cpp")] 140 paths = [os.path.join(output_dirname, name + ".h"), os.path.join(out put_dirname, name + ".cpp")]
117 if domain["has_exports"]: 141 if domain["has_exports"]:
118 paths.append(os.path.join(exported_dirname, name + ".h")) 142 paths.append(os.path.join(exported_dirname, name + ".h"))
119 if name in include_domains and domain["has_exports"]: 143 if name in imported_domains and domain["has_exports"]:
120 paths = [os.path.join(output_dirname, name + '.h')] 144 paths = [os.path.join(output_dirname, name + '.h')]
121 for path in paths: 145 for path in paths:
122 if not os.path.exists(path): 146 if not os.path.exists(path):
123 return False 147 return False
124 generated_ts = os.path.getmtime(path) 148 generated_ts = os.path.getmtime(path)
125 if generated_ts < template_ts: 149 if generated_ts < template_ts:
126 return False 150 return False
127 return True 151 return True
128 152
129 153
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 for item in json_value: 210 for item in json_value:
187 has_exports = calculate_exports_in_json(item) or has_exports 211 has_exports = calculate_exports_in_json(item) or has_exports
188 if isinstance(json_value, dict): 212 if isinstance(json_value, dict):
189 has_exports = ("exported" in json_value and json_value["exported"]) or has_exports 213 has_exports = ("exported" in json_value and json_value["exported"]) or has_exports
190 for key in json_value: 214 for key in json_value:
191 has_exports = calculate_exports_in_json(json_value[key]) or has_ exports 215 has_exports = calculate_exports_in_json(json_value[key]) or has_ exports
192 return has_exports 216 return has_exports
193 217
194 json_api["has_exports"] = False 218 json_api["has_exports"] = False
195 for domain_json in json_api["domains"]: 219 for domain_json in json_api["domains"]:
220 domain_name = domain_json["domain"]
196 domain_json["has_exports"] = calculate_exports_in_json(domain_json) 221 domain_json["has_exports"] = calculate_exports_in_json(domain_json)
197 json_api["has_exports"] = json_api["has_exports"] or domain_json["has_ex ports"] 222 if domain_json["has_exports"] and domain_name in generate_domains:
223 if not exporting:
224 sys.stderr.write("Domain %s is exported, but config is missing e xport entry\n\n" % domain_name)
225 exit(1)
226 json_api["has_exports"] = True
198 227
199 228
200 def create_include_type_definition(domain_name, type): 229 def create_imported_type_definition(domain_name, type):
201 # pylint: disable=W0622 230 # pylint: disable=W0622
202 return { 231 return {
203 "return_type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, type["id"]), 232 "return_type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, type["id"]),
204 "pass_type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, ty pe["id"]), 233 "pass_type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, ty pe["id"]),
205 "to_raw_type": "%s.get()", 234 "to_raw_type": "%s.get()",
206 "to_pass_type": "std::move(%s)", 235 "to_pass_type": "std::move(%s)",
207 "to_rvalue": "std::move(%s)", 236 "to_rvalue": "std::move(%s)",
208 "type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, type["i d"]), 237 "type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, type["i d"]),
209 "raw_type": "protocol::%s::API::%s" % (domain_name, type["id"]), 238 "raw_type": "protocol::%s::API::%s" % (domain_name, type["id"]),
210 "raw_pass_type": "protocol::%s::API::%s*" % (domain_name, type["id"]), 239 "raw_pass_type": "protocol::%s::API::%s*" % (domain_name, type["id"]),
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 357 }
329 358
330 359
331 def create_type_definitions(): 360 def create_type_definitions():
332 for domain in json_api["domains"]: 361 for domain in json_api["domains"]:
333 type_definitions[domain["domain"] + ".string"] = create_string_type_defi nition(domain["domain"]) 362 type_definitions[domain["domain"] + ".string"] = create_string_type_defi nition(domain["domain"])
334 if not ("types" in domain): 363 if not ("types" in domain):
335 continue 364 continue
336 for type in domain["types"]: 365 for type in domain["types"]:
337 type_name = domain["domain"] + "." + type["id"] 366 type_name = domain["domain"] + "." + type["id"]
338 if type["type"] == "object" and domain["domain"] in include_domains: 367 if type["type"] == "object" and domain["domain"] in imported_domains :
339 type_definitions[type_name] = create_include_type_definition(dom ain["domain"], type) 368 type_definitions[type_name] = create_imported_type_definition(do main["domain"], type)
340 elif type["type"] == "object": 369 elif type["type"] == "object":
341 type_definitions[type_name] = create_user_type_definition(domain ["domain"], type) 370 type_definitions[type_name] = create_user_type_definition(domain ["domain"], type)
342 elif type["type"] == "array": 371 elif type["type"] == "array":
343 items_type = type["items"]["type"] 372 items_type = type["items"]["type"]
344 type_definitions[type_name] = wrap_array_definition(type_definit ions[items_type]) 373 type_definitions[type_name] = wrap_array_definition(type_definit ions[items_type])
345 elif type["type"] == domain["domain"] + ".string": 374 elif type["type"] == domain["domain"] + ".string":
346 type_definitions[type_name] = create_string_type_definition(doma in["domain"]) 375 type_definitions[type_name] = create_string_type_definition(doma in["domain"])
347 else: 376 else:
348 type_definitions[type_name] = create_primitive_type_definition(t ype["type"]) 377 type_definitions[type_name] = create_primitive_type_definition(t ype["type"])
349 378
(...skipping 18 matching lines...) Expand all
368 return result 397 return result
369 398
370 399
371 def has_disable(commands): 400 def has_disable(commands):
372 for command in commands: 401 for command in commands:
373 if command["name"] == "disable": 402 if command["name"] == "disable":
374 return True 403 return True
375 return False 404 return False
376 405
377 406
407 def generate_with_context(template_context, template, file_name):
408 out_file = output_file(file_name)
409 out_file.write(template.render(template_context))
410 out_file.close()
411
412
378 def generate(domain_object, template, file_name): 413 def generate(domain_object, template, file_name):
379 template_context = { 414 template_context = {
380 "domain": domain_object, 415 "domain": domain_object,
381 "join_arrays": join_arrays, 416 "join_arrays": join_arrays,
382 "resolve_type": resolve_type, 417 "resolve_type": resolve_type,
383 "type_definition": type_definition, 418 "type_definition": type_definition,
384 "has_disable": has_disable, 419 "has_disable": has_disable,
385 "export_macro": export_macro, 420 "export_macro": export_macro,
386 "output_package": output_package, 421 "output_package": output_package
387 "exported_package": exported_package,
388 "include_package": include_package
389 } 422 }
390 out_file = output_file(file_name) 423 if exporting:
391 out_file.write(template.render(template_context)) 424 template_context["exported_package"] = exported_package
392 out_file.close() 425 if importing:
426 template_context["imported_package"] = imported_package
427 generate_with_context(template_context, template, file_name)
393 428
394 429
395 generate_domains = [] 430 def read_protocol_file(file_name, all_domains):
396 include_domains = [] 431 input_file = open(file_name, "r")
397 json_api = {}
398 json_api["domains"] = parsed_json["domains"]
399
400 for domain in parsed_json["domains"]:
401 generate_domains.append(domain["domain"])
402
403 if include_file:
404 input_file = open(include_file, "r")
405 json_string = input_file.read() 432 json_string = input_file.read()
406 parsed_json = json.loads(json_string) 433 parsed_json = json.loads(json_string)
434 domains = []
407 for domain in parsed_json["domains"]: 435 for domain in parsed_json["domains"]:
408 include_domains.append(domain["domain"]) 436 domains.append(domain["domain"])
409 json_api["domains"] += parsed_json["domains"] 437 all_domains["domains"] += parsed_json["domains"]
438 return domains
410 439
440
441 json_api = {"domains": []}
442 generate_domains = read_protocol_file(protocol_file, json_api)
443 imported_domains = read_protocol_file(imported_file, json_api) if importing else []
411 patch_full_qualified_refs() 444 patch_full_qualified_refs()
412 calculate_exports() 445 calculate_exports()
413 create_type_definitions() 446 create_type_definitions()
414 447
415 if up_to_date(): 448 if up_to_date():
416 sys.exit() 449 sys.exit()
417 if not os.path.exists(output_dirname): 450 if not os.path.exists(output_dirname):
418 os.mkdir(output_dirname) 451 os.mkdir(output_dirname)
419 if json_api["has_exports"] and not os.path.exists(exported_dirname): 452 if json_api["has_exports"] and not os.path.exists(exported_dirname):
420 os.mkdir(exported_dirname) 453 os.mkdir(exported_dirname)
421 454
422 jinja_env = initialize_jinja_env(output_dirname) 455 jinja_env = initialize_jinja_env(output_dirname)
423 h_template = jinja_env.get_template("/TypeBuilder_h.template") 456 h_template = jinja_env.get_template("/TypeBuilder_h.template")
424 cpp_template = jinja_env.get_template("/TypeBuilder_cpp.template") 457 cpp_template = jinja_env.get_template("/TypeBuilder_cpp.template")
425 exported_template = jinja_env.get_template("/Exported_h.template") 458 exported_template = jinja_env.get_template("/Exported_h.template")
426 imported_template = jinja_env.get_template("/Imported_h.template") 459 imported_template = jinja_env.get_template("/Imported_h.template")
427 460
428 for domain in json_api["domains"]: 461 for domain in json_api["domains"]:
429 class_name = domain["domain"] 462 class_name = domain["domain"]
430 if domain["domain"] in generate_domains: 463 if domain["domain"] in generate_domains:
431 generate(domain, h_template, output_dirname + "/" + class_name + ".h") 464 generate(domain, h_template, os.path.join(output_dirname, class_name + " .h"))
432 generate(domain, cpp_template, output_dirname + "/" + class_name + ".cpp ") 465 generate(domain, cpp_template, os.path.join(output_dirname, class_name + ".cpp"))
433 if domain["has_exports"]: 466 if domain["has_exports"]:
434 generate(domain, exported_template, exported_dirname + "/" + class_n ame + ".h") 467 generate(domain, exported_template, os.path.join(exported_dirname, c lass_name + ".h"))
435 if domain["domain"] in include_domains and domain["has_exports"]: 468 if domain["domain"] in imported_domains and domain["has_exports"]:
436 generate(domain, imported_template, output_dirname + "/" + class_name + ".h") 469 generate(domain, imported_template, os.path.join(output_dirname, class_n ame + ".h"))
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/BUILD.gn ('k') | third_party/WebKit/Source/platform/inspector_protocol/Imported_h.template » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698