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 a way to look up which sources specify a certain target #15

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@
public sealed interface Target {
String className();

/**
* Checks whether this target matches the given target description.
*
* @param className The FQN of the class containing the target
* @param type The type of the target
* @param targetName The name of the target (ignored for {@link TargetType#CLASS} and wildcard targets)
* @return whether this target matches the given target description
*/
boolean matches(final String className, final TargetType type, final String targetName);

record ClassTarget(String className) implements Target {
@Override
public String toString() {
return className() + " CLASS";
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.CLASS && this.className.equals(className);
}
}

record InnerClassTarget(String className, String innerName) implements Target {
Expand All @@ -16,33 +31,58 @@ public String toString() {
int idx = innerName().lastIndexOf('$');
return className() + " INNERCLASS " + innerName().substring(idx + 1);
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.CLASS && this.innerName.equals(className);
}
}

record FieldTarget(String className, String fieldName) implements Target {
@Override
public String toString() {
return className() + " FIELD " + fieldName();
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.FIELD && this.className.equals(className) && this.fieldName.equals(targetName);
}
}

record MethodTarget(String className, String methodName, String methodDescriptor) implements Target {
@Override
public String toString() {
return className() + " METHOD " + methodName() + methodDescriptor();
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.METHOD && this.className.equals(className) && targetName.equals(this.methodName + this.methodDescriptor);
}
}

record WildcardMethodTarget(String className) implements Target {
@Override
public String toString() {
return className() + " METHODWILDCARD";
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.METHOD && this.className.equals(className);
}
}

record WildcardFieldTarget(String className) implements Target {
@Override
public String toString() {
return className() + " FIELDWILDCARD";
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.FIELD && this.className.equals(className);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.neoforged.accesstransformer;
package net.neoforged.accesstransformer.parser;

public enum TargetType {
FIELD, METHOD, CLASS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.parser.Target;
import net.neoforged.accesstransformer.parser.TargetType;
import net.neoforged.accesstransformer.parser.Transformation;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.api.AccessTransformerEngine;
import net.neoforged.accesstransformer.parser.TargetType;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
Expand Down Expand Up @@ -82,4 +83,9 @@ public Set<Type> getTargets() {
public boolean containsClassTarget(Type type) {
return masterList.containsClassTarget(type);
}

@Override
public Set<String> getSourcesForTarget(final String className, final TargetType type, final String targetName) {
return masterList.getSourcesForTarget(className, type, targetName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.neoforged.accesstransformer.parser.AccessTransformerFiles;
import net.neoforged.accesstransformer.parser.Target;
import net.neoforged.accesstransformer.parser.TargetType;
import net.neoforged.accesstransformer.parser.Transformation;
import org.objectweb.asm.Type;

Expand All @@ -10,6 +11,7 @@
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -57,4 +59,19 @@ public Map<TargetType, Map<String, AccessTransformer<?>>> getTransformersForTarg
Collectors.toMap((Function<AccessTransformer<?>, String>) AccessTransformer::targetName, Function.<AccessTransformer<?>>identity())
));
}

public Set<String> getSourcesForTarget(final String className, final TargetType type, final String targetName) {
return atFiles.getAccessTransformers()
.entrySet()
.stream()
.filter(e -> e.getKey().matches(className, type, targetName))
.map(Map.Entry::getValue)
.map(Transformation::origins)
.map(HashSet::new)
.reduce((s1, s2) -> {
s1.addAll(s2);
return s1;
})
.orElse(null);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.parser.Target;
import net.neoforged.accesstransformer.parser.TargetType;
import net.neoforged.accesstransformer.parser.Transformation;
import org.objectweb.asm.tree.FieldNode;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.parser.Target;
import net.neoforged.accesstransformer.parser.TargetType;
import net.neoforged.accesstransformer.parser.Transformation;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.MethodNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.parser.Target;
import net.neoforged.accesstransformer.parser.TargetType;
import net.neoforged.accesstransformer.parser.Transformation;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.neoforged.accesstransformer.api;

import net.neoforged.accesstransformer.AccessTransformerEngineImpl;
import net.neoforged.accesstransformer.parser.TargetType;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;

Expand Down Expand Up @@ -51,6 +52,18 @@ public interface AccessTransformerEngine {
*/
boolean containsClassTarget(Type type);

/**
* Looks up AT file sources of entries matching the given target
*
* @param className the class containing the target
* @param type the type of the target
* @param targetName the target's name (null for class targets, full descriptor for method targets, name for field targets)
* @return The list of sources specifying the given target or null if none apply
*/
default Set<String> getSourcesForTarget(final String className, final TargetType type, final String targetName) {
return null;
}

/**
* Attempts to transform the given {@code classNode}, and apply ATs, if any.
* @param classNode the class to transform
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package net.neoforged.accesstransformer.test;

import net.neoforged.accesstransformer.AccessTransformerList;
import net.neoforged.accesstransformer.parser.TargetType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Set;

public class AccessTransformerPresenceTest {
@Test
public void testSourceLookup() throws IOException, URISyntaxException {
final AccessTransformerList atLoader = new AccessTransformerList();

Path filePath = Path.of(getClass().getClassLoader().getResource("forge_at.cfg").toURI());
atLoader.loadFromPath(filePath);

String sourcePrefix = filePath.toString();

// Class
Assertions.assertEquals(Set.of(sourcePrefix + ":99"), atLoader.getSourcesForTarget("net.minecraft.item.crafting.RecipeTippedArrow", TargetType.CLASS, null));
// Inner class
Assertions.assertEquals(Set.of(sourcePrefix + ":76"), atLoader.getSourcesForTarget("net.minecraft.world.gen.structure.StructureStrongholdPieces$Stronghold", TargetType.CLASS, null));
// Method
Assertions.assertEquals(Set.of(sourcePrefix + ":6"), atLoader.getSourcesForTarget("net.minecraft.block.Block", TargetType.METHOD, "func_149752_b(F)Lnet/minecraft/block/Block;"));
// Field
Assertions.assertEquals(Set.of(sourcePrefix + ":22"), atLoader.getSourcesForTarget("net.minecraft.entity.EntityTrackerEntry", TargetType.FIELD, "field_73134_o"));
// Method wildcard
Assertions.assertEquals(Set.of(sourcePrefix + ":29"), atLoader.getSourcesForTarget("net.minecraft.world.biome.Biome", TargetType.METHOD, "this_is_ignored(F)Ldoes/not/Matter;"));
// Field wildcard
Assertions.assertEquals(Set.of(sourcePrefix + ":51"), atLoader.getSourcesForTarget("net.minecraft.world.biome.BiomeDecorator", TargetType.FIELD, "this_is_ignored"));
}
}
Loading