Skip to content

Commit

Permalink
Get rid of generic hell. Use custom descriptor types. Use tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
xxDark committed Jan 27, 2024
1 parent 205d8ea commit a49a7d6
Show file tree
Hide file tree
Showing 31 changed files with 772 additions and 1,107 deletions.
142 changes: 1 addition & 141 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,144 +1,4 @@
# jlinker
Java resolution library for methods and fields.

## example

```Java
package dev.xdark.jlinker;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Example {
public static void main(String[] args) {
Function<String, ClassNode> fn = s -> {
// Ideally, the resolver should do that conversion,
// but it doesn't. Yet.
if (s.charAt(0) == '[') {
s = "java/lang/Object";
}
ClassReader reader;
try (InputStream in = ClassLoader.getSystemResourceAsStream(s + ".class")) {
if (in == null) {
throw new IllegalStateException(s);
}
reader = new ClassReader(in);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
ClassNode node = new ClassNode();
// We don't care about code or debug information
reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG);
return node;
};
// Create link resolver
LinkResolver<ClassNode, MethodNode, FieldNode> resolver = LinkResolver.jvm();
// Create class info for java/util/AbstractList
ClassInfo<ClassNode> classInfo = classInfo(fn.apply("java/util/AbstractList"), fn);
// Resolve virtual "containsAll" method
Resolution<ClassNode, MethodNode> resolution = resolver.resolveVirtualMethod(classInfo, "containsAll", "(Ljava/util/Collection;)Z").value();
ClassNode owner = resolution.owner().innerValue();
MethodNode m = resolution.member().innerValue();
// Should be java/util/AbstractCollection.containsAll(Ljava/util/Collection;)Z
System.out.println(owner.name + '.' + m.name + m.desc);
}

// Method information
private static MemberInfo<MethodNode> methodInfo(MethodNode node) {
return new MemberInfo<MethodNode>() {
@Override
public MethodNode innerValue() {
return node;
}

@Override
public int accessFlags() {
return node.access;
}

@Override
public boolean isPolymorphic() {
// To implement that, one should check for PolymorphicSignature annotation,
// doesn't matter in this example. Linker does not support polymorphic methods.
// Yet.
return false;
}
};
}

// Field information
private static MemberInfo<FieldNode> fieldInfo(FieldNode node) {
return new MemberInfo<FieldNode>() {
@Override
public FieldNode innerValue() {
return node;
}

@Override
public int accessFlags() {
return node.access;
}

@Override
public boolean isPolymorphic() {
return false;
}
};
}

// Class information
private static ClassInfo<ClassNode> classInfo(ClassNode node, Function<String, ClassNode> fn) {
return new ClassInfo<ClassNode>() {
@Override
public ClassNode innerValue() {
return node;
}

@Override
public int accessFlags() {
return node.access;
}

@Override
public ClassInfo<ClassNode> superClass() {
String superName = node.superName;
return superName == null ? null : classInfo(fn.apply(superName), fn);
}

@Override
public List<ClassInfo<ClassNode>> interfaces() {
return node.interfaces.stream().map(x -> classInfo(fn.apply(x), fn)).collect(Collectors.toList());
}

@Override
public MemberInfo<?> getMethod(String name, String descriptor) {
for (MethodNode method : node.methods) {
if (name.equals(method.name) && descriptor.equals(method.desc)) {
return methodInfo(method);
}
}
return null;
}

@Override
public MemberInfo<?> getField(String name, String descriptor) {
for (FieldNode field : node.fields) {
if (name.equals(field.name) && descriptor.equals(field.desc)) {
return fieldInfo(field);
}
}
return null;
}
};
}
}
```
See tests for examples
18 changes: 9 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'dev.xdark'
version '1.0.7'
version '2.0.0'

repositories {
mavenCentral()
Expand All @@ -20,19 +20,20 @@ sourceSets {
}

dependencies {
def junitVersion = '5.9.2'
def junitVersion = '5.10.1'
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
testImplementation "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"

testImplementation 'org.ow2.asm:asm:9.5'
testImplementation 'org.ow2.asm:asm-tree:9.5'

compileOnly 'org.jetbrains:annotations:24.0.1'
testCompileOnly 'org.jetbrains:annotations:23.0.0'
def annotationsVersion = '24.1.0'
compileOnly "org.jetbrains:annotations:$annotationsVersion"
testCompileOnly "org.jetbrains:annotations:$annotationsVersion"
}

tasks.withType(JavaCompile) {
tasks.withType(JavaCompile).configureEach {
options.compilerArgs.addAll(['-parameters', '-g:lines,source,vars'])
}

Expand Down Expand Up @@ -61,10 +62,9 @@ test {
useJUnitPlatform()
}

task sourcesJar(type: Jar) {
from sourceSets.main.java
from sourceSets.java11.java
classifier = 'sources'
java {
withJavadocJar()
withSourcesJar()
}

publishing {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
45 changes: 0 additions & 45 deletions src/main/java/dev/xdark/jlinker/Arena.java

This file was deleted.

16 changes: 0 additions & 16 deletions src/main/java/dev/xdark/jlinker/ArenaAllocator.java

This file was deleted.

17 changes: 6 additions & 11 deletions src/main/java/dev/xdark/jlinker/ClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,22 @@
*
* @author xDark
*/
public interface ClassInfo<C> {

/**
* @return Inner value, e.g. ASM ClassNode.
*/
C innerValue();
public interface ClassInfo {

/**
* @return Class access flags.
*/
int accessFlags();
int getAccessFlags();

/**
* @return Parent class.
*/
@Nullable ClassInfo<C> superClass();
@Nullable ClassInfo getSuperclass();

/**
* @return Class interfaces.
*/
@NotNull List<@NotNull ClassInfo<C>> interfaces();
@NotNull List<? extends @NotNull ClassInfo> getInterfaces();

/**
* Implementation may throw any exception.
Expand All @@ -40,7 +35,7 @@ public interface ClassInfo<C> {
* @param descriptor Method descriptor.
* @return Class method.
*/
@Nullable MemberInfo<?> getMethod(String name, String descriptor);
@Nullable MethodInfo getMethod(String name, Descriptor descriptor);

/**
* Implementation may throw any exception.
Expand All @@ -49,5 +44,5 @@ public interface ClassInfo<C> {
* @param descriptor Field descriptor.
* @return Class field.
*/
@Nullable MemberInfo<?> getField(String name, String descriptor);
@Nullable FieldInfo getField(String name, Descriptor descriptor);
}
4 changes: 4 additions & 0 deletions src/main/java/dev/xdark/jlinker/Descriptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package dev.xdark.jlinker;

public interface Descriptor {
}
25 changes: 25 additions & 0 deletions src/main/java/dev/xdark/jlinker/DescriptorString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.xdark.jlinker;

public final class DescriptorString implements MethodDescriptor, FieldDescriptor {
private final String value;

public DescriptorString(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
return o instanceof DescriptorString &&
value.equals(((DescriptorString) o).value);
}

@Override
public int hashCode() {
return value.hashCode();
}

@Override
public String toString() {
return value;
}
}
Loading

0 comments on commit a49a7d6

Please sign in to comment.