waves G-K: retype/casts/foreach/int-bool, nb+Cif enums, kotlin.Pair shim

This commit is contained in:
loki5512344 2026-10-03 14:27:08 +02:00
parent e11e749e4b
commit dbb0fc0607
Signed by: boba
GPG key ID: 253067914055423B
102 changed files with 1194 additions and 376 deletions

885
tools/waves_ghik.py Normal file
View file

@ -0,0 +1,885 @@
"""Волны поверх 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()