mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Looks like flake8 enables other rules when you add something to the exclusion list. We added W291
182 lines
6.5 KiB
Python
Executable File
182 lines
6.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function, unicode_literals
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
logging.basicConfig(format='%(message)s', level=logging.INFO)
|
|
|
|
|
|
class RoundTripTask(object):
|
|
def __init__(self, input_filename, action, swift_syntax_test,
|
|
skip_bad_syntax):
|
|
assert action == '-round-trip-parse' or action == '-round-trip-lex'
|
|
assert type(input_filename) == unicode
|
|
assert type(swift_syntax_test) == str
|
|
|
|
assert os.path.isfile(input_filename), \
|
|
"Input file {} is not accessible!".format(input_filename)
|
|
assert os.path.isfile(swift_syntax_test), \
|
|
"{} tool is not accessible!".format(swift_syntax_test)
|
|
self.input_filename = input_filename
|
|
self.action = action
|
|
self.swift_syntax_test = swift_syntax_test
|
|
self.skip_bad_syntax = skip_bad_syntax
|
|
self.returncode = None
|
|
self.stdout = None
|
|
self.stderr = None
|
|
|
|
@property
|
|
def test_command(self):
|
|
return [self.swift_syntax_test, self.action,
|
|
'-input-source-filename', self.input_filename]
|
|
|
|
@property
|
|
def diff_command(self):
|
|
return ['/usr/bin/diff', '-u', self.input_filename, '-']
|
|
|
|
def diff(self):
|
|
logging.debug(' '.join(self.diff_command))
|
|
diff = subprocess.Popen(self.diff_command, stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
stdout, stderr = diff.communicate(self.stdout)
|
|
if diff.returncode != 0:
|
|
return stdout
|
|
assert stdout == ''
|
|
assert stderr == ''
|
|
return None
|
|
|
|
def run(self):
|
|
command = self.test_command
|
|
logging.debug(' '.join(command))
|
|
self.output_file = tempfile.NamedTemporaryFile('w')
|
|
self.stderr_file = tempfile.NamedTemporaryFile('w')
|
|
|
|
process = subprocess.Popen(command, stdout=self.output_file,
|
|
stderr=self.stderr_file)
|
|
process.wait()
|
|
self.returncode = process.returncode
|
|
|
|
with open(self.output_file.name, 'r') as stdout_in:
|
|
self.stdout = stdout_in.read()
|
|
with open(self.stderr_file.name, 'r') as stderr_in:
|
|
self.stderr = stderr_in.read()
|
|
|
|
self.output_file.flush()
|
|
self.stderr_file.flush()
|
|
|
|
try:
|
|
if self.returncode != 0:
|
|
if self.skip_bad_syntax:
|
|
logging.warning('---===WARNING===--- Lex/parse had error'
|
|
' diagnostics, so not diffing. Skipping'
|
|
' this file due to -skip-bad-syntax.')
|
|
logging.error(' '.join(command))
|
|
return None
|
|
else:
|
|
logging.error('---===ERROR===--- Lex/parse had error'
|
|
' diagnostics, so not diffing.')
|
|
logging.error(' '.join(command))
|
|
logging.error(self.stdout)
|
|
logging.error(self.stderr)
|
|
raise RuntimeError()
|
|
finally:
|
|
self.output_file.close()
|
|
self.stderr_file.close()
|
|
|
|
diff = self.diff()
|
|
return diff
|
|
|
|
|
|
def swift_files_in_dir(d):
|
|
swift_files = []
|
|
for root, dirs, files in os.walk(d):
|
|
for basename in files:
|
|
if not basename.decode('utf-8').endswith('.swift'):
|
|
continue
|
|
abs_file = os.path.abspath(os.path.join(root, basename))
|
|
swift_files.append(abs_file)
|
|
return swift_files
|
|
|
|
|
|
def run_task(task):
|
|
try:
|
|
diff = task.run()
|
|
if diff is not None:
|
|
logging.error('---===ERROR===--- Diff failed!')
|
|
logging.error(' '.join(task.test_command))
|
|
logging.error(diff)
|
|
logging.error('')
|
|
return True
|
|
except RuntimeError as e:
|
|
logging.error(e.message)
|
|
return True
|
|
return False
|
|
|
|
|
|
def main():
|
|
tool_description = '''
|
|
Checks for round-trip lex/parse/print compatibility.
|
|
|
|
Swift's syntax representation should be "full-fidelity", meaning that there is
|
|
a perfect representation of what is in the source. When printing a syntax tree
|
|
to a file, that file should be identical to the file that was
|
|
originally parsed.
|
|
|
|
This driver invokes swift-syntax-test using -round-trip-lex and
|
|
-round-trip-parse on .swift files and .swift files in directories.
|
|
'''
|
|
parser = argparse.ArgumentParser(description=tool_description)
|
|
parser.add_argument('--directory', '-d', action='append',
|
|
dest='input_directories', default=[],
|
|
help='Add a directory, searching for .swift files'
|
|
' within')
|
|
parser.add_argument('--file', '-f', action='append',
|
|
dest='individual_input_files', default=[],
|
|
help='Add an individual file to test')
|
|
parser.add_argument('--swift-syntax-test', '-t', required=True,
|
|
dest='tool_path',
|
|
help='Absolute path to the swift-syntax-test tool')
|
|
parser.add_argument('--skip-bad-syntax',
|
|
action='store_true',
|
|
default=False,
|
|
help="Skip files that caused lex or parse diagnostics"
|
|
" to be emitted")
|
|
|
|
args = parser.parse_args()
|
|
|
|
dir_listings = [swift_files_in_dir(d) for d in args.input_directories]
|
|
all_input_files = [filename for dir_listing in dir_listings
|
|
for filename in dir_listing]
|
|
all_input_files += args.individual_input_files
|
|
all_input_files = [f.decode('utf-8') for f in all_input_files]
|
|
|
|
if len(all_input_files) == 0:
|
|
logging.error('No input files!')
|
|
sys.exit(1)
|
|
|
|
if not os.path.isfile(args.tool_path):
|
|
raise RuntimeError("Couldn't find swift-syntax-test at {}"
|
|
.format(args.tool_path))
|
|
|
|
lex_tasks = [RoundTripTask(filename, '-round-trip-lex', args.tool_path,
|
|
args.skip_bad_syntax)
|
|
for filename in all_input_files]
|
|
parse_tasks = [RoundTripTask(filename, '-round-trip-parse', args.tool_path,
|
|
args.skip_bad_syntax)
|
|
for filename in all_input_files]
|
|
|
|
failed = reduce(lambda a, b: a and b,
|
|
map(run_task, lex_tasks + parse_tasks))
|
|
sys.exit(1 if failed else 0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|