From ed225e7662133eda24d4e8d74f769684044b1e26 Mon Sep 17 00:00:00 2001 From: legendecas <8500303+legendecas@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:10:32 +0000 Subject: [PATCH] deps: update inspector_protocol to 1b1bcbbe060e8c8cd8704f00f78978c50991 --- deps/inspector_protocol/README.node | 2 +- deps/inspector_protocol/code_generator.py | 61 ++++++++++------ .../concatenate_protocols.py | 30 +++++++- .../inspector_protocol/inspector_protocol.gni | 62 +++++++++++++++- deps/inspector_protocol/pdl.py | 17 +++-- .../templates/TypeBuilder_h.template | 71 +++++++++++++------ 6 files changed, 187 insertions(+), 56 deletions(-) diff --git a/deps/inspector_protocol/README.node b/deps/inspector_protocol/README.node index f37ddb9e9280b6..6216d7a8ea06db 100644 --- a/deps/inspector_protocol/README.node +++ b/deps/inspector_protocol/README.node @@ -2,7 +2,7 @@ Name: inspector protocol Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: af7f5a8173fdbc29f0835ec94395932e328b2ea2 +Revision: 1b1bcbbe060e8c8cd8704f00f78978c50991b307 License: BSD License File: LICENSE Security Critical: no diff --git a/deps/inspector_protocol/code_generator.py b/deps/inspector_protocol/code_generator.py index ce989e4869002e..b25ffc29b0a96a 100755 --- a/deps/inspector_protocol/code_generator.py +++ b/deps/inspector_protocol/code_generator.py @@ -75,12 +75,18 @@ def init_defaults(config_tuple, path, defaults): "--inspector_protocol_dir", type=unicode, required=True, help=("directory with code_generator.py and C++ encoding / binding " "libraries, relative to the root of the source tree.")) + cmdline_parser.add_argument("--depfile", type=unicode, required=False) + cmdline_parser.add_argument("--stamp", type=unicode, required=False) arg_options = cmdline_parser.parse_args() jinja_dir = arg_options.jinja_dir output_base = arg_options.output_base config_file = arg_options.config config_base = os.path.dirname(config_file) config_values = arg_options.config_value + if bool(arg_options.depfile) != bool(arg_options.stamp): + raise Exception("--depfile requires --stamp and vice versa") + depfile = arg_options.depfile + stamp = arg_options.stamp inspector_protocol_dir = arg_options.inspector_protocol_dir.lstrip('/') except Exception: # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html @@ -122,7 +128,8 @@ def init_defaults(config_tuple, path, defaults): parts = key_value.split("=") if len(parts) == 2: defaults["." + parts[0]] = parts[1] - return (jinja_dir, config_file, init_defaults(config_partial, "", defaults)) + return (jinja_dir, config_file, init_defaults(config_partial, "", defaults), + depfile, stamp) except Exception: # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html exc = sys.exc_info()[1] @@ -360,6 +367,7 @@ class Protocol(object): def __init__(self, config): self.config = config self.json_api = {"domains": []} + self.source_set = set() self.imported_domains = [] self.exported_domains = [] self.generate_domains = self.read_protocol_file(config.protocol.path) @@ -381,7 +389,8 @@ def __init__(self, config): def read_protocol_file(self, file_name): input_file = open(file_name, "r") - parsed_json = pdl.loads(input_file.read(), file_name) + parsed_json = pdl.loads(input_file.read(), file_name, False, + self.source_set) input_file.close() version = '%s.%s' % (parsed_json["version"]["major"], parsed_json["version"]["minor"]) @@ -600,9 +609,10 @@ def is_imported_dependency(self, domain): def main(): - jinja_dir, config_file, config = read_config() + jinja_dir, config_file, config, deps_filename, stamp_filename = read_config() protocol = Protocol(config) + source_set = protocol.source_set if not config.exported and len(protocol.exported_domains): sys.stderr.write(("Domains [%s] are exported, but config is missing export " @@ -648,18 +658,26 @@ def main(): } if domain["domain"] in protocol.generate_domains: - outputs[os.path.join(config.protocol.output, to_file_name( - config, file_name + ".h"))] = h_template.render(template_context) - outputs[os.path.join(config.protocol.output, to_file_name( - config, file_name + ".cpp"))] = cpp_template.render(template_context) + output_h = os.path.join(config.protocol.output, to_file_name( + config, file_name + ".h")) + outputs[output_h] = h_template.render(template_context) + source_set.add(h_template.filename) + output_cpp = os.path.join(config.protocol.output, to_file_name( + config, file_name + ".cpp")) + outputs[output_cpp] = cpp_template.render(template_context) + source_set.add(cpp_template.filename) if domain["domain"] in protocol.exported_domains: - outputs[os.path.join(config.exported.output, to_file_name( - config, file_name + ".h"))] = exported_template.render( + output_export_h = os.path.join(config.exported.output, to_file_name( + config, file_name + ".h")) + outputs[output_export_h] = exported_template.render( template_context) + source_set.add(exported_template.filename) if domain["domain"] in protocol.imported_domains: - outputs[os.path.join(config.protocol.output, to_file_name( - config, file_name + ".h"))] = imported_template.render( + output_import_h = os.path.join(config.protocol.output, to_file_name( + config, file_name + ".h")) + outputs[output_import_h] = imported_template.render( template_context) + source_set.add(imported_template.filename) if config.lib: template_context = { @@ -702,6 +720,7 @@ def generate_lib_file(file_name, template_files): inputs.append(os.path.join(lib_templates_dir, template_file)) template = jinja_env.get_template("lib/" + template_file) parts.append(template.render(template_context)) + source_set.add(template.filename) outputs[file_name] = "\n\n".join(parts) generate_lib_file(os.path.join(config.lib.output, to_file_name( @@ -713,17 +732,9 @@ def generate_lib_file(file_name, template_files): generate_lib_file(os.path.join(config.lib.output, to_file_name( config, "Protocol.cpp")), protocol_cpp_templates) - # Make gyp / make generatos happy, otherwise make rebuilds world. - inputs_ts = max(map(os.path.getmtime, inputs)) - up_to_date = True - for output_file in outputs.keys(): - if (not os.path.exists(output_file) - or os.path.getmtime(output_file) < inputs_ts): - up_to_date = False - break - if up_to_date: - sys.exit() - + if stamp_filename: + with open(stamp_filename, "w"): + pass for file_name, content in outputs.items(): # Remove output file first to account for potential case changes. try: @@ -734,6 +745,12 @@ def generate_lib_file(file_name, template_files): out_file.write(content) out_file.close() + if deps_filename: + assert stamp_filename + with open(deps_filename, "w") as deps_file: + deps_file.write("%s: %s\n" % ( + stamp_filename, " ".join(sorted(source_set)))) + if __name__ == "__main__": main() diff --git a/deps/inspector_protocol/concatenate_protocols.py b/deps/inspector_protocol/concatenate_protocols.py index 11f1fed06c49f6..8ad4f6de712a21 100755 --- a/deps/inspector_protocol/concatenate_protocols.py +++ b/deps/inspector_protocol/concatenate_protocols.py @@ -5,6 +5,7 @@ import os.path import sys +import argparse try: import json @@ -14,29 +15,52 @@ import pdl def main(argv): - if len(argv) < 1: + cmdline_parser = argparse.ArgumentParser() + cmdline_parser.add_argument('filename', nargs='*') + cmdline_parser.add_argument("--depfile", required=False) + cmdline_parser.add_argument("--stamp", required=False) + arg_options = cmdline_parser.parse_args() + + if bool(arg_options.depfile) != bool(arg_options.stamp): + raise Exception("--depfile requires --stamp and vice versa") + + if len(arg_options.filename) < 1: sys.stderr.write( "Usage: %s [ [, ...]] " "\n" % sys.argv[0]) return 1 + filenames = arg_options.filename + deps_filename = arg_options.depfile + stamp_filename = arg_options.stamp domains = [] + source_set = set() version = None - for protocol in argv[:-1]: + for protocol in filenames[:-1]: file_name = os.path.normpath(protocol) if not os.path.isfile(file_name): sys.stderr.write("Cannot find %s\n" % file_name) return 1 input_file = open(file_name, "r") - parsed_json = pdl.loads(input_file.read(), file_name) + parsed_json = pdl.loads(input_file.read(), file_name, False, source_set) domains += parsed_json["domains"] version = parsed_json["version"] + if stamp_filename: + with open(stamp_filename, "w"): + pass + output_file = open(argv[-1], "w") json.dump({"version": version, "domains": domains}, output_file, indent=4, sort_keys=False, separators=(',', ': ')) output_file.close() + if deps_filename: + assert stamp_filename + with open(deps_filename, "w") as deps_file: + deps_file.write("%s: %s\n" % ( + stamp_filename, " ".join(sorted(source_set)))) + if __name__ == '__main__': sys.exit(main(sys.argv[1:])) diff --git a/deps/inspector_protocol/inspector_protocol.gni b/deps/inspector_protocol/inspector_protocol.gni index 15ffbf923ce3b8..6b278c9fa8ef90 100644 --- a/deps/inspector_protocol/inspector_protocol.gni +++ b/deps/inspector_protocol/inspector_protocol.gni @@ -47,6 +47,7 @@ template("inspector_protocol_generate") { "$inspector_protocol_dir/templates/TypeBuilder_cpp.template", "$inspector_protocol_dir/templates/TypeBuilder_h.template", ] + if (defined(invoker.inputs)) { inputs += invoker.inputs } @@ -61,6 +62,12 @@ template("inspector_protocol_generate") { ] } + outputs = get_path_info(rebase_path(invoker.outputs, ".", invoker.out_dir), + "abspath") + + _stampfile = outputs[0] + depfile = "${invoker.out_dir}/${target_name}.d" + args = [ "--jinja_dir", rebase_path(jinja_dir, root_build_dir), @@ -70,6 +77,10 @@ template("inspector_protocol_generate") { rebase_path(invoker.config_file, root_build_dir), "--inspector_protocol_dir", "$inspector_protocol_dir", + "--depfile", + rebase_path(depfile, root_build_dir), + "--stamp", + rebase_path(_stampfile, root_build_dir), ] if (use_embedder_types) { args += [ @@ -86,8 +97,55 @@ template("inspector_protocol_generate") { } } - outputs = get_path_info(rebase_path(invoker.outputs, ".", invoker.out_dir), - "abspath") + forward_variables_from(invoker, + [ + "visibility", + "deps", + "public_deps", + ]) + } +} + +# This template concatenates multiple protocol files +# into a single (JSON) file. +# +# Inputs +# +# inputs (required) +# Paths to .pdl or .json files with protocol definitions. +# +# output_file (required) +# Path to put the concatenated file in. It must be inside output or +# generated file directory. +# +# inspector_protocol_dir (required) +# Path to the inspector_protocol directory. +# +template("inspector_protocol_concatenate") { + assert(defined(invoker.inputs)) + assert(defined(invoker.output_file)) + assert(defined(invoker.inspector_protocol_dir)) + _inspector_protocol_dir = invoker.inspector_protocol_dir + + action(target_name) { + script = "$_inspector_protocol_dir/concatenate_protocols.py" + + inputs = invoker.inputs + outputs = [] + depfile = "${invoker.output_file}_${target_name}.d" + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--stamp", + rebase_path(invoker.output_file, root_build_dir), + ] + + inputs += invoker.inputs + args += rebase_path(invoker.inputs, root_build_dir) + + outputs += [invoker.output_file] + args += [rebase_path(invoker.output_file, root_build_dir)] forward_variables_from(invoker, [ diff --git a/deps/inspector_protocol/pdl.py b/deps/inspector_protocol/pdl.py index 20f505ea81e34e..5b53291fd5b33e 100644 --- a/deps/inspector_protocol/pdl.py +++ b/deps/inspector_protocol/pdl.py @@ -50,7 +50,8 @@ def createItem(d, experimental, deprecated, name=None): return result -def parse(data, file_name, map_binary_to_string=False): +def parse(data, file_name, map_binary_to_string, source_set): + assert source_set is None or isinstance(source_set, set) protocol = collections.OrderedDict() protocol['version'] = collections.OrderedDict() protocol['domains'] = [] @@ -58,6 +59,8 @@ def parse(data, file_name, map_binary_to_string=False): item = None subitems = None nukeDescription = False + if source_set is not None: + source_set.add(file_name) global description lines = data.split('\n') for i in range(0, len(lines)): @@ -90,11 +93,11 @@ def parse(data, file_name, map_binary_to_string=False): r'^include (.*)').match(line) if match: included_filename = match.group(1) - if path.isabs(included_filename): - raise Exception("Only relative paths are supported in include's") - resolved_path = path.normpath(path.join(path.dirname(file_name), included_filename)) + if os.path.isabs(included_filename): + raise Exception("Only relative paths are supported in includes") + resolved_path = os.path.normpath(os.path.join(os.path.dirname(file_name), included_filename)) with open(resolved_path, 'r') as file: - included_data = parse(file.read(), resolved_path, map_binary_to_string) + included_data = parse(file.read(), resolved_path, map_binary_to_string, source_set) protocol['domains'].extend(included_data['domains']) continue @@ -187,7 +190,7 @@ def parse(data, file_name, map_binary_to_string=False): return protocol -def loads(data, file_name, map_binary_to_string=False): +def loads(data, file_name, map_binary_to_string=False, source_set=None): if file_name.endswith(".pdl"): - return parse(data, file_name, map_binary_to_string) + return parse(data, file_name, map_binary_to_string, source_set) return json.loads(data) diff --git a/deps/inspector_protocol/templates/TypeBuilder_h.template b/deps/inspector_protocol/templates/TypeBuilder_h.template index 7c2a696ad0cbe4..33c5d1af5353f7 100644 --- a/deps/inspector_protocol/templates/TypeBuilder_h.template +++ b/deps/inspector_protocol/templates/TypeBuilder_h.template @@ -74,7 +74,7 @@ namespace {{param.name | to_title_case}}Enum { class {{config.protocol.export_macro}} {{type.id}} : public ::{{config.crdtp.namespace}}::ProtocolObject<{{type.id}}>{% if protocol.is_exported(domain.domain, type.id) %}, public API::{{type.id}}{% endif %} { public: - ~{{type.id}}() override { } + ~{{type.id}}() override; // Defined below {% for property in type.properties %} {% set property_type = protocol.resolve_type(property) %} {% set property_name = property.name | to_title_case %} @@ -105,7 +105,7 @@ public: {% else %} {{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}() { return {{property_type.to_raw_type % property_field}}; } {% endif %} - void {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { {{property_field}} = {{property_type.to_rvalue % "value"}}; } + void {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value); // Defined below {% endfor %} template @@ -126,18 +126,9 @@ public: {% set property_name = property.name | to_title_case %} {% if property.optional %} - {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) - { - m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); - return *this; - } + {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value); // Defined below {% else %} - {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) - { - static_assert(!(STATE & {{property_name}}Set), "property {{property.name}} should not be set yet"); - m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); - return castState<{{property_name}}Set>(); - } + {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value); // Defined below {% endif %} {% endfor %} @@ -167,14 +158,7 @@ public: private: DECLARE_SERIALIZATION_SUPPORT(); - {{type.id}}() - { - {% for property in type.properties %} - {% if not(property.optional) and "default_value" in protocol.resolve_type(property) %} - m_{{property.name}} = {{protocol.resolve_type(property).default_value}}; - {%endif %} - {% endfor %} - } + {{type.id}}(); // Defined below {% for property in type.properties %} {% if property.optional %} @@ -187,6 +171,51 @@ private: {% endfor %} +// ------------- Type and builder method definitions. +// +// These methods separate from the type declaration because of +// https://github.com/llvm/llvm-project/issues/59966. The DevTools protocol has +// mutually recursive types, so we cannot simply reorder the types. + {% for type in domain.types %} + {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %} + {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %} +inline {{type.id}}::~{{type.id}}() = default; + {% for property in type.properties %} + {% set property_type = protocol.resolve_type(property) %} + {% set property_name = property.name | to_title_case %} + {% set property_field = "m_" + property.name %} +inline void {{type.id}}::{{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { {{property_field}} = {{property_type.to_rvalue % "value"}}; } + {% endfor %} + + {% for property in type.properties %} + {% set property_type = protocol.resolve_type(property) %} + {% set property_name = property.name | to_title_case %} + {% if property.optional %} +template +inline {{type.id}}::{{type.id}}Builder& {{type.id}}::{{type.id}}Builder::{{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { + m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); + return *this; +} + {% else %} +template +inline {{type.id}}::{{type.id}}Builder::{{property_name}}Set>& +{{type.id}}::{{type.id}}Builder::{{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { + static_assert(!(STATE & {{property_name}}Set), "property {{property.name}} should not be set yet"); + m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); + return castState<{{property_name}}Set>(); +} + {% endif %} + {% endfor %} + +inline {{type.id}}::{{type.id}}() { + {% for property in type.properties %} + {% if not(property.optional) and "default_value" in protocol.resolve_type(property) %} + m_{{property.name}} = {{protocol.resolve_type(property).default_value}}; + {%endif %} + {% endfor %} +} + {% endfor %} + // ------------- Backend interface. class {{config.protocol.export_macro}} Backend {