Compare commits
9 Commits
0.9.37-bet
...
0.9.43-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
8a8de518a6
|
|||
|
099201e4ad
|
|||
|
f8553b79f9
|
|||
|
ba6462458c
|
|||
|
e33cdbb172
|
|||
|
fc6ddf7d3c
|
|||
|
7f275095a2
|
|||
|
90d019f92a
|
|||
|
6fb31be12c
|
@@ -1,4 +1,4 @@
|
|||||||
project_group = me.topchetoeu
|
project_group = me.topchetoeu
|
||||||
project_name = jscript
|
project_name = jscript
|
||||||
project_version = 0.9.27-beta
|
project_version = 0.9.41-beta
|
||||||
main_class = me.topchetoeu.jscript.utils.JScriptRepl
|
main_class = me.topchetoeu.jscript.utils.JScriptRepl
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class ContinueStatement extends Statement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(CompileResult target, boolean pollute) {
|
public void compile(CompileResult target, boolean pollute) {
|
||||||
target.add(Instruction.nop(loc(), "cont", label));
|
target.add(Instruction.nop("cont", label));
|
||||||
if (pollute) target.add(Instruction.pushUndefined());
|
if (pollute) target.add(Instruction.pushUndefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class FilesystemLib {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (fs.stat(path).type != EntryType.FILE) {
|
if (fs.stat(path).type != EntryType.FILE) {
|
||||||
throw new FilesystemException(ErrorReason.DOESNT_EXIST, "Not a file").setAction(ActionType.OPEN);
|
throw new FilesystemException(ErrorReason.DOESNT_EXIST, "Not a file").setAction(ActionType.OPEN).setPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileLib(fs.open(path, _mode));
|
return new FileLib(fs.open(path, _mode));
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
package me.topchetoeu.jscript.lib;
|
package me.topchetoeu.jscript.lib;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
|
import me.topchetoeu.jscript.runtime.Compiler;
|
||||||
|
import me.topchetoeu.jscript.runtime.Context;
|
||||||
|
import me.topchetoeu.jscript.runtime.scope.ValueVariable;
|
||||||
import me.topchetoeu.jscript.runtime.values.ArrayValue;
|
import me.topchetoeu.jscript.runtime.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.runtime.values.CodeFunction;
|
import me.topchetoeu.jscript.runtime.values.CodeFunction;
|
||||||
import me.topchetoeu.jscript.runtime.values.FunctionValue;
|
import me.topchetoeu.jscript.runtime.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.runtime.values.NativeFunction;
|
import me.topchetoeu.jscript.runtime.values.NativeFunction;
|
||||||
|
import me.topchetoeu.jscript.runtime.values.Values;
|
||||||
import me.topchetoeu.jscript.utils.interop.Arguments;
|
import me.topchetoeu.jscript.utils.interop.Arguments;
|
||||||
import me.topchetoeu.jscript.utils.interop.Expose;
|
import me.topchetoeu.jscript.utils.interop.Expose;
|
||||||
|
import me.topchetoeu.jscript.utils.interop.ExposeConstructor;
|
||||||
import me.topchetoeu.jscript.utils.interop.ExposeTarget;
|
import me.topchetoeu.jscript.utils.interop.ExposeTarget;
|
||||||
import me.topchetoeu.jscript.utils.interop.WrapperName;
|
import me.topchetoeu.jscript.utils.interop.WrapperName;
|
||||||
|
|
||||||
@WrapperName("Function")
|
@WrapperName("Function")
|
||||||
public class FunctionLib {
|
public class FunctionLib {
|
||||||
|
private static int i;
|
||||||
|
|
||||||
@Expose public static Object __apply(Arguments args) {
|
@Expose public static Object __apply(Arguments args) {
|
||||||
return args.self(FunctionValue.class).call(args.ctx, args.get(0), args.convert(1, ArrayValue.class).toArray());
|
return args.self(FunctionValue.class).call(args.ctx, args.get(0), args.convert(1, ArrayValue.class).toArray());
|
||||||
}
|
}
|
||||||
@@ -51,4 +59,25 @@ public class FunctionLib {
|
|||||||
public static FunctionValue __generator(Arguments args) {
|
public static FunctionValue __generator(Arguments args) {
|
||||||
return new GeneratorFunctionLib(args.convert(0, CodeFunction.class));
|
return new GeneratorFunctionLib(args.convert(0, CodeFunction.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExposeConstructor
|
||||||
|
public static Object __constructor(Arguments args) {
|
||||||
|
var compiler = Compiler.get(args);
|
||||||
|
|
||||||
|
var parts = args.convert(String.class);
|
||||||
|
if (parts.length == 0) parts = new String[] { "" };
|
||||||
|
|
||||||
|
var src = "return function(";
|
||||||
|
|
||||||
|
for (var i = 0; i < parts.length - 1; i++) {
|
||||||
|
if (i != 0) src += ",";
|
||||||
|
src += parts[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
src += "){" + parts[parts.length - 1] + "}";
|
||||||
|
|
||||||
|
var body = compiler.compile(new Filename("jscript", "func/" + i++), src);
|
||||||
|
var func = new CodeFunction(Context.clean(args.ctx), "", body, new ValueVariable[0]);
|
||||||
|
return Values.call(args, func, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class Context implements Extensions {
|
|||||||
return new Context(ext);
|
return new Context(ext);
|
||||||
}
|
}
|
||||||
public static Extensions clean(Extensions ext) {
|
public static Extensions clean(Extensions ext) {
|
||||||
if (ext instanceof Context) return ((Context)ext).extensions;
|
if (ext instanceof Context) return clean(((Context)ext).extensions);
|
||||||
else return ext;
|
else return ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class GlobalScope {
|
|||||||
return Values.hasMember(ext, obj, name, false);
|
return Values.hasMember(ext, obj, name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlobalScope globalChild() {
|
public GlobalScope child() {
|
||||||
var obj = new ObjectValue();
|
var obj = new ObjectValue();
|
||||||
Values.setPrototype(null, obj, this.obj);
|
Values.setPrototype(null, obj, this.obj);
|
||||||
return new GlobalScope(obj);
|
return new GlobalScope(obj);
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ public class JScriptRepl {
|
|||||||
private static void initEnv() {
|
private static void initEnv() {
|
||||||
environment = Internals.apply(environment);
|
environment = Internals.apply(environment);
|
||||||
|
|
||||||
var wp = NativeWrapperProvider.get(environment);
|
|
||||||
var glob = GlobalScope.get(environment);
|
var glob = GlobalScope.get(environment);
|
||||||
|
|
||||||
glob.define(null, false, new NativeFunction("exit", args -> {
|
glob.define(null, false, new NativeFunction("exit", args -> {
|
||||||
|
|||||||
@@ -397,7 +397,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) { }
|
catch (Exception e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public abstract class BaseFile<T> implements File {
|
|||||||
@Override public synchronized long seek(long offset, int pos) {
|
@Override public synchronized long seek(long offset, int pos) {
|
||||||
try {
|
try {
|
||||||
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
|
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
|
||||||
if (!mode.writable) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for seeking.");
|
if (mode == Mode.NONE) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for seeking.");
|
||||||
return onSeek(offset, pos);
|
return onSeek(offset, pos);
|
||||||
}
|
}
|
||||||
catch (FilesystemException e) { throw e.setAction(ActionType.SEEK); }
|
catch (FilesystemException e) { throw e.setAction(ActionType.SEEK); }
|
||||||
|
|||||||
@@ -54,16 +54,12 @@ public class FilesystemException extends RuntimeException {
|
|||||||
@Override public String getMessage() {
|
@Override public String getMessage() {
|
||||||
var parts = new ArrayList<String>(10);
|
var parts = new ArrayList<String>(10);
|
||||||
|
|
||||||
path = String.join(" ", parts).trim();
|
|
||||||
if (path.isEmpty()) path = null;
|
|
||||||
parts.clear();
|
|
||||||
|
|
||||||
parts.add(action == null ? "An action performed upon " : action.readable(reason.usePast));
|
parts.add(action == null ? "An action performed upon " : action.readable(reason.usePast));
|
||||||
|
|
||||||
if (entry == EntryType.FILE) parts.add("file");
|
if (entry == EntryType.FILE) parts.add("file");
|
||||||
if (entry == EntryType.FOLDER) parts.add("folder");
|
if (entry == EntryType.FOLDER) parts.add("folder");
|
||||||
|
|
||||||
if (path != null) parts.add(path);
|
if (path != null && !path.isBlank()) parts.add(path.trim());
|
||||||
|
|
||||||
parts.add(reason.readable);
|
parts.add(reason.readable);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.topchetoeu.jscript.utils.filesystem;
|
package me.topchetoeu.jscript.utils.filesystem;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -35,7 +36,8 @@ public class PhysicalFilesystem implements Filesystem {
|
|||||||
));
|
));
|
||||||
else return handles.put(new PhysicalFile(path, perms));
|
else return handles.put(new PhysicalFile(path, perms));
|
||||||
}
|
}
|
||||||
catch (IOException e) { throw new FilesystemException(ErrorReason.DOESNT_EXIST); }
|
catch (FileNotFoundException e) { throw new FilesystemException(ErrorReason.DOESNT_EXIST); }
|
||||||
|
catch (IOException e) { throw new FilesystemException(ErrorReason.NO_PERMISSION); }
|
||||||
}
|
}
|
||||||
catch (FilesystemException e) { throw e.setAction(ActionType.OPEN).setPath(_path); }
|
catch (FilesystemException e) { throw e.setAction(ActionType.OPEN).setPath(_path); }
|
||||||
}
|
}
|
||||||
@@ -68,12 +70,7 @@ public class PhysicalFilesystem implements Filesystem {
|
|||||||
|
|
||||||
if (!Files.exists(path)) return new FileStat(Mode.NONE, EntryType.NONE);
|
if (!Files.exists(path)) return new FileStat(Mode.NONE, EntryType.NONE);
|
||||||
|
|
||||||
var perms = Mode.NONE;
|
var perms = Mode.of(Files.isReadable(path), Files.isWritable(path));
|
||||||
|
|
||||||
if (Files.isReadable(path)) {
|
|
||||||
if (Files.isWritable(path)) perms = Mode.READ_WRITE;
|
|
||||||
else perms = Mode.READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perms == Mode.NONE) return new FileStat(Mode.NONE, EntryType.NONE);
|
if (perms == Mode.NONE) return new FileStat(Mode.NONE, EntryType.NONE);
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.runtime.Context;
|
import me.topchetoeu.jscript.runtime.Context;
|
||||||
@@ -30,6 +32,7 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
private final HashMap<Class<?>, ObjectValue> namespaces = new HashMap<>();
|
private final HashMap<Class<?>, ObjectValue> namespaces = new HashMap<>();
|
||||||
private final HashMap<Class<?>, Class<?>> classToProxy = new HashMap<>();
|
private final HashMap<Class<?>, Class<?>> classToProxy = new HashMap<>();
|
||||||
private final HashMap<Class<?>, Class<?>> proxyToClass = new HashMap<>();
|
private final HashMap<Class<?>, Class<?>> proxyToClass = new HashMap<>();
|
||||||
|
private final HashMap<Class<?>, Class<?>> interfaceToProxy = new HashMap<>();
|
||||||
private final HashSet<Class<?>> ignore = new HashSet<>();
|
private final HashSet<Class<?>> ignore = new HashSet<>();
|
||||||
|
|
||||||
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) {
|
||||||
@@ -83,10 +86,16 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
String.join(", ", Arrays.stream(actual).map(v -> v.getName()).collect(Collectors.toList()))
|
String.join(", ", Arrays.stream(actual).map(v -> v.getName()).collect(Collectors.toList()))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
private static String getName(Class<?> clazz) {
|
private static String getName(Class<?> ...classes) {
|
||||||
var classNat = clazz.getAnnotation(WrapperName.class);
|
String last = null;
|
||||||
if (classNat != null && !classNat.value().trim().equals("")) return classNat.value().trim();
|
|
||||||
else return clazz.getSimpleName();
|
for (var clazz : classes) {
|
||||||
|
var classNat = clazz.getAnnotation(WrapperName.class);
|
||||||
|
if (classNat != null && !classNat.value().trim().equals("")) return classNat.value().trim();
|
||||||
|
else if (last != null) last = clazz.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkUnderscore(Member member) {
|
private static void checkUnderscore(Member member) {
|
||||||
@@ -120,13 +129,13 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
|
|
||||||
for (var method : clazz.getDeclaredMethods()) {
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
for (var annotation : method.getAnnotationsByType(Expose.class)) {
|
for (var annotation : method.getAnnotationsByType(Expose.class)) {
|
||||||
|
any = true;
|
||||||
if (!annotation.target().shouldApply(target)) continue;
|
if (!annotation.target().shouldApply(target)) continue;
|
||||||
|
|
||||||
checkUnderscore(method);
|
checkUnderscore(method);
|
||||||
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 METHOD:
|
case METHOD:
|
||||||
@@ -162,13 +171,13 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
for (var annotation : method.getAnnotationsByType(ExposeField.class)) {
|
for (var annotation : method.getAnnotationsByType(ExposeField.class)) {
|
||||||
|
any = true;
|
||||||
if (!annotation.target().shouldApply(target)) continue;
|
if (!annotation.target().shouldApply(target)) continue;
|
||||||
|
|
||||||
checkUnderscore(method);
|
checkUnderscore(method);
|
||||||
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,13 +200,13 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
}
|
}
|
||||||
for (var field : clazz.getDeclaredFields()) {
|
for (var field : clazz.getDeclaredFields()) {
|
||||||
for (var annotation : field.getAnnotationsByType(ExposeField.class)) {
|
for (var annotation : field.getAnnotationsByType(ExposeField.class)) {
|
||||||
|
any = true;
|
||||||
if (!annotation.target().shouldApply(target)) continue;
|
if (!annotation.target().shouldApply(target)) continue;
|
||||||
|
|
||||||
checkUnderscore(field);
|
checkUnderscore(field);
|
||||||
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 {
|
||||||
@@ -237,12 +246,23 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
|
|
||||||
return any;
|
return any;
|
||||||
}
|
}
|
||||||
|
private static boolean apply(ObjectValue obj, ExposeTarget target, Class<?> ...appliers) {
|
||||||
|
var res = false;
|
||||||
|
|
||||||
private static Method getConstructor(Class<?> clazz) {
|
for (var i = appliers.length - 1; i >= 0; i--) {
|
||||||
for (var method : clazz.getDeclaredMethods()) {
|
res |= apply(obj, target, appliers[i]);
|
||||||
if (!method.isAnnotationPresent(ExposeConstructor.class)) continue;
|
}
|
||||||
checkSignature(method, true, Arguments.class);
|
|
||||||
return method;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method getConstructor(Class<?> ...appliers) {
|
||||||
|
for (var clazz : appliers) {
|
||||||
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
|
if (!method.isAnnotationPresent(ExposeConstructor.class)) continue;
|
||||||
|
checkSignature(method, true, Arguments.class);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -254,10 +274,10 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
* All accessors and methods will expect the this argument to be a native wrapper of the given class type.
|
* All accessors and methods will expect the this argument to be a native wrapper of the given class type.
|
||||||
* @param clazz The class for which a prototype should be generated
|
* @param clazz The class for which a prototype should be generated
|
||||||
*/
|
*/
|
||||||
public static ObjectValue makeProto(Class<?> clazz) {
|
public static ObjectValue makeProto(Class<?> ...appliers) {
|
||||||
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(appliers));
|
||||||
if (!apply(res, ExposeTarget.PROTOTYPE, clazz)) return null;
|
if (!apply(res, ExposeTarget.PROTOTYPE, appliers)) return null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -266,14 +286,14 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
* When the function gets called, the underlying constructor will get called, unless the constructor is inaccessible.
|
* When the function gets called, the underlying constructor will get called, unless the constructor is inaccessible.
|
||||||
* @param clazz The class for which a constructor should be generated
|
* @param clazz The class for which a constructor should be generated
|
||||||
*/
|
*/
|
||||||
public static FunctionValue makeConstructor(Class<?> clazz) {
|
public static FunctionValue makeConstructor(Class<?> ...appliers) {
|
||||||
var constr = getConstructor(clazz);
|
var constr = getConstructor(appliers);
|
||||||
|
|
||||||
FunctionValue res = constr == null ?
|
FunctionValue res = constr == null ?
|
||||||
new NativeFunction(getName(clazz), args -> { throw EngineException.ofError("This constructor is not invokable."); }) :
|
new NativeFunction(getName(appliers), args -> { throw EngineException.ofError("This constructor is not invokable."); }) :
|
||||||
create(getName(clazz), constr);
|
create(getName(appliers), constr);
|
||||||
|
|
||||||
apply(res, ExposeTarget.CONSTRUCTOR, clazz);
|
if (!apply(res, ExposeTarget.CONSTRUCTOR, appliers) && constr == null) return null;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -283,13 +303,27 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
* This method behaves almost like {@link NativeWrapperProvider#makeConstructor}, but will return an object instead.
|
* This method behaves almost like {@link NativeWrapperProvider#makeConstructor}, but will return an object instead.
|
||||||
* @param clazz The class for which a constructor should be generated
|
* @param clazz The class for which a constructor should be generated
|
||||||
*/
|
*/
|
||||||
public static ObjectValue makeNamespace(Class<?> clazz) {
|
public static ObjectValue makeNamespace(Class<?> ...appliers) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
res.defineProperty(null, Symbol.get("Symbol.typeName"), getName(clazz));
|
|
||||||
if (!apply(res, ExposeTarget.NAMESPACE, clazz)) return null;
|
if (!apply(res, ExposeTarget.NAMESPACE, appliers)) return null;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Class<?>[] getAppliers(Class<?> clazz) {
|
||||||
|
var res = new ArrayList<Class<?>>();
|
||||||
|
|
||||||
|
res.add(clazz);
|
||||||
|
|
||||||
|
if (classToProxy.containsKey(clazz)) res.add(classToProxy.get(clazz));
|
||||||
|
for (var intf : interfaceToProxy.keySet()) {
|
||||||
|
if (intf.isAssignableFrom(clazz)) res.add(interfaceToProxy.get(intf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.toArray(Class<?>[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateProtoChain(Class<?> clazz, ObjectValue proto, FunctionValue constr) {
|
private void updateProtoChain(Class<?> clazz, ObjectValue proto, FunctionValue constr) {
|
||||||
var parent = clazz;
|
var parent = clazz;
|
||||||
|
|
||||||
@@ -326,8 +360,10 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
clazz.isSynthetic()
|
clazz.isSynthetic()
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
if (constr == null) constr = makeConstructor(clazz);
|
var appliers = getAppliers(clazz);
|
||||||
if (proto == null) proto = makeProto(clazz);
|
|
||||||
|
if (constr == null) constr = makeConstructor(appliers);
|
||||||
|
if (proto == null) proto = makeProto(appliers);
|
||||||
|
|
||||||
if (constr == null || proto == null) return;
|
if (constr == null || proto == null) return;
|
||||||
|
|
||||||
@@ -386,30 +422,29 @@ public class NativeWrapperProvider implements Copyable {
|
|||||||
|
|
||||||
public void set(Class<?> clazz, Class<?> wrapper) {
|
public void set(Class<?> clazz, Class<?> wrapper) {
|
||||||
if (clazz == null) return;
|
if (clazz == null) return;
|
||||||
if (wrapper == null) wrapper = clazz;
|
|
||||||
if (classToProxy.get(clazz) == wrapper) return;
|
|
||||||
|
|
||||||
classToProxy.remove(wrapper);
|
if (clazz.isInterface()) {
|
||||||
proxyToClass.remove(clazz);
|
if (wrapper == null || wrapper == clazz) interfaceToProxy.remove(clazz);
|
||||||
|
else interfaceToProxy.put(clazz, wrapper);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (wrapper == null || wrapper == clazz) classToProxy.remove(clazz);
|
||||||
|
else classToProxy.put(clazz, wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
classToProxy.put(clazz, wrapper);
|
var classes = Stream.concat(
|
||||||
proxyToClass.put(wrapper, clazz);
|
Stream.of(clazz),
|
||||||
|
prototypes.keySet().stream().filter(clazz::isAssignableFrom)
|
||||||
|
).toArray(Class<?>[]::new);
|
||||||
|
|
||||||
ignore.remove(clazz);
|
for (var el : classes) {
|
||||||
|
prototypes.remove(el);
|
||||||
|
constructors.remove(el);
|
||||||
|
namespaces.remove(el);
|
||||||
|
}
|
||||||
|
|
||||||
var proto = makeProto(wrapper);
|
for (var el : classes) {
|
||||||
var constr = makeConstructor(wrapper);
|
initType(el, null, null);
|
||||||
|
|
||||||
prototypes.put(clazz, proto);
|
|
||||||
constructors.put(clazz, constr);
|
|
||||||
|
|
||||||
proto.defineProperty(null, "constructor", constr, true, false, false);
|
|
||||||
constr.defineProperty(null, "prototype", proto, true, false, false);
|
|
||||||
|
|
||||||
for (var el : prototypes.keySet()) {
|
|
||||||
if (clazz.isAssignableFrom(el)) {
|
|
||||||
updateProtoChain(el, getProto(el), getConstr(el));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import me.topchetoeu.jscript.common.Filename;
|
|||||||
import me.topchetoeu.jscript.runtime.Context;
|
import me.topchetoeu.jscript.runtime.Context;
|
||||||
import me.topchetoeu.jscript.runtime.Extensions;
|
import me.topchetoeu.jscript.runtime.Extensions;
|
||||||
import me.topchetoeu.jscript.runtime.Key;
|
import me.topchetoeu.jscript.runtime.Key;
|
||||||
|
import me.topchetoeu.jscript.runtime.scope.GlobalScope;
|
||||||
import me.topchetoeu.jscript.utils.filesystem.Filesystem;
|
import me.topchetoeu.jscript.utils.filesystem.Filesystem;
|
||||||
import me.topchetoeu.jscript.utils.filesystem.Mode;
|
import me.topchetoeu.jscript.utils.filesystem.Mode;
|
||||||
|
|
||||||
@@ -25,8 +26,10 @@ public interface ModuleRepo {
|
|||||||
|
|
||||||
if (modules.containsKey(name)) return modules.get(name);
|
if (modules.containsKey(name)) return modules.get(name);
|
||||||
|
|
||||||
var env = ctx.extensions.child();
|
var env = Context.clean(ctx.extensions).child();
|
||||||
env.add(CWD, fs.normalize(name, ".."));
|
env.add(CWD, fs.normalize(name, ".."));
|
||||||
|
var glob = env.get(GlobalScope.KEY);
|
||||||
|
env.add(GlobalScope.KEY, glob.child());
|
||||||
|
|
||||||
var mod = new SourceModule(filename, src, env);
|
var mod = new SourceModule(filename, src, env);
|
||||||
modules.put(name, mod);
|
modules.put(name, mod);
|
||||||
|
|||||||
Reference in New Issue
Block a user