Skip to content

Commit

Permalink
Add annotations. Migrate to Kotlin DSL. Fix invokespecial resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
xxDark committed May 4, 2024
1 parent 31d8652 commit 4e3a06d
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 121 deletions.
83 changes: 0 additions & 83 deletions build.gradle

This file was deleted.

36 changes: 36 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
java
`maven-publish`
}

group = "dev.xdark"
version = "2.1.0"

repositories.mavenCentral()

dependencies {
val 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")

val asmVersion = "9.7"
testImplementation("org.ow2.asm:asm:$asmVersion")
testImplementation("org.ow2.asm:asm-tree:$asmVersion")

val annotationsVersion = "24.1.0"
compileOnly("org.jetbrains:annotations:$annotationsVersion")
testCompileOnly("org.jetbrains:annotations:$annotationsVersion")
}

tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.addAll(listOf("-parameters", "-g:lines,source,vars"))
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
withSourcesJar()
}
2 changes: 0 additions & 2 deletions settings.gradle

This file was deleted.

1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = "jlinker"
14 changes: 8 additions & 6 deletions src/main/java/dev/xdark/jlinker/Error.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package dev.xdark.jlinker;

import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public final class Error<V> implements Result<V> {
private static final List<Error<?>> ERRORS = Arrays.stream(FailureReason.values())
.map(Error::new)
.collect(Collectors.toList());
.<Error<?>>map(Error::new)
.toList();
private final FailureReason reason;

Error(FailureReason reason) {
this.reason = reason;
}

@Override
public V getValue() {
throw new UnsupportedOperationException();
public @NotNull V value() {
throw new IllegalStateException();
}

@Override
public FailureReason getFailureReason() {
public @NotNull FailureReason failureReason() {
return reason;
}

static <V> Error<V> of(FailureReason reason) {
//noinspection unchecked
return (Error<V>) ERRORS.get(reason.ordinal());
}
}
21 changes: 11 additions & 10 deletions src/main/java/dev/xdark/jlinker/JVMLinkResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
final class JVMLinkResolver implements LinkResolver {

@Override
public Result<MethodInfo> resolveVirtualMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type) {
public @NotNull Result<MethodInfo> resolveVirtualMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type) {
if (Modifier.isInterface(info.getAccessFlags())) {
return Error.of(FailureReason.ACC_INTERFACE_SET);
}
Expand All @@ -22,7 +22,7 @@ public Result<MethodInfo> resolveVirtualMethod(@NotNull ClassInfo info, @NotNull
}

@Override
public Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type, boolean itf) {
public @NotNull Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type, boolean itf) {
MethodInfo method;
if (itf) {
if (!Modifier.isInterface(info.getAccessFlags())) {
Expand All @@ -45,16 +45,19 @@ public Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo info, @NotNull
}

@Override
public Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type, boolean itf) {
public @NotNull Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type, boolean itf) {
if (Modifier.isInterface(info.getAccessFlags()) != itf) {
return Error.of(itf ? FailureReason.ACC_INTERFACE_UNSET : FailureReason.ACC_INTERFACE_SET);
}
MethodInfo method = itf ? uncachedInterfaceMethod(info, name, type) : uncachedLookupMethod(info, name, type);
MethodInfo method;
if (itf || (method = uncachedLookupMethod(info, name, type)) == null) {
method = uncachedInterfaceMethod(info, name, type);
}
return checkVirtualMethod(method);
}

@Override
public Result<MethodInfo> resolveInterfaceMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type) {
public @NotNull Result<MethodInfo> resolveInterfaceMethod(@NotNull ClassInfo info, @NotNull String name, @NotNull MethodDescriptor type) {
if (!Modifier.isInterface(info.getAccessFlags())) {
return Error.of(FailureReason.ACC_INTERFACE_UNSET);
}
Expand All @@ -69,7 +72,7 @@ public Result<MethodInfo> resolveInterfaceMethod(@NotNull ClassInfo info, @NotNu
}

@Override
public Result<FieldInfo> resolveStaticField(@NotNull ClassInfo owner, @NotNull String name, @NotNull FieldDescriptor type) {
public @NotNull Result<FieldInfo> resolveStaticField(@NotNull ClassInfo owner, @NotNull String name, @NotNull FieldDescriptor type) {
ClassInfo info = owner;
FieldInfo field = null;
while (owner != null) {
Expand All @@ -93,7 +96,7 @@ public Result<FieldInfo> resolveStaticField(@NotNull ClassInfo owner, @NotNull S
}

@Override
public Result<FieldInfo> resolveVirtualField(@NotNull ClassInfo info, @NotNull String name, @NotNull FieldDescriptor type) {
public @NotNull Result<FieldInfo> resolveVirtualField(@NotNull ClassInfo info, @NotNull String name, @NotNull FieldDescriptor type) {
while (info != null) {
FieldInfo field = info.getField(name, type);
if (field != null) {
Expand All @@ -111,9 +114,8 @@ public Result<FieldInfo> resolveVirtualField(@NotNull ClassInfo info, @NotNull S
MethodInfo uncachedLookupMethod(ClassInfo owner, String name, MethodDescriptor descriptor) {
do {
MethodInfo method = owner.getMethod(name, descriptor);
if (method != null) {
if (method != null)
return method;
}
} while ((owner = owner.getSuperclass()) != null);
return null;
}
Expand Down Expand Up @@ -153,7 +155,6 @@ MethodInfo uncachedInterfaceMethod(ClassInfo owner, String name, MethodDescripto
private <V extends MemberInfo, T extends Descriptor> V uncachedInterfaceLookup(ClassInfo info, String name, T desc, boolean guessAbstract, UncachedResolve<V, T> resolve) {
V guess = null;
Deque<ClassInfo> queue = new ArrayDeque<>();
queue.push(info);
do {
if (Modifier.isInterface(info.getAccessFlags())) {
// Only check field/method if it's an interface.
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/dev/xdark/jlinker/JVMRuntimeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ final class JVMRuntimeResolver implements RuntimeResolver {
public @NotNull Result<MethodInfo> resolveVirtualMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor) {
Result<MethodInfo> result = linkResolver.resolveVirtualMethod(owner, name, descriptor);
if (result instanceof Success) {
if (Modifier.isAbstract(result.getValue().getAccessFlags())) {
if (Modifier.isAbstract(result.value().getAccessFlags())) {
return Error.of(FailureReason.ACC_ABSTRACT_SET);
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/dev/xdark/jlinker/LinkResolver.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.xdark.jlinker;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Modifier;
Expand All @@ -20,6 +21,7 @@ public interface LinkResolver {
* @param itf Whether the owner is an interface class.
* @return Resolution result.
*/
@NotNull
Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor, boolean itf);

/**
Expand All @@ -30,6 +32,7 @@ public interface LinkResolver {
* @param descriptor Method descriptor.
* @return Resolution result.
*/
@NotNull
default Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor) {
return resolveStaticMethod(owner, name, descriptor, Modifier.isInterface(owner.getAccessFlags()));
}
Expand All @@ -43,6 +46,7 @@ default Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo owner, @NotNul
* @param itf Whether the owner is an interface class.
* @return Resolution result.
*/
@NotNull
Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor, boolean itf);

/**
Expand All @@ -53,6 +57,7 @@ default Result<MethodInfo> resolveStaticMethod(@NotNull ClassInfo owner, @NotNul
* @param descriptor Method descriptor.
* @return Resolution result.
*/
@NotNull
default Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor) {
return resolveSpecialMethod(owner, name, descriptor, Modifier.isInterface(owner.getAccessFlags()));
}
Expand All @@ -65,6 +70,7 @@ default Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNu
* @param descriptor Method descriptor.
* @return Resolution result.
*/
@NotNull
Result<MethodInfo> resolveVirtualMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor);

/**
Expand All @@ -75,6 +81,7 @@ default Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNu
* @param descriptor Method descriptor.
* @return Resolution result.
*/
@NotNull
Result<MethodInfo> resolveInterfaceMethod(@NotNull ClassInfo owner, @NotNull String name, @NotNull MethodDescriptor descriptor);

/**
Expand All @@ -85,6 +92,7 @@ default Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNu
* @param descriptor Field descriptor.
* @return Resolution result.
*/
@NotNull
Result<FieldInfo> resolveStaticField(@NotNull ClassInfo owner, @NotNull String name, @NotNull FieldDescriptor descriptor);

/**
Expand All @@ -95,11 +103,14 @@ default Result<MethodInfo> resolveSpecialMethod(@NotNull ClassInfo owner, @NotNu
* @param descriptor Field descriptor.
* @return Resolution result.
*/
@NotNull
Result<FieldInfo> resolveVirtualField(@NotNull ClassInfo owner, @NotNull String name, @NotNull FieldDescriptor descriptor);

/**
* @return JVM link resolver.
*/
@NotNull
@Contract(pure = true)
static LinkResolver jvm() {
return new JVMLinkResolver();
}
Expand Down
23 changes: 20 additions & 3 deletions src/main/java/dev/xdark/jlinker/Result.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
package dev.xdark.jlinker;

public interface Result<V> {
import org.jetbrains.annotations.NotNull;

V getValue();
/**
* Resolution result.
*
* @author xDark
*/
public sealed interface Result<V> permits Success, Error {

FailureReason getFailureReason();
/**
* @return Resolution result.
* @throws IllegalStateException If in error state.
*/
@NotNull
V value();

/**
* @return Resolution result.
* @throws IllegalStateException If in success state.
*/
@NotNull
FailureReason failureReason();
}
6 changes: 3 additions & 3 deletions src/main/java/dev/xdark/jlinker/Success.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ public final class Success<V> implements Result<V> {
}

@Override
public @NotNull V getValue() {
public @NotNull V value() {
return value;
}

@Override
public @NotNull FailureReason getFailureReason() {
throw new UnsupportedOperationException();
public @NotNull FailureReason failureReason() {
throw new IllegalStateException();
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module dev.xdark.jlinker {
exports dev.xdark.jlinker;
requires static org.jetbrains.annotations;
}
9 changes: 0 additions & 9 deletions src/main/java11/dev/xdark/jlinker/Java11Hack.java

This file was deleted.

Loading

0 comments on commit 4e3a06d

Please sign in to comment.