Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        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);
            });
        }
Beispiel #4
0
 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);
 }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 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);
 }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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));
        }
Beispiel #11
0
        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();
        }