Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/tools/patchtests.py
2723 views
1
#!/usr/bin/python3
2
# This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
3
4
# This code can be used to patch Compiler.test.cpp following bytecode changes, based on error output
5
import sys
6
import re
7
8
(_, filename) = sys.argv
9
input = sys.stdin.readlines()
10
11
errors = []
12
13
# 0: looking for error, 1: looking for replacement, 2: collecting replacement, 3: collecting initial text
14
state = 0
15
16
# parse input into errors[] with the state machine; this is using doctest output and expects multi-line match failures
17
for line in input:
18
if state == 0:
19
if sys.platform == "win32":
20
match = re.match("[^(]+\((\d+)\): ERROR: CHECK_EQ", line)
21
else:
22
match = re.match("tests/[^:]+:(\d+): ERROR: CHECK_EQ", line)
23
24
if match:
25
error_line = int(match[1])
26
state = 1
27
elif state == 1:
28
if re.match("\s*values: CHECK_EQ\(\s*$", line):
29
error_repl = []
30
state = 2
31
elif re.match("\s*values: CHECK_EQ", line):
32
state = 0 # skipping single-line checks since we can't patch them
33
elif state == 2:
34
if line.strip() == ",":
35
error_orig = []
36
state = 3
37
else:
38
error_repl.append(line)
39
elif state == 3:
40
if line.strip() == ")":
41
errors.append((error_line, error_orig, error_repl))
42
state = 0
43
else:
44
error_orig.append(line)
45
46
# make sure we fully process each individual check
47
assert(state == 0)
48
49
errors.sort(key = lambda e: e[0])
50
51
with open(filename, "r") as fp:
52
source = fp.readlines()
53
54
# patch source text into result[] using errors[]; we expect every match to appear at or after the line error was reported at
55
result = []
56
57
current = 0
58
index = 0
59
target = 0
60
61
while index < len(source):
62
line = source[index]
63
error = errors[current] if current < len(errors) else None
64
65
if error:
66
target = error[0] if sys.platform != "win32" else error[0] - len(error[1]) - 1
67
68
if not error or index < target or line != error[1][0]:
69
result.append(line)
70
index += 1
71
else:
72
# validate that the patch has a complete match in source text
73
for v in range(len(error[1])):
74
assert(source[index + v] == error[1][v])
75
76
result += error[2]
77
index += len(error[1])
78
current += 1
79
80
# make sure we patch all errors
81
assert(current == len(errors))
82
83
with open(filename, "w") as fp:
84
fp.writelines(result)
85
86