Files
swift-mirror/utils/refactor-check-compiles.py
Ben Barham 762337cc9b [Refactoring] Add @completionHandlerAsync to sync function
When adding an async alternative, add the @completionHandlerAsync
attribute to the sync function. Check for this attribute in addition to
the name check, ie. convert a call if the callee has either
@completionHandlerAsync or a name that is completion-handler-like name.

The addition of the attribute is currently gated behind the experimental
concurrency flag.

Resolves rdar://77486504
2021-05-14 20:19:02 +10:00

117 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python
from __future__ import print_function
import argparse
import os
import subprocess
import sys
def run_cmd(cmd, desc):
try:
return subprocess.check_output(cmd)
except subprocess.CalledProcessError:
print('FAILED ' + desc + ':', file=sys.stderr)
print(' '.join(cmd), file=sys.stderr)
sys.exit(1)
def parse_args():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""
A drop-in replacement for a 'swift-refactor -dump-text' call that
1. Checks that the file still compiles after the refactoring by doing
'swift-refactor -dump-rewritten' and feeding the result to
'swift-frontend -typecheck'
2. Outputting the result of the 'swift-refactor -dump-text' call
All arguments other than the following will be forwarded to
'swift-refactor':
- swift-frontend
- swift-refactor
- temp-dir
- enable-experimental-concurrency (sent to both)
""")
parser.add_argument(
'-swift-frontend',
help='The path to the swift-frontend executable'
)
parser.add_argument(
'-swift-refactor',
help='The path to the swift-refactor executable'
)
parser.add_argument(
'-temp-dir',
help='A temporary directory to save the rewritten file in'
)
parser.add_argument(
'-dump-text',
action='store_true',
help='''
Required argument to indicate that the outputted text will be that of
swift-refactor -dump-text. This makes this script a drop-in replacement.
'''
)
parser.add_argument(
'-source-filename',
help='The file to refactor'
)
parser.add_argument(
'-pos',
help='The position to invoke the refactoring at'
)
parser.add_argument(
'-enable-experimental-concurrency',
action='store_true',
help='''
Whether to enable experimental concurrency in both swift-refactor and
swift-frontend
'''
)
return parser.parse_known_args()
def main():
(args, extra_refactor_args) = parse_args()
temp_file_name = os.path.split(args.source_filename)[-1] + '.' + \
args.pos.replace(':', '.')
temp_file_path = os.path.join(args.temp_dir, temp_file_name)
extra_frontend_args = []
if args.enable_experimental_concurrency:
extra_refactor_args.append('-enable-experimental-concurrency')
extra_frontend_args.append('-enable-experimental-concurrency')
# FIXME: `refactor-check-compiles` should generate both `-dump-text` and
# `dump-rewritten` from a single `swift-refactor` invocation (SR-14587).
dump_text_output = run_cmd([
args.swift_refactor,
'-dump-text',
'-source-filename', args.source_filename,
'-pos', args.pos
] + extra_refactor_args, desc='producing edit').decode("utf-8")
dump_rewritten_output = run_cmd([
args.swift_refactor,
'-dump-rewritten',
'-source-filename', args.source_filename,
'-pos', args.pos
] + extra_refactor_args, desc='producing rewritten file')
with open(temp_file_path, 'wb') as f:
f.write(dump_rewritten_output)
run_cmd([
args.swift_frontend,
'-typecheck',
temp_file_path,
'-disable-availability-checking'
] + extra_frontend_args, desc='checking that rewritten file compiles')
sys.stdout.write(dump_text_output)
if __name__ == '__main__':
main()