f30f481525
Since most Torque-defined extern classes use @generateCppClass, it makes more sense to instead annotate the small number that don't. This is part of the cleanup work that Nico recommended in [1]. Classes that still have to opt out: - Those that can be converted by https://crrev.com/c/3015666 - HeapObject: sort of special since it's the root of the inheritance hierarchy. Generated code would include two declarations that don't compile until HeapObject is defined: bool IsHeapObject_NonInline(HeapObject o); explicit TorqueGeneratedHeapObject( Address ptr, HeapObject::AllowInlineSmiStorage allow_smi); - SmallOrdered*: these classes use templates on the C++ side, which is not currently representable in Torque. - SwissNameDictionary: according to a comment, the Torque generation for this class is incorrect. I haven't investigated further. Drive-by fix: make the Torque formatter keep LF on Windows rather than writing CRLF. [1] https://docs.google.com/document/d/1q_gZLnXd4bGnCx3IUfbln46K3bSs9UHBGasy9McQtHI/edit# Bug: v8:8952 Change-Id: I1fbb5290f0c645842b84c53816c09bb3398206a5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3028721 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/master@{#75841}
161 lines
5.6 KiB
Python
Executable File
161 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
# Copyright 2014 the V8 project 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 program either generates the parser files for Torque, generating
|
||
the source and header files directly in V8's src directory."""
|
||
|
||
# for py2/py3 compatibility
|
||
from __future__ import print_function
|
||
|
||
import subprocess
|
||
import sys
|
||
import re
|
||
from subprocess import Popen, PIPE
|
||
|
||
kPercentEscape = r'α'; # Unicode alpha
|
||
kDerefEscape = r'☆'; # Unicode star
|
||
kAddressofEscape = r'⌂'; # Unicode house
|
||
|
||
def preprocess(input):
|
||
# Special handing of '%' for intrinsics, turn the percent
|
||
# into a unicode character so that it gets treated as part of the
|
||
# intrinsic's name if it's already adjacent to it.
|
||
input = re.sub(r'%([A-Za-z])', kPercentEscape + r'\1', input)
|
||
# Similarly, avoid treating * and & as binary operators when they're
|
||
# probably used as address operators.
|
||
input = re.sub(r'([^/])\*([a-zA-Z(])', r'\1' + kDerefEscape + r'\2', input)
|
||
input = re.sub(r'&([a-zA-Z(])', kAddressofEscape + r'\1', input)
|
||
|
||
|
||
input = re.sub(r'(if\s+)constexpr(\s*\()', r'\1/*COxp*/\2', input)
|
||
input = re.sub(r'(\s+)operator\s*(\'[^\']+\')', r'\1/*_OPE \2*/', input)
|
||
input = re.sub(r'\btypeswitch\s*(\([^{]*\))\s{', r' if /*tPsW*/ \1 {', input)
|
||
input = re.sub(r'\bcase\s*(\([^{]*\))\s*:\s*deferred\s*{', r' if /*cAsEdEfF*/ \1 {', input)
|
||
input = re.sub(r'\bcase\s*(\([^{]*\))\s*:\s*{', r' if /*cA*/ \1 {', input)
|
||
|
||
input = re.sub(r'\bgenerates\s+\'([^\']+)\'\s*',
|
||
r'_GeNeRaTeS00_/*\1@*/', input)
|
||
input = re.sub(r'\bconstexpr\s+\'([^\']+)\'\s*',
|
||
r' _CoNsExP_/*\1@*/', input)
|
||
input = re.sub(r'\notherwise',
|
||
r'\n otherwise', input)
|
||
input = re.sub(r'(\n\s*\S[^\n]*\s)otherwise',
|
||
r'\1_OtheSaLi', input)
|
||
input = re.sub(r'@if\(', r'@iF(', input)
|
||
input = re.sub(r'@export', r'@eXpOrT', input)
|
||
input = re.sub(r'js-implicit[ \n]+', r'jS_iMpLiCiT_', input)
|
||
input = re.sub(r'^(\s*namespace\s+[a-zA-Z_0-9]+\s*{)(\s*)$', r'\1}\2', input, flags = re.MULTILINE)
|
||
|
||
# includes are not recognized, change them into comments so that the
|
||
# formatter ignores them first, until we can figure out a way to format cpp
|
||
# includes within a JS file.
|
||
input = re.sub(r'^#include', r'// InClUdE', input, flags=re.MULTILINE)
|
||
|
||
return input
|
||
|
||
def postprocess(output):
|
||
output = re.sub(r'\/\*COxp\*\/', r'constexpr', output)
|
||
output = re.sub(r'(\S+)\s*: type([,>])', r'\1: type\2', output)
|
||
output = re.sub(r'(\n\s*)labels( [A-Z])', r'\1 labels\2', output)
|
||
output = re.sub(r'\/\*_OPE \'([^\']+)\'\*\/', r"operator '\1'", output)
|
||
output = re.sub(r'\bif\s*\/\*tPsW\*\/', r'typeswitch', output)
|
||
output = re.sub(r'\bif\s*\/\*cA\*\/\s*(\([^{]*\))\s*{', r'case \1: {', output)
|
||
output = re.sub(r'\bif\s*\/\*cAsEdEfF\*\/\s*(\([^{]*\))\s*{', r'case \1: deferred {', output)
|
||
output = re.sub(r'\n_GeNeRaTeS00_\s*\/\*([^@]+)@\*\/',
|
||
r"\n generates '\1'", output)
|
||
output = re.sub(r'_GeNeRaTeS00_\s*\/\*([^@]+)@\*\/',
|
||
r"generates '\1'", output)
|
||
output = re.sub(r'_CoNsExP_\s*\/\*([^@]+)@\*\/',
|
||
r"constexpr '\1'", output)
|
||
output = re.sub(r'\n(\s+)otherwise',
|
||
r"\n\1 otherwise", output)
|
||
output = re.sub(r'\n(\s+)_OtheSaLi',
|
||
r"\n\1otherwise", output)
|
||
output = re.sub(r'_OtheSaLi',
|
||
r"otherwise", output)
|
||
output = re.sub(r'@iF\(', r'@if(', output)
|
||
output = re.sub(r'@eXpOrT',
|
||
r"@export", output)
|
||
output = re.sub(r'jS_iMpLiCiT_',
|
||
r"js-implicit ", output)
|
||
output = re.sub(r'}\n *label ', r'} label ', output);
|
||
output = re.sub(r'^(\s*namespace\s+[a-zA-Z_0-9]+\s*{)}(\s*)$', r'\1\2', output, flags = re.MULTILINE);
|
||
|
||
output = re.sub(kPercentEscape, r'%', output)
|
||
output = re.sub(kDerefEscape, r'*', output)
|
||
output = re.sub(kAddressofEscape, r'&', output)
|
||
|
||
|
||
output = re.sub( r'^// InClUdE',r'#include', output, flags=re.MULTILINE)
|
||
|
||
return output
|
||
|
||
def process(filename, lint, should_format):
|
||
with open(filename, 'r') as content_file:
|
||
content = content_file.read()
|
||
|
||
original_input = content
|
||
|
||
if sys.platform.startswith('win'):
|
||
p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
|
||
else:
|
||
p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||
output, err = p.communicate(preprocess(content))
|
||
output = postprocess(output)
|
||
rc = p.returncode
|
||
if (rc != 0):
|
||
print("error code " + str(rc) + " running clang-format. Exiting...")
|
||
sys.exit(rc);
|
||
|
||
if (output != original_input):
|
||
if lint:
|
||
print(filename + ' requires formatting', file=sys.stderr)
|
||
|
||
if should_format:
|
||
output_file = open(filename, 'wb')
|
||
output_file.write(output);
|
||
output_file.close()
|
||
|
||
def print_usage():
|
||
print('format-torque -i file1[, file2[, ...]]')
|
||
print(' format and overwrite input files')
|
||
print('format-torque -l file1[, file2[, ...]]')
|
||
print(' merely indicate which files need formatting')
|
||
|
||
def Main():
|
||
if len(sys.argv) < 3:
|
||
print("error: at least 2 arguments required")
|
||
print_usage();
|
||
sys.exit(-1)
|
||
|
||
def is_option(arg):
|
||
return arg in ['-i', '-l', '-il']
|
||
|
||
should_format = lint = False
|
||
use_stdout = True
|
||
|
||
flag, files = sys.argv[1], sys.argv[2:]
|
||
if is_option(flag):
|
||
if '-i' == flag:
|
||
should_format = True
|
||
elif '-l' == flag:
|
||
lint = True
|
||
else:
|
||
lint = True
|
||
should_format = True
|
||
else:
|
||
print("error: -i and/or -l flags must be specified")
|
||
print_usage();
|
||
sys.exit(-1);
|
||
|
||
for filename in files:
|
||
process(filename, lint, should_format)
|
||
|
||
return 0
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(Main());
|