This commit is contained in:
kunfei 2023-03-25 17:25:03 +08:00
parent f173ea9988
commit 49ef82b010
4 changed files with 80 additions and 10 deletions

View File

@ -5,9 +5,26 @@ import io.legado.app.constant.SCRIPT_ENGINE
import org.intellij.lang.annotations.Language
import org.junit.Assert
import org.junit.Test
import org.mozilla.javascript.Context
class JsTest {
@Language("js")
private val printJs = """
function print(str, newline) {
if (typeof(str) == 'undefined') {
str = 'undefined';
} else if (str == null) {
str = 'null';
}
java.lang.System.out.print(String(str));
if (newline) java.lang.System.out.print("\n");
}
function println(str) {
print(str, true);
}
""".trimIndent()
@Test
fun testMap() {
val map = hashMapOf("id" to "3242532321")
@ -20,9 +37,11 @@ class JsTest {
Assert.assertEquals("12314123", result)
}
@Test
fun testFor() {
val context = SCRIPT_ENGINE.getScriptContext(SimpleBindings())
val scope = SCRIPT_ENGINE.getRuntimeScope(context)
Context.enter().evaluateString(scope, printJs, "print", 1, null)
@Language("js")
val jsFor = """
let result = 0
@ -30,16 +49,19 @@ class JsTest {
let l=a.length
for (let i = 0;i<l;i++){
result = result + a[i]
println(i)
}
for (let o of a){
result = result + o
println(o)
}
for (let o in a){
result = result + o
println(o)
}
result
""".trimIndent()
val result = SCRIPT_ENGINE.eval(jsFor).toString()
val result = SCRIPT_ENGINE.eval(jsFor, scope).toString()
Assert.assertEquals("12012", result)
}

View File

@ -3,7 +3,9 @@
*/
package com.script
import org.mozilla.javascript.Scriptable
import java.io.Reader
import java.io.StringReader
abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngine {
@ -51,6 +53,15 @@ abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngi
return nn?.get(key)
}
override fun eval(script: String, scope: Scriptable): Any? {
return this.eval(StringReader(script), scope)
}
@Throws(ScriptException::class)
override fun eval(reader: Reader, context: ScriptContext): Any? {
return this.eval(reader, getRuntimeScope(context))
}
@Throws(ScriptException::class)
override fun eval(reader: Reader, bindings: Bindings): Any? {
return this.eval(reader, getScriptContext(bindings))
@ -71,13 +82,18 @@ abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngi
return this.eval(script, context)
}
protected fun getScriptContext(nn: Bindings): ScriptContext {
@Throws(ScriptException::class)
override fun eval(script: String, context: ScriptContext): Any? {
return this.eval(StringReader(script), context)
}
override fun getScriptContext(bindings: Bindings): ScriptContext {
val ctx = SimpleScriptContext()
val gs = getBindings(200)
if (gs != null) {
ctx.setBindings(gs, 200)
}
ctx.setBindings(nn, 100)
ctx.setBindings(bindings, 100)
ctx.reader = context.reader
ctx.writer = context.writer
ctx.errorWriter = context.errorWriter

View File

@ -3,6 +3,7 @@
*/
package com.script
import org.mozilla.javascript.Scriptable
import java.io.Reader
interface ScriptEngine {
@ -10,6 +11,12 @@ interface ScriptEngine {
fun createBindings(): Bindings?
@Throws(ScriptException::class)
fun eval(reader: Reader, scope: Scriptable): Any?
@Throws(ScriptException::class)
fun eval(script: String, scope: Scriptable): Any?
@Throws(ScriptException::class)
fun eval(reader: Reader): Any?
@ -28,6 +35,10 @@ interface ScriptEngine {
@Throws(ScriptException::class)
fun eval(script: String, context: ScriptContext): Any?
fun getRuntimeScope(context: ScriptContext): Scriptable
fun getScriptContext(bindings: Bindings): ScriptContext
operator fun get(key: String): Any?
fun getBindings(scope: Int): Bindings?

View File

@ -48,6 +48,32 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
private val indexedProps: MutableMap<Any, Any?>
private val implementor: InterfaceImplementor
@Throws(ScriptException::class)
override fun eval(reader: Reader, scope: Scriptable): Any? {
val cx = Context.enter()
val ret: Any?
try {
var filename = this["javax.script.filename"] as? String
filename = filename ?: "<Unknown source>"
ret = cx.evaluateReader(scope, reader, filename, 1, null)
} catch (re: RhinoException) {
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
val msg: String = if (re is JavaScriptException) {
re.value.toString()
} else {
re.toString()
}
val se = ScriptException(msg, re.sourceName(), line)
se.initCause(re)
throw se
} catch (var14: IOException) {
throw ScriptException(var14)
} finally {
Context.exit()
}
return unwrapReturnValue(ret)
}
@Throws(ScriptException::class)
override fun eval(reader: Reader, context: ScriptContext): Any? {
val cx = Context.enter()
@ -75,11 +101,6 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
return unwrapReturnValue(ret)
}
@Throws(ScriptException::class)
override fun eval(script: String, context: ScriptContext): Any? {
return this.eval(StringReader(script) as Reader, context)
}
override fun createBindings(): Bindings {
return SimpleBindings()
}
@ -152,7 +173,7 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
}
}
fun getRuntimeScope(context: ScriptContext): Scriptable {
override fun getRuntimeScope(context: ScriptContext): Scriptable {
val newScope: Scriptable = ExternalScriptable(context, indexedProps)
newScope.prototype = topLevel
newScope.put("context", newScope, context)