blob: 137633c78bbcb5c52d642a591774389ac81eaf86 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tool for generating go code from automation.js
Used to create src/chromiumos/tast/local/chrome/ui2/nodewith/*/constants.go.
Usage example:
# ./generate_automation_constants.py \
/path/to/chromium/src/third_party/closure_compiler/externs/automation.js \
/path/to/chromeos/src/platform/tast-tests/src/chromiumos/tast/local/chrome/ui2/
Make sure to apply gofmt to the output of this script.
TODO(hirokisato): Currently this script reads closure compiler's definition js
file, because it's easy to parse. But the automation IDL file is the source of
truth.
"""
import os
import sys
import re
HEADER = """\
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is generated by `tools/generate_automation2_constants.py`.
"""
def to_camel_case(snake_case_str):
"""Converts a SNAKE_CASE string into a CamelCase string."""
return ''.join(s.lower().title() for s in snake_case_str.split('_'))
def generate_definitions(
lines, defined_type_name, go_type_name, description, output_none=False):
"""Generates Golang type definitions.
Args:
lines: List of strings that is read from a js file.
defined_type_name: Enum type name in a source file which is parsed here.
go_type_name: Enum type name to be generated as Golang definition.
description: A string that is used to generate a Go doc comment.
output_none: Whether or not to output an empty string as the "None" value.
"""
item_pattern = re.compile(r'\s*(\w*):\s\'(\w*)\'')
defs = []
reading = False
for l in lines:
if reading:
match = item_pattern.match(l)
if not match:
reading = False
break
defs.append((to_camel_case(match.group(1)), match.group(2)))
elif l.startswith('chrome.automation.%s' % defined_type_name):
reading = True
out = '// %s describes %s.\n' % (go_type_name, description)
out += 'type %s string\n\n' % go_type_name
out += '// As defined in https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/automation.idl\n'
out += 'const (\n'
for r in defs:
out += '\t%s %s = "%s"\n' % (r[0], go_type_name, r[1])
if output_none:
out += '\t%s %s = ""\n' % ("None", go_type_name)
out += ')\n'
return out
def generate_package(
lines,
parent_folder,
defined_type_name,
go_type_name,
description,
output_none=False):
"""Generates a Golang package for the constants.
Args:
lines: List of strings that is read from a js file.
parent_folder: A string with the path to the folder to generate the package in.
defined_type_name: Enum type name in a source file which is parsed here.
go_type_name: Enum type name to be generated as Golang definition.
description: A string that is used to generate a Go doc comment.
output_none: Whether or not to output an empty string as the "None" value.
"""
pkg_name = go_type_name.lower()
pkg_folder = os.path.join(parent_folder, pkg_name)
if not os.path.exists(pkg_folder):
os.makedirs(pkg_folder)
out = HEADER
out += '// Package %s describes %s.\n' % (pkg_name, description)
out += 'package %s\n\n' % pkg_name
out += generate_definitions(
lines, defined_type_name, go_type_name, description, output_none)
f = open(os.path.join(pkg_folder, 'constants.go'), 'w')
f.write(out)
f.close()
def main(argv):
f = open(argv[1], 'r')
lines = f.readlines()
f.close()
folder = argv[2]
generate_package(
lines, folder, 'StateType', 'State',
'characteristics of a chrome.automation AutomationNode')
generate_package(
lines, folder, 'RoleType', 'Role',
'the purpose of a chrome.automation AutomationNode')
generate_package(
lines, folder, 'EventType', 'Event',
'the type of a chrome.automation AutomationEvent')
generate_package(
lines, folder, 'Restriction', 'Restriction',
'the restriction state of a chrome.automation AutomationNode', True)
if __name__ == '__main__':
main(sys.argv)