diff --git a/.editorconfig b/.editorconfig index 05586dfd..6ef7c0dc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ tab_width = 4 [*.{gradle,java}] ij_continuation_indent_size = 8 -ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.** +ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.**,|,matcher.** ij_java_class_count_to_use_import_on_demand = 999 [*.{yml,yaml}] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..cc23192c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto eol=lf +*.bat text eol=crlf diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0419eb06..1204ab4c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -4,15 +4,15 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v3 + - name: Set up JDK + uses: actions/setup-java@v4 with: - java-version: "17" + java-version: "21" distribution: "temurin" - name: Validate Gradle wrapper @@ -22,7 +22,7 @@ jobs: run: ./gradlew build --stacktrace --warning-mode=fail - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: build-artifacts path: build/libs diff --git a/build.gradle b/build.gradle index bd0ffe46..c642745e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,23 +3,27 @@ plugins { id 'application' id 'maven-publish' id "checkstyle" + id 'com.diffplug.spotless' id 'org.openjfx.javafxplugin' - id 'com.github.johnrengelman.shadow' id 'org.gradlex.extra-java-module-info' + id 'com.gradleup.shadow' id 'eclipse' } repositories { mavenCentral() maven { - name "Fabric" - url 'https://maven.fabricmc.net/' + name = "Fabric" + url = 'https://maven.fabricmc.net/' } } -archivesBaseName = 'matcher' group = 'net.fabricmc' +base { + archivesName = 'matcher' +} + def ENV = System.getenv() checkstyle { @@ -27,6 +31,17 @@ checkstyle { toolVersion = project.checkstyle_version } +spotless { + lineEndings = com.diffplug.spotless.LineEnding.UNIX + + java { + removeUnusedImports() + importOrder('java.', 'javax.', '', 'net.fabricmc.', 'matcher.') + indentWithTabs() + trimTrailingWhitespace() + } +} + java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 @@ -68,8 +83,10 @@ dependencies { implementation "org.bitbucket.mstrobel:procyon-compilertools:${procyon_version}" implementation ("io.github.skylot:jadx-core:${jadx_version}") { exclude group: 'com.android.tools.build', module: 'aapt2-proto' + exclude group: 'com.google.protobuf', module: 'protobuf-java' } implementation ("io.github.skylot:jadx-java-input:${jadx_version}") { + exclude group: 'com.android.tools.build', module: 'aapt2-proto' exclude group: 'io.github.skylot', module: 'raung-disasm' } runtimeOnly "org.tinylog:tinylog-impl:${tinylog_version}" @@ -107,7 +124,6 @@ extraJavaModuleInfo { // JADX automaticModule("io.github.skylot:jadx-core", "jadx.core") - automaticModule("io.github.skylot:jadx-plugins-api", "jadx.plugins.api") automaticModule("io.github.skylot:jadx-java-input", "jadx.plugins.java_input") } diff --git a/checkstyle.xml b/checkstyle.xml index 705b7661..483f4860 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -5,9 +5,10 @@ + - - + + @@ -47,6 +48,7 @@ if is a space, indicating a formatting error or ' */', it'll ignore the instance if is a tab, indicating a continued line, it'll ignore the instance is 'if', 'do', 'while', 'for', 'try' or nothing (instance initializer block) + - first \n: with positive lookbehind (?<=\n) to move the error marker to a more reasonable place - capture tabs for , later referenced via \1 - remaining preceding line as a non-comment (doesn't start with '/', '//', ' ' or '\t') or multiple lines where all but the first are a single line comment with the same indentation @@ -66,6 +68,13 @@ + + + + + + + @@ -74,7 +83,7 @@ - + @@ -112,11 +121,11 @@ - + - - - + + + @@ -128,8 +137,7 @@ - + @@ -159,6 +167,8 @@ + + diff --git a/gradle.properties b/gradle.properties index 457ad746..081e8790 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,22 +2,23 @@ org.gradle.jvmargs=-Xmx2G # Gradle Plugins +spotless_version = 6.25.0 javafx_plugin_version = 0.1.0 -shadow_version = 7.1.2 -extra_java_module_info_version = 1.6 +extra_java_module_info_version = 1.9 +shadow_version = 8.3.5 -# Poject Properties +# Project Properties version = 0.1.0 # Project Dependencies -asm_version = 9.6 -fabric_cfr_version = 0.2.1 -vineflower_version = 1.9.3 +asm_version = 9.7.1 +fabric_cfr_version = 0.2.2 +vineflower_version = 1.10.1 procyon_version = 0.6.0 -jadx_version = 1.4.7 -mappingio_version = 0.5.0 -javaparser_version = 3.25.6 -javafx_version = 21.0.1 -checkstyle_version = 10.12.5 -slf4j_version = 2.0.12 +jadx_version = 1.5.1 +mappingio_version = 0.7.1 +javaparser_version = 3.26.3 +javafx_version = 21.0.6 +checkstyle_version = 10.21.2 +slf4j_version = 2.0.16 tinylog_version = 2.7.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f..249e5832 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661e..e382118b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c7873..a69d9cb6 100755 --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd32..f127cfd4 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 797324ea..3567a5af 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,9 +4,10 @@ pluginManagement { mavenCentral(); } plugins { + id 'com.diffplug.spotless' version "${spotless_version}" id 'org.openjfx.javafxplugin' version "${javafx_plugin_version}" - id 'com.github.johnrengelman.shadow' version "${shadow_version}" id 'org.gradlex.extra-java-module-info' version "${extra_java_module_info_version}" + id 'com.gradleup.shadow' version "${shadow_version}" } } diff --git a/src/main/java/matcher/gui/menu/UidMenu.java b/src/main/java/matcher/gui/menu/UidMenu.java index 84df5d9d..7c5cd0f9 100644 --- a/src/main/java/matcher/gui/menu/UidMenu.java +++ b/src/main/java/matcher/gui/menu/UidMenu.java @@ -26,8 +26,8 @@ import matcher.type.ClassEnvironment; import matcher.type.ClassInstance; import matcher.type.FieldInstance; -import matcher.type.Matchable; import matcher.type.MatchType; +import matcher.type.Matchable; import matcher.type.MemberInstance; import matcher.type.MethodInstance; import matcher.type.MethodVarInstance; diff --git a/src/main/java/matcher/srcprocess/HtmlPrinter.java b/src/main/java/matcher/srcprocess/HtmlPrinter.java index 1bca18ca..379baa7b 100644 --- a/src/main/java/matcher/srcprocess/HtmlPrinter.java +++ b/src/main/java/matcher/srcprocess/HtmlPrinter.java @@ -1,8 +1,8 @@ /* - * Most of this file is copied from DefaultPrettyPrinterVisitor (commit 19e0559), + * Most of this file is copied from DefaultPrettyPrinterVisitor (commit 85bb189), * tweaked to output HTML instead of plain text. Original license: * - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2024 The JavaParser Team. * * This file is part of JavaParser. * @@ -120,7 +120,6 @@ import com.github.javaparser.ast.type.ReferenceType; import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.TypeParameter; -import com.github.javaparser.ast.type.UnknownType; import com.github.javaparser.ast.type.VarType; import com.github.javaparser.ast.type.VoidType; import com.github.javaparser.ast.type.WildcardType; @@ -1168,7 +1167,7 @@ public void visit(final Parameter n, final Void arg) { printer.print("..."); } - if (!(n.getType() instanceof UnknownType)) { + if (!(n.getType().isUnknownType())) { printer.print(" "); } @@ -1270,6 +1269,16 @@ public void visit(final SwitchEntry n, final Void arg) { } } + // `case null, default -> ...` added in JEP 441 + if (n.getLabels().isNonEmpty() && n.isDefault()) { + printer.print(", default"); + } + + if (n.getGuard().isPresent()) { + printer.print(" when "); + n.getGuard().get().accept(this, arg); + } + printer.print(separator); } diff --git a/src/main/java/matcher/srcprocess/Jadx.java b/src/main/java/matcher/srcprocess/Jadx.java index 7ccc9aa9..bc7c98ed 100644 --- a/src/main/java/matcher/srcprocess/Jadx.java +++ b/src/main/java/matcher/srcprocess/Jadx.java @@ -1,17 +1,10 @@ package matcher.srcprocess; -import java.io.IOException; -import java.util.function.Consumer; - import jadx.api.CommentsLevel; import jadx.api.JadxArgs; import jadx.api.JadxDecompiler; import jadx.api.impl.NoOpCodeCache; -import jadx.api.plugins.input.data.IClassData; -import jadx.api.plugins.input.data.ILoadResult; -import jadx.api.plugins.input.data.IResourceData; -import jadx.plugins.input.java.JavaClassReader; -import jadx.plugins.input.java.data.JavaClassData; +import jadx.plugins.input.java.JavaInputPlugin; import matcher.NameType; import matcher.Util; @@ -21,28 +14,11 @@ public class Jadx implements Decompiler { @Override public String decompile(ClassInstance cls, ClassFeatureExtractor env, NameType nameType) { - String errorMessage = null; - final String fullClassName = cls.getName(NameType.PLAIN, true); - - try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) { - jadx.addCustomLoad(new ILoadResult() { - @Override - public void close() throws IOException { } - - @Override - public void visitClasses(Consumer consumer) { - consumer.accept(new JavaClassData(new JavaClassReader(0, - fullClassName + ".class", cls.serialize(nameType)))); - } + String fullClassName = cls.getName(NameType.PLAIN, true); + String errorMessage; - @Override - public void visitResources(Consumer consumer) { } - - @Override - public boolean isEmpty() { - return false; - } - }); + try (JadxDecompiler jadx = new JadxDecompiler(createJadxArgs())) { + jadx.addCustomCodeLoader(JavaInputPlugin.loadSingleClass(cls.serialize(nameType), fullClassName)); jadx.load(); assert jadx.getClassesWithInners().size() == 1; @@ -54,22 +30,17 @@ public boolean isEmpty() { throw new RuntimeException(errorMessage != null ? errorMessage : "JADX couldn't find the requested class"); } - private static final JadxArgs jadxArgs; - - static { - jadxArgs = new JadxArgs() { - @Override - public void close() { - return; - } - }; - jadxArgs.setCodeCache(NoOpCodeCache.INSTANCE); - jadxArgs.setShowInconsistentCode(true); - jadxArgs.setInlineAnonymousClasses(false); - jadxArgs.setInlineMethods(false); - jadxArgs.setSkipResources(true); - jadxArgs.setRenameValid(false); - jadxArgs.setRespectBytecodeAccModifiers(true); - jadxArgs.setCommentsLevel(CommentsLevel.INFO); + private JadxArgs createJadxArgs() { + JadxArgs args = new JadxArgs(); + args.setCodeCache(NoOpCodeCache.INSTANCE); + args.setShowInconsistentCode(true); + args.setInlineAnonymousClasses(false); + args.setInlineMethods(false); + args.setRespectBytecodeAccModifiers(true); + args.setRenameValid(false); + args.setCodeIndentStr("\t"); + args.setCommentsLevel(CommentsLevel.INFO); + + return args; } } diff --git a/src/main/java/matcher/srcprocess/SrcDecorator.java b/src/main/java/matcher/srcprocess/SrcDecorator.java index f694af43..a8fc5da4 100644 --- a/src/main/java/matcher/srcprocess/SrcDecorator.java +++ b/src/main/java/matcher/srcprocess/SrcDecorator.java @@ -8,6 +8,7 @@ import com.github.javaparser.JavaParser; import com.github.javaparser.JavaToken; +import com.github.javaparser.JavaToken.Kind; import com.github.javaparser.ParseResult; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ParserConfiguration.LanguageLevel; @@ -15,7 +16,6 @@ import com.github.javaparser.Problem; import com.github.javaparser.Range; import com.github.javaparser.TokenRange; -import com.github.javaparser.JavaToken.Kind; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; diff --git a/src/main/java/matcher/srcprocess/TypeResolver.java b/src/main/java/matcher/srcprocess/TypeResolver.java index 1faeb31a..27302ebb 100644 --- a/src/main/java/matcher/srcprocess/TypeResolver.java +++ b/src/main/java/matcher/srcprocess/TypeResolver.java @@ -24,10 +24,10 @@ import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.VoidType; -import matcher.type.ClassInstance; -import matcher.type.FieldInstance; import matcher.NameType; import matcher.type.ClassEnv; +import matcher.type.ClassInstance; +import matcher.type.FieldInstance; import matcher.type.Matchable; import matcher.type.MethodInstance; diff --git a/src/main/java/matcher/srcprocess/Vineflower.java b/src/main/java/matcher/srcprocess/Vineflower.java index 78efffcb..52a48f02 100644 --- a/src/main/java/matcher/srcprocess/Vineflower.java +++ b/src/main/java/matcher/srcprocess/Vineflower.java @@ -30,7 +30,7 @@ public String decompile(ClassInstance cls, ClassFeatureExtractor env, NameType n Map properties = new HashMap<>(IFernflowerPreferences.DEFAULTS); properties.put(IFernflowerPreferences.REMOVE_BRIDGE, "0"); properties.put(IFernflowerPreferences.REMOVE_SYNTHETIC, "0"); - properties.put(IFernflowerPreferences.INDENT_STRING, "\n"); + properties.put(IFernflowerPreferences.INDENT_STRING, "\t"); properties.put(IFernflowerPreferences.THREADS, String.valueOf(Math.max(1, Runtime.getRuntime().availableProcessors() - 2))); properties.put(IFernflowerPreferences.LOG_LEVEL, IFernflowerLogger.Severity.WARN.name()); diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 3ac85dbe..68fa7dc0 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -27,7 +27,6 @@ requires org.objectweb.asm.util; requires procyon.compilertools; requires jadx.core; - requires jadx.plugins.api; requires jadx.plugins.java_input; requires transitive net.fabricmc.mappingio;