1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
def run_cmd(cmd, desc):
try:
return subprocess.check_output(cmd, universal_newlines=True)
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 -disable-availability-checking
-warn-on-editor-placeholder'
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)
- I (sent to both)
- sdk (sent to both)
- target (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
'''
)
parser.add_argument(
'-I',
action='append',
help='Add a directory to the import search path'
)
parser.add_argument(
'-sdk',
help='Path to the SDK to build against'
)
parser.add_argument(
'-target',
help='The target triple to build for'
)
parser.add_argument(
'-resource-dir',
help='The resource dir where the stdlib is stored')
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_both_args = []
if args.enable_experimental_concurrency:
extra_both_args.append('-enable-experimental-concurrency')
if args.I:
for path in args.I:
extra_both_args += ['-I', path]
if args.sdk:
extra_both_args += ['-sdk', args.sdk]
if args.target:
extra_both_args += ['-target', args.target]
if args.resource_dir:
extra_both_args += ['-resource-dir', args.resource_dir]
dump_text_output = run_cmd([
args.swift_refactor,
'-dump-text',
'-source-filename', args.source_filename,
'-rewritten-output-file', temp_file_path,
'-pos', args.pos
] + extra_refactor_args + extra_both_args, desc='producing edit')
sys.stdout.write(dump_text_output)
run_cmd([
args.swift_frontend,
'-typecheck',
temp_file_path,
'-disable-availability-checking',
'-warn-on-editor-placeholder'
] + extra_both_args, desc='checking that rewritten file compiles')
if __name__ == '__main__':
main()
|