Пример #1
0
        MemberConverter GetMemberConverter(ITypeDefinition ce)
        {
            MemberConverter export;
            var             isExtJs  = Sk.IsExtJsType(ce);
            var             isGlobal = Sk.IsGlobalType(ce) && !isExtJs;
            var             isNative = Sk.IsNativeType(ce) && !isExtJs;

            if (isGlobal)
            {
                if (GlobalConverter == null)
                {
                    GlobalConverter = new MemberConverter_Global();
                }
                export = GlobalConverter;
            }
            else if (isNative)
            {
                if (NativeConverter == null)
                {
                    NativeConverter = new MemberConverter_Native();
                }
                export = NativeConverter;
            }
            else if (isExtJs)
            {
                if (ExtJsConverter == null)
                {
                    ExtJsConverter = new MemberConverter_ExtJs();
                }
                export = ExtJsConverter;
            }
            else
            {
                if (ClrConverter == null)
                {
                    ClrConverter = new MemberConverter_Clr();
                }
                export = ClrConverter;
            }
            OnConfigureMemberConverter(export);
            return(export);
        }
Пример #2
0
        void TransformIntoBaseMethodCallIfNeeded(CSharpInvocationResolveResult res, JsInvocationExpression node2)
        {
            var target = res.TargetResult as ThisResolveResult;

            if (target != null && target.CausesNonVirtualInvocation) //base.
            {
                //var info = res.GetInfo();
                //var node = info.Nodes.FirstOrDefault();
                var ce = target.Type;// node.FindThisEntity();
                if (ce != null && Sk.IsExtJsType(ce.GetDefinitionOrArrayType()))
                {
                    node2.Member = Js.This().Member("callParent");
                    if (node2.Arguments.IsNotNullOrEmpty())
                    {
                        node2.Arguments = new List <JsExpression> {
                            Js.NewJsonArray(node2.Arguments.ToArray())
                        }
                    }
                    ;
                    //var me2 = (node2.Member as JsMemberExpression);
                    //me2.Name = "callParent";
                    return;
                }
                IMethod me2;
                var     me = res.Member;
                if (me is IProperty)
                {
                    me2 = ((IProperty)me).Getter;
                }
                else if (me is IMethod)
                {
                    me2 = (IMethod)res.Member;
                }
                else
                {
                    throw new Exception("Can't resolve method from member: " + res.Member);
                }
                var member = SkJs.EntityMethodToJsFunctionRef(me2);
                member       = member.Member("call");
                node2.Member = member;
                if (node2.Arguments == null)
                {
                    node2.Arguments = new List <JsExpression>();
                }
                node2.Arguments.Insert(0, Js.This());
            }
        }

        void ProcessByRefs1()
        {
            ByRefs       = new List <ByReferenceResolveResult>();
            ByRefIndexes = new List <int>();
            RefToRefs    = new List <int>();
            var c = 0;

            foreach (var bin in PrmBindings)
            {
                var binding = bin.Binding;
                var byRef   = binding.CallResult as ByReferenceResolveResult;
                if (byRef == null)
                {
                    c++;
                    continue;
                }
                var x = byRef.ElementResult as LocalResolveResult;
                if (x != null && x.Variable != null && x.Variable.Type.Kind == TypeKind.ByReference)
                {
                    if (binding.Parameter.IsRef || binding.Parameter.IsOut)
                    {
                        RefToRefs.Add(c);
                    }
                    c++;
                    continue;
                }
                ByRefs.Add(byRef);
                ByRefIndexes.Add(c);
                c++;
            }
        }

        void ProcessByRefs2()
        {
            var c = 0;

            for (var i = 0; i < Node2.Arguments.Count; i++)
            {
                if (Node2.Arguments[i] is JsMemberExpression)
                {
                    JsMemberExpression jsmex = Node2.Arguments[i] as JsMemberExpression;
                    if (RefToRefs.Contains(i))
                    {
                        Node2.Arguments[i] = jsmex.PreviousMember; //remove the .Value ref wrapper
                    }
                    else if (ByRefIndexes.Contains(i))
                    {
                        Node2.Arguments[i] = Js.Member(RefIndexToName(c));
                        c++;
                    }
                }
                else if (Node2.Arguments[i] is JsIndexerAccessExpression)
                {
                    if (ByRefIndexes.Contains(i))
                    {
                        Node2.Arguments[i] = Js.Member(RefIndexToName(c));
                        c++;
                    }
                }
            }
        }

        void ProcessByRefs3()
        {
            if (ByRefs.IsNotNullOrEmpty())
            {
                var func = Js.Function();

                //It must assigned to a temporary variable, because typed arrays do not acceppt json.
                //调整原来使用临时对象.Value的赋值方式,修改为Object.defineProperty定义get|set方法的实现
                //临时对象统一调用jsclr里的$Ref方法进行创建
                for (var i = 0; i < ByRefs.Count; i++)
                {
                    var byRef = ByRefs[i];
                    var expr  = VisitExpression(byRef);
                    if (expr is JsMemberExpression)
                    {
                        var memberExpr = expr as JsMemberExpression;
                        if (memberExpr.PreviousMember != null)
                        {
                            var refFuncInvoke = new JsInvocationExpression
                            {
                                Member = new JsMemberExpression {
                                    Name = "$Ref"
                                },
                                Arguments = new List <JsExpression> {
                                    memberExpr.PreviousMember, Js.String(memberExpr.Name)
                                }
                            };
                            func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement());
                        }
                        else
                        {
                            //如果是局部变量的话使用旧实现方式
                            var refFuncInvoke = new JsInvocationExpression
                            {
                                Member = new JsMemberExpression {
                                    Name = "$Ref"
                                },
                                Arguments = new List <JsExpression> {
                                    Js.Member("null"), memberExpr
                                }
                            };
                            func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement());
                        }
                    }
                    else if (expr is JsIndexerAccessExpression)
                    {
                        var indexerExpr   = expr as JsIndexerAccessExpression;
                        var indexArg      = indexerExpr.Arguments[0];
                        var refFuncInvoke = new JsInvocationExpression
                        {
                            Member = new JsMemberExpression {
                                Name = "$Ref"
                            },
                            Arguments = new List <JsExpression> {
                                indexerExpr.Member, indexArg
                            }
                        };
                        func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement());
                    }
                }

                func.Add(Js.Var("$res", Node2).Statement());

                for (var i = 0; i < ByRefs.Count; i++)
                {
                    var byRef      = ByRefs[i];
                    var memberExpr = VisitExpression(byRef) as JsMemberExpression;
                    if (memberExpr != null && memberExpr.PreviousMember == null)
                    {
                        func.Add(memberExpr.Assign(Js.Member(RefIndexToName(i)).Member("Value")).Statement());
                    }
                }

                func.Add(Js.Return(Js.Member("$res")));
                Node2 = Importer.WrapFunctionAndInvoke(Res, func);
            }
        }
