Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transitive access wideners for display entity tracked data fields #4229

Open
wants to merge 4 commits into
base: 1.21.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 67 additions & 2 deletions fabric-transitive-access-wideners-v1/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ testDependencies(project, [


import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
Expand All @@ -19,7 +21,6 @@ import java.nio.file.FileSystem
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path
import java.util.stream.Collectors

task generateAccessWidener {
doLast {
Expand All @@ -38,6 +39,8 @@ task generateAccessWidener {
lines.add("")
generateItemConstructors(lines, fs)
lines.add("")
generateDisplayEntityTrackedDataMethods(lines, fs)
lines.add("")
}

Path clientJar = loom.namedMinecraftProvider.parentMinecraftProvider.clientOnlyJar.path
Expand Down Expand Up @@ -128,16 +131,78 @@ def generateRenderPhaseInnerClasses(List<String> lines, FileSystem fs) {
}
}

def generateTrackedDataFields(String className, List<String> lines, FileSystem fs) {
// using a set to prevent duplicates from multiple dataTracker references in a single method
// linked to preserve order and improve generated access widener readability
Set<String> collectedWideners = new LinkedHashSet<>()

loadClass(fs.getPath("${className}.class")).accept(
new ClassVisitor(Opcodes.ASM9) {
@Override
MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
// check for desired methods
if (!name.startsWith("get") && !name.startsWith("set")) {
return null
}

// check methods as genuine basic getter/setters
long parameterCount = getMethodParameterCount(descriptor)
andantet marked this conversation as resolved.
Show resolved Hide resolved

if (name.startsWith("get") && parameterCount != 0) {
return null
}

if (name.startsWith("set") && parameterCount != 1) {
return null
}

// check needs widening
if ((access & Opcodes.ACC_PRIVATE) != 0 && (access & Opcodes.ACC_STATIC) != 0) {
return null
}

return new MethodVisitor(Opcodes.ASM9) {
@Override
void visitFieldInsn(int opcode, String owner, String fieldName, String fieldDescriptor) {
// check references its dataTracker field
if (fieldName == "dataTracker" && opcode == Opcodes.GETFIELD) {
collectedWideners.add("transitive-accessible method $className $name $descriptor")
}
}
}
}
}
)

lines.addAll(collectedWideners)
}

def generateDisplayEntityTrackedDataMethods(List<String> lines, FileSystem fs) {
lines.add("# Private tracked data getter/setter methods of DisplayEntity and its subclasses")

generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity", lines, fs)
generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$ItemDisplayEntity", lines, fs)
generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$BlockDisplayEntity", lines, fs)
generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$TextDisplayEntity", lines, fs)
}

ClassNode loadClass(Path path) {
def node = new ClassNode()

Files.newInputStream(path).withCloseable { is ->
new ClassReader(is).accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)
new ClassReader(is).accept(node, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)
}

return node
}

def getMethodParameterCount(String descriptor) {
def parameterPart = descriptor.substring(descriptor.indexOf('(') + 1, descriptor.indexOf(')'))
if (parameterPart.isEmpty()) return 0
def matcher = parameterPart =~ /(\[*[ZCBSIJFD]|L[^;]+;)/
return matcher.size()
}

def validateAccessWidener(List<String> lines) {
List<String> exceptions = new ArrayList<>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,48 @@ transitive-accessible method net/minecraft/block/WitherSkullBlock <init> (Lnet/m
# Constructors of non-abstract item classes
transitive-accessible method net/minecraft/item/MiningToolItem <init> (Lnet/minecraft/item/ToolMaterial;Lnet/minecraft/registry/tag/TagKey;FFLnet/minecraft/item/Item$Settings;)V

# Private tracked data getter/setter methods of DisplayEntity and its subclasses
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setTransformation (Lnet/minecraft/util/math/AffineTransformation;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setInterpolationDuration (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getInterpolationDuration ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setStartInterpolation (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getStartInterpolation ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setTeleportDuration (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getTeleportDuration ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setBillboardMode (Lnet/minecraft/entity/decoration/DisplayEntity$BillboardMode;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBillboardMode ()Lnet/minecraft/entity/decoration/DisplayEntity$BillboardMode;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setBrightness (Lnet/minecraft/entity/decoration/Brightness;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBrightnessUnpacked ()Lnet/minecraft/entity/decoration/Brightness;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBrightness ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setViewRange (F)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getViewRange ()F
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setShadowRadius (F)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getShadowRadius ()F
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setShadowStrength (F)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getShadowStrength ()F
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setDisplayWidth (F)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getDisplayWidth ()F
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setDisplayHeight (F)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getGlowColorOverride ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setGlowColorOverride (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getDisplayHeight ()F
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity getItemStack ()Lnet/minecraft/item/ItemStack;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity setItemStack (Lnet/minecraft/item/ItemStack;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity setTransformationMode (Lnet/minecraft/item/ModelTransformationMode;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity getTransformationMode ()Lnet/minecraft/item/ModelTransformationMode;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$BlockDisplayEntity getBlockState ()Lnet/minecraft/block/BlockState;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$BlockDisplayEntity setBlockState (Lnet/minecraft/block/BlockState;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getText ()Lnet/minecraft/text/Text;
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setText (Lnet/minecraft/text/Text;)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getLineWidth ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setLineWidth (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getTextOpacity ()B
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setTextOpacity (B)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getBackground ()I
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setBackground (I)V
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getDisplayFlags ()B
transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setDisplayFlags (B)V

# Protected static fields of RenderPhase
transitive-accessible field net/minecraft/client/render/RenderPhase NO_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency;
transitive-accessible field net/minecraft/client/render/RenderPhase ADDITIVE_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency;
Expand Down
Loading