feat(gui): add run, check and format script actions

This commit is contained in:
Skylot
2022-10-29 21:00:15 +01:00
parent 98cc1b1022
commit a2f018a00b
40 changed files with 719 additions and 83 deletions
@@ -6,12 +6,18 @@ dependencies {
implementation("io.github.microutils:kotlin-logging-jvm:3.0.2")
// script context support in IDE is poor, use stubs and manual imports for now
// kotlinScriptDef(project(":jadx-plugins:jadx-script:jadx-script-runtime"))
// manual imports (IDE can't import dependencies by scripts annotations)
implementation("com.github.javafaker:javafaker:1.0.2")
}
sourceSets {
main {
java.srcDirs("scripts", "context")
kotlin.srcDirs(
"scripts",
"context"
)
}
}
@@ -3,11 +3,14 @@ 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.ReplAnalyzerResult
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.analysisDiagnostics
import kotlin.script.experimental.api.renderedResultType
import kotlin.script.experimental.api.valueOrNull
import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.util.toSourceCodePosition
@@ -19,14 +22,30 @@ data class ScriptCompletionResult(
val reports: List<ScriptDiagnostic>
)
class JadxScriptAutoComplete(private val scriptName: String) {
data class ScriptAnalyzeResult(
val errors: List<ScriptDiagnostic>,
val renderType: String?,
val reports: List<ScriptDiagnostic>
)
class ScriptCompiler(private val scriptName: String) {
private val replCompiler = KJvmReplCompilerWithIdeServices()
private val compileConf = ScriptEval().buildCompileConf()
fun complete(code: String, cursor: Int): ScriptCompletionResult {
val result = complete(code.toScriptSource(scriptName), cursor)
return ScriptCompletionResult(
completions = result.valueOrNull()?.toList() ?: listOf(),
completions = result.valueOrNull()?.toList() ?: emptyList(),
reports = result.reports
)
}
fun analyze(code: String, cursor: Int): ScriptAnalyzeResult {
val result = analyze(code.toScriptSource(scriptName), cursor)
val analyzerResult = result.valueOrNull()
return ScriptAnalyzeResult(
errors = analyzerResult?.get(ReplAnalyzerResult.analysisDiagnostics)?.toList() ?: emptyList(),
renderType = analyzerResult?.get(ReplAnalyzerResult.renderedResultType),
reports = result.reports
)
}
@@ -36,4 +55,10 @@ class JadxScriptAutoComplete(private val scriptName: String) {
replCompiler.complete(code, cursor.toSourceCodePosition(code), compileConf)
}
}
private fun analyze(code: SourceCode, cursor: Int): ResultWithDiagnostics<ReplAnalyzerResult> {
return runBlocking {
replCompiler.analyze(code, cursor.toSourceCodePosition(code), compileConf)
}
}
}
@@ -2,8 +2,8 @@ package jadx.plugins.script.runner
import jadx.api.JadxDecompiler
import jadx.api.plugins.JadxPluginContext
import jadx.plugins.script.runtime.JadxScript
import jadx.plugins.script.runtime.JadxScriptData
import jadx.plugins.script.runtime.JadxScriptTemplate
import jadx.plugins.script.runtime.data.JadxScriptAllOptions
import mu.KotlinLogging
import java.io.File
@@ -43,10 +43,10 @@ class ScriptEval {
processEvalResult(result, scriptFile)
}
fun buildCompileConf() = createJvmCompilationConfigurationFromTemplate<JadxScript>()
fun buildCompileConf() = createJvmCompilationConfigurationFromTemplate<JadxScriptTemplate>()
fun buildEvalConf(scriptData: JadxScriptData): ScriptEvaluationConfiguration {
return createJvmEvaluationConfigurationFromTemplate<JadxScript> {
return createJvmEvaluationConfigurationFromTemplate<JadxScriptTemplate> {
constructorArgs(scriptData)
}
}
@@ -5,12 +5,13 @@ plugins {
dependencies {
api(project(":jadx-core"))
implementation("org.jetbrains.kotlin:kotlin-scripting-common")
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm")
implementation(kotlin("stdlib"))
implementation(kotlin("scripting-common"))
implementation(kotlin("scripting-jvm"))
// allow to use maven dependencies in scripts
implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies")
implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies-maven")
implementation(kotlin("scripting-dependencies"))
implementation(kotlin("scripting-dependencies-maven"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("io.github.microutils:kotlin-logging-jvm:3.0.2")
@@ -1,6 +1,7 @@
package jadx.plugins.script.runtime
import kotlinx.coroutines.runBlocking
import mu.KotlinLogging
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.ScriptAcceptedLocation
@@ -9,11 +10,11 @@ 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.isStandalone
import kotlin.script.experimental.api.onSuccess
import kotlin.script.experimental.api.refineConfiguration
import kotlin.script.experimental.api.with
@@ -31,7 +32,22 @@ import kotlin.script.experimental.jvm.jvm
fileExtension = "jadx.kts",
compilationConfiguration = JadxScriptConfiguration::class
)
abstract class JadxScript
abstract class JadxScriptTemplate(
private val scriptData: JadxScriptData
) {
val scriptName = scriptData.scriptName
val log = KotlinLogging.logger("JadxScript:$scriptName")
fun getJadxInstance() = JadxScriptInstance(scriptData, log)
fun println(message: Any?) {
log.info(message?.toString())
}
fun print(message: Any?) {
log.info(message?.toString())
}
}
object JadxScriptConfiguration : ScriptCompilationConfiguration({
defaultImports(DependsOn::class, Repository::class)
@@ -45,11 +61,11 @@ object JadxScriptConfiguration : ScriptCompilationConfiguration({
acceptedLocations(ScriptAcceptedLocation.Everywhere)
}
baseClass(JadxScriptBaseClass::class)
refineConfiguration {
onAnnotations(DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations)
}
isStandalone(false)
})
private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), MavenDependenciesResolver())
@@ -17,24 +17,8 @@ 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")
fun getJadxInstance() = JadxScriptInstance(scriptData, log)
fun println(message: Any?) {
log.info(message?.toString())
}
fun print(message: Any?) {
log.info(message?.toString())
}
}
class JadxScriptData(
val jadxInstance: JadxDecompiler,
val pluginContext: JadxPluginContext,
@@ -45,7 +45,6 @@ class JadxScriptOptions(
private val jadx: JadxScriptInstance,
private val options: JadxScriptAllOptions
) {
fun <T> register(
name: String,
desc: String,