Skip to content

Commit

Permalink
Add a way to look up which sources specify a certain target (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
XFactHD authored Dec 24, 2024
1 parent bb0f9f1 commit 3ffc89d
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 7 deletions.
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.api.TargetType;
import net.neoforged.accesstransformer.parser.AccessTransformerList;
import org.antlr.v4.runtime.CharStream;
import org.objectweb.asm.Opcodes;
Expand Down Expand Up @@ -80,4 +81,9 @@ public void loadATFromResource(String resourceName) throws URISyntaxException, I
public Set<Type> getTargets() {
return masterList.getTargets();
}

@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
@@ -1,5 +1,6 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.tree.*;

import java.util.*;
Expand All @@ -24,4 +25,9 @@ public void apply(final ClassNode node, final AccessTransformer.Modifier targetA
inner.access = targetFinalState.mergeWith(inner.access);
});
}

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

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.tree.*;

import java.util.*;
Expand Down Expand Up @@ -48,4 +49,9 @@ public String targetName() {
public String getFieldName() {
return fieldName;
}

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

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.tree.*;

import java.util.*;

public class InnerClassTarget extends Target<ClassNode> {
private final String originalInnerName;
private final String innerName;

public InnerClassTarget(final String className, final String innerName) {
super(className);
this.innerName = innerName;
this.originalInnerName = innerName;
this.innerName = innerName.replace('.', '/');
}

@Override
Expand Down Expand Up @@ -41,4 +44,9 @@ public void apply(final ClassNode node, final AccessTransformer.Modifier targetA
inner.access = targetFinalState.mergeWith(inner.access);
});
}

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

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;

Expand Down Expand Up @@ -63,4 +64,8 @@ public void apply(final MethodNode node, final AccessTransformer.Modifier target

}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == TargetType.METHOD && getClassName().equals(className) && this.targetName.equals(targetName);
}
}
12 changes: 12 additions & 0 deletions src/main/java/net/neoforged/accesstransformer/Target.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.neoforged.accesstransformer;

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.*;

import java.util.*;
Expand Down Expand Up @@ -42,5 +43,16 @@ public int hashCode() {
}

public abstract String targetName();

/**
* 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
*/
public abstract boolean matches(final String className, final TargetType type, final String targetName);

public abstract void apply(final T node, final AccessTransformer.Modifier targetAccess, final AccessTransformer.FinalState targetFinalState, Set<String> privateChanged);
}
5 changes: 0 additions & 5 deletions src/main/java/net/neoforged/accesstransformer/TargetType.java

This file was deleted.

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

import net.neoforged.accesstransformer.api.TargetType;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;

Expand Down Expand Up @@ -58,4 +59,9 @@ public void apply(final ClassNode node, final AccessTransformer.Modifier targetA
}
}
}

@Override
public boolean matches(final String className, final TargetType type, final String targetName) {
return type == this.type && getClassName().equals(className);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ public interface AccessTransformerEngine {
*/
Set<Type> getTargets();

/**
* 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,7 @@
package net.neoforged.accesstransformer.api;

public enum TargetType {
FIELD,
METHOD,
CLASS
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public Void visitEntry(final AtParser.EntryContext ctx) {
int idx = className.lastIndexOf('$'); //Java uses this to identify inner classes, Scala/others use it for synthetics. Either way we should be fine as it will skip over classes that don't exist.
if (idx != -1) {
String parent = className.substring(0, idx);
accessTransformers.add(new AccessTransformer(new InnerClassTarget(parent, className.replace('.', '/')), ModifierProcessor.modifier(modifier), ModifierProcessor.finalState(modifier), this.origin, ctx.getStart().getLine()));
accessTransformers.add(new AccessTransformer(new InnerClassTarget(parent, className), ModifierProcessor.modifier(modifier), ModifierProcessor.finalState(modifier), this.origin, ctx.getStart().getLine()));
}
}
return super.visitEntry(ctx);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.neoforged.accesstransformer.parser;

import net.neoforged.accesstransformer.api.TargetType;
import net.neoforged.accesstransformer.generated.*;

import net.neoforged.accesstransformer.*;
Expand Down Expand Up @@ -97,4 +98,17 @@ public Map<TargetType, Map<String,AccessTransformer>> getTransformersForTarget(f
.collect(Collectors.groupingBy(o->o.getTarget().getType(), HashMap::new, Collectors.toMap(at->at.getTarget().targetName(), Function.identity())));
}

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

import net.neoforged.accesstransformer.api.TargetType;
import net.neoforged.accesstransformer.parser.AccessTransformerList;
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"));
}
}

0 comments on commit 3ffc89d

Please sign in to comment.