mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package io.legado.app
|
||||
|
||||
import com.script.SimpleBindings
|
||||
import io.legado.app.constant.SCRIPT_ENGINE
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
@@ -12,21 +10,10 @@ import org.junit.Test
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
52
app/src/test/java/io/legado/app/JsTest.kt
Normal file
52
app/src/test/java/io/legado/app/JsTest.kt
Normal file
@@ -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)) {
|
||||
null
|
||||
} else {
|
||||
val accCtxt = AccessController.getContext()
|
||||
val accContext = AccessController.getContext()
|
||||
iface.cast(
|
||||
Proxy.newProxyInstance(
|
||||
iface.classLoader,
|
||||
arrayOf<Class<*>>(iface),
|
||||
InterfaceImplementorInvocationHandler(thiz, accCtxt)
|
||||
InterfaceImplementorInvocationHandler(thiz, accContext)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -67,7 +67,7 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
||||
}
|
||||
|
||||
@Throws(ScriptException::class)
|
||||
protected open fun convertResult(method: Method?, res: Any): Any {
|
||||
protected open fun convertResult(method: Method?, res: Any): Any? {
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -78,10 +78,11 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
||||
|
||||
private inner class InterfaceImplementorInvocationHandler(
|
||||
private val thiz: Any?,
|
||||
private val accCtxt: AccessControlContext
|
||||
private val accContext: AccessControlContext
|
||||
) : InvocationHandler {
|
||||
|
||||
@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 result = AccessController.doPrivileged(PrivilegedExceptionAction {
|
||||
if (thiz == null) engine.invokeFunction(
|
||||
@@ -90,8 +91,9 @@ open class InterfaceImplementor(private val engine: Invocable) {
|
||||
) else engine.invokeMethod(
|
||||
thiz, method.name, *finalArgs
|
||||
)
|
||||
} as PrivilegedExceptionAction<Any>, accCtxt)
|
||||
} as PrivilegedExceptionAction<Any>, accContext)
|
||||
return convertResult(method, result)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -156,48 +156,11 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
||||
}
|
||||
}
|
||||
|
||||
fun getRuntimeScope(ctxt: ScriptContext?): Scriptable {
|
||||
return if (ctxt == null) {
|
||||
throw NullPointerException("脚本context为空")
|
||||
} else {
|
||||
val newScope: Scriptable = ExternalScriptable(ctxt, indexedProps)
|
||||
newScope.prototype = topLevel
|
||||
newScope.put("context", newScope, ctxt)
|
||||
/*
|
||||
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
|
||||
}
|
||||
fun getRuntimeScope(context: ScriptContext): Scriptable {
|
||||
val newScope: Scriptable = ExternalScriptable(context, indexedProps)
|
||||
newScope.prototype = topLevel
|
||||
newScope.put("context", newScope, context)
|
||||
return newScope
|
||||
}
|
||||
|
||||
@Throws(ScriptException::class)
|
||||
@@ -260,6 +223,7 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
||||
}
|
||||
indexedProps = HashMap()
|
||||
implementor = object : InterfaceImplementor(this) {
|
||||
|
||||
override fun isImplemented(thiz: Any?, iface: Class<*>): Boolean {
|
||||
var thiz1 = thiz
|
||||
return try {
|
||||
@@ -289,12 +253,11 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertResult(method: Method?, res: Any): Any {
|
||||
val desiredType = method!!.returnType
|
||||
return (if (desiredType == Void.TYPE) null else Context.jsToJava(
|
||||
res,
|
||||
desiredType
|
||||
))!!
|
||||
override fun convertResult(method: Method?, res: Any): Any? {
|
||||
method ?: return null
|
||||
val desiredType = method.returnType
|
||||
if (desiredType == Void.TYPE) return null
|
||||
return Context.jsToJava(res, desiredType)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,30 +265,6 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
||||
@Suppress("unused")
|
||||
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 {
|
||||
ContextFactory.initGlobal(object : ContextFactory() {
|
||||
|
||||
@@ -352,16 +291,16 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
|
||||
thisObj: Scriptable,
|
||||
args: Array<Any>
|
||||
): Any? {
|
||||
var accCtxt: AccessControlContext? = null
|
||||
var accContext: AccessControlContext? = null
|
||||
val global = ScriptableObject.getTopLevelScope(scope)
|
||||
val globalProto = global.prototype
|
||||
if (globalProto is RhinoTopLevel) {
|
||||
accCtxt = globalProto.accessContext
|
||||
accContext = globalProto.accessContext
|
||||
}
|
||||
return if (accCtxt != null) AccessController.doPrivileged(
|
||||
return if (accContext != null) AccessController.doPrivileged(
|
||||
PrivilegedAction {
|
||||
superDoTopCall(callable, cx, scope, thisObj, args)
|
||||
} as PrivilegedAction<*>, accCtxt) else superDoTopCall(
|
||||
} as PrivilegedAction<*>, accContext) else superDoTopCall(
|
||||
callable,
|
||||
cx,
|
||||
scope,
|
||||
|
||||
Reference in New Issue
Block a user