优化
This commit is contained in:
@@ -5,9 +5,26 @@ import io.legado.app.constant.SCRIPT_ENGINE
|
|||||||
import org.intellij.lang.annotations.Language
|
import org.intellij.lang.annotations.Language
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mozilla.javascript.Context
|
||||||
|
|
||||||
class JsTest {
|
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
|
@Test
|
||||||
fun testMap() {
|
fun testMap() {
|
||||||
val map = hashMapOf("id" to "3242532321")
|
val map = hashMapOf("id" to "3242532321")
|
||||||
@@ -20,9 +37,11 @@ class JsTest {
|
|||||||
Assert.assertEquals("12314123", result)
|
Assert.assertEquals("12314123", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFor() {
|
fun testFor() {
|
||||||
|
val context = SCRIPT_ENGINE.getScriptContext(SimpleBindings())
|
||||||
|
val scope = SCRIPT_ENGINE.getRuntimeScope(context)
|
||||||
|
Context.enter().evaluateString(scope, printJs, "print", 1, null)
|
||||||
@Language("js")
|
@Language("js")
|
||||||
val jsFor = """
|
val jsFor = """
|
||||||
let result = 0
|
let result = 0
|
||||||
@@ -30,16 +49,19 @@ class JsTest {
|
|||||||
let l=a.length
|
let l=a.length
|
||||||
for (let i = 0;i<l;i++){
|
for (let i = 0;i<l;i++){
|
||||||
result = result + a[i]
|
result = result + a[i]
|
||||||
|
println(i)
|
||||||
}
|
}
|
||||||
for (let o of a){
|
for (let o of a){
|
||||||
result = result + o
|
result = result + o
|
||||||
|
println(o)
|
||||||
}
|
}
|
||||||
for (let o in a){
|
for (let o in a){
|
||||||
result = result + o
|
result = result + o
|
||||||
|
println(o)
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
val result = SCRIPT_ENGINE.eval(jsFor).toString()
|
val result = SCRIPT_ENGINE.eval(jsFor, scope).toString()
|
||||||
Assert.assertEquals("12012", result)
|
Assert.assertEquals("12012", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.script
|
package com.script
|
||||||
|
|
||||||
|
import org.mozilla.javascript.Scriptable
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
|
import java.io.StringReader
|
||||||
|
|
||||||
abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngine {
|
abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngine {
|
||||||
|
|
||||||
@@ -51,6 +53,15 @@ abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngi
|
|||||||
return nn?.get(key)
|
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)
|
@Throws(ScriptException::class)
|
||||||
override fun eval(reader: Reader, bindings: Bindings): Any? {
|
override fun eval(reader: Reader, bindings: Bindings): Any? {
|
||||||
return this.eval(reader, getScriptContext(bindings))
|
return this.eval(reader, getScriptContext(bindings))
|
||||||
@@ -71,13 +82,18 @@ abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngi
|
|||||||
return this.eval(script, context)
|
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 ctx = SimpleScriptContext()
|
||||||
val gs = getBindings(200)
|
val gs = getBindings(200)
|
||||||
if (gs != null) {
|
if (gs != null) {
|
||||||
ctx.setBindings(gs, 200)
|
ctx.setBindings(gs, 200)
|
||||||
}
|
}
|
||||||
ctx.setBindings(nn, 100)
|
ctx.setBindings(bindings, 100)
|
||||||
ctx.reader = context.reader
|
ctx.reader = context.reader
|
||||||
ctx.writer = context.writer
|
ctx.writer = context.writer
|
||||||
ctx.errorWriter = context.errorWriter
|
ctx.errorWriter = context.errorWriter
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.script
|
package com.script
|
||||||
|
|
||||||
|
import org.mozilla.javascript.Scriptable
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
|
|
||||||
interface ScriptEngine {
|
interface ScriptEngine {
|
||||||
@@ -10,6 +11,12 @@ interface ScriptEngine {
|
|||||||
|
|
||||||
fun createBindings(): Bindings?
|
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)
|
@Throws(ScriptException::class)
|
||||||
fun eval(reader: Reader): Any?
|
fun eval(reader: Reader): Any?
|
||||||
|
|
||||||
@@ -28,6 +35,10 @@ interface ScriptEngine {
|
|||||||
@Throws(ScriptException::class)
|
@Throws(ScriptException::class)
|
||||||
fun eval(script: String, context: ScriptContext): Any?
|
fun eval(script: String, context: ScriptContext): Any?
|
||||||
|
|
||||||
|
fun getRuntimeScope(context: ScriptContext): Scriptable
|
||||||
|
|
||||||
|
fun getScriptContext(bindings: Bindings): ScriptContext
|
||||||
|
|
||||||
operator fun get(key: String): Any?
|
operator fun get(key: String): Any?
|
||||||
|
|
||||||
fun getBindings(scope: Int): Bindings?
|
fun getBindings(scope: Int): Bindings?
|
||||||
|
|||||||
@@ -48,6 +48,32 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
private val indexedProps: MutableMap<Any, Any?>
|
private val indexedProps: MutableMap<Any, Any?>
|
||||||
private val implementor: InterfaceImplementor
|
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)
|
@Throws(ScriptException::class)
|
||||||
override fun eval(reader: Reader, context: ScriptContext): Any? {
|
override fun eval(reader: Reader, context: ScriptContext): Any? {
|
||||||
val cx = Context.enter()
|
val cx = Context.enter()
|
||||||
@@ -75,11 +101,6 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
return unwrapReturnValue(ret)
|
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 {
|
override fun createBindings(): Bindings {
|
||||||
return SimpleBindings()
|
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)
|
val newScope: Scriptable = ExternalScriptable(context, indexedProps)
|
||||||
newScope.prototype = topLevel
|
newScope.prototype = topLevel
|
||||||
newScope.put("context", newScope, context)
|
newScope.put("context", newScope, context)
|
||||||
|
|||||||
Reference in New Issue
Block a user