From 40d1ae3e92d823b108de157c188f2fccf46f7996 Mon Sep 17 00:00:00 2001 From: Sam Cao Date: Sun, 26 Nov 2023 10:29:42 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=84=20refactor:=20Refactor=20class=20J?= =?UTF-8?q?avetShell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/build.gradle.kts | 1 + .../{JavetShell.kt => BaseJavetShell.kt} | 38 ++++------------ .../com/caoccao/javet/shell/JavetShellNode.kt | 43 +++++++++++++++++++ .../com/caoccao/javet/shell/JavetShellV8.kt | 38 ++++++++++++++++ .../kotlin/com/caoccao/javet/shell/Main.kt | 6 ++- 5 files changed, 96 insertions(+), 30 deletions(-) rename console/src/main/kotlin/com/caoccao/javet/shell/{JavetShell.kt => BaseJavetShell.kt} (74%) create mode 100644 console/src/main/kotlin/com/caoccao/javet/shell/JavetShellNode.kt create mode 100644 console/src/main/kotlin/com/caoccao/javet/shell/JavetShellV8.kt diff --git a/console/build.gradle.kts b/console/build.gradle.kts index 6d83c03..76c36fb 100644 --- a/console/build.gradle.kts +++ b/console/build.gradle.kts @@ -29,6 +29,7 @@ version = "0.1.0" dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10") implementation("com.caoccao.javet:javet:3.0.2") + implementation("com.caoccao.javet:javenode:0.3.0") // https://github.com/Kotlin/kotlinx-cli // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-cli-jvm diff --git a/console/src/main/kotlin/com/caoccao/javet/shell/JavetShell.kt b/console/src/main/kotlin/com/caoccao/javet/shell/BaseJavetShell.kt similarity index 74% rename from console/src/main/kotlin/com/caoccao/javet/shell/JavetShell.kt rename to console/src/main/kotlin/com/caoccao/javet/shell/BaseJavetShell.kt index 598db65..f2224e4 100644 --- a/console/src/main/kotlin/com/caoccao/javet/shell/JavetShell.kt +++ b/console/src/main/kotlin/com/caoccao/javet/shell/BaseJavetShell.kt @@ -21,7 +21,6 @@ import com.caoccao.javet.exceptions.JavetCompilationException import com.caoccao.javet.exceptions.JavetExecutionException import com.caoccao.javet.interop.V8Host import com.caoccao.javet.interop.V8Runtime -import com.caoccao.javet.interop.callback.JavetBuiltInModuleResolver import com.caoccao.javet.shell.constants.Constants import com.caoccao.javet.shell.entities.Options import com.caoccao.javet.shell.enums.ExitCode @@ -30,15 +29,17 @@ import java.io.File import java.util.* import java.util.concurrent.TimeUnit -class JavetShell( - private val options: Options, +abstract class BaseJavetShell( + protected val options: Options, ) : Runnable { + protected var v8Runtime: V8Runtime? = null + private var daemonThread: Thread? = null @Volatile private var running = false - private var v8Runtime: V8Runtime? = null + abstract val prompt: String fun execute(): ExitCode { println("${Constants.Application.NAME} v${Constants.Application.VERSION} (${options.jsRuntimeType.name} ${options.jsRuntimeType.version})") @@ -47,37 +48,14 @@ class JavetShell( V8Host.getInstance(options.jsRuntimeType).createV8Runtime().use { v8Runtime -> running = true this.v8Runtime = v8Runtime - if (options.jsRuntimeType.isNode) { - v8Runtime.v8ModuleResolver = JavetBuiltInModuleResolver() - v8Runtime.getExecutor( - """const process = require('process'); - process.on('unhandledRejection', (reason, promise) => { - console.error(); - console.error(reason.toString()); - console.error(); - });""" - ).executeVoid() - } else { - v8Runtime.setPromiseRejectCallback { _, _, value -> - println() - println(value.toString()) - println() - } - } + registerPromiseRejectCallback() daemonThread = Thread(this) daemonThread?.start() Scanner(System.`in`).use { scanner -> val sb = StringBuilder() var isMultiline = false while (running) { - val prompt = if (isMultiline) { - ">>> " - } else if (options.jsRuntimeType.isNode) { - "N > " - } else { - "V > " - } - print(prompt) + print(if (isMultiline) ">>> " else prompt) try { sb.appendLine(scanner.nextLine()) v8Runtime @@ -118,6 +96,8 @@ class JavetShell( return ExitCode.NoError } + protected abstract fun registerPromiseRejectCallback() + override fun run() { while (running) { v8Runtime?.await(V8AwaitMode.RunOnce) diff --git a/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellNode.kt b/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellNode.kt new file mode 100644 index 0000000..dc195cf --- /dev/null +++ b/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellNode.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.caoccao.javet.shell + +import com.caoccao.javet.interop.callback.JavetBuiltInModuleResolver +import com.caoccao.javet.shell.entities.Options + +class JavetShellNode( + options: Options, +) : BaseJavetShell(options) { + init { + assert(options.jsRuntimeType.isNode) { "JS runtime type must be Node." } + } + + override val prompt: String + get() = "N > " + + override fun registerPromiseRejectCallback() { + v8Runtime?.v8ModuleResolver = JavetBuiltInModuleResolver() + v8Runtime?.getExecutor( + """const process = require('process'); + process.on('unhandledRejection', (reason, promise) => { + console.error(); + console.error(reason.toString()); + console.error(); + });""" + )?.executeVoid() + } +} \ No newline at end of file diff --git a/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellV8.kt b/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellV8.kt new file mode 100644 index 0000000..650808b --- /dev/null +++ b/console/src/main/kotlin/com/caoccao/javet/shell/JavetShellV8.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.caoccao.javet.shell + +import com.caoccao.javet.shell.entities.Options + +class JavetShellV8( + options: Options, +) : BaseJavetShell(options) { + init { + assert(options.jsRuntimeType.isV8) { "JS runtime type must be V8." } + } + + override val prompt: String + get() = "V > " + + override fun registerPromiseRejectCallback() { + v8Runtime?.setPromiseRejectCallback { _, _, value -> + System.err.println() + System.err.println(value.toString()) + System.err.println() + } + } +} \ No newline at end of file diff --git a/console/src/main/kotlin/com/caoccao/javet/shell/Main.kt b/console/src/main/kotlin/com/caoccao/javet/shell/Main.kt index b7e5b31..96d0c9e 100644 --- a/console/src/main/kotlin/com/caoccao/javet/shell/Main.kt +++ b/console/src/main/kotlin/com/caoccao/javet/shell/Main.kt @@ -48,7 +48,11 @@ fun main(args: Array) { module, scriptName, ) - val javetShell = JavetShell(options) + val javetShell = if (options.jsRuntimeType.isNode) { + JavetShellNode(options) + } else { + JavetShellV8(options) + } val exitCode = try { javetShell.execute()