build: configure spotless for kotlin, apply code style fixes

This commit is contained in:
Skylot
2022-10-28 14:58:31 +01:00
parent 6912ed40b4
commit 745f46f81f
26 changed files with 169 additions and 104 deletions
+20 -6
View File
@@ -1,6 +1,10 @@
//file:noinspection UnnecessaryQualifiedReference
plugins {
id 'com.github.ben-manes.versions' version '0.45.0'
id 'com.diffplug.spotless' version '6.13.0'
id 'org.jetbrains.kotlin.jvm' version '1.7.20' // needed for spotless
}
ext.jadxVersion = System.getenv('JADX_VERSION') ?: "dev"
@@ -9,6 +13,7 @@ println("jadx version: ${jadxVersion}")
allprojects {
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'checkstyle'
version = jadxVersion
@@ -49,11 +54,6 @@ allprojects {
mavenLocal()
mavenCentral()
google()
// Commented out for now since we're using a local mapping-io fork atm.
// maven {
// name 'FabricMC'
// url 'https://maven.fabricmc.net/'
// }
}
}
@@ -75,8 +75,22 @@ spotless {
trimTrailingWhitespace()
endWithNewline()
}
kotlin {
target fileTree(rootDir).matching {
include 'jadx-plugins/jadx-script/**/*.kt'
// include 'jadx-plugins/jadx-script/examples/scripts/**/*.jadx.kts'
}
ktlint()
.setUseExperimental(false)
.editorConfigOverride([indent_style: "tab"])
lineEndings(com.diffplug.spotless.LineEnding.UNIX)
encoding("UTF-8")
trimTrailingWhitespace()
endWithNewline()
}
format 'misc', {
target '**/*.gradle', '**/*.md', '**/*.xml', '**/.gitignore', '**/.properties'
target '**/*.gradle', '**/*.xml', '**/.gitignore', '**/.properties'
targetExclude ".gradle/**", ".idea/**", "*/build/**"
lineEndings(com.diffplug.spotless.LineEnding.UNIX)
@@ -71,4 +71,9 @@ public class DeobfuscatorVisitor extends AbstractVisitor {
}
}
}
@Override
public String toString() {
return "DeobfuscatorVisitor";
}
}
@@ -45,4 +45,9 @@ public class SaveDeobfMapping extends AbstractVisitor {
LOG.error("Failed to save deobfuscation map file '{}'", deobfMapFile.toAbsolutePath(), e);
}
}
@Override
public String toString() {
return "SaveDeobfMapping";
}
}
@@ -22,4 +22,9 @@ public abstract class AbstractVisitor implements IDexTreeVisitor {
public void visit(MethodNode mth) throws JadxException {
// no op implementation
}
@Override
public String toString() {
return this.getClass().getSimpleName();
}
}
@@ -1,3 +1,7 @@
/**
For script usage check https://github.com/skylot/jadx/blob/master/jadx-plugins/jadx-script/readme.md
*/
val jadx = getJadxInstance()
jadx.afterLoad {
@@ -4,7 +4,8 @@ NOTE: work still in progress!
### Examples
Check script examples in `examples/scripts/` (start with `hello`)
Check script examples in [`examples/scripts/`](https://github.com/skylot/jadx/tree/master/jadx-plugins/jadx-script/examples/scripts)
(start with [`hello`](https://github.com/skylot/jadx/blob/master/jadx-plugins/jadx-script/examples/scripts/hello.jadx.kts))
### Script usage
@@ -21,7 +22,7 @@ Just add script file as input
### Script development
Jadx-gui for now don't support autocompletion, errors highlighting, docs and code navigation
Jadx-gui for now don't support ~~autocompletion,~~ errors highlighting, docs and code navigation,
so best approach for script editing is to open jadx project in IntelliJ Idea and write your script in `examples/scripts/` folder.
Also, this will allow to debug your scripts: for that you need to create run configuration for jadx-cli or jadx-gui
add breakpoints and next run it in debug mode (jadx-gui is preferred because of faster script reload).
@@ -1,7 +1,3 @@
plugins {
kotlin("jvm") version "1.7.20"
}
dependencies {
implementation(project(":jadx-plugins:jadx-script:jadx-script-runtime"))
@@ -1,7 +1,3 @@
plugins {
kotlin("jvm") version "1.7.20"
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-scripting-common")
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm")
@@ -3,7 +3,12 @@ package jadx.plugins.script.ide
import jadx.plugins.script.runner.ScriptEval
import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
import kotlin.script.experimental.api.*
import kotlin.script.experimental.api.ReplCompletionResult
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.SourceCode
import kotlin.script.experimental.api.SourceCodeCompletionVariant
import kotlin.script.experimental.api.valueOrNull
import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.util.toSourceCodePosition
@@ -1,7 +1,5 @@
plugins {
id("jadx-library")
kotlin("jvm") version "1.7.20"
}
dependencies {
@@ -7,7 +7,12 @@ import jadx.plugins.script.runtime.JadxScriptData
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
import mu.KotlinLogging
import java.io.File
import kotlin.script.experimental.api.*
import kotlin.script.experimental.api.EvaluationResult
import kotlin.script.experimental.api.ResultValue
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
import kotlin.script.experimental.api.constructorArgs
import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
@@ -1,7 +1,5 @@
plugins {
id("jadx-library")
kotlin("jvm") version "1.7.20"
}
dependencies {
@@ -7,15 +7,22 @@ import jadx.api.JadxDecompiler
import jadx.api.JavaClass
import jadx.api.plugins.JadxPluginContext
import jadx.api.plugins.pass.JadxPass
import jadx.plugins.script.runtime.data.*
import jadx.plugins.script.runtime.data.Debug
import jadx.plugins.script.runtime.data.Decompile
import jadx.plugins.script.runtime.data.Gui
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
import jadx.plugins.script.runtime.data.JadxScriptOptions
import jadx.plugins.script.runtime.data.Rename
import jadx.plugins.script.runtime.data.Replace
import jadx.plugins.script.runtime.data.Search
import jadx.plugins.script.runtime.data.Stages
import mu.KLogger
import mu.KotlinLogging
import java.io.File
open class JadxScriptBaseClass(private val scriptData: JadxScriptData) {
val scriptName = scriptData.scriptName
val log = KotlinLogging.logger("JadxScript:${scriptName}")
val log = KotlinLogging.logger("JadxScript:$scriptName")
fun getJadxInstance() = JadxScriptInstance(scriptData, log)
@@ -46,7 +53,7 @@ class JadxScriptInstance(
private val decompiler = scriptData.jadxInstance
val options: JadxScriptOptions by lazy { JadxScriptOptions(this, scriptData.options) }
val rename: RenamePass by lazy { RenamePass(this) }
val rename: Rename by lazy { Rename(this) }
val stages: Stages by lazy { Stages(this) }
val replace: Replace by lazy { Replace(this) }
val decompile: Decompile by lazy { Decompile(this) }
@@ -2,9 +2,27 @@ package jadx.plugins.script.runtime
import kotlinx.coroutines.runBlocking
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.*
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.ScriptAcceptedLocation
import kotlin.script.experimental.api.ScriptCollectedData
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.ScriptConfigurationRefinementContext
import kotlin.script.experimental.api.acceptedLocations
import kotlin.script.experimental.api.asSuccess
import kotlin.script.experimental.api.baseClass
import kotlin.script.experimental.api.collectedAnnotations
import kotlin.script.experimental.api.defaultImports
import kotlin.script.experimental.api.dependencies
import kotlin.script.experimental.api.ide
import kotlin.script.experimental.api.onSuccess
import kotlin.script.experimental.api.refineConfiguration
import kotlin.script.experimental.api.with
import kotlin.script.experimental.dependencies.CompoundDependenciesResolver
import kotlin.script.experimental.dependencies.DependsOn
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
import kotlin.script.experimental.dependencies.Repository
import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver
import kotlin.script.experimental.dependencies.resolveFromScriptSourceAnnotations
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
import kotlin.script.experimental.jvm.jvm
@@ -20,7 +20,7 @@ class JadxScriptAllOptions : JadxPluginOptions {
class ScriptOption<T>(
val name: String,
val id: String,
private val getter: () -> T,
private val getter: () -> T
) {
private var validate: ((T) -> Boolean)? = null
@@ -0,0 +1,52 @@
package jadx.plugins.script.runtime.data
import jadx.core.dex.attributes.AFlag
import jadx.core.dex.attributes.IAttributeNode
import jadx.core.dex.nodes.IDexNode
import jadx.core.dex.nodes.RootNode
import jadx.plugins.script.runtime.JadxScriptInstance
class Rename(private val jadx: JadxScriptInstance) {
fun all(makeNewName: (String) -> String?) {
all { name, _ -> makeNewName.invoke(name) }
}
fun all(makeNewName: (String, IDexNode) -> String?) {
jadx.addPass(object : ScriptOrderedPreparePass(
jadx,
"RenameAll",
runBefore = listOf("RenameVisitor")
) {
override fun init(root: RootNode) {
for (pkgNode in root.packages) {
rename(makeNewName, pkgNode, pkgNode.pkgInfo.name)
}
for (cls in root.classes) {
rename(makeNewName, cls, cls.name)
for (mth in cls.methods) {
if (!mth.isConstructor) {
rename(makeNewName, mth, mth.name)
}
}
for (fld in cls.fields) {
rename(makeNewName, fld, fld.name)
}
}
}
private inline fun <T : IDexNode> rename(
makeNewName: (String, IDexNode) -> String?,
node: T,
name: String
) {
if (node is IAttributeNode && node.contains(AFlag.DONT_RENAME)) {
return
}
makeNewName.invoke(name, node)?.let {
node.rename(it)
}
}
})
}
}
@@ -14,12 +14,12 @@ class Stages(private val jadx: JadxScriptInstance) {
"StageRawInsns",
runAfter = listOf("start")
) {
override fun visit(mth: MethodNode) {
mth.instructions?.let {
block.invoke(mth, it)
override fun visit(mth: MethodNode) {
mth.instructions?.let {
block.invoke(mth, it)
}
}
}
})
})
}
fun mthEarlyBlocks(block: (MethodNode, List<BlockNode>) -> Unit) {
@@ -35,12 +35,12 @@ class Stages(private val jadx: JadxScriptInstance) {
"StageMthBlocks",
runBefore = listOf(beforePass)
) {
override fun visit(mth: MethodNode) {
mth.basicBlocks?.let {
block.invoke(mth, it)
override fun visit(mth: MethodNode) {
mth.basicBlocks?.let {
block.invoke(mth, it)
}
}
}
})
})
}
fun mthRegions(block: (MethodNode, Region) -> Unit) {
@@ -49,11 +49,11 @@ class Stages(private val jadx: JadxScriptInstance) {
"StageMthRegions",
runBefore = listOf("PrepareForCodeGen")
) {
override fun visit(mth: MethodNode) {
mth.region?.let {
block.invoke(mth, it)
override fun visit(mth: MethodNode) {
mth.region?.let {
block.invoke(mth, it)
}
}
}
})
})
}
}
@@ -1,28 +1,30 @@
package jadx.plugins.script.runtime.data
import jadx.api.plugins.pass.types.JadxDecompilePass
import jadx.api.plugins.pass.JadxPass
import jadx.api.plugins.pass.types.JadxPreparePass
import jadx.api.plugins.pass.impl.OrderedJadxPassInfo
import jadx.api.plugins.pass.impl.SimpleJadxPassInfo
import jadx.api.plugins.pass.types.JadxDecompilePass
import jadx.api.plugins.pass.types.JadxPreparePass
import jadx.core.dex.nodes.ClassNode
import jadx.core.dex.nodes.MethodNode
import jadx.core.dex.nodes.RootNode
import jadx.plugins.script.runtime.JadxScriptInstance
private fun buildScriptName(jadx: JadxScriptInstance, name: String) = "JadxScript${name}(${jadx.scriptName})"
private fun buildScriptName(jadx: JadxScriptInstance, name: String) = "JadxScript$name(${jadx.scriptName})"
private fun buildSimplePassInfo(jadx: JadxScriptInstance, name: String) =
SimpleJadxPassInfo(buildScriptName(jadx, name))
abstract class ScriptPreparePass(
private val jadx: JadxScriptInstance, private val name: String
private val jadx: JadxScriptInstance,
private val name: String
) : JadxPreparePass {
override fun getInfo() = buildSimplePassInfo(jadx, name)
}
abstract class ScriptDecompilePass(
private val jadx: JadxScriptInstance, private val name: String
private val jadx: JadxScriptInstance,
private val name: String
) : JadxDecompilePass {
override fun getInfo() = buildSimplePassInfo(jadx, name)
@@ -50,11 +52,17 @@ abstract class ScriptOrderedPass(
}
abstract class ScriptOrderedPreparePass(
jadx: JadxScriptInstance, name: String, runAfter: List<String> = listOf(), runBefore: List<String> = listOf()
) : ScriptOrderedPass(jadx, name, runAfter, runBefore), JadxPreparePass {}
jadx: JadxScriptInstance,
name: String,
runAfter: List<String> = listOf(),
runBefore: List<String> = listOf()
) : ScriptOrderedPass(jadx, name, runAfter, runBefore), JadxPreparePass
abstract class ScriptOrderedDecompilePass(
jadx: JadxScriptInstance, name: String, runAfter: List<String> = listOf(), runBefore: List<String> = listOf()
jadx: JadxScriptInstance,
name: String,
runAfter: List<String> = listOf(),
runBefore: List<String> = listOf()
) : ScriptOrderedPass(jadx, name, runAfter, runBefore), JadxDecompilePass {
override fun init(root: RootNode) {
@@ -1,52 +0,0 @@
package jadx.plugins.script.runtime.data
import jadx.core.dex.attributes.AFlag
import jadx.core.dex.attributes.IAttributeNode
import jadx.core.dex.nodes.IDexNode
import jadx.core.dex.nodes.RootNode
import jadx.plugins.script.runtime.JadxScriptInstance
class RenamePass(private val jadx: JadxScriptInstance) {
fun all(makeNewName: (String) -> String?) {
all { name, _ -> makeNewName.invoke(name) }
}
fun all(makeNewName: (String, IDexNode) -> String?) {
jadx.addPass(object : ScriptOrderedPreparePass(
jadx,
"RenameAll",
runBefore = listOf("RenameVisitor")
) {
override fun init(root: RootNode) {
for (pkgNode in root.packages) {
rename(makeNewName, pkgNode, pkgNode.pkgInfo.name)
}
for (cls in root.classes) {
rename(makeNewName, cls, cls.name)
for (mth in cls.methods) {
if (!mth.isConstructor) {
rename(makeNewName, mth, mth.name)
}
}
for (fld in cls.fields) {
rename(makeNewName, fld, fld.name)
}
}
}
private inline fun <T : IDexNode> rename(
makeNewName: (String, IDexNode) -> String?,
node: T,
name: String
) {
if (node is IAttributeNode && node.contains(AFlag.DONT_RENAME)) {
return
}
makeNewName.invoke(name, node)?.let {
node.rename(it)
}
}
})
}
}