diff --git a/JAVA_MIGRATION.md b/JAVA_MIGRATION.md index b81d9b8..d6037a9 100644 --- a/JAVA_MIGRATION.md +++ b/JAVA_MIGRATION.md @@ -1459,3 +1459,23 @@ generated-trait compatibility work. Scala-runtime removal remains a later projec and the clean jar repeats the API/disassembly/dump matches above. The forced Scala-compilation version guard is retained; all five `@Mod` annotations match both packaged jar versions. External Scala-trait coverage remains green and the existing manual client checks and Java-source bridge limitations remain outstanding. +- Added six Forge characterization cases for `ASMMixinCompiler.getSuper`, passing on untouched Scala and committed + separately as `c0df2e0`: owner/name filter short-circuiting, greedy Scala super-name stripping, exact inherited + signature selection and visibility, receiver recognition, argument indexing, failure paths, stack preservation, + virtual getter/callback order, returned option identity and descriptor rereads. Baseline: 326 JVM / 141 Forge. + The compiler singleton requires Forge initialization, so these behavior tests use its existing harness. +- Moved only `getSuper` into the existing Java `ClassInfoLookup`, retaining the public Scala entry point and + `Option.flatMap` callback dispatch. The current argument-count/stack-slot mismatch for wide arguments remains, + as do the lack of invocation-opcode and `This.owner` validation and the limited target-owner check. The caller's + `INVOKESPECIAL` guard, all trait rewrites and metadata/model behavior remain unchanged; algorithm fixes are separate. +- Saved reference source/jar, reports and 40 generated dumps in ignored `run/migration-super-reference/`. All 16 named + compiler APIs retain their names/descriptors/modifiers/generic signatures and private fields; 14 named classfiles + are byte-identical. All 218 other named compiler methods, 34 algorithm closures, 17 existing metadata-helper methods + and 143 other ASM/generator disassemblies match. All dump names/hashes match. One private Scala closure becomes a + Java callback, leaving 450 packaged classes and no new divergence entry. Sources total 209 Java files and 9 Scala + files / 1,675 nonblank Scala lines. Next: `ASMMixinCompiler.listSideOnly` annotation filtering, characterized first. +- Formatting/checkstyle/build and Forge pass, including clean verification after stopping Gradle: 326 JVM / 141 Forge, + zero failures/errors/skips. Characterization tests remain unchanged. The clean jar repeats the API/disassembly/dump + matches, the local dev config is unchanged, and all five `@Mod` versions match both packaged jar versions with the + forced Scala-compilation guard retained. External Scala-trait tests remain green; existing manual client checks and + Java-source model-bridge limitations remain outstanding. diff --git a/JAVA_MIGRATION_HANDOFF.md b/JAVA_MIGRATION_HANDOFF.md index 7150824..eaea7ad 100644 --- a/JAVA_MIGRATION_HANDOFF.md +++ b/JAVA_MIGRATION_HANDOFF.md @@ -12,8 +12,8 @@ what breaks, and what is left. The other documents hold the reasoning. | `JAVA_MIGRATION_MANUAL_CHECKS.md` | What no automated test can cover, and must be checked by hand in a client | | `JAVA_MIGRATION_PROFILE.md` | The focused baseline, first measured result, findings, and exact rerun command | -Branch: `algent/java`. Base: `master`. 178 commits including the API-cleanup plan, divergence-log cleanup, ports -through the ASM descriptor/bridge helper extraction, and the ASM characterization backfill and review fixes. +Branch: `algent/java`. Base: `master`. 180 commits including the API-cleanup plan, divergence-log cleanup, ports +through ASM super-call lookup, and the ASM characterization backfill and review fixes. ## The one rule that matters @@ -74,7 +74,7 @@ awk -F'"' '/ - case _ => return None // have to be invoked on this - } - - getClassInfo(stack.owner.getInternalName).superClass - .flatMap(_.findPublicImpl(methodName, minsn.desc)) - } + ): Option[MethodInfo] = ClassInfoLookup.getSuper(minsn, stack) def getAndRegisterParentTraits(cnode: ClassNode) = cnode.interfaces.map(getClassInfo).collect { diff --git a/src/main/scala/codechicken/multipart/asm/ClassInfoLookup.java b/src/main/scala/codechicken/multipart/asm/ClassInfoLookup.java index 40ed42b..33446d5 100644 --- a/src/main/scala/codechicken/multipart/asm/ClassInfoLookup.java +++ b/src/main/scala/codechicken/multipart/asm/ClassInfoLookup.java @@ -3,13 +3,18 @@ package codechicken.multipart.asm; import java.lang.reflect.Method; import java.util.Objects; +import org.objectweb.asm.Type; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import codechicken.multipart.asm.ASMMixinCompiler.ClassInfo; import codechicken.multipart.asm.ASMMixinCompiler.ClassInfo$; import codechicken.multipart.asm.ASMMixinCompiler.MethodInfo; +import codechicken.multipart.asm.StackAnalyser.Load; +import codechicken.multipart.asm.StackAnalyser.StackEntry; +import codechicken.multipart.asm.StackAnalyser.This; import scala.Array$; import scala.Function1; import scala.Function3; @@ -173,4 +178,24 @@ final class ClassInfoLookup { private static R throwUnchecked(Throwable throwable) throws E { throw (E) throwable; } + + static Option getSuper(final MethodInsnNode call, StackAnalyser stack) { + if (Objects.equals(call.owner, stack.owner().getInternalName())) return Option.empty(); + + final String methodName = stack.m().name.replaceAll(".+\\Q$$super$\\E", ""); + if (!Objects.equals(call.name, methodName)) return Option.empty(); + + // Preserve the compiler's argument-count indexing, including its behavior for wide stack values. + StackEntry receiver = stack.peek(Type.getType(call.desc).getArgumentTypes().length); + if (!(receiver instanceof Load) || !(((Load) receiver).e() instanceof This)) return Option.empty(); + + return ASMMixinCompiler$.MODULE$.getClassInfo(stack.owner().getInternalName()).superClass() + .flatMap(new AbstractFunction1>() { + + @Override + public Option apply(ClassInfo parent) { + return parent.findPublicImpl(methodName, call.desc); + } + }); + } }