Skip to content

Commit d14eab8

Browse files
authored
Merge pull request #9699 from github/redsun82/swift-stop-stub-reverts
Swift: yet another fix to stub revert prevention
2 parents f539be3 + bc44007 commit d14eab8

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

swift/codegen/generators/qlgen.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import logging
44
import pathlib
5+
import re
56
import subprocess
67
import typing
8+
import itertools
79

810
import inflection
911

@@ -93,7 +95,10 @@ def get_classes_used_by(cls: ql.Class):
9395
return sorted(set(t for t in get_types_used_by(cls) if t[0].isupper()))
9496

9597

96-
def _is_generated_stub(file, check_modification=False):
98+
_generated_stub_re = re.compile(r"private import .*\n\nclass \w+ extends \w+ \{[ \n]\}", re.MULTILINE)
99+
100+
101+
def _is_generated_stub(file):
97102
with open(file) as contents:
98103
for line in contents:
99104
if not line.startswith("// generated"):
@@ -102,12 +107,12 @@ def _is_generated_stub(file, check_modification=False):
102107
else:
103108
# no lines
104109
return False
105-
if check_modification:
106-
# one line already read, if we can read 5 other we are past the normal stub generation
107-
line_threshold = 5
108-
if sum(1 for _ in zip(range(line_threshold), contents)) == line_threshold:
109-
raise ModifiedStubMarkedAsGeneratedError(
110-
f"{file.name} stub was modified but is still marked as generated")
110+
# one line already read, if we can read 5 other we are past the normal stub generation
111+
line_threshold = 5
112+
first_lines = list(itertools.islice(contents, line_threshold))
113+
if len(first_lines) == line_threshold or not _generated_stub_re.match("".join(first_lines)):
114+
raise ModifiedStubMarkedAsGeneratedError(
115+
f"{file.name} stub was modified but is still marked as generated")
111116
return True
112117

113118

@@ -157,8 +162,9 @@ def generate(opts, renderer):
157162
stub_out = opts.ql_stub_output
158163
test_out = opts.ql_test_output
159164
missing_test_source_filename = "MISSING_SOURCE.txt"
165+
160166
existing = {q for q in out.rglob("*.qll")}
161-
existing |= {q for q in stub_out.rglob("*.qll") if _is_generated_stub(q, check_modification=True)}
167+
existing |= {q for q in stub_out.rglob("*.qll") if _is_generated_stub(q)}
162168
existing |= {q for q in test_out.rglob("*.ql")}
163169
existing |= {q for q in test_out.rglob(missing_test_source_filename)}
164170

swift/codegen/test/test_qlgen.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def test_non_empty_cleanup(opts, generate, renderer):
366366
test_c = opts.ql_test_output / "B.txt"
367367
write(ql_a)
368368
write(ql_b)
369-
write(stub_a, "// generated\nfoo\n")
369+
write(stub_a, "// generated\nprivate import bla\n\nclass foo extends bar {\n}\n")
370370
write(stub_b, "bar\n")
371371
write(test_a)
372372
write(test_b)
@@ -378,7 +378,15 @@ def test_non_empty_cleanup(opts, generate, renderer):
378378

379379
def test_modified_stub_still_generated(qlgen_opts, renderer):
380380
stub = qlgen_opts.ql_stub_output / "A.qll"
381-
write(stub, "// generated\nprivate import foo\n\nclass Bar extends BarBase {\n int x() { none() }\n}\n")
381+
write(stub, "// generated\nprivate import bla\n\nclass foo extends bar, baz {\n}\n")
382+
with pytest.raises(qlgen.ModifiedStubMarkedAsGeneratedError):
383+
run_generation(qlgen.generate, qlgen_opts, renderer)
384+
385+
386+
def test_extended_stub_still_generated(qlgen_opts, renderer):
387+
stub = qlgen_opts.ql_stub_output / "A.qll"
388+
write(stub,
389+
"// generated\nprivate import bla\n\nclass foo extends bar {\n}\n\nclass other {\n other() { none() }\n}")
382390
with pytest.raises(qlgen.ModifiedStubMarkedAsGeneratedError):
383391
run_generation(qlgen.generate, qlgen_opts, renderer)
384392

0 commit comments

Comments
 (0)