mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
02a7b4ebdf
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly. To produce this patch I did all of the following: 1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions. 2. Run ./mach lint --linter black --fix 3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks. 4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat. 5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023). # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D94045
205 lines
6.2 KiB
Python
205 lines
6.2 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import string
|
|
import sys
|
|
import textwrap
|
|
import yaml
|
|
|
|
###############################################################################
|
|
# Language-agnostic functionality #
|
|
###############################################################################
|
|
|
|
template_header = (
|
|
"/* This file was autogenerated by "
|
|
"toolkit/crashreporter/generate_crash_reporter_sources.py. DO NOT EDIT */\n\n"
|
|
)
|
|
|
|
|
|
def validate_annotations(annotations):
|
|
""" Ensure that the annotations have all the required fields """
|
|
|
|
for (name, data) in sorted(annotations.items()):
|
|
if "description" not in data:
|
|
print("Annotation " + name + " does not have a description\n")
|
|
sys.exit(1)
|
|
if "type" not in data:
|
|
print("Annotation " + name + " does not have a type\n")
|
|
sys.exit(1)
|
|
else:
|
|
annotation_type = data.get("type")
|
|
valid_types = ["boolean", "integer", "string"]
|
|
if not any(annotation_type == t for t in valid_types):
|
|
print(
|
|
"Annotation "
|
|
+ name
|
|
+ " has an unknown type: "
|
|
+ annotation_type
|
|
+ "\n"
|
|
)
|
|
sys.exit(1)
|
|
|
|
|
|
def read_annotations(annotations_filename):
|
|
"""Read the annotations from a YAML file.
|
|
If an error is encountered quit the program."""
|
|
|
|
try:
|
|
with open(annotations_filename, "r") as annotations_file:
|
|
annotations = yaml.safe_load(annotations_file)
|
|
except (IOError, ValueError) as e:
|
|
print("Error parsing " + annotations_filename + ":\n" + str(e) + "\n")
|
|
sys.exit(1)
|
|
|
|
validate_annotations(annotations)
|
|
|
|
return annotations
|
|
|
|
|
|
def read_template(template_filename):
|
|
"""Read the contents of the template.
|
|
If an error is encountered quit the program."""
|
|
|
|
try:
|
|
with open(template_filename, "r") as template_file:
|
|
template = template_file.read()
|
|
except IOError as ex:
|
|
print("Error when reading " + template_filename + ":\n" + str(ex) + "\n")
|
|
sys.exit(1)
|
|
|
|
return template
|
|
|
|
|
|
def extract_crash_ping_whitelist(annotations):
|
|
"""Extract an array holding the names of the annotations whitelisted for
|
|
inclusion in the crash ping."""
|
|
|
|
return [
|
|
name for (name, data) in sorted(annotations.items()) if data.get("ping", False)
|
|
]
|
|
|
|
|
|
###############################################################################
|
|
# C++ code generation #
|
|
###############################################################################
|
|
|
|
|
|
def generate_strings(annotations):
|
|
"""Generate strings corresponding to every annotation."""
|
|
|
|
names = [
|
|
' "' + data.get("altname", name) + '"'
|
|
for (name, data) in sorted(annotations.items())
|
|
]
|
|
|
|
return ",\n".join(names)
|
|
|
|
|
|
def generate_enum(annotations):
|
|
"""Generate the C++ typed enum holding all the annotations and return it
|
|
as a string."""
|
|
|
|
enum = ""
|
|
|
|
for i, (name, _) in enumerate(sorted(annotations.items())):
|
|
enum += " " + name + " = " + str(i) + ",\n"
|
|
|
|
enum += " Count = " + str(len(annotations))
|
|
|
|
return enum
|
|
|
|
|
|
def generate_array_initializer(contents):
|
|
"""Generates the initializer for a C++ array of annotations."""
|
|
|
|
initializer = [" Annotation::" + name for name in contents]
|
|
|
|
return ",\n".join(initializer)
|
|
|
|
|
|
def generate_header(template, annotations):
|
|
"""Generate a header by filling the template with the the list of
|
|
annotations and return it as a string."""
|
|
|
|
whitelist = extract_crash_ping_whitelist(annotations)
|
|
|
|
return template_header + string.Template(template).substitute(
|
|
{
|
|
"enum": generate_enum(annotations),
|
|
"strings": generate_strings(annotations),
|
|
"whitelist": generate_array_initializer(whitelist),
|
|
}
|
|
)
|
|
|
|
|
|
def emit_header(output, template_filename, annotations_filename):
|
|
"""Generate the C++ header from the template and write it out."""
|
|
|
|
annotations = read_annotations(annotations_filename)
|
|
template = read_template(template_filename)
|
|
generated_header = generate_header(template, annotations)
|
|
|
|
try:
|
|
output.write(generated_header)
|
|
except IOError as ex:
|
|
print("Error while writing out the generated file:\n" + str(ex) + "\n")
|
|
sys.exit(1)
|
|
|
|
|
|
###############################################################################
|
|
# Java code generation #
|
|
###############################################################################
|
|
|
|
|
|
def generate_java_array_initializer(contents):
|
|
"""Generates the initializer for an array of strings.
|
|
Effectively turns `["a", "b"]` into ' \"a\",\n \"b\"\n'."""
|
|
|
|
initializer = ""
|
|
|
|
for name in contents:
|
|
initializer += ' "' + name + '",\n'
|
|
|
|
return initializer.strip(",\n")
|
|
|
|
|
|
def generate_class(template, annotations):
|
|
"""Fill the class template from the list of annotations."""
|
|
|
|
whitelist = extract_crash_ping_whitelist(annotations)
|
|
|
|
return template_header + string.Template(template).substitute(
|
|
{
|
|
"whitelist": generate_java_array_initializer(whitelist),
|
|
}
|
|
)
|
|
|
|
|
|
def emit_class(output, annotations_filename):
|
|
"""Generate the CrashReporterConstants.java file."""
|
|
|
|
template = textwrap.dedent(
|
|
"""\
|
|
package org.mozilla.gecko;
|
|
|
|
/**
|
|
* Constants used by the crash reporter. These are generated so that they
|
|
* are kept in sync with the other C++ and JS users.
|
|
*/
|
|
public class CrashReporterConstants {
|
|
public static final String[] ANNOTATION_WHITELIST = {
|
|
${whitelist}
|
|
};
|
|
}"""
|
|
)
|
|
|
|
annotations = read_annotations(annotations_filename)
|
|
generated_class = generate_class(template, annotations)
|
|
|
|
try:
|
|
output.write(generated_class)
|
|
except IOError as ex:
|
|
print("Error while writing out the generated file:\n" + str(ex) + "\n")
|
|
sys.exit(1)
|