evo/tools/waves_ghik.py

885 lines
28 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Волны поверх vfbuild13: G=retype+usage-cast, H=for-each/toArray, I=this-cast+text,
J=(Object[])→float[], K=int/boolean, M=структурные (nb, Cif, sh, Pair, импорты).
Таблицы жёстко привязаны к номерам строк vfbuild13. Все line-правки применяются
по убыванию номера строки внутри файла. Запуск: python3 tools/waves_ghik.py
"""
import re, 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):
L = get(rel)
i = ln - 1
if i >= len(L):
stats[tag + "_MISS"] += 1
print(f"MISS {rel}:{ln} (file has {len(L)} lines)")
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):
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
else:
if any(new in l for l in L):
stats[tag + "_skip"] += 1
else:
stats[tag + "_MISS"] += 1
print(f"MISS-ALL {rel}: {old!r}")
DECL_PAT = lambda var: re.compile(
r"^\s*[A-Za-z_][\w.\[\]<>]*\s+%s\s*=" % re.escape(var)
)
def find_decl(rel, ln, var):
"""Индекс строки-декларации `Type var = ...` выше ln в пределах метода."""
L = get(rel)
i = ln - 2
pat = DECL_PAT(var)
while i >= 0:
l = L[i]
if l.strip() and (len(l) - len(l.lstrip())) <= 3:
return None
if pat.match(l):
return i
i -= 1
return None
def retype(rel, err_ln, var, newtype, tag):
idx = find_decl(rel, err_ln, var)
if idx is None:
stats[tag + "_MISS"] += 1
print(f"DECL-MISS {rel}:{err_ln} var={var}")
return
L = get(rel)
old = L[idx]
L[idx] = re.sub(
r"^(\s*)[A-Za-z_][\w.\[\]<>]*\s+%s\s*=" % re.escape(var),
r"\g<1>%s %s =" % (newtype, var),
old,
count=1,
)
if L[idx] == old and ("%s %s =" % (newtype, var)) in old:
stats[tag + "_skip"] += 1
elif L[idx] == old:
stats[tag + "_MISS"] += 1
print(f"RETYPE-MISS {rel}:{idx + 1}: {old!r}")
else:
stats[tag] += 1
def cast_usage(rel, ln, var, ctype, tag):
L = get(rel)
i = ln - 1
if i >= len(L):
stats[tag + "_MISS"] += 1
print(f"CAST-MISS {rel}:{ln} (oob)")
return
needle = "%s." % var
already = "((%s)%s)." % (ctype, var)
if already in L[i]:
stats[tag + "_skip"] += 1
return
if needle not in L[i]:
stats[tag + "_MISS"] += 1
print(f"CAST-MISS {rel}:{ln}: {needle!r}\n got: {L[i].strip()!r}")
return
L[i] = L[i].replace(needle, "((%s)%s)." % (ctype, var))
stats[tag] += 1
FOREACH_PAT = re.compile(r"^(.*\bfor \()([A-Za-z_][\w.\[\]]*) (\w+) : (.*)$")
PRIM = {
"long": "Long",
"int": "Integer",
"double": "Double",
"float": "Float",
"boolean": "Boolean",
"char": "Character",
"byte": "Byte",
"short": "Short",
}
def foreach_cast(rel, ln, tag):
L = get(rel)
i = ln - 1
if i >= len(L):
stats[tag + "_MISS"] += 1
print(f"FE-MISS {rel}:{ln} (oob)")
return
l = L[i]
if "(Iterable<" in l:
stats[tag + "_skip"] += 1
return
m = FOREACH_PAT.match(l)
if not m:
stats[tag + "_MISS"] += 1
print(f"FE-MISS {rel}:{ln}: {l.strip()!r}")
return
pfx, typ, var, rest = m.groups()
ityp = PRIM.get(typ, typ)
L[i] = f"{pfx}{typ} {var} : (Iterable<{ityp}>){rest}"
stats[tag] += 1
def wrap_assign_rhs(rel, ln, tag):
"""Обернуть RHS бинарного присваивающего оператора в `(EXPR) ? 1 : 0` перед `;`."""
L = get(rel)
i = ln - 1
if i >= len(L) or "? 1 : 0" in L[i]:
if i < len(L) and "? 1 : 0" in L[i]:
stats[tag + "_skip"] += 1
return
depth = 0
for j in range(i, len(L)):
for k, ch in enumerate(L[j]):
if ch in "([{":
depth += 1
elif ch in ")]}":
depth -= 1
elif ch == ";" and depth == 0:
L[j] = L[j][:k] + " ? 1 : 0" + L[j][k:]
stats[tag] += 1
return
stats[tag + "_MISS"] += 1
print(f"WRAP-MISS {rel}:{ln}")
def insert_after(rel, anchor, newline, tag):
L = get(rel)
if newline in L:
stats[tag + "_skip"] += 1
return
for i, l in enumerate(L):
if l.strip() == anchor:
L.insert(i + 1, newline)
stats[tag] += 1
return
stats[tag + "_MISS"] += 1
print(f"IMPORT-MISS {rel}: anchor {anchor!r}")
# ============================ G: retype ============================
# (rel, err_line, var, newtype)
RETYPE = [
("defpackage/gq.java", 88, "var2x", "Int2FloatMap"),
("defpackage/ed.java", 345, "var7", "File"),
("defpackage/acf.java", 187, "var8", "String"),
("defpackage/acf.java", 586, "var1", "Optional<ModContainer>"),
("defpackage/ajq.java", 135, "var4", "Info"),
("defpackage/akz.java", 126, "var5", "File"),
("defpackage/akz.java", 802, "var9", "String"),
("defpackage/aua.java", 251, "var19", "Vertex"),
("defpackage/aua.java", 276, "var15", "Polygon"),
("defpackage/auv.java", 359, "var8", "Direction"),
("defpackage/bt.java", 20, "var4", "Method"),
("defpackage/bx.java", 19, "var5", "Method"),
("defpackage/cc.java", 18, "var4", "Field"),
("defpackage/op.java", 1334, "var4", "od"),
("defpackage/qs.java", 1269, "var5", "ItemStack"),
("defpackage/im.java", 66, "var5", "StackTraceElement"),
("defpackage/cm.java", 178, "var5", "String"),
("defpackage/mw.java", 573, "var9", "Enum"),
("defpackage/aah.java", 2471, "var11", "ArrayList<aeb>"),
("defpackage/aah.java", 1115, "var3", "ArrayList<float[]>"),
("defpackage/aah.java", 1291, "var3", "ArrayList<float[]>"),
("defpackage/aah.java", 1504, "var3", "ArrayList<float[]>"),
("defpackage/aah.java", 1813, "var3", "ArrayList<float[]>"),
("defpackage/ahn.java", 751, "var22", "ArrayList<float[]>"),
("defpackage/je.java", 447, "var1", "ArrayList<long[]>"),
("defpackage/je.java", 431, "var9", "ArrayList<Long>"),
("defpackage/jz.java", 60, "var1", "ArrayList<long[]>"),
("defpackage/jz.java", 50, "var9", "ArrayList<Long>"),
("defpackage/ms.java", 197, "var8", "Object"),
("defpackage/auk.java", 65, "var2", "Set<Float>"),
("defpackage/auk.java", 114, "var2", "Set<Float>"),
]
# ======================= G2: usage-casts =======================
# (rel, line, var, casttype)
CASTS = [
# ms (merged slots; var8 retype to Object + ItemStack casts)
("defpackage/ms.java", 175, "var5", "Iterator"),
("defpackage/ms.java", 182, "var7", "Iterator"),
("defpackage/ms.java", 189, "var6", "Iterator"),
("defpackage/ms.java", 196, "var6", "Iterator"),
("defpackage/ms.java", 197, "var7", "Entry"),
("defpackage/ms.java", 198, "var5", "List"),
("defpackage/ms.java", 200, "var7", "Entry"),
("defpackage/ms.java", 219, "var7", "Iterator"),
("defpackage/ms.java", 229, "var5", "Iterator"),
# ahn
("defpackage/ahn.java", 272, "var2", "Iterator"),
("defpackage/ahn.java", 279, "var2", "Iterator"),
("defpackage/ahn.java", 284, "var3", "Iterator"),
("defpackage/ahn.java", 292, "var2", "List"),
("defpackage/ahn.java", 301, "var2", "List"),
("defpackage/ahn.java", 312, "var3", "Iterator"),
# aid (JsonArray | Iterator)
("defpackage/aid.java", 280, "var5", "Iterator"),
("defpackage/aid.java", 287, "var5", "Iterator"),
("defpackage/aid.java", 302, "var5", "JsonArray"),
("defpackage/aid.java", 303, "var5", "JsonArray"),
("defpackage/aid.java", 304, "var5", "JsonArray"),
("defpackage/aid.java", 309, "var5", "JsonArray"),
("defpackage/aid.java", 310, "var5", "JsonArray"),
("defpackage/aid.java", 311, "var5", "JsonArray"),
# adv (Entry)
("defpackage/adv.java", 907, "var8", "Entry"),
("defpackage/adv.java", 908, "var8", "Entry"),
("defpackage/adv.java", 938, "var8", "Entry"),
# gt (Iterator)
("defpackage/gt.java", 504, "var21", "Iterator"),
("defpackage/gt.java", 513, "var21", "Iterator"),
]
# ms: профилактические касты после retype var8→Object (строки не в логе ошибок)
MS_EXTRA = [
(220, "stackKey(var8)", "stackKey((ItemStack)var8)"),
(222, "var8.getItem()", "((ItemStack)var8).getItem()"),
(223, "= var3.computeIfAbsent(var9,", "= (long[])var3.computeIfAbsent(var9,"),
(225, "var8.getCount()", "((ItemStack)var8).getCount()"),
]
# ============================ H: for-each ============================
# (rel, line)
FOREACH = [
("defpackage/aah.java", 190),
("defpackage/aah.java", 1819),
("defpackage/aaj.java", 659),
("defpackage/aaj.java", 663),
("defpackage/aaj.java", 1970),
("defpackage/aaj.java", 1978),
("defpackage/aaj.java", 1989),
("defpackage/abs.java", 141),
("defpackage/afp.java", 547),
("defpackage/afp.java", 558),
("defpackage/afp.java", 581),
("defpackage/afp.java", 592),
("defpackage/ahf.java", 436),
("defpackage/ahi.java", 217),
("defpackage/aiq.java", 181),
("defpackage/aiq.java", 190),
("defpackage/akd.java", 44),
("defpackage/ajx.java", 105),
("defpackage/akt.java", 828),
("defpackage/ald.java", 105),
("defpackage/an.java", 76),
("defpackage/anb.java", 574),
("defpackage/anb.java", 623),
("defpackage/anb.java", 632),
("defpackage/anb.java", 636),
("defpackage/anb.java", 687),
("defpackage/ans.java", 759),
("defpackage/hl.java", 94),
("defpackage/hl.java", 170),
("defpackage/hn.java", 565),
("defpackage/j.java", 495),
("defpackage/j.java", 502),
("defpackage/je.java", 431),
("defpackage/jt.java", 255),
("defpackage/jt.java", 276),
("defpackage/jt.java", 342),
("defpackage/jz.java", 50),
("defpackage/ka.java", 78),
("defpackage/ko.java", 48),
("defpackage/ko.java", 55),
("defpackage/mk.java", 132),
("defpackage/mr.java", 48),
("defpackage/ql.java", 32),
("defpackage/ri.java", 1249),
("defpackage/ue.java", 1449),
("defpackage/uq.java", 252),
("defpackage/uq.java", 269),
("defpackage/vp.java", 885),
("defpackage/ado.java", 147),
]
# ==================== H2: toArray cast result ====================
# (rel, line, old, new)
TOARRAY = [
(
"defpackage/ahi.java",
131,
"var3.toArray(new aho[0])",
"(aho[])var3.toArray(new aho[0])",
),
(
"defpackage/ahi.java",
327,
"var1.values().toArray(new String[0])",
"(String[])var1.values().toArray(new String[0])",
),
(
"defpackage/akz.java",
449,
"var44.toArray(new BlockState[0])",
"(BlockState[])var44.toArray(new BlockState[0])",
),
(
"defpackage/akz.java",
522,
"var20.toArray(new BlockState[0])",
"(BlockState[])var20.toArray(new BlockState[0])",
),
(
"defpackage/akz.java",
586,
"var7.toArray(new BlockState[0])",
"(BlockState[])var7.toArray(new BlockState[0])",
),
(
"defpackage/ald.java",
127,
"var6.toArray(new BakedQuad[0])",
"(BakedQuad[])var6.toArray(new BakedQuad[0])",
),
(
"defpackage/aua.java",
101,
"var1.toArray(new ModelPart[0])",
"(ModelPart[])var1.toArray(new ModelPart[0])",
),
]
# ====================== I: this-cast миксины ======================
# (rel, line, old, new)
THISCAST = [
("b/ag.java", 16, "(LocalPlayer)this", "(LocalPlayer)(Object)this"),
("b/ap.java", 27, "(TitleScreen)this", "(TitleScreen)(Object)this"),
(
"b/bd.java",
17,
"this instanceof ModelFeatureRenderer",
"((Object)this) instanceof ModelFeatureRenderer",
),
("b/be.java", 17, "(Screen)this", "(Screen)(Object)this"),
(
"b/bm.java",
89,
"this instanceof InventoryScreen",
"((Object)this) instanceof InventoryScreen",
),
(
"b/bp.java",
55,
"(AbstractContainerScreen<?>)this",
"(AbstractContainerScreen<?>)(Object)this",
),
(
"b/bp.java",
67,
"(AbstractContainerScreen<?>)this",
"(AbstractContainerScreen<?>)(Object)this",
),
(
"b/bp.java",
74,
"(AbstractContainerScreen<?>)this",
"(AbstractContainerScreen<?>)(Object)this",
),
(
"b/br.java",
32,
"(AbstractContainerScreen<?>)this",
"(AbstractContainerScreen<?>)(Object)this",
),
("b/bt.java", 17, "this != mc.player", "(Object)this != mc.player"),
("b/bt.java", 22, "this == mc.player", "(Object)this == mc.player"),
("b/bt.java", 29, "this == mc.player", "(Object)this == mc.player"),
(
"b/bu.java",
28,
"this instanceof LocalPlayer player",
"((Object)this) instanceof LocalPlayer player",
),
(
"b/bu.java",
39,
"this instanceof LocalPlayer player",
"((Object)this) instanceof LocalPlayer player",
),
("b/bu.java", 48, "(Player)this", "(Player)(Object)this"),
(
"b/cb.java",
30,
"(RenderLayer<AvatarRenderState, PlayerModel>)this",
"(RenderLayer<AvatarRenderState, PlayerModel>)(Object)this",
),
("b/cv.java", 15, "(PlayerModel)this", "(PlayerModel)(Object)this"),
(
"b/dd.java",
22,
"this instanceof ClientLevel",
"((Object)this) instanceof ClientLevel",
),
(
"b/dd.java",
83,
"!(this instanceof ClientLevel)",
"!(((Object)this) instanceof ClientLevel)",
),
(
"b/q.java",
18,
"(AbstractClientPlayer)this",
"(AbstractClientPlayer)(Object)this",
),
("b/z.java", 20, "this == mc.player", "(Object)this == mc.player"),
(
"b/z.java",
30,
"this instanceof LocalPlayer",
"((Object)this) instanceof LocalPlayer",
),
(
"b/z.java",
35,
"this instanceof LocalPlayer",
"((Object)this) instanceof LocalPlayer",
),
("b/bg.java", 83, "((aqe)line.parent())", "((aqe)(Object)line.parent())"),
("a/f.java", 137, "this == Minecraft.getInstance().player", "(Object)this == Minecraft.getInstance().player"),
]
# =================== I2: квалификации/одиночные ===================
# (rel, line, old, new)
TEXTC = [
("b/bx.java", 27, "defpackage.defpackage.bz", "defpackage.bz"),
("b/t.java", 49, "defpackage.defpackage.bz", "defpackage.bz"),
("b/cr.java", 18, "((defpackage.b.ck)this)", "((ck)this)"),
(
"b/dd.java",
18,
"private final ct evo$smoothSkipAnim",
"private final defpackage.ct evo$smoothSkipAnim",
),
(
"b/z.java",
40,
"bz evolution = defpackage.bz.getInstance()",
"defpackage.bz evolution = defpackage.bz.getInstance()",
),
("a/o.java", 62, "((b.l)this)", "((l)this)"),
("defpackage/sh.java", 14, "this(var1, var2);", "this(var1, var2, new String[0]);"),
("a/l.java", 385, "((x)item)", "((x)(Object)item)"),
("defpackage/bn.java", 241, "((x)var1)", "((x)(Object)var1)"),
("defpackage/bn.java", 295, "((x)var1)", "((x)(Object)var1)"),
("defpackage/bn.java", 305, "((x)var1)", "((x)(Object)var1)"),
("defpackage/bn.java", 358, "((x)var1)", "((x)(Object)var1)"),
("defpackage/bn.java", 410, "((x)var1)", "((x)(Object)var1)"),
]
# ======================== J: (Object[])→float[] ========================
ARRAYS = [
("defpackage/aah.java", "((Object[])var15)", "((float[])var15)"),
("defpackage/adf.java", "((Object[])var8)", "((float[])var8)"),
("defpackage/adv.java", "((Object[])var12)", "((float[])var12)"),
]
# ======================== K: int/boolean ========================
# (rel, line, old, new)
INTBOOL = [
("defpackage/ajn.java", 324, "if (!var2 &&", "if (var2 == 0 &&"),
("defpackage/ajn.java", 329, "if (!var3 &&", "if (var3 == 0 &&"),
("defpackage/ajn.java", 334, "if (var3 &&", "if (var3 != 0 &&"),
("defpackage/ajn.java", 340, "if (var2 &&", "if (var2 != 0 &&"),
("defpackage/ajn.java", 346, "} else if (var6 &&", "} else if (var6 != 0 &&"),
("defpackage/afp.java", 637, "int var16x = var29 &&", "int var16x = var29 != 0 &&"),
(
"defpackage/afp.java",
647,
"apply(var30, var13, var31, var16x,",
"apply(var30, var13, var31, (var16x != 0),",
),
("defpackage/agx.java", 398, "int var18 = var10 &&", "int var18 = var10 != 0 &&"),
(
"defpackage/agx.java",
401,
"apply(var11, var7, var6, var18,",
"apply(var11, var7, var6, (var18 != 0),",
),
("defpackage/anl.java", 145, "sharing = var1;", "sharing = var1 != 0;"),
("defpackage/anl.java", 146, "if (!var1) {", "if (var1 == 0) {"),
("defpackage/vr.java", 101, "return var2;", "return var2 != 0;"),
("defpackage/up.java", 444, "return var2;", "return var2 != 0;"),
("defpackage/ajm.java", 22, "return 0;", "return false;"),
(
"defpackage/zk.java",
54,
"this.val$syncing[0] = 1;",
"this.val$syncing[0] = true;",
),
(
"defpackage/zk.java",
56,
"this.val$syncing[0] = 0;",
"this.val$syncing[0] = false;",
),
(
"defpackage/zm.java",
46,
"this.val$pushed[0] = (IsEnabled == true ? 1 : 0) == true ? 1 : 0;",
"this.val$pushed[0] = IsEnabled;",
),
("defpackage/zm.java", 47, ", IsEnabled == true ? 1 : 0);", ", IsEnabled);"),
(
"defpackage/zm.java",
61,
"this.val$pushed[0] = (flag == true ? 1 : 0) == true ? 1 : 0;",
"this.val$pushed[0] = flag;",
),
("defpackage/zm.java", 62, "setEnabled(flag == true ? 1 : 0)", "setEnabled(flag)"),
(
"defpackage/zr.java",
215,
"if (var1x != var2[0]) {",
"if ((var1x != 0) != var2[0]) {",
),
(
"defpackage/zr.java",
228,
"if (var2x != var2[0]) {",
"if ((var2x != 0) != var2[0]) {",
),
(
"defpackage/aab.java",
151,
"if (var1 != this.lastEnabled) {",
"if ((var1 != 0) != this.lastEnabled) {",
),
(
"defpackage/anh.java",
189,
"if (var5 != var2.visible) {",
"if ((var5 != 0) != var2.visible) {",
),
("defpackage/yy.java", 356, "if (var4 != var6) {", "if (var4 != (var6 != 0)) {"),
(
"defpackage/atf.java",
918,
"shapeCommands[var20] != var14",
"(shapeCommands[var20] ? 1 : 0) != var14",
),
(
"defpackage/aul.java",
248,
"if (var0 == shaderPackConflict) {",
"if ((var0 != 0) == shaderPackConflict) {",
),
("defpackage/aid.java", 636, "byte var33 = var18;", "byte var33 = var18 ? 1 : 0;"),
("defpackage/aid.java", 639, "var33 = (byte)(var18 == 0", "var33 = (byte)(!var18"),
(
"defpackage/aid.java",
640,
"? 1: (1597328994 | -1597328994) + (1597328994 & -1597328994));",
"? 1: 0);",
),
(
"defpackage/aid.java",
641,
'} else if (var18 != 0 && "east".equals(var0)) {',
'} else if (var18 && "east".equals(var0)) {',
),
(
"defpackage/aid.java",
643,
'} else if (var18 != 0 && "west".equals(var0)) {',
'} else if (var18 && "west".equals(var0)) {',
),
("defpackage/ww.java", 558, " (boolean)var6,", " (var6 != 0),"),
(
"defpackage/bn.java",
533,
"new ad((boolean)var8, (boolean)var7,",
"new ad((var8 != 0), (var7 != 0),",
),
(
"defpackage/apm.java",
171,
"new Input((boolean)var4, (boolean)var5,",
"new Input((var4 != 0), (var5 != 0),",
),
(
"defpackage/im.java",
187,
'var4 |= var9.getClassName().startsWith("evo.");',
'var4 |= var9.getClassName().startsWith("evo.") ? 1 : 0;',
),
(
"defpackage/aod.java",
729,
"this.reap(var4, var5, var3, var6)",
"this.reap(var4, var5, var3, var6 != 0)",
),
("defpackage/aod.java", 795, "if (!var5) {", "if (var5 == 0) {"),
(
"defpackage/agt.java",
69,
"var8, var9, var3, var10)",
"var8, var9, var3, var10 != 0)",
),
("defpackage/ld.java", 281, "if (!var6) {", "if (var6 == 0) {"),
("defpackage/jb.java", 21, "return i;", "return i != 0;"),
("defpackage/anu.java", 40, "return i;", "return i != 0;"),
("defpackage/kk.java", 25, "return i;", "return i != 0;"),
]
# многострочные `|= boolean` (vl): обёртка RHS
VL_WRAP = [
("defpackage/vl.java", 1844),
("defpackage/vl.java", 1975),
("defpackage/vl.java", 1998),
("defpackage/vl.java", 2021),
("defpackage/vl.java", 2049),
("defpackage/vl.java", 2086),
("defpackage/vl.java", 2222),
]
# ==================== M: структурные фиксы ====================
NB_CONSTS = """ NORMAL("Normal", null),
PROTANOPIA("Protanopia", new float[]{0.152286F, 1.052583F, -0.204868F, 0.114503F, 0.786281F, 0.099216F, -0.003882F, -0.048116F, 1.051998F}),
DEUTERANOPIA("Deuteranopia", new float[]{0.367322F, 0.860646F, -0.227968F, 0.280085F, 0.672501F, 0.047413F, -0.01182F, 0.04294F, 0.968881F}),
TRITANOPIA("Tritanopia", new float[]{1.255528F, -0.076749F, -0.178779F, 0.147602F, 0.930809F, -0.078411F, 0.004733F, 0.691367F, 0.3039F}),
ACHROMATOPSIA("Achromatopsia", new float[]{0.2126F, 0.7152F, 0.0722F, 0.2126F, 0.7152F, 0.0722F, 0.2126F, 0.7152F, 0.0722F});"""
def fix_nb():
rel = "defpackage/nb.java"
L = get(rel)
# 1) константы в заголовке
try:
i0 = next(i for i, l in enumerate(L) if l.strip().startswith("NORMAL("))
i1 = next(i for i, l in enumerate(L) if l.strip().startswith("ACHROMATOPSIA;"))
except StopIteration:
if any("0.152286F" in l for l in L):
stats["nb_skip"] += 1
else:
stats["nb_MISS"] += 1
print("NB-MISS: constants header not found")
return
L[i0 : i1 + 1] = NB_CONSTS.splitlines()
stats["nb"] += 1
# 2) удалить static-блок с присваиваниями
try:
s = next(i for i, l in enumerate(L) if "Failed to inline enum fields" in l)
except StopIteration:
stats["nb_block_MISS"] += 1
print("NB-MISS: static block not found")
return
# конец блока: строка ` }` после ACHROMATOPSIA = new nb(...)
e = next(i for i in range(s, len(L)) if "ACHROMATOPSIA = new nb(" in L[i])
e2 = next(i for i in range(e, len(L)) if L[i].strip() == "}")
del L[s : e2 + 1]
stats["nb_block"] += 1
CIF_CONST_RE = re.compile(r"^\s*public static final Cif (\w+) = new Cif\((.*)\);\s*$")
def fix_cif():
rel = "defpackage/Cif.java"
L = get(rel)
if not any(l.strip().startswith("public final class Cif") for l in L):
if any(l.strip().startswith("public enum Cif") for l in L):
stats["Cif_skip"] += 1
else:
stats["Cif_MISS"] += 1
print("CIF-MISS: class decl not found")
return
# собрать константы
consts = []
keep = []
for l in L:
m = CIF_CONST_RE.match(l)
if m:
consts.append((m.group(1), m.group(2)))
else:
keep.append(l)
if len(consts) != 15:
stats["Cif_MISS"] += 1
print(f"CIF-MISS: found {len(consts)} constants")
return
L = keep
# class → enum
for i, l in enumerate(L):
if l.strip().startswith("public final class Cif"):
L[i] = l.replace("public final class Cif", "public enum Cif")
break
# вставить константы сразу после заголовка enum
hi = next(i for i, l in enumerate(L) if l.strip().startswith("public enum Cif"))
lines = []
for n, (name, args) in enumerate(consts):
sep = "," if n < len(consts) - 1 else ";"
lines.append(f" {name}({args}){sep}")
L[hi + 1 : hi + 1] = lines
stats["Cif"] += 1
out = []
skip_until = None
mode = None
i = 0
while i < len(L):
l = L[i]
s = l.strip()
if s.startswith("private static final /* synthetic */ Cif[] $VALUES"):
i += 1
continue
if s.startswith("public static Cif[] values()") or s.startswith(
"public static Cif valueOf("
):
# пропустить до закрывающей скобки метода (уровень отступа метода)
ind = len(l) - len(l.lstrip())
i += 1
while i < len(L) and not (
L[i].strip() == "}" and (len(L[i]) - len(L[i].lstrip())) == ind
):
i += 1
i += 1
continue
if s.startswith("private static /* synthetic */ Cif[] $values()"):
ind = len(l) - len(l.lstrip())
i += 1
while i < len(L) and not (
L[i].strip() == "}" and (len(L[i]) - len(L[i].lstrip())) == ind
):
i += 1
i += 1
# и пустая строка после
if i < len(L) and not L[i].strip():
i += 1
continue
if s == "super(str, i);":
i += 1
continue
if s == "return 0;":
out.append(l.replace("return 0;", "return false;"))
i += 1
continue
if s == "return i;":
out.append(l.replace("return i;", "return i != 0;"))
i += 1
continue
out.append(l)
i += 1
files[os.path.join(JAVA, rel)] = out
stats["Cif_cleanup"] += 1
PAIR_SRC = """package kotlin;
public class Pair<A, B> {
private final A first;
private final B second;
public Pair(A var1, B var2) {
this.first = var1;
this.second = var2;
}
public A getFirst() {
return this.first;
}
public B getSecond() {
return this.second;
}
}
"""
def write_pair():
p = os.path.join(JAVA, "kotlin/Pair.java")
os.makedirs(os.path.dirname(p), exist_ok=True)
if os.path.exists(p):
stats["Pair_skip"] += 1
return
with open(p, "w", encoding="utf-8") as f:
f.write(PAIR_SRC)
stats["Pair"] += 1
def main():
# line-правки по убыванию внутри файла
def apply_line_edits(table, tag):
by = collections.defaultdict(list)
for row in table:
by[row[0]].append(row)
for rel, rows in by.items():
for row in sorted(rows, key=lambda r: -r[1]):
edit_line(rel, row[1], row[2], row[3], tag)
for rel, ln, var, nt in sorted(RETYPE, key=lambda r: -r[1]):
retype(rel, ln, var, nt, "retype")
for rel, ln, var, ct in sorted(CASTS, key=lambda r: -r[1]):
cast_usage(rel, ln, var, ct, "cast")
for ln, old, new in sorted(MS_EXTRA, key=lambda r: -r[0]):
edit_line("defpackage/ms.java", ln, old, new, "ms_extra")
for rel, ln in sorted(FOREACH, key=lambda r: -r[1]):
foreach_cast(rel, ln, "foreach")
apply_line_edits(TOARRAY, "toarray")
apply_line_edits(THISCAST, "thiscast")
apply_line_edits(TEXTC, "text")
for rel, old, new in ARRAYS:
edit_all(rel, old, new, "array")
apply_line_edits(INTBOOL, "intbool")
for rel, ln in VL_WRAP:
wrap_assign_rhs(rel, ln, "vlwrap")
# структурные
fix_nb()
fix_cif()
write_pair()
# импорты
insert_after(
"defpackage/acf.java",
"import net.fabricmc.loader.api.FabricLoader;",
"import net.fabricmc.loader.api.ModContainer;",
"import",
)
insert_after("a/o.java", "import defpackage.*;", "import b.l;", "import")
# сохранить
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 k.endswith("_MISS")}
if miss:
print("MISSES:", dict(miss))
sys.exit(1)
if __name__ == "__main__":
main()