-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathrefactor-check-compiles.py
executable file
·116 lines (100 loc) · 3.51 KB
/
refactor-check-compiles.py
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
#!/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()