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

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

Issue 2035653005: DevTools: split protocol.json into files per domain. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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 string 7 import string
8 import optparse 8 import optparse
9 import re 9 import re
10 try: 10 try:
(...skipping 15 matching lines...) Expand all
26 module_path, os.pardir, os.pardir, os.pardir, os.pardir)) 26 module_path, os.pardir, os.pardir, os.pardir, os.pardir))
27 27
28 # jinja2 is in chromium's third_party directory. 28 # jinja2 is in chromium's third_party directory.
29 # Insert at 1 so at front to override system libraries, and 29 # Insert at 1 so at front to override system libraries, and
30 # after path[0] == invoking script dir 30 # after path[0] == invoking script dir
31 31
32 sys.path.insert(1, third_party_dir) 32 sys.path.insert(1, third_party_dir)
33 import jinja2 33 import jinja2
34 34
35 cmdline_parser = optparse.OptionParser() 35 cmdline_parser = optparse.OptionParser()
36 cmdline_parser.add_option("--domains") 36 cmdline_parser.add_option("--protocol_dir")
37 cmdline_parser.add_option("--include_dir")
38 cmdline_parser.add_option("--string_type")
39 cmdline_parser.add_option("--export_macro")
37 cmdline_parser.add_option("--output_dir") 40 cmdline_parser.add_option("--output_dir")
38 cmdline_parser.add_option("--output_package") 41 cmdline_parser.add_option("--output_package")
39 cmdline_parser.add_option("--string_type")
40 cmdline_parser.add_option("--export_macro")
41
42 generate_domains = set()
43 42
44 try: 43 try:
45 arg_options, arg_values = cmdline_parser.parse_args() 44 arg_options, arg_values = cmdline_parser.parse_args()
46 if (len(arg_values) == 0): 45 protocol_dir = arg_options.protocol_dir
47 raise Exception("At least one plain argument expected (found %s)" % len( arg_values)) 46 if not protocol_dir:
47 raise Exception("Protocol directory must be specified")
48 include_dir = arg_options.include_dir
48 output_dirname = arg_options.output_dir 49 output_dirname = arg_options.output_dir
49 if not output_dirname: 50 if not output_dirname:
50 raise Exception("Output directory must be specified") 51 raise Exception("Output directory must be specified")
51 output_package = arg_options.output_package 52 output_package = arg_options.output_package
52 if not output_package: 53 if not output_package:
53 raise Exception("Output package must be specified") 54 raise Exception("Output package must be specified")
54 string_type = arg_options.string_type 55 string_type = arg_options.string_type
55 if not string_type: 56 if not string_type:
56 raise Exception("String type must be specified") 57 raise Exception("String type must be specified")
57 export_macro = arg_options.export_macro 58 export_macro = arg_options.export_macro
58 if not export_macro: 59 if not export_macro:
59 raise Exception("Export macro must be specified") 60 raise Exception("Export macro must be specified")
60 output_domains = arg_options.domains
61 if output_domains and len(output_domains):
62 for domain in output_domains.split(","):
63 generate_domains.add(domain)
64 except Exception: 61 except Exception:
65 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html 62 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
66 exc = sys.exc_info()[1] 63 exc = sys.exc_info()[1]
67 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) 64 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
68 sys.stderr.write("Usage: <script> --output_dir <output_dir> protocol.json .. .\n")
69 exit(1) 65 exit(1)
70 66
71 json_api = {"domains": []}
72 67
73 json_timestamp = 0 68 # Make gyp / make generatos happy, otherwise make rebuilds world.
69 def up_to_date():
70 template_ts = max(
71 os.path.getmtime(__file__),
72 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_h.template")),
73 os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template") ))
74 74
75 for filename in arg_values: 75 for name in os.listdir(protocol_dir):
76 json_timestamp = max(os.path.getmtime(filename), json_timestamp) 76 filename = os.path.join(protocol_dir, name)
77 input_file = open(filename, "r") 77 if name.endswith(".json") and os.path.isfile(filename):
78 json_string = input_file.read() 78 h_path = os.path.join(output_dirname, name.replace(".json", ".h"))
79 parsed_json = json.loads(json_string) 79 cpp_path = os.path.join(output_dirname, name.replace(".json", ".cpp" ))
80 json_api["domains"] += parsed_json["domains"] 80 if not os.path.exists(h_path) or not os.path.exists(cpp_path):
81 return False
82 protocol_ts = os.path.getmtime(filename)
83 generated_ts = max(os.path.getmtime(h_path), os.path.getmtime(cpp_pa th))
84 if generated_ts < template_ts or generated_ts < protocol_ts:
85 return False
86 return True
87
88
89 if up_to_date():
90 sys.exit()
91
81 92
82 def to_title_case(name): 93 def to_title_case(name):
83 return name[:1].upper() + name[1:] 94 return name[:1].upper() + name[1:]
84 95
85 96
86 def dash_to_camelcase(word): 97 def dash_to_camelcase(word):
87 return ''.join(to_title_case(x) or '-' for x in word.split('-')) 98 return ''.join(to_title_case(x) or '-' for x in word.split('-'))
88 99
89 100
90 def initialize_jinja_env(cache_dir): 101 def initialize_jinja_env(cache_dir):
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 "raw_return_type": typedefs[type], 216 "raw_return_type": typedefs[type],
206 } 217 }
207 218
208 type_definitions = {} 219 type_definitions = {}
209 type_definitions["number"] = create_primitive_type_definition("number") 220 type_definitions["number"] = create_primitive_type_definition("number")
210 type_definitions["integer"] = create_primitive_type_definition("integer") 221 type_definitions["integer"] = create_primitive_type_definition("integer")
211 type_definitions["boolean"] = create_primitive_type_definition("boolean") 222 type_definitions["boolean"] = create_primitive_type_definition("boolean")
212 type_definitions["object"] = create_object_type_definition() 223 type_definitions["object"] = create_object_type_definition()
213 type_definitions["any"] = create_any_type_definition() 224 type_definitions["any"] = create_any_type_definition()
214 225
226
215 def wrap_array_definition(type): 227 def wrap_array_definition(type):
216 return { 228 return {
217 "return_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"] , 229 "return_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"] ,
218 "pass_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], 230 "pass_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"],
219 "to_raw_type": "%s.get()", 231 "to_raw_type": "%s.get()",
220 "to_pass_type": "std::move(%s)", 232 "to_pass_type": "std::move(%s)",
221 "to_rvalue": "std::move(%s)", 233 "to_rvalue": "std::move(%s)",
222 "type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], 234 "type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"],
223 "raw_type": "protocol::Array<%s>" % type["raw_type"], 235 "raw_type": "protocol::Array<%s>" % type["raw_type"],
224 "raw_pass_type": "protocol::Array<%s>*" % type["raw_type"], 236 "raw_pass_type": "protocol::Array<%s>*" % type["raw_type"],
(...skipping 12 matching lines...) Expand all
237 if type["type"] == "object": 249 if type["type"] == "object":
238 type_definitions[domain["domain"] + "." + type["id"]] = create_u ser_type_definition(domain["domain"], type) 250 type_definitions[domain["domain"] + "." + type["id"]] = create_u ser_type_definition(domain["domain"], type)
239 elif type["type"] == "array": 251 elif type["type"] == "array":
240 items_type = type["items"]["type"] 252 items_type = type["items"]["type"]
241 type_definitions[domain["domain"] + "." + type["id"]] = wrap_arr ay_definition(type_definitions[items_type]) 253 type_definitions[domain["domain"] + "." + type["id"]] = wrap_arr ay_definition(type_definitions[items_type])
242 elif type["type"] == domain["domain"] + ".string": 254 elif type["type"] == domain["domain"] + ".string":
243 type_definitions[domain["domain"] + "." + type["id"]] = create_s tring_type_definition(domain["domain"]) 255 type_definitions[domain["domain"] + "." + type["id"]] = create_s tring_type_definition(domain["domain"])
244 else: 256 else:
245 type_definitions[domain["domain"] + "." + type["id"]] = create_p rimitive_type_definition(type["type"]) 257 type_definitions[domain["domain"] + "." + type["id"]] = create_p rimitive_type_definition(type["type"])
246 258
247 patch_full_qualified_refs()
248 create_type_definitions()
249
250 259
251 def type_definition(name): 260 def type_definition(name):
252 return type_definitions[name] 261 return type_definitions[name]
253 262
254 263
255 def resolve_type(property): 264 def resolve_type(property):
256 if "$ref" in property: 265 if "$ref" in property:
257 return type_definitions[property["$ref"]] 266 return type_definitions[property["$ref"]]
258 if property["type"] == "array": 267 if property["type"] == "array":
259 return wrap_array_definition(resolve_type(property["items"])) 268 return wrap_array_definition(resolve_type(property["items"]))
260 return type_definitions[property["type"]] 269 return type_definitions[property["type"]]
261 270
262 271
263 def join_arrays(dict, keys): 272 def join_arrays(dict, keys):
264 result = [] 273 result = []
265 for key in keys: 274 for key in keys:
266 if key in dict: 275 if key in dict:
267 result += dict[key] 276 result += dict[key]
268 return result 277 return result
269 278
270 279
271 def has_disable(commands): 280 def has_disable(commands):
272 for command in commands: 281 for command in commands:
273 if command["name"] == "disable": 282 if command["name"] == "disable":
274 return True 283 return True
275 return False 284 return False
276 285
277 286
278 if os.path.exists(__file__): 287 generate_domains = []
279 current_script_timestamp = os.path.getmtime(__file__) 288 filenames = []
280 else: 289 for f in os.listdir(protocol_dir):
281 current_script_timestamp = 0 290 name = os.path.join(protocol_dir, f)
291 if name.endswith(".json") and os.path.isfile(name):
292 filenames.append(name)
293 generate_domains.append(f.replace(".json", ""))
282 294
295 if include_dir:
296 for f in os.listdir(include_dir):
297 name = os.path.join(include_dir, f)
298 if name.endswith(".json") and os.path.isfile(name):
299 filenames.append(name)
283 300
284 def is_up_to_date(file, template): 301 json_api = {"domains": []}
285 if not os.path.exists(file): 302
286 return False 303 for filename in filenames:
287 timestamp = os.path.getmtime(file) 304 input_file = open(filename, "r")
288 return timestamp > max(os.path.getmtime(module_path + template), 305 json_string = input_file.read()
289 current_script_timestamp, json_timestamp) 306 parsed_json = json.loads(json_string)
307 json_api["domains"].append(parsed_json)
308
309 patch_full_qualified_refs()
310 create_type_definitions()
290 311
291 if not os.path.exists(output_dirname): 312 if not os.path.exists(output_dirname):
292 os.mkdir(output_dirname) 313 os.mkdir(output_dirname)
293 jinja_env = initialize_jinja_env(output_dirname) 314 jinja_env = initialize_jinja_env(output_dirname)
294 315
295 h_template_name = "/TypeBuilder_h.template" 316 h_template_name = "/TypeBuilder_h.template"
296 cpp_template_name = "/TypeBuilder_cpp.template" 317 cpp_template_name = "/TypeBuilder_cpp.template"
297 h_template = jinja_env.get_template(h_template_name) 318 h_template = jinja_env.get_template(h_template_name)
298 cpp_template = jinja_env.get_template(cpp_template_name) 319 cpp_template = jinja_env.get_template(cpp_template_name)
299 320
300 321
301 def generate(domain): 322 def generate(domain):
302 class_name = domain["domain"] 323 class_name = domain["domain"]
303 h_file_name = output_dirname + "/" + class_name + ".h" 324 h_file_name = output_dirname + "/" + class_name + ".h"
304 cpp_file_name = output_dirname + "/" + class_name + ".cpp" 325 cpp_file_name = output_dirname + "/" + class_name + ".cpp"
305 326
306 if (is_up_to_date(cpp_file_name, cpp_template_name) and
307 is_up_to_date(h_file_name, h_template_name)):
308 return
309
310 template_context = { 327 template_context = {
311 "domain": domain, 328 "domain": domain,
312 "join_arrays": join_arrays, 329 "join_arrays": join_arrays,
313 "resolve_type": resolve_type, 330 "resolve_type": resolve_type,
314 "type_definition": type_definition, 331 "type_definition": type_definition,
315 "has_disable": has_disable, 332 "has_disable": has_disable,
316 "export_macro": export_macro, 333 "export_macro": export_macro,
317 "output_package": output_package, 334 "output_package": output_package,
318 } 335 }
319 h_file = output_file(h_file_name) 336 h_file = output_file(h_file_name)
320 cpp_file = output_file(cpp_file_name) 337 cpp_file = output_file(cpp_file_name)
321 h_file.write(h_template.render(template_context)) 338 h_file.write(h_template.render(template_context))
322 cpp_file.write(cpp_template.render(template_context)) 339 cpp_file.write(cpp_template.render(template_context))
323 h_file.close() 340 h_file.close()
324 cpp_file.close() 341 cpp_file.close()
325 342
326 343
327 for domain in json_api["domains"]: 344 for domain in json_api["domains"]:
328 if domain["domain"] in generate_domains: 345 if domain["domain"] in generate_domains:
329 generate(domain) 346 generate(domain)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698