Skip to content

Commit

Permalink
debugSkipStub
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Dec 7, 2024
1 parent 978dee0 commit 97d6f74
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,17 @@ interface DowngradeFlags: TransformParameters {
@get:Optional
val downgradeFromMultiReleases: Property<Boolean>

/**
* this skips applying specific stub classes/methods, for example to disable the JEP 400, you would put
* {@link xyz.wagyourtail.jvmdg.j18.stub.java_base.J_L_System} in.
*
* To add to this list, add either classes with `Lpackage/to/ClassName;` or methods/fields like `Lpackage/to/ClassName;methodName;()V`.
* where each part is seperated by a `;` (with the first one pulling double-duty as the class descriptor terminator)
*
* @since 1.3.0
*/
@get:Input
@get:Optional
val debugSkipStub: SetProperty<String>

}
1 change: 1 addition & 0 deletions src/main/java/xyz/wagyourtail/jvmdg/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class Constants {
public static final String IGNORE_WARNINGS = "jvmdg.ignoreWarnings";

public static final String DEBUG = "jvmdg.debug";
public static final String DEBUG_SKIP_STUB = "jvmdg.debug.skipStub";
public static final String DEBUG_SKIP_STUBS = "jvmdg.debug.skipStubs";
public static final String DEBUG_DUMP_CLASSES = "jvmdg.debug.dumpClasses";

Expand Down
24 changes: 22 additions & 2 deletions src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import xyz.wagyourtail.jvmdg.logging.Logger;
import xyz.wagyourtail.jvmdg.util.Consumer;
import xyz.wagyourtail.jvmdg.util.Function;
import xyz.wagyourtail.jvmdg.version.map.FullyQualifiedMemberNameAndDesc;

import java.beans.XMLDecoder;
import java.io.File;
Expand Down Expand Up @@ -86,13 +87,22 @@ public class Flags {
* {@link xyz.wagyourtail.jvmdg.version.VersionProvider#otherTransforms(ClassNode, Set, Function, Set)}
* such as {@code INVOKE_INTERFACE} -> {@code INVOKE_SPECIAL} for private interface methods in java 9 -> 8
*/
public Set<Integer> debugSkipStubs = new HashSet<>(getDebugSkip());
public Set<Integer> debugSkipStubs = new HashSet<>(getDebugSkipStubs());
/**
* sets if classes should be dumped to the {@link Constants#DEBUG_DIR} directory
*
* @since 0.9.0
*/
public boolean debugDumpClasses = Boolean.getBoolean(Constants.DEBUG_DUMP_CLASSES);

/**
* this skips applying specific stub classes/methods, for example to disable the JEP 400, you would put
* {@link xyz.wagyourtail.jvmdg.j18.stub.java_base.J_L_System} in.
*
* @since 1.3.0
*/
public Set<FullyQualifiedMemberNameAndDesc> debugSkipStub = new HashSet<>(getDebugSkipStub());

/**
* if should move the original class file to the multi-release directory
*
Expand Down Expand Up @@ -287,7 +297,17 @@ public boolean checkInIgnoreWarnings(String className) {
}

/* initialization methods */
private Set<Integer> getDebugSkip() {
private Set<FullyQualifiedMemberNameAndDesc> getDebugSkipStub() {
Set<FullyQualifiedMemberNameAndDesc> skip = new HashSet<>();
String skipStubs = System.getProperty(Constants.DEBUG_SKIP_STUB);
if (skipStubs == null) return skip;
for (String s : skipStubs.split("\\|")) {
skip.add(FullyQualifiedMemberNameAndDesc.of(s));
}
return skip;
}

private Set<Integer> getDebugSkipStubs() {
Set<Integer> skip = new HashSet<>();
String skipStubs = System.getProperty(Constants.DEBUG_SKIP_STUBS);
if (skipStubs == null) return skip;
Expand Down
102 changes: 53 additions & 49 deletions src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -261,65 +261,69 @@ public List<ClassMapping> init() {
public void stub(Class<?> clazz) {
Set<String> warnings = new LinkedHashSet<>();
try {
if (clazz.isAnnotationPresent(Adapter.class)) {
Adapter stub = clazz.getAnnotation(Adapter.class);
if (stub.value().isEmpty()) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Adapter must have a ref");
} else {
Type value;
if (stub.value().startsWith("L") && stub.value().endsWith(";")) {
value = Type.getType(stub.value());
} else {
value = Type.getObjectType(stub.value());
}
// if (classStubs.containsKey(type)) {
// throw new IllegalArgumentException("Class " + clazz.getName() + ", @Adapter ref " + type.getInternalName() + " already exists");
// }
Type target;
if (stub.target().isEmpty()) {
target = Type.getType(clazz);
FullyQualifiedMemberNameAndDesc fqm = FullyQualifiedMemberNameAndDesc.of(clazz);
if (!downgrader.flags.debugSkipStub.contains(fqm)) {
if (clazz.isAnnotationPresent(Adapter.class)) {
Adapter stub = clazz.getAnnotation(Adapter.class);
if (stub.value().isEmpty()) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Adapter must have a ref");
} else {
if (stub.target().startsWith("L") && stub.target().endsWith(";")) {
target = Type.getType(stub.target());
Type value;
if (stub.value().startsWith("L") && stub.value().endsWith(";")) {
value = Type.getType(stub.value());
} else {
value = Type.getObjectType(stub.value());
}
// if (classStubs.containsKey(type)) {
// throw new IllegalArgumentException("Class " + clazz.getName() + ", @Adapter ref " + type.getInternalName() + " already exists");
// }
Type target;
if (stub.target().isEmpty()) {
target = Type.getType(clazz);
} else {
target = Type.getObjectType(stub.target());
if (stub.target().startsWith("L") && stub.target().endsWith(";")) {
target = Type.getType(stub.target());
} else {
target = Type.getObjectType(stub.target());
}
}
classStubs.put(value, new Pair<>(target, new Pair<Class<?>, Adapter>(clazz, stub)));
}
classStubs.put(value, new Pair<>(target, new Pair<Class<?>, Adapter>(clazz, stub)));
}
}
try {
for (Method method : clazz.getDeclaredMethods()) {
try {
if (method.isAnnotationPresent(Stub.class)) {
Stub stub = method.getAnnotation(Stub.class);
FullyQualifiedMemberNameAndDesc target = resolveStubTarget(method, stub.ref());
Type owner = target.getOwner();
MemberNameAndDesc member = target.toMemberNameAndDesc();
getStubMapper(owner, warnings).addStub(member, method, stub);
} else if (method.isAnnotationPresent(Modify.class)) {
Modify modify = method.getAnnotation(Modify.class);
FullyQualifiedMemberNameAndDesc target = resolveModifyTarget(method, modify.ref());
Type owner = target.getOwner();
MemberNameAndDesc member = target.toMemberNameAndDesc();
// ensure method parameters are valid
Class<?>[] params = method.getParameterTypes();
for (int i = 0; i < params.length; i++) {
if (i >= Modify.MODIFY_SIG.length) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Modify method " + method.getName() + " has too many parameters");
}
if (params[i] != Modify.MODIFY_SIG[i]) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Modify method " + method.getName() + " parameter " + i + " must be of type " + Modify.MODIFY_SIG[i].getName());
try {
for (Method method : clazz.getDeclaredMethods()) {
if (downgrader.flags.debugSkipStub.contains(FullyQualifiedMemberNameAndDesc.of(method))) continue;
try {
if (method.isAnnotationPresent(Stub.class)) {
Stub stub = method.getAnnotation(Stub.class);
FullyQualifiedMemberNameAndDesc target = resolveStubTarget(method, stub.ref());
Type owner = target.getOwner();
MemberNameAndDesc member = target.toMemberNameAndDesc();
getStubMapper(owner, warnings).addStub(member, method, stub);
} else if (method.isAnnotationPresent(Modify.class)) {
Modify modify = method.getAnnotation(Modify.class);
FullyQualifiedMemberNameAndDesc target = resolveModifyTarget(method, modify.ref());
Type owner = target.getOwner();
MemberNameAndDesc member = target.toMemberNameAndDesc();
// ensure method parameters are valid
Class<?>[] params = method.getParameterTypes();
for (int i = 0; i < params.length; i++) {
if (i >= Modify.MODIFY_SIG.length) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Modify method " + method.getName() + " has too many parameters");
}
if (params[i] != Modify.MODIFY_SIG[i]) {
throw new IllegalArgumentException("Class " + clazz.getName() + ", @Modify method " + method.getName() + " parameter " + i + " must be of type " + Modify.MODIFY_SIG[i].getName());
}
}
getStubMapper(owner, warnings).addModify(member, method, modify);
}
getStubMapper(owner, warnings).addModify(member, method, modify);
} catch (Throwable e) {
logger.warn("failed to create stub for " + clazz.getName(), e);
}
} catch (Throwable e) {
logger.warn("failed to create stub for " + clazz.getName(), e);
}
} catch (Throwable e) {
logger.warn("failed to resolve methods for " + clazz.getName(), e);
}
} catch (Throwable e) {
logger.warn("failed to resolve methods for " + clazz.getName(), e);
}
try {
// inner classes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ public FullyQualifiedMemberNameAndDesc(Type owner, String name, Type desc) {
this.desc = desc;
}

public static FullyQualifiedMemberNameAndDesc of(String value) {
String[] vals = value.split(";", 3);
Type owner;
if (vals.length == 1) {
if (value.startsWith("L") && value.endsWith(";")) {
owner = Type.getType(value);
} else {
owner = Type.getObjectType(value);
}
return FullyQualifiedMemberNameAndDesc.of(owner);
} else {
owner = Type.getObjectType(vals[0].substring(1));
}
String name = vals[1];
Type desc = vals.length == 2 ? null : Type.getType(vals[2]);
return new FullyQualifiedMemberNameAndDesc(owner, name, desc);
}

public static FullyQualifiedMemberNameAndDesc of(Class<?> clazz) {
return new FullyQualifiedMemberNameAndDesc(Type.getType(clazz), null, null);
}

public static FullyQualifiedMemberNameAndDesc of(Ref ref) {
String owner;
if (ref.value().startsWith("L") && ref.value().endsWith(";")) {
Expand Down

0 comments on commit 97d6f74

Please sign in to comment.