feat: add support for member class wrappers
This commit is contained in:
parent
7e6a1e03c8
commit
6da7720c67
@ -8,7 +8,6 @@ import me.topchetoeu.jscript.engine.CallContext.DataKey;
|
|||||||
import me.topchetoeu.jscript.engine.debug.DebugState;
|
import me.topchetoeu.jscript.engine.debug.DebugState;
|
||||||
import me.topchetoeu.jscript.engine.modules.ModuleManager;
|
import me.topchetoeu.jscript.engine.modules.ModuleManager;
|
||||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||||
import me.topchetoeu.jscript.engine.values.CodeFunction;
|
|
||||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.engine.values.ObjectValue.PlaceholderProto;
|
import me.topchetoeu.jscript.engine.values.ObjectValue.PlaceholderProto;
|
||||||
@ -181,7 +180,7 @@ public class Engine {
|
|||||||
return msg.notifier;
|
return msg.notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CodeFunction compile(GlobalScope scope, String filename, String raw) throws InterruptedException {
|
public FunctionValue compile(GlobalScope scope, String filename, String raw) throws InterruptedException {
|
||||||
return Parsing.compile(scope, filename, raw);
|
return Parsing.compile(scope, filename, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR })
|
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Native {
|
public @interface Native {
|
||||||
public String value() default "";
|
public String value() default "";
|
||||||
|
@ -71,15 +71,45 @@ public class NativeTypeRegister {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static void applyClasses(boolean member, ObjectValue target, Class<?> clazz) {
|
||||||
|
for (var cl : clazz.getDeclaredClasses()) {
|
||||||
|
if (!Modifier.isStatic(cl.getModifiers()) != member) continue;
|
||||||
|
var nat = cl.getAnnotation(Native.class);
|
||||||
|
|
||||||
|
if (nat != null) {
|
||||||
|
var name = nat.value();
|
||||||
|
if (name.equals("")) name = cl.getSimpleName();
|
||||||
|
|
||||||
|
var getter = new OverloadFunction("get " + name).add(Overload.getter(member ? clazz : null, (ctx, thisArg, args) -> {
|
||||||
|
return ctx.engine().typeRegister().getConstr(cl);
|
||||||
|
}));
|
||||||
|
|
||||||
|
target.defineProperty(name, getter, null, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a prototype for the given class.
|
||||||
|
* The returned object will have appropriate wrappers for all instance members.
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
public static ObjectValue makeProto(Class<?> clazz) {
|
public static ObjectValue makeProto(Class<?> clazz) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
|
|
||||||
applyMethods(true, res, clazz);
|
applyMethods(true, res, clazz);
|
||||||
applyFields(true, res, clazz);
|
applyFields(true, res, clazz);
|
||||||
|
applyClasses(true, res, clazz);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Generates a constructor for the given class.
|
||||||
|
* The returned function will have appropriate wrappers for all static members.
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
public static FunctionValue makeConstructor(Class<?> clazz) {
|
public static FunctionValue makeConstructor(Class<?> clazz) {
|
||||||
FunctionValue func = new OverloadFunction(clazz.getName());
|
FunctionValue func = new OverloadFunction(clazz.getName());
|
||||||
|
|
||||||
@ -94,16 +124,24 @@ public class NativeTypeRegister {
|
|||||||
|
|
||||||
applyMethods(false, func, clazz);
|
applyMethods(false, func, clazz);
|
||||||
applyFields(false, func, clazz);
|
applyFields(false, func, clazz);
|
||||||
|
applyClasses(false, func, clazz);
|
||||||
|
|
||||||
func.special = true;
|
func.special = true;
|
||||||
|
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Generates a namespace for the given class.
|
||||||
|
* The returned function will have appropriate wrappers for all static members.
|
||||||
|
* This method behaves almost like {@link NativeTypeRegister#makeConstructor}, but will return an object instead.
|
||||||
|
* @param clazz The class for which a constructor should be generated
|
||||||
|
*/
|
||||||
public static ObjectValue makeNamespace(Class<?> clazz) {
|
public static ObjectValue makeNamespace(Class<?> clazz) {
|
||||||
ObjectValue res = new ObjectValue();
|
ObjectValue res = new ObjectValue();
|
||||||
|
|
||||||
applyMethods(false, res, clazz);
|
applyMethods(false, res, clazz);
|
||||||
applyFields(false, res, clazz);
|
applyFields(false, res, clazz);
|
||||||
|
applyClasses(false, res, clazz);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public class Overload {
|
|||||||
IllegalArgumentException;
|
IllegalArgumentException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Overload.OverloadRunner runner;
|
public final OverloadRunner runner;
|
||||||
public final boolean variadic;
|
public final boolean variadic;
|
||||||
public final Class<?> thisArg;
|
public final Class<?> thisArg;
|
||||||
public final Class<?>[] params;
|
public final Class<?>[] params;
|
||||||
@ -52,8 +52,15 @@ public class Overload {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Overload getter(Class<?> thisArg, OverloadRunner runner) {
|
||||||
|
return new Overload(
|
||||||
|
(ctx, th, args) -> runner.run(ctx, th, args), false,
|
||||||
|
thisArg,
|
||||||
|
new Class[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public Overload(Overload.OverloadRunner runner, boolean variadic, Class<?> thisArg, Class<?> args[]) {
|
public Overload(OverloadRunner runner, boolean variadic, Class<?> thisArg, Class<?> args[]) {
|
||||||
this.runner = runner;
|
this.runner = runner;
|
||||||
this.variadic = variadic;
|
this.variadic = variadic;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
|
Loading…
Reference in New Issue
Block a user