public ClrProperty(global::Jint.Engine engine, DomConverter converter, PropertyInfo property) { Get = property.GetMethod != null && property.GetMethod.IsPublic ? new ClrFunctionInstance(engine, (jsThis, values) => { var clrThis = converter.ConvertFromJs(jsThis); return(JsValue.FromObject(engine, property.GetValue(clrThis))); }) : null; var setter = new Lazy <Action <object, JsValue> >(() => CreateSetter(converter, property)); Set = property.SetMethod != null && property.SetMethod.IsPublic ? new ClrFunctionInstance(engine, (jsThis, values) => { try { var clrThis = converter.ConvertFromJs(jsThis); if (values.Length == 0) { return(JsValue.Undefined); } setter.Value(clrThis, values[0]); return(JsValue.Undefined); } catch (Exception e) { throw new JavaScriptException(e.Message); } }) : new ClrFunctionInstance(engine, (value, values) => JsValue.Undefined); }
public JintJsEngine(object global) { _typeConverter = new DomConverter(() => _engine); _engine = new Engine(o => o.AddObjectConverter(_typeConverter)); if (global != null) { _typeConverter.SetGlobal(global); _typeConverter.DefineProperties(_engine.Global, global.GetType()); foreach (var method in global.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance)) { var ctorAttribute = method.GetCustomAttribute <JsCtorAttribute>(); if (ctorAttribute == null) { continue; } //todo: optimize, write test. var type = method.ReturnType; AddGlobalType(ctorAttribute.Name ?? type.GetName(), global, method); } } }
public ClrEvent(global::Jint.Engine engine, DomConverter converter, EventInfo eventInfo) { Get = new ClrFunctionInstance(engine, (clrThis, args) => { var attachedEvents = converter.GetAttachedEventsFor(clrThis); return(attachedEvents.TryGetValue(eventInfo, out var func) ? func : JsValue.Null); }); Set = new ClrFunctionInstance(engine, (jsThis, args) => { var objectInstance = jsThis.AsObject(); var clrThis = converter.ConvertFromJs(jsThis); var attachedEvents = converter.GetAttachedEventsFor(objectInstance); if (attachedEvents.TryGetValue(eventInfo, out var existHandler)) { var clrHandler = converter.ConvertToClr(existHandler, eventInfo.EventHandlerType, jsThis); eventInfo.RemoveMethod.Invoke(clrThis, new object[] { clrHandler }); attachedEvents.Remove(eventInfo); } if (args.Length != 0 && !args[0].IsNull() && !args[0].IsUndefined() && args[0].AsObject() is FunctionInstance functionInstance) { var clrHandler = converter.ConvertToClr(functionInstance, eventInfo.EventHandlerType, jsThis); eventInfo.AddMethod.Invoke(clrThis, new object[] { clrHandler }); attachedEvents[eventInfo] = functionInstance; } return(null); }); }
public ClrPrototype(global::Jint.Engine engine, DomConverter converter, Type type, ObjectInstance prototype) : base(engine) { Prototype = prototype; Class = type.GetJsName(); Extensible = true; converter.DefineProperties(this, type); }
public ClrCtor(Engine engine, DomConverter converter, Type type) : base(engine, null, null, false) { _type = type; _converter = converter; Prototype = engine.Function.PrototypeObject; FastAddProperty("prototype", _converter.GetPrototype(type), false, false, false); DomConverter.DefineStatic(this, type); }
public ClrFuncCtor(Type clrType, Engine engine, Func <JsValue[], ObjectInstance> act, ObjectInstance prototype) : base(engine, null, null, false) { _act = act; _clrType = clrType; FastAddProperty("prototype", prototype, false, false, false); DomConverter.DefineStatic(this, clrType); }
public ClrMethodInfoFunc(DomConverter converter, global::Jint.Engine engine, MethodInfo[] methods, JsValue owner) : base(engine, null, null, false) { _converter = converter; _owner = owner; _methods = methods.OrderByDescending(x => x.GetParameters().Length).ToArray(); _invokers = new Func <object, JsValue[], object> [methods.Length]; Prototype = engine.Function.PrototypeObject; var name = methods.First().GetName(); FastAddProperty("name", new JsValue(name), false, false, false); }
private static Action <object, JsValue> CreateSetter(DomConverter converter, PropertyInfo property) { var expThisArg = Expression.Parameter(typeof(object), "clrThis"); var expValueArg = Expression.Parameter(typeof(JsValue), "jsValue"); var setterExpression = Expression.Assign( Expression.Property(Expression.Convert(expThisArg, property.DeclaringType), property), converter.CreateConverterExpr(property.PropertyType, expValueArg, expThisArg)); var setterLambda = Expression.Lambda <Action <object, JsValue> >(setterExpression, expThisArg, expValueArg) .Compile(); return(setterLambda); }
public ObjectInstance Construct(JsValue[] arguments) { var argsValues = arguments.Select(x => x.ToObject()).ToArray(); var argTypes = argsValues.Select(x => x?.GetType()).ToArray(); if (argTypes.All(x => x != null)) { //todo: why we here do not onvert args? var exactCtor = _type.GetConstructor(argTypes); if (exactCtor != null) { var obj = exactCtor.Invoke(argsValues); JsValue val; if (_converter.TryConvert(obj, out val)) { return(val.AsObject() as ClrObject); } } } foreach (var ctor in _type.GetConstructors()) { var ctorParameters = ctor.GetParameters(); if (ctorParameters.Length == argTypes.Length) { var notMatch = false; for (var i = 0; i < ctorParameters.Length && !notMatch; i++) { if (!DomConverter.Convertible(argTypes[i], ctorParameters[i].ParameterType)) { notMatch = true; } } if (!notMatch) { var args = ConvertArgs(argsValues, ctorParameters.Select(x => x.ParameterType)) .ToArray(); var obj = ctor.Invoke(args); return(new ClrObject(Engine, obj, _converter.GetPrototype(obj.GetType()), _converter)); } } } throw new Exception("Unable to find proper constructor for the type: " + _type.Name); }
public static PropertyDescriptor Create(global::Jint.Engine engine, DomConverter converter, string propertyName, MethodInfo[] methods, JsValue owner) { var func = new ClrMethodInfoFunc(converter, engine, methods, owner); //todo: check if this necessary func.FastAddProperty("toString", new JsValue(new ClrFunctionInstance(engine, (value, values) => new JsValue("function " + propertyName + "() { [native code] }"))), false, false, false); return(new PropertyDescriptor(func, false, true, false)); }
public ClrObject(Engine engine, Object obj, ObjectInstance prototype, DomConverter converter) : base(engine) { _converter = converter; Target = obj; Prototype = prototype; Extensible = true; //todo: optimize reflection. _indexPropertyStr = Target.GetType().GetRecursive(x => x.BaseType).SelectMany(x => x.GetProperties().Where(p => p.GetIndexParameters().Length != 0 && p.GetCustomAttribute <JsHiddenAttribute>() == null && p.GetIndexParameters()[0].ParameterType == typeof(string))) .FirstOrDefault(); _indexPropertyInt = Target.GetType().GetRecursive(x => x.BaseType).SelectMany(x => x.GetProperties().Where(p => p.GetIndexParameters().Length != 0 && p.GetCustomAttribute <JsHiddenAttribute>() == null && p.GetIndexParameters()[0].ParameterType == typeof(int))) .FirstOrDefault(); _indexPropertyUlong = Target.GetType().GetRecursive(x => x.BaseType).SelectMany(x => x.GetProperties().Where(p => p.GetIndexParameters().Length != 0 && p.GetCustomAttribute <JsHiddenAttribute>() == null && p.GetIndexParameters()[0].ParameterType == typeof(ulong))) .FirstOrDefault(); _indexPropertyObject = Target.GetType().GetRecursive(x => x.BaseType).SelectMany(x => x.GetProperties().Where(p => p.GetIndexParameters().Length != 0 && p.GetCustomAttribute <JsHiddenAttribute>() == null && p.GetIndexParameters()[0].ParameterType == typeof(object))) .FirstOrDefault(); }