Compare commits
8 Commits
0.9.14-bet
...
0.9.22-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
c291328cc3
|
|||
|
7cb267b0d9
|
|||
|
4e31766665
|
|||
|
b5b63c4342
|
|||
|
18f70a0d58
|
|||
|
d38b600366
|
|||
|
0ac7af2ea3
|
|||
|
5185c93663
|
@@ -36,6 +36,10 @@ public class DebugContext {
|
|||||||
this.debugger = debugger;
|
this.debugger = debugger;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
public boolean detachDebugger(DebugHandler debugger) {
|
||||||
|
if (this.debugger != debugger) return false;
|
||||||
|
return detachDebugger();
|
||||||
|
}
|
||||||
public boolean detachDebugger() {
|
public boolean detachDebugger() {
|
||||||
this.debugger = null;
|
this.debugger = null;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
package me.topchetoeu.jscript.runtime.values;
|
package me.topchetoeu.jscript.runtime.values;
|
||||||
|
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.runtime.Context;
|
import me.topchetoeu.jscript.runtime.Context;
|
||||||
|
import me.topchetoeu.jscript.runtime.Extensions;
|
||||||
|
import me.topchetoeu.jscript.runtime.Key;
|
||||||
|
|
||||||
public class NativeWrapper extends ObjectValue {
|
public class NativeWrapper extends ObjectValue {
|
||||||
|
private static final Key<WeakHashMap<Object, NativeWrapper>> WRAPPERS = new Key<>();
|
||||||
private static final Object NATIVE_PROTO = new Object();
|
private static final Object NATIVE_PROTO = new Object();
|
||||||
public final Object wrapped;
|
public final Object wrapped;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectValue getPrototype(Context ctx) {
|
public ObjectValue getPrototype(Context ctx) {
|
||||||
if (ctx.environment != null && prototype == NATIVE_PROTO) return ctx.environment.wrappers.getProto(wrapped.getClass());
|
if (ctx.environment != null && prototype == NATIVE_PROTO) {
|
||||||
else return super.getPrototype(ctx);
|
var clazz = wrapped.getClass();
|
||||||
|
var res = ctx.environment.wrappers.getProto(clazz);
|
||||||
|
if (res != null) return res;
|
||||||
|
}
|
||||||
|
return super.getPrototype(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -25,8 +34,20 @@ public class NativeWrapper extends ObjectValue {
|
|||||||
return wrapped.hashCode();
|
return wrapped.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NativeWrapper(Object wrapped) {
|
private NativeWrapper(Object wrapped) {
|
||||||
this.wrapped = wrapped;
|
this.wrapped = wrapped;
|
||||||
prototype = NATIVE_PROTO;
|
prototype = NATIVE_PROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NativeWrapper of(Extensions exts, Object wrapped) {
|
||||||
|
var wrappers = exts == null ? null : exts.get(WRAPPERS);
|
||||||
|
|
||||||
|
if (wrappers == null) return new NativeWrapper(wrapped);
|
||||||
|
if (wrappers.containsKey(wrapped)) return wrappers.get(wrapped);
|
||||||
|
|
||||||
|
var res = new NativeWrapper(wrapped);
|
||||||
|
wrappers.put(wrapped, res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,18 +153,18 @@ public class ObjectValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ObjectValue getPrototype(Context ctx) {
|
public ObjectValue getPrototype(Context ctx) {
|
||||||
|
if (prototype instanceof ObjectValue || prototype == null) return (ObjectValue)prototype;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (prototype == OBJ_PROTO) return ctx.get(Environment.OBJECT_PROTO);
|
|
||||||
if (prototype == ARR_PROTO) return ctx.get(Environment.ARRAY_PROTO);
|
if (prototype == ARR_PROTO) return ctx.get(Environment.ARRAY_PROTO);
|
||||||
if (prototype == FUNC_PROTO) return ctx.get(Environment.FUNCTION_PROTO);
|
if (prototype == FUNC_PROTO) return ctx.get(Environment.FUNCTION_PROTO);
|
||||||
if (prototype == ERR_PROTO) return ctx.get(Environment.ERROR_PROTO);
|
if (prototype == ERR_PROTO) return ctx.get(Environment.ERROR_PROTO);
|
||||||
if (prototype == RANGE_ERR_PROTO) return ctx.get(Environment.RANGE_ERR_PROTO);
|
if (prototype == RANGE_ERR_PROTO) return ctx.get(Environment.RANGE_ERR_PROTO);
|
||||||
if (prototype == SYNTAX_ERR_PROTO) return ctx.get(Environment.SYNTAX_ERR_PROTO);
|
if (prototype == SYNTAX_ERR_PROTO) return ctx.get(Environment.SYNTAX_ERR_PROTO);
|
||||||
if (prototype == TYPE_ERR_PROTO) return ctx.get(Environment.TYPE_ERR_PROTO);
|
if (prototype == TYPE_ERR_PROTO) return ctx.get(Environment.TYPE_ERR_PROTO);
|
||||||
|
return ctx.get(Environment.OBJECT_PROTO);
|
||||||
}
|
}
|
||||||
catch (NullPointerException e) { return null; }
|
catch (NullPointerException e) { return null; }
|
||||||
|
|
||||||
return (ObjectValue)prototype;
|
|
||||||
}
|
}
|
||||||
public final boolean setPrototype(PlaceholderProto val) {
|
public final boolean setPrototype(PlaceholderProto val) {
|
||||||
if (!extensible()) return false;
|
if (!extensible()) return false;
|
||||||
|
|||||||
@@ -58,9 +58,8 @@ public class Values {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T wrapper(Object val, Class<T> clazz) {
|
public static <T> T wrapper(Object val, Class<T> clazz) {
|
||||||
if (!isWrapper(val)) val = new NativeWrapper(val);
|
if (isWrapper(val)) val = ((NativeWrapper)val).wrapped;
|
||||||
var res = (NativeWrapper)val;
|
if (val != null && clazz.isInstance(val)) return (T)val;
|
||||||
if (res != null && clazz.isInstance(res.wrapped)) return (T)res.wrapped;
|
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +470,7 @@ public class Values {
|
|||||||
else return ctx.environment.wrappers.getConstr((Class<?>)val);
|
else return ctx.environment.wrappers.getConstr((Class<?>)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeWrapper(val);
|
return NativeWrapper.of(ctx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -536,7 +535,7 @@ public class Values {
|
|||||||
if (obj == null) return null;
|
if (obj == null) return null;
|
||||||
if (clazz.isInstance(obj)) return (T)obj;
|
if (clazz.isInstance(obj)) return (T)obj;
|
||||||
if (clazz.isAssignableFrom(NativeWrapper.class)) {
|
if (clazz.isAssignableFrom(NativeWrapper.class)) {
|
||||||
return (T)new NativeWrapper(obj);
|
return (T)NativeWrapper.of(ctx, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ConvertException(type(obj), clazz.getSimpleName());
|
throw new ConvertException(type(obj), clazz.getSimpleName());
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import me.topchetoeu.jscript.runtime.EventLoop;
|
|||||||
import me.topchetoeu.jscript.runtime.Frame;
|
import me.topchetoeu.jscript.runtime.Frame;
|
||||||
import me.topchetoeu.jscript.runtime.debug.DebugContext;
|
import me.topchetoeu.jscript.runtime.debug.DebugContext;
|
||||||
import me.topchetoeu.jscript.runtime.exceptions.EngineException;
|
import me.topchetoeu.jscript.runtime.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||||
import me.topchetoeu.jscript.runtime.scope.GlobalScope;
|
import me.topchetoeu.jscript.runtime.scope.GlobalScope;
|
||||||
import me.topchetoeu.jscript.runtime.values.ArrayValue;
|
import me.topchetoeu.jscript.runtime.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.runtime.values.FunctionValue;
|
import me.topchetoeu.jscript.runtime.values.FunctionValue;
|
||||||
@@ -41,7 +42,9 @@ import me.topchetoeu.jscript.runtime.values.Values;
|
|||||||
public class SimpleDebugger implements Debugger {
|
public class SimpleDebugger implements Debugger {
|
||||||
public static final Set<String> VSCODE_EMPTY = Set.of(
|
public static final Set<String> VSCODE_EMPTY = Set.of(
|
||||||
"function(...runtimeArgs){\n let t = 1024; let e = null;\n if(e)try{let r=\"<<default preview>>\",i=e.call(this,r);if(i!==r)return String(i)}catch(r){return`<<indescribable>>${JSON.stringify([String(r),\"object\"])}`}if(typeof this==\"object\"&&this){let r;for(let i of[Symbol.for(\"debug.description\"),Symbol.for(\"nodejs.util.inspect.custom\")])try{r=this[i]();break}catch{}if(!r&&!String(this.toString).includes(\"[native code]\")&&(r=String(this)),r&&!r.startsWith(\"[object \"))return r.length>=t?r.slice(0,t)+\"\\u2026\":r}\n ;\n\n}",
|
"function(...runtimeArgs){\n let t = 1024; let e = null;\n if(e)try{let r=\"<<default preview>>\",i=e.call(this,r);if(i!==r)return String(i)}catch(r){return`<<indescribable>>${JSON.stringify([String(r),\"object\"])}`}if(typeof this==\"object\"&&this){let r;for(let i of[Symbol.for(\"debug.description\"),Symbol.for(\"nodejs.util.inspect.custom\")])try{r=this[i]();break}catch{}if(!r&&!String(this.toString).includes(\"[native code]\")&&(r=String(this)),r&&!r.startsWith(\"[object \"))return r.length>=t?r.slice(0,t)+\"\\u2026\":r}\n ;\n\n}",
|
||||||
|
"function(...runtimeArgs){\n let r = 1024; let e = null;\n if(e)try{let t=\"<<default preview>>\",n=e.call(this,t);if(n!==t)return String(n)}catch(t){return`<<indescribable>>${JSON.stringify([String(t),\"object\"])}`}if(typeof this==\"object\"&&this){let t;for(let n of[Symbol.for(\"debug.description\"),Symbol.for(\"nodejs.util.inspect.custom\")])if(typeof this[n]==\"function\")try{t=this[n]();break}catch{}if(!t&&!String(this.toString).includes(\"[native code]\")&&(t=String(this)),t&&!t.startsWith(\"[object\"))return t.length>=r?t.slice(0,r)+\"\\u2026\":t};}",
|
||||||
"function(...runtimeArgs){\n let t = 1024; let e = null;\n let r={},i=\"<<default preview>>\";if(typeof this!=\"object\"||!this)return r;for(let[n,s]of Object.entries(this)){if(e)try{let o=e.call(s,i);if(o!==i){r[n]=String(o);continue}}catch(o){r[n]=`<<indescribable>>${JSON.stringify([String(o),n])}`;continue}if(typeof s==\"object\"&&s){let o;for(let a of runtimeArgs[0])try{o=s[a]();break}catch{}!o&&!String(s.toString).includes(\"[native code]\")&&(o=String(s)),o&&!o.startsWith(\"[object \")&&(r[n]=o.length>=t?o.slice(0,t)+\"\\u2026\":o)}}return r\n ;\n\n}",
|
"function(...runtimeArgs){\n let t = 1024; let e = null;\n let r={},i=\"<<default preview>>\";if(typeof this!=\"object\"||!this)return r;for(let[n,s]of Object.entries(this)){if(e)try{let o=e.call(s,i);if(o!==i){r[n]=String(o);continue}}catch(o){r[n]=`<<indescribable>>${JSON.stringify([String(o),n])}`;continue}if(typeof s==\"object\"&&s){let o;for(let a of runtimeArgs[0])try{o=s[a]();break}catch{}!o&&!String(s.toString).includes(\"[native code]\")&&(o=String(s)),o&&!o.startsWith(\"[object \")&&(r[n]=o.length>=t?o.slice(0,t)+\"\\u2026\":o)}}return r\n ;\n\n}",
|
||||||
|
"function(...runtimeArgs){\n let r = 1024; let e = null;\n let t={},n=\"<<default preview>>\";if(typeof this!=\"object\"||!this)return t;for(let[i,o]of Object.entries(this)){if(e)try{let s=e.call(o,n);if(s!==n){t[i]=String(s);continue}}catch(s){t[i]=`<<indescribable>>${JSON.stringify([String(s),i])}`;continue}if(typeof o==\"object\"&&o){let s;for(let a of runtimeArgs[0])if(typeof o[a]==\"function\")try{s=o[a]();break}catch{}!s&&!String(o.toString).includes(\"[native code]\")&&(s=String(o)),s&&!s.startsWith(\"[object \")&&(t[i]=s.length>=r?s.slice(0,r)+\"\\u2026\":s)}}return t\n ;\n\n}",
|
||||||
"function(){let t={__proto__:this.__proto__\n},e=Object.getOwnPropertyNames(this);for(let r=0;r<e.length;++r){let i=e[r],n=i>>>0;if(String(n>>>0)===i&&n>>>0!==4294967295)continue;let s=Object.getOwnPropertyDescriptor(this,i);s&&Object.defineProperty(t,i,s)}return t}",
|
"function(){let t={__proto__:this.__proto__\n},e=Object.getOwnPropertyNames(this);for(let r=0;r<e.length;++r){let i=e[r],n=i>>>0;if(String(n>>>0)===i&&n>>>0!==4294967295)continue;let s=Object.getOwnPropertyDescriptor(this,i);s&&Object.defineProperty(t,i,s)}return t}",
|
||||||
"function(){return[Symbol.for(\"debug.description\"),Symbol.for(\"nodejs.util.inspect.custom\")]\n}"
|
"function(){return[Symbol.for(\"debug.description\"),Symbol.for(\"nodejs.util.inspect.custom\")]\n}"
|
||||||
);
|
);
|
||||||
@@ -202,6 +205,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
|
|
||||||
private ObjectValue emptyObject = new ObjectValue();
|
private ObjectValue emptyObject = new ObjectValue();
|
||||||
|
|
||||||
|
private WeakHashMap<DebugContext, DebugContext> contexts = new WeakHashMap<>();
|
||||||
private WeakHashMap<FunctionBody, FunctionMap> mappings = new WeakHashMap<>();
|
private WeakHashMap<FunctionBody, FunctionMap> mappings = new WeakHashMap<>();
|
||||||
private WeakHashMap<FunctionBody, HashMap<Location, Breakpoint>> bpLocs = new WeakHashMap<>();
|
private WeakHashMap<FunctionBody, HashMap<Location, Breakpoint>> bpLocs = new WeakHashMap<>();
|
||||||
|
|
||||||
@@ -226,6 +230,8 @@ public class SimpleDebugger implements Debugger {
|
|||||||
private int stepOutPtr = 0;
|
private int stepOutPtr = 0;
|
||||||
|
|
||||||
private boolean compare(String src, String target) {
|
private boolean compare(String src, String target) {
|
||||||
|
src = src.replaceAll("\\s", "");
|
||||||
|
target = target.replaceAll("\\s", "");
|
||||||
if (src.length() != target.length()) return false;
|
if (src.length() != target.length()) return false;
|
||||||
var diff = 0;
|
var diff = 0;
|
||||||
var all = 0;
|
var all = 0;
|
||||||
@@ -333,10 +339,10 @@ public class SimpleDebugger implements Debugger {
|
|||||||
}
|
}
|
||||||
private JSONMap serializeObj(Context ctx, Object val, boolean byValue) {
|
private JSONMap serializeObj(Context ctx, Object val, boolean byValue) {
|
||||||
val = Values.normalize(null, val);
|
val = Values.normalize(null, val);
|
||||||
var newCtx = new Context();
|
var newEnv = new Environment();
|
||||||
newCtx.addAll(ctx);
|
newEnv.addAll(ctx);
|
||||||
newCtx.add(DebugContext.IGNORE);
|
newEnv.add(DebugContext.IGNORE);
|
||||||
ctx = newCtx;
|
ctx = newEnv.context();
|
||||||
|
|
||||||
if (val == Values.NULL) {
|
if (val == Values.NULL) {
|
||||||
return new JSONMap()
|
return new JSONMap()
|
||||||
@@ -366,6 +372,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
if (subtype != null) res.set("subtype", subtype);
|
if (subtype != null) res.set("subtype", subtype);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
res.set("className", className);
|
res.set("className", className);
|
||||||
|
res.set("description", className);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof ArrayValue) res.set("description", "Array(" + ((ArrayValue)obj).size() + ")");
|
if (obj instanceof ArrayValue) res.set("description", "Array(" + ((ArrayValue)obj).size() + ")");
|
||||||
@@ -381,7 +388,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
catch (Exception e) { }
|
catch (Exception e) { }
|
||||||
|
|
||||||
try { res.set("description", className + (defaultToString ? "" : " { " + Values.toString(ctx, obj) + " }")); }
|
try { res.set("description", className + (defaultToString ? "" : " { " + Values.toString(ctx, obj) + " }")); }
|
||||||
catch (EngineException e) { res.set("description", className); }
|
catch (EngineException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -537,10 +544,12 @@ public class SimpleDebugger implements Debugger {
|
|||||||
var ctx = new Context(env);
|
var ctx = new Context(env);
|
||||||
var awaiter = engine.pushMsg(false, ctx.environment, new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args);
|
var awaiter = engine.pushMsg(false, ctx.environment, new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args);
|
||||||
|
|
||||||
engine.run(true);
|
try {
|
||||||
|
engine.run(true);
|
||||||
try { return new RunResult(ctx, awaiter.await(), null); }
|
return new RunResult(ctx, awaiter.await(), null);
|
||||||
|
}
|
||||||
catch (EngineException e) { return new RunResult(ctx, null, e); }
|
catch (EngineException e) { return new RunResult(ctx, null, e); }
|
||||||
|
catch (SyntaxException e) { return new RunResult(ctx, null, EngineException.ofSyntax(e.toString())); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectValue vscodeAutoSuggest(Context ctx, Object target, String query, boolean variable) {
|
private ObjectValue vscodeAutoSuggest(Context ctx, Object target, String query, boolean variable) {
|
||||||
@@ -634,11 +643,10 @@ public class SimpleDebugger implements Debugger {
|
|||||||
execptionType = CatchType.NONE;
|
execptionType = CatchType.NONE;
|
||||||
state = State.RESUMED;
|
state = State.RESUMED;
|
||||||
|
|
||||||
// idToBptCand.clear();
|
mappings.clear();
|
||||||
|
bpLocs.clear();
|
||||||
|
|
||||||
idToBreakpoint.clear();
|
idToBreakpoint.clear();
|
||||||
// locToBreakpoint.clear();
|
|
||||||
// tmpBreakpts.clear();
|
|
||||||
|
|
||||||
filenameToId.clear();
|
filenameToId.clear();
|
||||||
idToSource.clear();
|
idToSource.clear();
|
||||||
@@ -656,6 +664,9 @@ public class SimpleDebugger implements Debugger {
|
|||||||
stepOutFrame = currFrame = null;
|
stepOutFrame = currFrame = null;
|
||||||
stepOutPtr = 0;
|
stepOutPtr = 0;
|
||||||
|
|
||||||
|
for (var ctx : contexts.keySet()) ctx.detachDebugger(this);
|
||||||
|
contexts.clear();
|
||||||
|
|
||||||
updateNotifier.next();
|
updateNotifier.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1033,6 +1044,7 @@ public class SimpleDebugger implements Debugger {
|
|||||||
|
|
||||||
public SimpleDebugger attach(DebugContext ctx) {
|
public SimpleDebugger attach(DebugContext ctx) {
|
||||||
ctx.attachDebugger(this);
|
ctx.attachDebugger(this);
|
||||||
|
contexts.put(ctx, ctx);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
private final HashMap<Class<?>, FunctionValue> constructors = new HashMap<>();
|
private final HashMap<Class<?>, FunctionValue> constructors = new HashMap<>();
|
||||||
private final HashMap<Class<?>, ObjectValue> prototypes = new HashMap<>();
|
private final HashMap<Class<?>, ObjectValue> prototypes = new HashMap<>();
|
||||||
private final HashMap<Class<?>, ObjectValue> namespaces = new HashMap<>();
|
private final HashMap<Class<?>, ObjectValue> namespaces = new HashMap<>();
|
||||||
|
private final HashSet<Class<?>> ignore = new HashSet<>();
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
|
|
||||||
private static Object call(Context ctx, String name, Method method, Object thisArg, Object... args) {
|
private static Object call(Context ctx, String name, Method method, Object thisArg, Object... args) {
|
||||||
@@ -106,11 +107,12 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
else return name;
|
else return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void apply(ObjectValue obj, Environment env, ExposeTarget target, Class<?> clazz) {
|
private static boolean apply(ObjectValue obj, Environment env, ExposeTarget target, Class<?> clazz) {
|
||||||
var getters = new HashMap<Object, FunctionValue>();
|
var getters = new HashMap<Object, FunctionValue>();
|
||||||
var setters = new HashMap<Object, FunctionValue>();
|
var setters = new HashMap<Object, FunctionValue>();
|
||||||
var props = new HashSet<Object>();
|
var props = new HashSet<Object>();
|
||||||
var nonProps = new HashSet<Object>();
|
var nonProps = new HashSet<Object>();
|
||||||
|
var any = false;
|
||||||
|
|
||||||
for (var method : clazz.getDeclaredMethods()) {
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
for (var annotation : method.getAnnotationsByType(Expose.class)) {
|
for (var annotation : method.getAnnotationsByType(Expose.class)) {
|
||||||
@@ -120,6 +122,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
var name = getName(method, annotation.value());
|
var name = getName(method, annotation.value());
|
||||||
var key = getKey(name);
|
var key = getKey(name);
|
||||||
var repeat = false;
|
var repeat = false;
|
||||||
|
any = true;
|
||||||
|
|
||||||
switch (annotation.type()) {
|
switch (annotation.type()) {
|
||||||
case INIT:
|
case INIT:
|
||||||
@@ -168,6 +171,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
var name = getName(method, annotation.value());
|
var name = getName(method, annotation.value());
|
||||||
var key = getKey(name);
|
var key = getKey(name);
|
||||||
var repeat = false;
|
var repeat = false;
|
||||||
|
any = true;
|
||||||
|
|
||||||
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
||||||
else {
|
else {
|
||||||
@@ -191,6 +195,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
var name = getName(field, annotation.value());
|
var name = getName(field, annotation.value());
|
||||||
var key = getKey(name);
|
var key = getKey(name);
|
||||||
var repeat = false;
|
var repeat = false;
|
||||||
|
any = true;
|
||||||
|
|
||||||
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
||||||
else {
|
else {
|
||||||
@@ -227,6 +232,8 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var key : props) obj.defineProperty(null, key, getters.get(key), setters.get(key), true, false);
|
for (var key : props) obj.defineProperty(null, key, getters.get(key), setters.get(key), true, false);
|
||||||
|
|
||||||
|
return any;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method getConstructor(Environment env, Class<?> clazz) {
|
private static Method getConstructor(Environment env, Class<?> clazz) {
|
||||||
@@ -248,7 +255,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
public static ObjectValue makeProto(Environment env, Class<?> clazz) {
|
public static ObjectValue makeProto(Environment env, Class<?> clazz) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
res.defineProperty(null, Symbol.get("Symbol.typeName"), getName(clazz));
|
res.defineProperty(null, Symbol.get("Symbol.typeName"), getName(clazz));
|
||||||
apply(res, env, ExposeTarget.PROTOTYPE, clazz);
|
if (!apply(res, env, ExposeTarget.PROTOTYPE, clazz)) return null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -277,12 +284,27 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
public static ObjectValue makeNamespace(Environment ctx, Class<?> clazz) {
|
public static ObjectValue makeNamespace(Environment ctx, Class<?> clazz) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
res.defineProperty(null, Symbol.get("Symbol.typeName"), getName(clazz));
|
res.defineProperty(null, Symbol.get("Symbol.typeName"), getName(clazz));
|
||||||
apply(res, ctx, ExposeTarget.NAMESPACE, clazz);
|
if (!apply(res, ctx, ExposeTarget.NAMESPACE, clazz)) return null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProtoChain(Class<?> clazz, ObjectValue proto, FunctionValue constr) {
|
||||||
|
var parent = clazz;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
parent = parent.getSuperclass();
|
||||||
|
if (parent == null) return;
|
||||||
|
|
||||||
|
var parentProto = getProto(parent);
|
||||||
|
var parentConstr = getConstr(parent);
|
||||||
|
|
||||||
|
if (parentProto != null) Values.setPrototype(Context.NULL, proto, parentProto);
|
||||||
|
if (parentConstr != null) Values.setPrototype(Context.NULL, constr, parentConstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initType(Class<?> clazz, FunctionValue constr, ObjectValue proto) {
|
private void initType(Class<?> clazz, FunctionValue constr, ObjectValue proto) {
|
||||||
if (constr != null && proto != null) return;
|
if (constr != null && proto != null || ignore.contains(clazz)) return;
|
||||||
// i vomit
|
// i vomit
|
||||||
if (
|
if (
|
||||||
clazz == Object.class ||
|
clazz == Object.class ||
|
||||||
@@ -301,44 +323,72 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
if (constr == null) constr = makeConstructor(env, clazz);
|
if (constr == null) constr = makeConstructor(env, clazz);
|
||||||
if (proto == null) proto = makeProto(env, clazz);
|
if (proto == null) proto = makeProto(env, clazz);
|
||||||
|
|
||||||
|
if (constr == null || proto == null) return;
|
||||||
|
|
||||||
proto.defineProperty(null, "constructor", constr, true, false, false);
|
proto.defineProperty(null, "constructor", constr, true, false, false);
|
||||||
constr.defineProperty(null, "prototype", proto, true, false, false);
|
constr.defineProperty(null, "prototype", proto, true, false, false);
|
||||||
|
|
||||||
prototypes.put(clazz, proto);
|
prototypes.put(clazz, proto);
|
||||||
constructors.put(clazz, constr);
|
constructors.put(clazz, constr);
|
||||||
|
|
||||||
var parent = clazz.getSuperclass();
|
updateProtoChain(clazz, proto, constr);
|
||||||
if (parent == null) return;
|
|
||||||
|
|
||||||
var parentProto = getProto(parent);
|
|
||||||
var parentConstr = getConstr(parent);
|
|
||||||
|
|
||||||
if (parentProto != null) Values.setPrototype(Context.NULL, proto, parentProto);
|
|
||||||
if (parentConstr != null) Values.setPrototype(Context.NULL, constr, parentConstr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectValue getProto(Class<?> clazz) {
|
public ObjectValue getProto(Class<?> clazz) {
|
||||||
initType(clazz, constructors.get(clazz), prototypes.get(clazz));
|
initType(clazz, constructors.get(clazz), prototypes.get(clazz));
|
||||||
return prototypes.get(clazz);
|
while (clazz != null) {
|
||||||
|
var res = prototypes.get(clazz);
|
||||||
|
if (res != null) return res;
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
public ObjectValue getNamespace(Class<?> clazz) {
|
public ObjectValue getNamespace(Class<?> clazz) {
|
||||||
if (!namespaces.containsKey(clazz)) namespaces.put(clazz, makeNamespace(env, clazz));
|
if (!namespaces.containsKey(clazz)) namespaces.put(clazz, makeNamespace(env, clazz));
|
||||||
return namespaces.get(clazz);
|
while (clazz != null) {
|
||||||
|
var res = namespaces.get(clazz);
|
||||||
|
if (res != null) return res;
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
public FunctionValue getConstr(Class<?> clazz) {
|
public FunctionValue getConstr(Class<?> clazz) {
|
||||||
initType(clazz, constructors.get(clazz), prototypes.get(clazz));
|
initType(clazz, constructors.get(clazz), prototypes.get(clazz));
|
||||||
return constructors.get(clazz);
|
while (clazz != null) {
|
||||||
|
var res = constructors.get(clazz);
|
||||||
|
if (res != null) return res;
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public WrapperProvider fork(Environment env) {
|
@Override public WrapperProvider fork(Environment env) {
|
||||||
return new NativeWrapperProvider(env);
|
return new NativeWrapperProvider(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProto(Class<?> clazz, ObjectValue value) {
|
public void set(Class<?> clazz, Class<?> wrapper) {
|
||||||
prototypes.put(clazz, value);
|
if (wrapper == null) set(clazz, null, null);
|
||||||
|
else set(clazz, makeProto(env, wrapper), makeConstructor(env, wrapper));
|
||||||
}
|
}
|
||||||
public void setConstr(Class<?> clazz, FunctionValue value) {
|
public void set(Class<?> clazz, ObjectValue proto, FunctionValue constructor) {
|
||||||
constructors.put(clazz, value);
|
if (proto != null && constructor != null) {
|
||||||
|
prototypes.put(clazz, proto);
|
||||||
|
constructors.put(clazz, constructor);
|
||||||
|
ignore.remove(clazz);
|
||||||
|
|
||||||
|
for (var el : prototypes.keySet()) {
|
||||||
|
if (clazz.isAssignableFrom(el)) {
|
||||||
|
updateProtoChain(el, getProto(el), getConstr(el));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prototypes.remove(clazz);
|
||||||
|
constructors.remove(clazz);
|
||||||
|
ignore.remove(clazz);
|
||||||
|
|
||||||
|
initType(clazz, constructor, proto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initError() {
|
private void initError() {
|
||||||
@@ -354,8 +404,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
proto.defineProperty(null, "constructor", constr, true, false, false);
|
proto.defineProperty(null, "constructor", constr, true, false, false);
|
||||||
constr.defineProperty(null, "prototype", proto, true, false, false);
|
constr.defineProperty(null, "prototype", proto, true, false, false);
|
||||||
|
|
||||||
setProto(Throwable.class, proto);
|
set(Throwable.class, proto, constr);
|
||||||
setConstr(Throwable.class, constr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NativeWrapperProvider(Environment env) {
|
public NativeWrapperProvider(Environment env) {
|
||||||
|
|||||||
Reference in New Issue
Block a user