blob: 6dae772491826a38ea6b4f459a9b8183e6ecba9a [file] [edit]
#!/usr/bin/env python3
#
# Copyright (C) 2026 Devin Rousso <webkit@devinrousso.com>. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
import argparse
import glob
import json
import os
import re
import sys
LICENSE = """/*
* Copyright (C) 2026 Devin Rousso <webkit@devinrousso.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/"""
HEADER = """// DO NOT EDIT THIS FILE. It is automatically generated by the script: Source/WebInspectorUI/Scripts/update-NativeFunctionParameters.py"""
def js_string(value):
return '"{}"'.format(value.replace("\\", "\\\\").replace('"', '\\"'))
def js_key(name):
if re.match(r"^[A-Za-z_$][\w$]*$", name):
return name
return js_string(name)
def merge(generated, overrides):
merged = {}
for name, entry in generated.items():
merged[name] = {kind: dict(methods) for kind, methods in entry.items()}
for name, entry in overrides.items():
target = merged.setdefault(name, {})
for kind, methods in entry.items():
target.setdefault(kind, {}).update(methods) # Overrides win.
return merged
def generate_object(target, data):
lines = ["{} = {{".format(target)]
for name in sorted(data):
methods = data[name]
if not methods:
continue
lines.append(" {}: {{".format(js_key(name)))
for method in sorted(methods):
lines.append(" {}: {},".format(js_key(method), js_string(methods[method])))
lines.append(" __proto__: null,")
lines.append(" },")
lines.append("};")
return "\n".join(lines)
def main():
parser = argparse.ArgumentParser(description="Regenerate NativeFunctionParameters.js from WebCore's IDL and any handwritten overrides.")
parser.add_argument("--json", required=True, help="Path to InspectorNativeFunctionParameters.json.")
parser.add_argument("--overrides", required=True, help="Path to NativeFunctionParameters-overrides.json.")
parser.add_argument("--output", required=True, help="Path to write NativeFunctionParameters.js.")
args = parser.parse_args()
try:
with open(args.json) as file:
generated = json.load(file)
except (OSError, json.JSONDecodeError) as error:
print("warning: Failed to load generated native function parameters: {}. Falling back to overrides.".format(error), file=sys.stderr)
generated = {}
with open(args.overrides) as file:
overrides = json.load(file)
merged = merge(generated, overrides)
constructors = {name: entry["constructor"] for name, entry in merged.items() if entry.get("constructor")}
prototypes = {name: entry["prototype"] for name, entry in merged.items() if entry.get("prototype")}
contents = "\n".join([
LICENSE,
"",
HEADER,
"",
generate_object("WI.NativeConstructorFunctionParameters", constructors),
"",
generate_object("WI.NativePrototypeFunctionParameters", prototypes),
"",
])
existing = None
if os.path.isfile(args.output):
with open(args.output) as file:
existing = file.read()
if existing != contents:
with open(args.output, "w") as file:
file.write(contents)
return 0
if __name__ == "__main__":
sys.exit(main())