From 97d6f749ee2014a7d90f250d914341fd93501032 Mon Sep 17 00:00:00 2001 From: Wagyourtail Date: Fri, 6 Dec 2024 20:04:40 -0600 Subject: [PATCH] debugSkipStub --- .../jvmdg/gradle/flags/DowngradeFlags.kt | 13 +++ .../java/xyz/wagyourtail/jvmdg/Constants.java | 1 + .../java/xyz/wagyourtail/jvmdg/cli/Flags.java | 24 ++++- .../jvmdg/version/VersionProvider.java | 102 +++++++++--------- .../map/FullyQualifiedMemberNameAndDesc.java | 22 ++++ 5 files changed, 111 insertions(+), 51 deletions(-) diff --git a/gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags/DowngradeFlags.kt b/gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags/DowngradeFlags.kt index c5323db..3b50ca7 100644 --- a/gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags/DowngradeFlags.kt +++ b/gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags/DowngradeFlags.kt @@ -114,4 +114,17 @@ interface DowngradeFlags: TransformParameters { @get:Optional val downgradeFromMultiReleases: Property + /** + * 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 + } diff --git a/src/main/java/xyz/wagyourtail/jvmdg/Constants.java b/src/main/java/xyz/wagyourtail/jvmdg/Constants.java index dc4b945..27531d1 100644 --- a/src/main/java/xyz/wagyourtail/jvmdg/Constants.java +++ b/src/main/java/xyz/wagyourtail/jvmdg/Constants.java @@ -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"; diff --git a/src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java b/src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java index 613ac0c..cb85d8c 100644 --- a/src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java +++ b/src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java @@ -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; @@ -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 debugSkipStubs = new HashSet<>(getDebugSkip()); + public Set 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 debugSkipStub = new HashSet<>(getDebugSkipStub()); + /** * if should move the original class file to the multi-release directory * @@ -287,7 +297,17 @@ public boolean checkInIgnoreWarnings(String className) { } /* initialization methods */ - private Set getDebugSkip() { + private Set getDebugSkipStub() { + Set 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 getDebugSkipStubs() { Set skip = new HashSet<>(); String skipStubs = System.getProperty(Constants.DEBUG_SKIP_STUBS); if (skipStubs == null) return skip; diff --git a/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java b/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java index 8ee0e8f..0cb09ef 100644 --- a/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java +++ b/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java @@ -261,65 +261,69 @@ public List init() { public void stub(Class clazz) { Set 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, Adapter>(clazz, stub))); } - classStubs.put(value, new Pair<>(target, new Pair, 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 diff --git a/src/main/java/xyz/wagyourtail/jvmdg/version/map/FullyQualifiedMemberNameAndDesc.java b/src/main/java/xyz/wagyourtail/jvmdg/version/map/FullyQualifiedMemberNameAndDesc.java index 8a57811..c2251f3 100644 --- a/src/main/java/xyz/wagyourtail/jvmdg/version/map/FullyQualifiedMemberNameAndDesc.java +++ b/src/main/java/xyz/wagyourtail/jvmdg/version/map/FullyQualifiedMemberNameAndDesc.java @@ -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(";")) {