优化
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
package io.legado.app
|
package io.legado.app
|
||||||
|
|
||||||
import com.script.SimpleBindings
|
|
||||||
import io.legado.app.constant.SCRIPT_ENGINE
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -12,21 +10,10 @@ import org.junit.Test
|
|||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
*/
|
*/
|
||||||
class ExampleUnitTest {
|
class ExampleUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun addition_isCorrect() {
|
fun addition_isCorrect() {
|
||||||
assertEquals(4, 2 + 2)
|
assertEquals(4, 2 + 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun jsTest() {
|
|
||||||
val map = hashMapOf("id" to "3242532321")
|
|
||||||
map["id"] = "12314123"
|
|
||||||
val bindings = SimpleBindings()
|
|
||||||
bindings["result"] = map
|
|
||||||
val js = "$=result;id=$.id;id"
|
|
||||||
val result = SCRIPT_ENGINE.eval(js, bindings)?.toString()
|
|
||||||
assertEquals("12314123", result)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package io.legado.app
|
||||||
|
|
||||||
|
import com.script.SimpleBindings
|
||||||
|
import io.legado.app.constant.SCRIPT_ENGINE
|
||||||
|
import org.intellij.lang.annotations.Language
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class JsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMap() {
|
||||||
|
val map = hashMapOf("id" to "3242532321")
|
||||||
|
map["id"] = "12314123"
|
||||||
|
val bindings = SimpleBindings()
|
||||||
|
bindings["result"] = map
|
||||||
|
@Language("js")
|
||||||
|
val jsMap = "$=result;id=$.id;id"
|
||||||
|
val result = SCRIPT_ENGINE.eval(jsMap, bindings)?.toString()
|
||||||
|
Assert.assertEquals("12314123", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFor() {
|
||||||
|
@Language("js")
|
||||||
|
val jsFor = """
|
||||||
|
let result = 0
|
||||||
|
let a=[1,2,3]
|
||||||
|
let l=a.length
|
||||||
|
for (let i = 0;i<l;i++){
|
||||||
|
result = result + a[i]
|
||||||
|
}
|
||||||
|
for (let o of a){
|
||||||
|
result = result + o
|
||||||
|
}
|
||||||
|
for (let o in a){
|
||||||
|
result = result + o
|
||||||
|
}
|
||||||
|
result
|
||||||
|
""".trimIndent()
|
||||||
|
val result = SCRIPT_ENGINE.eval(jsFor).toString()
|
||||||
|
Assert.assertEquals("12012", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testReturnNull() {
|
||||||
|
val result = SCRIPT_ENGINE.eval("null")
|
||||||
|
Assert.assertEquals(null, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -48,12 +48,12 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
|||||||
if (!isImplemented(thiz, iface)) {
|
if (!isImplemented(thiz, iface)) {
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
val accCtxt = AccessController.getContext()
|
val accContext = AccessController.getContext()
|
||||||
iface.cast(
|
iface.cast(
|
||||||
Proxy.newProxyInstance(
|
Proxy.newProxyInstance(
|
||||||
iface.classLoader,
|
iface.classLoader,
|
||||||
arrayOf<Class<*>>(iface),
|
arrayOf<Class<*>>(iface),
|
||||||
InterfaceImplementorInvocationHandler(thiz, accCtxt)
|
InterfaceImplementorInvocationHandler(thiz, accContext)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ScriptException::class)
|
@Throws(ScriptException::class)
|
||||||
protected open fun convertResult(method: Method?, res: Any): Any {
|
protected open fun convertResult(method: Method?, res: Any): Any? {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +78,11 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
|||||||
|
|
||||||
private inner class InterfaceImplementorInvocationHandler(
|
private inner class InterfaceImplementorInvocationHandler(
|
||||||
private val thiz: Any?,
|
private val thiz: Any?,
|
||||||
private val accCtxt: AccessControlContext
|
private val accContext: AccessControlContext
|
||||||
) : InvocationHandler {
|
) : InvocationHandler {
|
||||||
|
|
||||||
@Throws(Throwable::class)
|
@Throws(Throwable::class)
|
||||||
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any {
|
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any? {
|
||||||
val finalArgs = convertArguments(method, args)
|
val finalArgs = convertArguments(method, args)
|
||||||
val result = AccessController.doPrivileged(PrivilegedExceptionAction {
|
val result = AccessController.doPrivileged(PrivilegedExceptionAction {
|
||||||
if (thiz == null) engine.invokeFunction(
|
if (thiz == null) engine.invokeFunction(
|
||||||
@@ -90,8 +91,9 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
|||||||
) else engine.invokeMethod(
|
) else engine.invokeMethod(
|
||||||
thiz, method.name, *finalArgs
|
thiz, method.name, *finalArgs
|
||||||
)
|
)
|
||||||
} as PrivilegedExceptionAction<Any>, accCtxt)
|
} as PrivilegedExceptionAction<Any>, accContext)
|
||||||
return convertResult(method, result)
|
return convertResult(method, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,48 +156,11 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRuntimeScope(ctxt: ScriptContext?): Scriptable {
|
fun getRuntimeScope(context: ScriptContext): Scriptable {
|
||||||
return if (ctxt == null) {
|
val newScope: Scriptable = ExternalScriptable(context, indexedProps)
|
||||||
throw NullPointerException("脚本context为空")
|
|
||||||
} else {
|
|
||||||
val newScope: Scriptable = ExternalScriptable(ctxt, indexedProps)
|
|
||||||
newScope.prototype = topLevel
|
newScope.prototype = topLevel
|
||||||
newScope.put("context", newScope, ctxt)
|
newScope.put("context", newScope, context)
|
||||||
/*
|
return newScope
|
||||||
val cx = Context.enter()
|
|
||||||
try {
|
|
||||||
@Language("js")
|
|
||||||
val js = """
|
|
||||||
function print(str, newline) {
|
|
||||||
if (typeof(str) == 'undefined') {
|
|
||||||
str = 'undefined';
|
|
||||||
} else if (str == null) {
|
|
||||||
str = 'null';
|
|
||||||
}
|
|
||||||
var out = context.getWriter();
|
|
||||||
if (!(out instanceof java.io.PrintWriter))
|
|
||||||
out = new java.io.PrintWriter(out);
|
|
||||||
out.print(String(str));
|
|
||||||
if (newline) out.print('\\n');
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
function println(str) {
|
|
||||||
print(str, true);
|
|
||||||
}
|
|
||||||
""".trimIndent()
|
|
||||||
cx.evaluateString(
|
|
||||||
newScope,
|
|
||||||
js,
|
|
||||||
"print",
|
|
||||||
1,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
} finally {
|
|
||||||
Context.exit()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
newScope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ScriptException::class)
|
@Throws(ScriptException::class)
|
||||||
@@ -260,6 +223,7 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
}
|
}
|
||||||
indexedProps = HashMap()
|
indexedProps = HashMap()
|
||||||
implementor = object : InterfaceImplementor(this) {
|
implementor = object : InterfaceImplementor(this) {
|
||||||
|
|
||||||
override fun isImplemented(thiz: Any?, iface: Class<*>): Boolean {
|
override fun isImplemented(thiz: Any?, iface: Class<*>): Boolean {
|
||||||
var thiz1 = thiz
|
var thiz1 = thiz
|
||||||
return try {
|
return try {
|
||||||
@@ -289,12 +253,11 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun convertResult(method: Method?, res: Any): Any {
|
override fun convertResult(method: Method?, res: Any): Any? {
|
||||||
val desiredType = method!!.returnType
|
method ?: return null
|
||||||
return (if (desiredType == Void.TYPE) null else Context.jsToJava(
|
val desiredType = method.returnType
|
||||||
res,
|
if (desiredType == Void.TYPE) return null
|
||||||
desiredType
|
return Context.jsToJava(res, desiredType)
|
||||||
))!!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,30 +265,6 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val DEBUG = false
|
|
||||||
|
|
||||||
/*
|
|
||||||
@Language("js")
|
|
||||||
private val printSource = """
|
|
||||||
function print(str, newline) {
|
|
||||||
if (typeof str == "undefined") {
|
|
||||||
str = "undefined";
|
|
||||||
} else if (str == null) {
|
|
||||||
str = "null";
|
|
||||||
}
|
|
||||||
var out = context.getWriter();
|
|
||||||
if (!(out instanceof java.io.PrintWriter))
|
|
||||||
out = new java.io.PrintWriter(out);
|
|
||||||
out.print(String(str));
|
|
||||||
if (newline) out.print("\\n");
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
function println(str) {
|
|
||||||
print(str, true);
|
|
||||||
}
|
|
||||||
""".trimIndent()
|
|
||||||
*/
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
ContextFactory.initGlobal(object : ContextFactory() {
|
ContextFactory.initGlobal(object : ContextFactory() {
|
||||||
|
|
||||||
@@ -352,16 +291,16 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
|||||||
thisObj: Scriptable,
|
thisObj: Scriptable,
|
||||||
args: Array<Any>
|
args: Array<Any>
|
||||||
): Any? {
|
): Any? {
|
||||||
var accCtxt: AccessControlContext? = null
|
var accContext: AccessControlContext? = null
|
||||||
val global = ScriptableObject.getTopLevelScope(scope)
|
val global = ScriptableObject.getTopLevelScope(scope)
|
||||||
val globalProto = global.prototype
|
val globalProto = global.prototype
|
||||||
if (globalProto is RhinoTopLevel) {
|
if (globalProto is RhinoTopLevel) {
|
||||||
accCtxt = globalProto.accessContext
|
accContext = globalProto.accessContext
|
||||||
}
|
}
|
||||||
return if (accCtxt != null) AccessController.doPrivileged(
|
return if (accContext != null) AccessController.doPrivileged(
|
||||||
PrivilegedAction {
|
PrivilegedAction {
|
||||||
superDoTopCall(callable, cx, scope, thisObj, args)
|
superDoTopCall(callable, cx, scope, thisObj, args)
|
||||||
} as PrivilegedAction<*>, accCtxt) else superDoTopCall(
|
} as PrivilegedAction<*>, accContext) else superDoTopCall(
|
||||||
callable,
|
callable,
|
||||||
cx,
|
cx,
|
||||||
scope,
|
scope,
|
||||||
|
|||||||
Reference in New Issue
Block a user