"""Волна N+1 поверх vfbuild15 (13 ошибок). Запуск: python3 tools/waves_n1.py""" import os, sys, collections ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) JAVA = os.path.join(ROOT, "src/main/java") stats = collections.Counter() files = {} def get(rel): p = rel if os.path.isabs(rel) else os.path.join(JAVA, rel) if p not in files: files[p] = open(p, encoding="utf-8", errors="replace").read().splitlines() return files[p] def edit_line(rel, ln, old, new, tag="n"): L = get(rel) i = ln - 1 if i >= len(L): stats[tag + "_MISS"] += 1 print(f"MISS {rel}:{ln} (oob {len(L)})") return if old in L[i]: L[i] = L[i].replace(old, new, 1) stats[tag] += 1 elif new in L[i]: stats[tag + "_skip"] += 1 else: stats[tag + "_MISS"] += 1 print(f"MISS {rel}:{ln}: {old!r}\n got: {L[i].strip()!r}") def edit_all(rel, old, new, tag="n"): L = get(rel) c = 0 for i, l in enumerate(L): if old in l: L[i] = l.replace(old, new) c += 1 if c: stats[tag] += c elif any(new in l for l in L): stats[tag + "_skip"] += 1 else: stats[tag + "_MISS"] += 1 print(f"MISS-ALL {rel}: {old!r}") def insert_before(rel, ln, lines, tag="ins"): L = get(rel) i = ln - 1 if i > len(L): stats[tag + "_MISS"] += 1 print(f"INS-MISS {rel}:{ln} oob") return if lines[0] in L[max(0, i - 3) : i]: stats[tag + "_skip"] += 1 return L[i:i] = lines stats[tag] += len(lines) # line edits, per file descending EDIT_LINE_TABLE = [ ( "defpackage/yc.java", 1563, "if (var3x.getCategory() == var2) {", "if (var3x.getCategory() == var2f) {", ), ( "defpackage/yc.java", 1555, ".contains(var1)) ? 1 : 0;", ".contains(var1f)) ? 1 : 0;", ), ( "defpackage/yc.java", 258, "if (!var1.contains(var2x.getTheme())) {", "if (!var1f.contains(var2x.getTheme())) {", ), ( "defpackage/tf.java", 489, "new EntityHitResult(var2, var1x.getLocation())", "new EntityHitResult(var2, var1x)", ), ( "defpackage/tf.java", 482, "Optional var13 = null;", "Optional var13 = null;", ), ( "defpackage/tf.java", 279, "var16 = var15.clip(var2, var3).map(BlockHitResult::getLocation);", "var16 = var15.clip(var2, var3);", ), ( "defpackage/ans.java", 154, "ArrayList var4 = null;", "ArrayList var4 = null;", ), ( "defpackage/ach.java", 458, "Comparator.comparing(", "Comparator.comparing(", ), ( "b/t.java", 55, "(ParseResults)this.currentParse", "(ParseResults)(Object)this.currentParse", ), ( "b/t.java", 50, "this.currentParse = defpackage.bz.getInstance()", "this.currentParse = (ParseResults)(Object)defpackage.bz.getInstance()", ), ] # inserts (line numbers = pre-insert file; applied in descending order below) INSERTS = [ ( "defpackage/yc.java", 1547, [ " final String var1f = var1;", " final rl var2f = var2;", ], ), ("defpackage/yc.java", 231, [" final List var1f = var1;"]), ] CONTENT_EDITS = [ ("defpackage/alc.java", "private alc(", "alc("), ("defpackage/hh.java", "private double weight()", "double weight()"), ( "defpackage/uw.java", "private void render(VertexConsumer var1, Pose var2, Vec3 var3, long var4, long var6, boolean var8, boolean var9, float var10, uv var11)", "void render(VertexConsumer var1, Pose var2, Vec3 var3, long var4, long var6, boolean var8, boolean var9, float var10, uv var11)", ), ] def main(): # merge: all line-scope ops for same file in one descending pass ops = collections.defaultdict(list) for row in EDIT_LINE_TABLE: ops[row[0]].append(("edit", row[1], row[2], row[3])) for rel, ln, lines in INSERTS: ops[rel].append(("ins", ln, lines, None)) for rel, rows in ops.items(): for kind, ln, a, b in sorted(rows, key=lambda r: -r[1]): if kind == "edit": edit_line(rel, ln, a, b) else: insert_before(rel, ln, a) for rel, old, new in CONTENT_EDITS: edit_all(rel, old, new, "content") for p, L in files.items(): with open(p, "w", encoding="utf-8") as f: f.write("\n".join(L) + "\n") print(dict(stats)) miss = {k: v for k, v in stats.items() if "MISS" in k} if miss: print("PROBLEMS:", dict(miss)) sys.exit(1) if __name__ == "__main__": main()