Пример #3
0
        protected JsBlock ExportConstructorBody(IMethod ctor)
        {
            var            ctorNode = (ConstructorDeclaration)ctor.GetDeclaration();
            BlockStatement ccc      = null;

            if (ctorNode != null)
            {
                ccc = ctorNode.Body;
            }
            //var ccc = ctor.GetDefinition();//.decl as CsConstructor;
            //var ccc = ctor.GetDefinition();
            var block2 = (JsBlock)AstNodeConverter.Visit(ccc);

            if (block2 == null)
            {
                block2 = new JsBlock {
                    Statements = new List <JsStatement>()
                }
            }
            ;
            var ce          = ctor.GetDeclaringTypeDefinition();
            var isClr       = Sk.IsClrType(ce);
            var isPrototype = Sk.IsNativeType(ce);
            var statements  = new List <JsStatement>();

            //instance fields initializations
            if (!Sk.InlineFields(ce))
            {
                var isGlobal = Sk.IsGlobalType(ce);
                var fields   = GetExportedDeclaredAndGeneratedFields(ce, ctor.IsStatic);
                //var fields = ctor.GetDeclaringTypeDefinition().GetFields(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList();
                //fields = fields.Where(ShouldExportField).ToList();
                //fields.AddRange(GeneratePropertyFields(ctor.DeclaringTypeDefinition, ctor.IsStatic));

                //var props = ctor.GetDeclaringTypeDefinition().GetProperties(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList();
                //props = props.Where(t=>Sk.IsNativeField(t)).ToList();
                //props = props.Where(t => Sk.IsJsExported(t)).ToList();
                //var fieldsAndProperties = fields.Cast<IEntity>().Concat(props.Cast<IEntity>());
                var initializers = fields.Select(fe => ExportInitializer(fe, null, isGlobal, false)).Cast <JsStatement>().ToList();
                if (initializers.Contains(null))
                {
                    Log.Warn("Some field initializers were not exported");
                }
                statements.AddRange(initializers.Where(t => t != null));
            }

            if (!ctor.IsStatic)
            {
                //base/this ctor invocation
                var invocation = GetConstructorBaseOrThisInvocation2(ctor);
                if (invocation != null)
                {
                    var baseThisCe      = invocation.Member.DeclaringType;
                    var isBaseClr       = Sk.IsClrType(baseThisCe.GetDefinition());
                    var isBasePrototype = Sk.IsNativeType(baseThisCe.GetDefinition()) && !Sk.IsJsonMode(baseThisCe.GetDefinition()) && !Sk.IsGlobalType(baseThisCe.GetDefinition()); //happens when prototype inherits from json
                    if (isBaseClr == isClr && isBasePrototype == isPrototype)                                                                                                        //base and derived are both prototype, or both are clr
                    {
                        var newObjExp2 = AstNodeConverter.VisitExpression(invocation);
                        JsInvocationExpression invocation2;
                        if (newObjExp2 is JsNewObjectExpression)
                        {
                            var newObjExp = (JsNewObjectExpression)newObjExp2;
                            invocation2 = newObjExp.Invocation;
                        }
                        else if (newObjExp2 is JsInvocationExpression)
                        {
                            invocation2 = (JsInvocationExpression)newObjExp2;
                        }
                        else
                        {
                            throw new Exception("Unexpected node: " + newObjExp2);
                        }
                        if (Sk.IsExtJsType(ce))
                        {
                            var invocation3 = Js.This().Member("callParent").Invoke();
                            if (invocation2.Arguments.IsNotNullOrEmpty())
                            {
                                invocation3.Arguments = new List <JsExpression> {
                                    Js.NewJsonArray(invocation2.Arguments.NotNull().ToArray())
                                }
                            }
                            ;
                            statements.Add(invocation3.Statement());
                        }
                        else
                        {
                            JsRefactorer.ToCallWithContext(invocation2, new JsThis());
                            statements.Add(invocation2.Statement());
                        }
                    }
                }
            }
            if (block2.Statements == null)
            {
                block2.Statements = new List <JsStatement>();
            }
            block2.Statements.InsertRange(0, statements);

            return(block2);
        }

        void ExportConstructorParameters(IMethod ctor, JsFunction func)
        {
            var ce   = ctor.GetDeclaringTypeDefinition();
            var list = new List <string>();

            if (!Sk.IgnoreTypeArguments(ce))
            {
                //danel
                var gprms = ce.TypeParameters.ToList();//.GetGenericArguments().Where(ga => ga.isGenericParam()).ToList();
                if (gprms.IsNotNullOrEmpty())
                {
                    var i = 0;
                    foreach (var gprm in gprms)
                    {
                        func.Parameters.Add(gprm.Name);
                        if (!ctor.IsStatic && func.Block != null)
                        {
                            func.Block.Statements.Insert(i, Js.This().Member(gprm.Name).Assign(Js.Member(gprm.Name)).Statement());
                            i++;
                        }
                    }
                }
            }
            var prms = ctor.Parameters;

            if (prms != null)
            {
                func.Parameters.AddRange(prms.Select(t => t.Name));
            }
        }