Generate access wideners for DataProvider.getName implementations ()

* Generate AW for DataProvider.getName impls

* Remove final

* Typo + improve memory usage
This commit is contained in:
modmuss50 2022-12-11 13:50:46 +00:00 committed by GitHub
parent a9337210f9
commit 112a38be2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 17 deletions
fabric-data-generation-api-v1
build.gradle
src/main
java/net/fabricmc/fabric/api/datagen/v1/provider
resources

View file

@ -56,6 +56,8 @@ import org.objectweb.asm.ClassReader
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.ClassNode
import java.lang.reflect.Modifier
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
task generateAccessWidener() {
@ -63,14 +65,16 @@ task generateAccessWidener() {
File inputJar = loom.namedMinecraftProvider.parentMinecraftProvider.commonJar.toFile()
String accessWidener = file("template.accesswidener").text + "\n"
visitMethods(inputJar, "net/minecraft/data/server/recipe/RecipeProvider.class") { name, desc, owner ->
def classes = getClasses(inputJar)
visitMethods(classes["net/minecraft/data/server/recipe/RecipeProvider"]) { name, desc, owner ->
if (it.name == "generate")
return
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
}
visitMethods(inputJar, "net/minecraft/data/client/BlockStateModelGenerator.class") { name, desc, owner ->
visitMethods(classes["net/minecraft/data/client/BlockStateModelGenerator"]) { name, desc, owner ->
if (desc == "()V")
// Skip over methods that dont take any arguments, as they are specific to minecraft.
return
@ -78,40 +82,100 @@ task generateAccessWidener() {
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
}
visitMethods(inputJar, "net/minecraft/data/server/loottable/BlockLootTableGenerator.class") { name, desc, owner ->
visitMethods(classes["net/minecraft/data/server/loottable/BlockLootTableGenerator"]) { name, desc, owner ->
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
}
visitMethods(inputJar, "net/minecraft/data/client/ItemModelGenerator.class") { name, desc, owner ->
visitMethods(classes["net/minecraft/data/client/ItemModelGenerator"]) { name, desc, owner ->
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
}
classes.values().forEach { classNode ->
visitFinalMethods(classNode) { name, desc, owner ->
if (name != "getName" || desc != "()Ljava/lang/String;") {
// Not the method we are after
return
}
if (!hasAncestor(classNode, classes, "net/minecraft/data/DataProvider")) {
// Not a descendant of DataProvider
return
}
accessWidener += "transitive-extendable\tmethod\t${owner}\t${name}\t${desc}\n"
}
}
file("src/main/resources/fabric-data-generation-api-v1.accesswidener").text = accessWidener
}
}
def visitMethods(File input, String className, closure) {
def clazz = getClassNode(input, className)
clazz.methods.forEach {
def visitMethods(ClassNode classNode, closure) {
classNode.methods.forEach {
if ((it.access & Opcodes.ACC_SYNTHETIC) != 0 || (it.access & Opcodes.ACC_PUBLIC) != 0)
return
if (it.name.startsWith("<"))
return
closure(it.name, it.desc, clazz.name)
closure(it.name, it.desc, classNode.name)
}
}
ClassNode getClassNode(File input, String className) {
new ZipFile(input).withCloseable { ZipFile zip ->
zip.getInputStream(zip.getEntry(className)).withCloseable { is ->
ClassReader reader = new ClassReader(is)
ClassNode classNode = new ClassNode()
reader.accept(classNode, 0)
def visitFinalMethods(ClassNode classNode, closure) {
classNode.methods.forEach {
if (!Modifier.isFinal(it.access))
return
return classNode
if (it.name.startsWith("<"))
return
closure(it.name, it.desc, classNode.name)
}
}
// Return a map of all class names to classNodes
def getClasses(File input) {
Map<String, ClassNode> classes = [:]
new ZipFile(input).withCloseable { ZipFile zip ->
zip.entries().toList().forEach { ZipEntry entry ->
if (!entry.name.endsWith(".class")) {
return
}
zip.getInputStream(entry).withCloseable { is ->
ClassReader reader = new ClassReader(is)
ClassNode classNode = new ClassNode()
reader.accept(classNode, ClassReader.SKIP_CODE)
classes.put(classNode.name, classNode)
}
}
}
return classes
}
def hasAncestor(ClassNode classNode, Map<String, ClassNode> classes, String ancestorName) {
if (classNode.superName == ancestorName) {
return true
}
// Recuse through the super classes
def superClass = classes.get(classNode.superName)
if (superClass != null && hasAncestor(superClass, classes, ancestorName)) {
return true
}
for (def interfaceName : classNode.interfaces) {
if (interfaceName == ancestorName) {
return true
}
def ifaceClass = classes.get(interfaceName)
if (ifaceClass != null && hasAncestor(ifaceClass, classes, ancestorName)) {
return true
}
}
}

View file

@ -102,7 +102,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
}
@Override
public final String getName() {
public String getName() {
return "Language (%s)".formatted(languageCode);
}

View file

@ -284,3 +284,16 @@ transitive-accessible method net/minecraft/data/client/ItemModelGenerator regist
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerCompass (Lnet/minecraft/item/Item;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator registerClock (Lnet/minecraft/item/Item;)V
transitive-extendable method net/minecraft/data/server/advancement/AdvancementProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/CommandSyntaxProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/BlockListProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/RegistryDumpProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/loottable/LootTableProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/MetadataProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/client/ModelProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/BiomeParametersProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/dev/NbtProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/SnbtProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/recipe/RecipeProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/report/DynamicRegistriesProvider getName ()Ljava/lang/String;
transitive-extendable method net/minecraft/data/server/tag/AbstractTagProvider getName ()Ljava/lang/String;