示例#1
0
        private void ProjectProperties(BaristaContext context, JsObject targetObject, IEnumerable <PropertyInfo> properties)
        {
            foreach (var prop in properties)
            {
                var propertyAttribute  = BaristaPropertyAttribute.GetAttribute(prop);
                var propertyName       = propertyAttribute.Name;
                var propertyDescriptor = context.CreateObject();

                if (propertyAttribute.Configurable)
                {
                    propertyDescriptor.SetProperty("configurable", context.True);
                }
                if (propertyAttribute.Enumerable)
                {
                    propertyDescriptor.SetProperty("enumerable", context.True);
                }

                if (prop.GetMethod != null)
                {
                    var jsGet = context.CreateFunction(new BaristaFunctionDelegate((calleeObj, isConstructCall, thisObj, args) =>
                    {
                        return(GetPropertyValue(context, prop, propertyName, thisObj));
                    }));

                    propertyDescriptor.SetProperty("get", jsGet);
                }

                if (prop.SetMethod != null)
                {
                    var jsSet = context.CreateFunction(new BaristaFunctionDelegate((calleeObj, isConstructCall, thisObj, args) =>
                    {
                        return(SetPropertyValue(context, prop, propertyName, thisObj, args));
                    }));

                    propertyDescriptor.SetProperty("set", jsSet);
                }

                targetObject.SetProperty(context.CreateString(propertyName), propertyDescriptor);
            }
        }
示例#2
0
        private void ProjectMethods(BaristaContext context, JsObject targetObject, ObjectReflector reflector, IDictionary <string, IList <MethodInfo> > methods)
        {
            foreach (var method in methods)
            {
                var methodName  = method.Key;
                var methodInfos = method.Value;

                var fn = context.CreateFunction(new BaristaFunctionDelegate((calleeObj, isConstructCall, thisObj, args) =>
                {
                    object targetObj = null;

                    if (thisObj == null)
                    {
                        context.CurrentScope.SetException(context.CreateTypeError($"Could not call function '{methodName}': Invalid 'this' context."));
                        return(context.Undefined);
                    }

                    if (thisObj.TryGetBean(out JsExternalObject xoObj))
                    {
                        targetObj = xoObj.Target;
                    }

                    try
                    {
                        var bestMethod = reflector.GetMethodBestMatch(methodInfos, args);
                        if (bestMethod == null)
                        {
                            var ex = context.CreateTypeError($"Failed to call function '{methodName}': Could not find a matching function for the provided arguments.");
                            context.CurrentScope.SetException(ex);
                            return(context.Undefined);
                        }

                        //Convert the args into the native args of the method.
                        var methodParams  = bestMethod.GetParameters();
                        var convertedArgs = ConvertArgsToParamTypes(context, args, methodParams);

                        var result = bestMethod.Invoke(targetObj, convertedArgs);
                        if (context.Converter.TryFromObject(context, result, out JsValue resultValue))
                        {
                            return(resultValue);
                        }
                        else
                        {
                            context.CurrentScope.SetException(context.CreateTypeError($"The call to '{methodName}' was successful, but the result could not be converted into a JavaScript object."));
                            return(context.Undefined);
                        }
                    }
                    catch (Exception ex)
                    {
                        context.CurrentScope.SetException(context.CreateError(ex.Message));
                        return(context.Undefined);
                    }
                }));

                var functionDescriptor = context.CreateObject();

                if (methodInfos.All(mi => BaristaPropertyAttribute.GetAttribute(mi).Configurable))
                {
                    functionDescriptor.SetProperty("configurable", context.True);
                }
                if (methodInfos.All(mi => BaristaPropertyAttribute.GetAttribute(mi).Enumerable))
                {
                    functionDescriptor.SetProperty("enumerable", context.True);
                }
                if (methodInfos.All(mi => BaristaPropertyAttribute.GetAttribute(mi).Writable))
                {
                    functionDescriptor.SetProperty("writable", context.True);
                }

                functionDescriptor.SetProperty("value", fn);

                targetObject.SetProperty(context.CreateString(methodName), functionDescriptor);
            }
        }