Plain-JVM coverage for the half that needs no world: the id guard on
createTileFromNBT and the whole of IPartTileConverter. MultipartSaveLoad
cannot class-initialize headless, which makes it a usable probe -- returning
null rather than raising a LinkageError is what proves the guard short-circuits
before the loadingWorld assignment.
Forge server coverage for the rest, none of which is reachable headless:
createTileFromParts runs the ASM generator, the NBT round trip needs the
save/load hooks, registerTileConverter appends to a Scala MutableList, and
sendDescPacket needs a loaded chunk.
Also pins the two static descriptors other jars link against and the
MultipartHelper/MultipartHelper$ names guidenh reflects on, which the ABI diff
cannot see.
107 plain-JVM tests, 10 Forge server tests.
Splits the characterization across both layers, because part registration
needs FML's active mod container and throws without one, so it cannot run
headless at all.
Plain JVM covers what is reachable: converters are dispatched per block,
a converter returning null does not stop the scan, converters registered
for another block are never consulted, a converter claiming several blocks
is registered for each, and an unknown mod container throws rather than
returning null.
The Forge server suite covers registration itself, and deliberately
exercises both overloads downstream depends on. Content registers through
the deprecated IPartFactory array form that seven jars use, and each
microblock class registers through the IPartFactory2 varargs form that
ProjRed uses, so resolving mc_torch and mcr_face proves both paths. Part
ids also round trip through the shared IDWriter carrier.
78 plain-JVM tests and 5 server tests, all passing against the untouched
Scala.
Replaces TFacePart.scala with a Java interface and retains the
TFacePart$class bridge for OpenComputers, ProjRed and ProjectBlue. The
interface is descriptor-identical to the reference; the bridge adds only a
private constructor.
This is the first converted trait where Java default methods are safe.
TMultiPart declares neither solid nor redstoneConductionMap, and neither
does anything in the microblock superclass chain, so there is no
superclass method for a default to lose to. Both members therefore become
real defaults rather than staying abstract with explicit forwarders, and
no in-repo Scala needed changing. The rule for the remaining traits is to
check that condition before choosing.
A side effect is that Java classes can now inherit these members;
McSidedMetaPart previously had to declare both just to accept the
defaults, and stays descriptor-identical.
Adds the first functional coverage of runtime class generation against a
ported type. Microblock classes are built by ASM at run time, so the
server suite now checks that a generated FaceMicroblock resolves the
inherited default and that a generated HollowMicroblock still returns its
own overrides.
Validated with 43 plain-JVM tests, a clean build, and the Java 8 Forge
dedicated-server suite at 3 tests.