Esempio n. 1
0
        public JsNode VisitMethodGroupResolveResult(MethodGroupResolveResult res)
        {
            var     info = res.GetInfo();
            IMethod me;

            if (info != null && info.Conversion != null && info.Conversion.Method != null)
            {
                me = info.Conversion.Method;
            }
            else //happens when invoking a method with overloads, and a parameter is dynamic
            {
                var list = res.Methods.ToList();
                if (list.Count == 0)
                {
                    throw new Exception("Method group not resolved to any method");
                }
                else if (list.Count == 1)
                {
                    me = list[0];
                }
                else
                {
                    me = list[0];
                }
                //TODO: verify all methods has the same js name
            }
            var          isExtensionMethodStyle = me.IsExtensionMethod && !(res.TargetResult is TypeResolveResult) && info != null && info.Conversion != null && info.Conversion.DelegateCapturesFirstArgument;//TODO: IsExtensionMethodStyle(new CsInvocationExpression { entity = me, expression = node });
            JsExpression firstPrm = null;

            if (isExtensionMethodStyle)
            {
                firstPrm = (JsExpression)Visit(res.TargetResult);
            }
            var          node2 = SkJs.EntityToMember(me);
            JsExpression node3;
            JsExpression instanceContext = null;

            if (me.IsStatic || res.TargetResult == null) //getting ThisResolveResult even on static methods, getting TargetResult=null when MethodGroupResolveResult when using delegates
            {
                node3 = node2;
            }
            else
            {
                instanceContext = VisitExpression(res.TargetResult);
                node3           = instanceContext.Member(node2);
            }
            if (info != null && (instanceContext != null || firstPrm != null))
            {
                var conv = info.Conversion;
                if (info.ConversionTargetType != null && !UseNativeFunctions(info.ConversionTargetType))//delegate type
                {
                    var parentMethod = info.Nodes.FirstOrDefault().GetCurrentMethod();
                    if (parentMethod == null || !Sk.ForceDelegatesAsNativeFunctions(parentMethod))
                    {
                        if (parentMethod == null)
                        {
                            Log.Warn(info.Nodes.FirstOrDefault(), "GetParentMethod() returned null");
                        }
                        var func = (JsExpression)node2;
                        if (instanceContext != null)
                        {
                            node3 = CreateJsDelegate(instanceContext, func);
                        }
                        else if (firstPrm != null)
                        {
                            node3 = CreateJsExtensionDelegate(firstPrm, func);
                        }
                    }
                }
            }
            return(node3);
        }
Esempio n. 2
0
        public JsNode VisitMethodGroupResolveResult(MethodGroupResolveResult res)
        {
            var     info = res.GetInfo();
            IMethod me;

            if (info != null && info.Conversion != null && info.Conversion.Method != null)
            {
                me = info.Conversion.Method;
            }
            else //happens when invoking a method with overloads, and a parameter is dynamic
            {
                var list = res.Methods.ToList();
                if (list.Count == 0)
                {
                    throw new Exception("Method group not resolved to any method");
                }
                else if (list.Count == 1)
                {
                    me = list[0];
                }
                else
                {
                    me = list[0];
                }
                //TODO: verify all methods has the same js name
            }
            var          isExtensionMethodStyle = me.IsExtensionMethod && !(res.TargetResult is TypeResolveResult) && info != null && info.Conversion != null && info.Conversion.DelegateCapturesFirstArgument;//TODO: IsExtensionMethodStyle(new CsInvocationExpression { entity = me, expression = node });
            JsExpression firstPrm = null;

            if (isExtensionMethodStyle)
            {
                firstPrm = (JsExpression)Visit(res.TargetResult);
            }
            var          node2 = SkJs.EntityToMember(me);
            JsExpression node3;
            JsExpression instanceContext = null;

            if (me.IsStatic || res.TargetResult == null) //getting ThisResolveResult even on static methods, getting TargetResult=null when MethodGroupResolveResult when using delegates
            {
                node3 = node2;
            }
            else
            {
                instanceContext = VisitExpression(res.TargetResult);
                node3           = instanceContext.Member(node2);
            }

            if (info != null && (instanceContext != null || firstPrm != null))
            {
                if (info.ConversionTargetType != null && !UseNativeFunctions(info.ConversionTargetType))//delegate type
                {
                    var parentMethod = info.Nodes.FirstOrDefault().GetCurrentMethod();
                    if (parentMethod == null || !Sk.ForceDelegatesAsNativeFunctions(parentMethod))
                    {
                        if (parentMethod == null)
                        {
                            Log.Warn(info.Nodes.FirstOrDefault(), "GetParentMethod() returned null");
                        }
                        var func = (JsExpression)node2;
                        if (instanceContext != null)
                        {
                            node3 = CreateJsDelegate(instanceContext, func);
                        }
                        else if (firstPrm != null)
                        {
                            node3 = CreateJsExtensionDelegate(firstPrm, func);
                        }
                    }
                }
            }

            // 其实以下的处理,也可以改代码,改成 Lambda 写法即可
            // 这样子引用的并不是同一个函数,可能会造成内存泄露
            if (res.TypeArguments.Count > 0 && info.Conversion.IsImplicit && me is SpecializedMethod)
            {
                var delegateFunc = node3 as JsInvocationExpression;

                var sme  = (SpecializedMethod)me;
                var pars = sme.TypeArguments.Select(type => SkJs.EntityTypeRefToMember(type, false)).ToList();
                pars.AddRange(sme.Parameters.Select(t => new JsCodeExpression
                {
                    Code = JsIdentifier(t.Name),
                }));
                var body = delegateFunc == null?node3.Invoke(pars.ToArray()) : delegateFunc.Arguments[1].Invoke(pars.ToArray());

                var func = new JsFunction()
                {
                    Parameters = sme.Parameters.Select(t => JsIdentifier(t.Name)).ToList(),
                };
                JsStatement st;
                if (sme.ReturnType.IsVoid())
                {
                    st = new JsExpressionStatement {
                        Expression = body
                    };
                }
                else
                {
                    st = new JsReturnStatement {
                        Expression = body
                    };
                }
                func.Block = new JsBlock {
                    Statements = new List <JsStatement> {
                        st
                    }
                };

                if (delegateFunc == null)
                {
                    node3 = func;
                }
                else
                {
                    delegateFunc.Arguments[1] = func;
                }
            }

            return(node3);
        }