Пример #1
0
        public JsNode VisitConstantResolveResult(ConstantResolveResult res)
        {
            if (res.Type is DefaultTypeParameter)
            {
                return(Js.Member("Default").Invoke(SkJs.EntityTypeRefToMember(res.Type)));
            }
            if (res.Type != null && res.Type.Kind == TypeKind.Enum)
            {
                var enumMembers = res.Type.GetFields();
                var me          = enumMembers.Where(t => (t.ConstantValue != null) && t.ConstantValue.Equals(res.ConstantValue)).FirstOrDefault();
                if (me != null)
                {
                    return(Visit(me.AccessSelf()));//.Access().Member(c.CreateTypeRef(en), defaultEnumMember);
                }
                //TODO:
                //return Visit(JsTypeImporter.GetValueTypeInitializer(res.Type, Project));
            }
            var nodes = res.GetNodes();

            if (nodes.IsNotNullOrEmpty())
            {
                if (nodes[0] != null)
                {
                    bool isPrimitiveExpr = nodes[0] is PrimitiveExpression;
                    if (!isPrimitiveExpr)
                    {
                        return(Js.Value(res.ConstantValue, string.Format(" /* {0} */", nodes[0].ToString())));
                    }
                }
            }
            return(Js.Value(res.ConstantValue));
        }
Пример #2
0
        protected virtual JsUnit OnAfterExportType(ITypeDefinition ce, JsClrType jsType)
        {
            //HACK: backward
            if (jsType.Kind == JsClrTypeKind.Interface && jsType.baseTypeName.IsNullOrEmpty())
            {
                jsType.baseTypeName = "System.Object";
            }
            var unit = new JsUnit {
                Statements = new List <JsStatement>()
            };

            unit.Statements.Add(VerifyJsTypesArrayStatement.Clone());

            var json      = (JsJsonObjectExpression)Serialize(jsType);
            var moveToEnd = json.NamesValues.Where(t => t.Name.Name.Contains("definition")).ToList();

            moveToEnd.ForEach(t => json.NamesValues.Remove(t));
            json.NamesValues.AddRange(moveToEnd);

            var ceVarName = GetJsTypeName(ce).Replace(".", "$");

            unit.Statements.Add(Js.Var(ceVarName, json).Statement());
            unit.Statements.Add(Js.Member("JsTypes").Member("push").Invoke(Js.Member(ceVarName)).Statement());
            return(unit);
        }
Пример #3
0
        public override JsNode _VisitDelegate(ITypeDefinition ce)
        {
            var CurrentType = new JsClrType {
                Kind = JsClrTypeKind.Delegate
            };

            CurrentType.fullname = GetJsTypeName(ce);

            //Generate constructor
            var genericParams = new List <ITypeParameter>(ce.GetGenericArguments());
            var func          = new JsFunction();

            func.Parameters = genericParams.Select(t => t.Name).ToList();
            func.Parameters.Add("obj");
            func.Parameters.Add("func");
            func.Block = Js.Block();
            foreach (var ga in genericParams)
            {
                func.Block.Add(Js.This().Member(ga.Name).Assign(Js.Member(ga.Name)).Statement());
            }
            func.Block.Add(Js.Members("System.MulticastDelegate.ctor.call").Invoke(Js.This(), Js.Member("obj"), Js.Member("func")).Statement());
            CurrentType.GetDefinition(false)["ctor"] = func;
            return(OnAfterExportType(ce, CurrentType));
            //return func;

            //FullName',{ ShortName:function(T1,T2,T3,...,obj,func){this.T1=T1;....;this.construct(obj,func);},   })");
        }
Пример #4
0
        public JsNode VisitUsingStatement(UsingStatement node)
        {
            var st3 = Visit(node.ResourceAcquisition);
            JsVariableDeclarationStatement stVar;

            if (st3 is JsExpression)
            {
                stVar = Js.Var("$r" + VariableResourceCounter++, (JsExpression)st3).Statement();
            }
            else
            {
                stVar = (JsVariableDeclarationStatement)st3;
            }
            var trySt = VisitStatement(node.EmbeddedStatement);
            var st2   = new JsTryStatement {
                TryBlock = trySt.ToBlock(), FinallyBlock = Js.Block()
            };

            //var resource = node.ResourceAcquisition;
            //var decl = resource as VariableDeclarationStatement;
            //if (decl == null || decl.Variables.Count == 0)
            //    throw new Exception("using statement is supported only with the var keyword in javascript. Example: using(var g = new MyDisposable()){}");
            foreach (var dr in stVar.Declaration.Declarators)
            {
                st2.FinallyBlock.Add(Js.Member(dr.Name).Member("Dispose").Invoke().Statement());
            }
            return(Js.Block().Add(stVar).Add(st2));            //TODO: get rid of block
        }
Пример #5
0
        public static JsMemberExpression EntityMethodToJsFunctionRef(IMethod me)
        {
            var ownerType = me.GetDeclaringTypeDefinition();

            if (Sk.IsGlobalMethod(me))
            {
                var member = Js.Member(SkJs.GetEntityJsName(me));
                return(member);
            }
            else
            {
                var member = SkJs.EntityToMember(ownerType);
                if (!me.IsStatic)
                {
                    if (Sk.IsNativeType(ownerType))
                    {
                        member = member.Member("prototype");
                    }
                    else
                    {
                        member = member.Member("commonPrototype");
                    }
                }
                member = member.Member(SkJs.GetEntityJsName(me));
                return(member);
            }
        }
Пример #6
0
 public JsNode VisitCSharpInvocationResolveResult(CSharpInvocationResolveResult res)
 {
     if (res.Member.IsConstructor())
     {
         if (res.Type is AnonymousType)
         {
             //TODO: check context class JsType.NativeJsons
             var json       = InitializersToJson(res.InitializerStatements, res.Type);
             var parentType = res.GetParentType();
             if (parentType != null && !Sk.UseNativeJsons(parentType))
             {
                 return(Js.Member("$CreateAnonymousObject").Invoke(json));
             }
             return(json);
         }
         else
         {
             return(VisitInvocationResolveResultAsCtor(res));
         }
     }
     else
     {
         return(VisitInvocationResolveResult(res));
     }
 }
        void ExportNamespace(JsUnit unit, string ns)
        {
            var Writer = new StringWriter();

            if (ns.IsNotNullOrEmpty())
            {
                var tokens = ns.Split('.');
                for (var i = 0; i < tokens.Length; i++)
                {
                    var         ns2 = tokens.Take(i + 1).StringJoin(".");
                    JsStatement st;
                    if (i == 0)
                    {
                        st = Js.Var(ns2, Js.Json()).Statement();
                    }
                    else
                    {
                        st = Js.Member(ns2).Assign(Js.Json()).Statement();
                    }
                    var st2 = Js.If(Js.Typeof(Js.Member(ns2)).Equal(Js.String("undefined"))).Then(st);
                    unit.Statements.Add(st2);
                    st2.AddAnnotation(new NamespaceVerificationAnnotation {
                        Namespace = ns2
                    });                                                                        //.Ex(true).NamespaceVerification = ns2;
                }
            }
        }
Пример #8
0
        public JsNode VisitConstantResolveResult(ConstantResolveResult res)
        {
            var nodes = res.GetNodes();

            if (res.Type is DefaultTypeParameter)
            {
                return(Js.Member("Default").Invoke(SkJs.EntityTypeRefToMember(res.Type)));
            }
            if (res.Type != null && res.Type.Kind == TypeKind.Enum)
            {
                var enumMembers = res.Type.GetFields();
                var me          = enumMembers.Where(t => (t.ConstantValue != null) && t.ConstantValue.Equals(res.ConstantValue)).FirstOrDefault();
                if (me != null)
                {
                    return(Visit(me.AccessSelf()));//.Access().Member(c.CreateTypeRef(en), defaultEnumMember);
                }
                //TODO:
                //return Visit(JsTypeImporter.GetValueTypeInitializer(res.Type, Project));
            }
            //var nodes = res.GetNodes();
            //if (nodes.IsNotNullOrEmpty())
            //{
            //    var node = nodes[0];
            //    if (node != null && node is PrimitiveExpression)
            //    {
            //        var node2 = Visit(node); //use literal value instead
            //        return node2;
            //    }
            //}
            return(Js.Value(res.ConstantValue));
        }
Пример #9
0
        public JsNode VisitLocalResolveResult(LocalResolveResult res)
        {
            var node2 = Js.Member(JsIdentifier(res.Variable.Name));

            if (res.Variable != null && res.Variable.Type.Kind == TypeKind.ByReference)
            {
                node2 = node2.Member("Value");
            }
            return(node2);
        }
Пример #10
0
        void YieldReturnInCurrentStep(JsExpression item)
        {
            var result    = Js.Value(true);
            var stepIndex = Steps.Count - 1;

            AddToCurrentStep(Js.This().Member("_current").Assign(item).Statement());
            AddToCurrentStep(_state().Assign(Js.Value(stepIndex + 1)).Statement());
            AddToCurrentStep(Js.Member("result").Assign(result).Statement());
            AddToCurrentStep(Js.Return(result));
        }
Пример #11
0
        public JsNode VisitInitializedObjectResolveResult(InitializedObjectResolveResult res)
        {
            var varName = Initializers.TryGetValue(res);

            if (varName == null)
            {
                varName           = "$v" + VariableInitializerCounter++;
                Initializers[res] = varName;
            }
            return(Js.Member(varName));
        }
Пример #12
0
        protected virtual JsFunction GenerateAutomaticEventAccessor(IEvent ee, bool isRemove)
        {
            if (isRemove)
            {
                var remover = Js.Function("value").Add(Js.This().Member(ee.Name).Assign(Js.Member("$RemoveDelegate").Invoke(Js.This().Member(ee.Name), Js.Member("value"))).Statement());
                return(remover);
            }
            var adder = Js.Function("value").Add(Js.This().Member(ee.Name).Assign(Js.Member("$CombineDelegates").Invoke(Js.This().Member(ee.Name), Js.Member("value"))).Statement());

            return(adder);
        }
Пример #13
0
        public static JsMemberExpression EntityToMember(IEntity me)
        {
            if (me == null)
            {
                return(null);
            }
            if (me.DeclaringType != null && (me.DeclaringType.IsGenericMethodArgument() || me.DeclaringType.IsGenericTypeParameter()))
            {
                var x = (JsMemberExpression)EntityTypeRefToMember(me.DeclaringType);
                var s = x.ToJs();
                return(x);
            }
            var name = GetEntityJsName(me);

            if (me is ITypeDefinition)
            {
                return(Js.Member(name));
            }
            else if (me.IsStatic())
            {
                var member = Js.Member(name);
                if (Sk.IsGlobalMember(me))
                {
                    return(member);
                }
                if (me is IMethod && Sk.ExtensionImplementedInInstance((IMethod)me))
                {
                    return(member);
                }
                member.PreviousMember = EntityToMember(me.GetDeclaringTypeDefinition());
                return(member);
            }
            else if (me.SymbolKind == SymbolKind.Constructor)
            {
                var att = Sk.GetJsMethodAttribute((IMethod)me);
                if (att != null && att.Name != null) //TODO: hack
                {
                    return(Js.Member(att.Name));
                }
                var ce     = me.GetDeclaringTypeDefinition();
                var member = EntityToMember(ce);
                var att2   = Sk.GetJsTypeAttribute(ce);
                if (att2 != null && att2.NativeConstructors)
                {
                    return(member);
                }
                member = member.Member(name);
                return(member);
            }
            return(Js.Member(name));
        }
Пример #14
0
        public static JsReturnStatement GenerateYieldReturnStatement(IMethod me)
        {
            JsReturnStatement node2;

            if (me != null && me.ReturnType != null && me.ReturnType.FullName.StartsWith("System.Collections.Generic.IEnumerator"))
            {
                node2 = Js.Return(Js.Member("$yield").Member("GetEnumerator").Invoke());
            }
            else
            {
                node2 = Js.Return(Js.Member("$yield"));
            }
            return(node2);
        }
Пример #15
0
        public JsNode VisitYieldReturnStatement(YieldReturnStatement node)
        {
            var exp2 = VisitExpression(node.Expression);

            if (SupportClrYield)
            {
                return(new JsYieldReturnStatement {
                    Expression = exp2
                });
            }
            var node2 = Js.Member("$yield.push").Invoke(exp2).Statement();

            return(node2);
        }
Пример #16
0
        public override JsNode _Visit(IProperty pe)
        {
            var list = GetAccessorsToExport(pe);

            if (Sk.IsNativeProperty(pe))
            {
                var statements = new List <JsStatement>();

                statements.AddRange(list.Select(ExportMethod).Cast <JsStatement>());

                var json = new JsJsonObjectExpression();
                foreach (var accessor in list)
                {
                    if (accessor == pe.Getter)
                    {
                        json.Add("get", ExportTypePrefix(pe.Getter.GetDeclaringTypeDefinition(), pe.IsStatic).Member("get_" + pe.Name));
                    }
                    if (accessor == pe.Setter)
                    {
                        json.Add("set", ExportTypePrefix(pe.Setter.GetDeclaringTypeDefinition(), pe.IsStatic).Member("set_" + pe.Name));
                    }
                }

                if (Sk.IsNativePropertyEnumerable(pe))
                {
                    json.Add("enumerable", Js.True());
                }

                var defineStatement = Js.Member("Object").Member("defineProperty").Invoke(
                    ExportTypePrefix(pe.GetDeclaringTypeDefinition(), pe.IsStatic),
                    Js.String(pe.Name),
                    json).Statement();

                statements.Add(defineStatement);

                return(new JsUnit()
                {
                    Statements = statements
                });
            }
            else
            {
                var list2 = list.Select(ExportMethod).Cast <JsStatement>().ToList();
                return(new JsUnit {
                    Statements = list2
                });
            }
        }
Пример #17
0
        public JsNode VisitYieldReturnStatement(YieldReturnStatement node)
        {
            qiucw.AddYieldReturn(node);

            var exp2 = VisitExpression(node.Expression);

            if (SupportClrYield)
            {
                return(new JsYieldReturnStatement {
                    Expression = exp2
                });
            }
            //var node2 = Js.Member("$yield.push").Invoke(exp2).Statement();
            //return node2;

            return(Js.Member("yield").Invoke(exp2).Statement());
        }
Пример #18
0
        public override JsNode _VisitClass(ITypeDefinition ce)
        {
            var unit = new JsUnit {
                Statements = new List <JsStatement>()
            };

            ExportTypeNamespace(unit, ce);
            var members = GetMembersToExport(ce);

            VisitToUnit(unit, members);
            var baseCe = ce.GetBaseTypeDefinition();

            if (baseCe != null && Sk.IsNativeType(baseCe) && !Sk.IsGlobalType(baseCe) && !Sk.OmitInheritance(ce))
            {
                unit.Statements.Add(Js.Member("$Inherit").Invoke(SkJs.EntityToMember(ce), SkJs.EntityToMember(baseCe)).Statement());
            }
            return(unit);
        }
Пример #19
0
        public JsNode VisitThrowStatement(ThrowStatement node)
        {
            JsExpression node2;
            IType        exceptionType;

            if (node.Expression == null || node.Expression.IsNull)             //happens when performing "throw;"
            {
                var cc = node.GetParent <CatchClause>();
                if (cc != null)
                {
                    node2 = Js.Member(cc.VariableName);
                    var type = cc.Type;
                    if (type == null || type.IsNull)
                    {
                        exceptionType = Project.Compilation.FindType(KnownTypeCode.Exception);
                    }
                    else
                    {
                        exceptionType = cc.Type.Resolve().Type;
                    }
                }
                else
                {
                    throw new Exception("Rethrow not supported, catch clause not found");
                }
            }
            else
            {
                node2 = VisitExpression(node.Expression);
                var res = node.Expression.Resolve();
                exceptionType = res.Type;
                if (res is ConversionResolveResult)
                {
                    exceptionType = ((ConversionResolveResult)res).Input.Type;
                }
            }
            if (!Sk.IsNativeError(exceptionType.GetDefinitionOrArrayType()))
            {
                node2 = Js.Member("$CreateException").Invoke(node2, Js.New(Js.Member("Error")));
            }
            return(new JsThrowStatement {
                Expression = node2
            });
        }
Пример #20
0
        public void Process()
        {
            AfterFunction = BeforeFunction;
            SetParents(BeforeFunction.Block);
            foreach (var me in BeforeFunction.Block.Descendants <JsMemberExpression>().ToList())
            {
                if (me.PreviousMember == null && me.NodeType == JsNodeType.MemberExpression)
                {
                    me.PreviousMember = Js.This();
                }
            }

            BeginNewStep();
            ProcessStatement(BeforeFunction.Block);
            BeforeFunction.Block.Statements.Clear();

            var func = new JsFunction {
                Block = new JsBlock {
                    Statements = new List <JsStatement>()
                }
            };
            var i = 0;

            func.Block.Statements.Add(Js.Var("result").Statement());
            var stSwitch = Js.Switch(_state());
            var lastStep = Js.Block().Add(_state().Assign(Js.Value(Steps.Count)).Statement()).Add(new JsBreakStatement());

            Steps.Add(new YieldStep {
                Statements = { lastStep }
            });
            foreach (var step in Steps)
            {
                stSwitch.Case(Js.Value(i), step.Statements);
                i++;
            }
            func.Block.Statements.Add(stSwitch);
            func.Block.Statements.Add(Js.Member("result").Assign(Js.Value(false)).Statement());
            func.Block.Statements.Add(Js.Return(Js.Member("result")));

            BeforeFunction.Block.Statements.Add(Js.Return(Js.New(Js.Member("CustomEnumerable"), func)));
            return;
        }
Пример #21
0
        /// <summary>
        /// Wraps a setter invocation with a js function that returns the setter value back, if another assignment operation occurs
        /// var x = contact.Name = "Shooki";
        /// var x = contact.setName("Shooki"); //error
        /// var x = (function(arg){contact.setName(arg);return arg;}).call(this, "Shooki");
        /// </summary>
        /// <param name="res"></param>
        /// <param name="node2"></param>
        /// <returns></returns>
        internal JsNode WrapSetterToReturnValueIfNeeded(OperatorResolveResult res, JsNode node2)
        {
            var node3 = node2 as JsInvocationExpression;

            if (node3 == null)
            {
                return(node2);
            }

            if (RequiresWrapSetterToReturnValue(res))
            {
                var lastArg = node3.Arguments.Last();
                var prmName = "$p" + ParameterNameCounter++;
                node3.Arguments[node3.Arguments.Count - 1] = Js.Member(prmName);

                var func = Js.Function(prmName).Add(((JsExpression)node2).Statement());
                func.Add(Js.Return(Js.Member(prmName)));
                node2 = WrapFunctionAndInvoke(res, func, lastArg);
            }
            return(node2);
        }
Пример #22
0
 public JsNode VisitTypeIsResolveResult(TypeIsResolveResult res)
 {
     if (Sk.OmitCasts(res.TargetType))
     {
         return(Js.True());
         //var node2 = Visit(res.Input);
         //return node2;
     }
     else if (Sk.NativeCasts(res.TargetType))
     {
         var typeFieldName = Sk.GetJsonTypeFieldName(res.TargetType.GetDefinitionOrArrayType());
         if (typeFieldName != null && Sk.IsJsonMode(res.TargetType.GetDefinitionOrArrayType()))
         {
             return(Js.Parentheses(VisitExpression(res.Input).Or(Js.Json())).Member(typeFieldName).Equal(SkJs.EntityTypeRefToMember(res.TargetType)));
         }
         var node2 = VisitExpression(res.Input).InstanceOf(SkJs.EntityTypeRefToMember(res.TargetType));
         return(node2);
     }
     else
     {
         var node2 = Js.Member("Is").Invoke(VisitExpression(res.Input), SkJs.EntityTypeRefToMember(res.TargetType));
         return(node2);
     }
 }
Пример #23
0
 public JsNode VisitUnknownMethodResolveResult(UnknownMethodResolveResult res)
 {
     return(Js.Member("UNKNOWN_METHOD"));
 }
Пример #24
0
 public JsNode VisitTypeOfResolveResult(TypeOfResolveResult res)
 {
     return(Js.Member("Typeof").Invoke(SkJs.EntityTypeRefToMember(res.ReferencedType)));
 }
Пример #25
0
        public JsNode VisitForeachStatement(ForeachStatement node)
        {
            if (node.InExpression != null)
            {
                var expRes = node.InExpression.Resolve();
                var et     = expRes.Type.GetDefinitionOrArrayType();
                //var et = node.expression.entity_typeref.GetEntityType();
                if (et != null)
                {
                    var jta = Sk.GetJsTypeAttribute(et);
                    if (jta != null && jta.NativeEnumerator)
                    {
                        var node2 = new JsForInStatement
                        {
                            Initializer = Js.Var(node.VariableName),
                            Member      = VisitExpression(node.InExpression),
                            Statement   = VisitStatement(node.EmbeddedStatement)
                        };
                        return(node2);
                    }
                    else if (jta != null && jta.NativeArrayEnumerator)
                    {
                        VariableIteratorCounter++;
                        var iteratorName    = "$i" + VariableIteratorCounter;
                        var lengthCacheName = "$l" + VariableIteratorCounter;
                        var exp2            = VisitExpression(node.InExpression);
                        var target          = exp2;
                        var targetCacheName = "$t" + VariableIteratorCounter;
                        if (exp2.NodeType != JsNodeType.MemberExpression || ((JsMemberExpression)exp2).PreviousMember != null)                        //is not simple name
                        {
                            target = Js.Member(targetCacheName);
                        }
                        var itemAccess = target.IndexerAccess(Js.Member(iteratorName));
                        var node2      = new JsForStatement();

                        node2.Condition = Js.Member(iteratorName).LessThan(Js.Member(lengthCacheName));
                        node2.Iterators = new List <JsStatement> {
                            Js.Member(iteratorName).PlusPlus().Statement(), Js.Member(node.VariableName).Assign(itemAccess).Statement()
                        };
                        if (target != exp2)                        //use target caching
                        {
                            node2.Initializers = new List <JsStatement> {
                                Js.Var(iteratorName, Js.Value(0)).AndVar(targetCacheName, exp2.Clone()).AndVar(lengthCacheName, target.Clone().Member("length")).AndVar(node.VariableName, itemAccess.Clone()).Statement()
                            };
                        }
                        else
                        {
                            node2.Initializers = new List <JsStatement> {
                                Js.Var(iteratorName, Js.Value(0)).AndVar(lengthCacheName, exp2.Clone().Member("length")).AndVar(node.VariableName, itemAccess.Clone()).Statement()
                            };
                        }
                        node2.Statement = VisitStatement(node.EmbeddedStatement);
                        return(node2);
                    }
                }
            }

            var iteratorName2 = "$it" + VariableIteratorCounter;

            VariableIteratorCounter++;
            var     node3               = Js.Var(iteratorName2, VisitExpression(node.InExpression).Member("GetEnumerator").Invoke()).Statement();
            var     whileNode           = Js.While(Js.Member(iteratorName2).Member("MoveNext").Invoke());
            var     getCurrentStatement = Js.Var(node.VariableName, Js.Member(iteratorName2).Member("get_Current").Invoke()).Statement();
            var     jsStatement         = VisitStatement(node.EmbeddedStatement);
            JsBlock block;

            if (jsStatement is JsBlock)
            {
                block = (JsBlock)jsStatement;
            }
            else
            {
                block = Js.Block().Add(jsStatement);
            }
            block.Statements.Insert(0, getCurrentStatement);
            whileNode.Statement = block;

            var block2 = Js.Block().Add(node3).Add(whileNode);

            return(block2);
        }
Пример #26
0
        public JsNode VisitCatchClause(CatchClause node)
        {
            var node2 = new JsCatchClause();

            if (node.VariableName.IsNullOrEmpty())
            {
                node.VariableName = "$$e" + (VariableExceptionCounter++);                 //Generate a psuedo-unique variable name
            }
            node2.IdentifierName = node.VariableName;

            node2.Block = (JsBlock)Visit(node.Body);
            if (node2.Block != null)
            {
                node2.Descendants <JsThrowStatement>().Where(t => t.Expression == null).ForEach(t => t.Expression = Js.Member(node2.IdentifierName));
            }
            return(node2);
        }
Пример #27
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);
            }
        }
Пример #28
0
        public JsNode VisitInvocationResolveResultAsCtor(CSharpInvocationResolveResult res)
        {
            if (res.Type.Kind == TypeKind.Delegate)
            {
                return(Visit(res.Arguments.Single()));
            }
            var me    = (IMethod)res.Member;
            var meAtt = Sk.GetJsMethodAttribute(me);
            var ce    = me.GetDeclaringTypeDefinition();
            var att   = ce == null ? null : ce.GetJsTypeAttribute();

            if (att != null && att.Mode == JsMode.Json && (meAtt == null || meAtt.Name == null))
            {
                var jtfn  = ce == null ? null : Sk.GetJsonTypeFieldName(ce);
                var node2 = VisitInvocationResolveResult(res);
                var json  = Importer.InitializersToJson(res.InitializerStatements, res.Type);
                if (jtfn != null)
                {
                    var x = json as JsJsonObjectExpression;
                    if (x != null)
                    {
                        x.Add(jtfn, SkJs.EntityTypeRefToMember(res.Type));
                    }
                }
                return(json);
            }
            else
            {
                var invokeExp = (JsInvocationExpression)VisitInvocationResolveResult(res);
                var newExp    = new JsNewObjectExpression {
                    Invocation = invokeExp
                };
                JsExpression finalExp;
                if (meAtt != null && meAtt.OmitNewOperator)
                {
                    finalExp = invokeExp;
                }
                else
                {
                    finalExp = newExp;
                }

                if (meAtt != null && meAtt.JsonInitializers)
                {
                    var json = Importer.InitializersToJson(res.InitializerStatements, res.Type);
                    invokeExp.Arguments.Add(json);
                }
                else if (res.InitializerStatements.IsNotNullOrEmpty())
                {
                    var func = Js.Function();

                    var inits2 = res.InitializerStatements.Select(t => Visit(t)).ToList();
                    //var init1 = res.InitializerStatements[0];

                    var target  = AstNodeConverter.FindInitializedObjectResolveResult(res);// ((init1 as OperatorResolveResult).Operands[0] as MemberResolveResult).TargetResult as InitializedObjectResolveResult;
                    var varName = Importer.Initializers[target];
                    func.Add(Js.Var(varName, finalExp).Statement());

                    foreach (var init in inits2)
                    {
                        var exp = ((JsExpression)init);
                        func.Add(exp.Statement());
                    }
                    func.Add(Js.Return(Js.Member(varName)));
                    finalExp = Importer.WrapFunctionAndInvoke(res, func);
                }

                return(finalExp);
            }
        }
Пример #29
0
        private JsNode VisitConversion(ResolveResult input, Conversion conversion, IType conversionType)
        {
            ////TODO: HACK: https://github.com/icsharpcode/NRefactory/issues/183
            //var isImplicit = res.Conversion.IsImplicit;
            //if (!isImplicit && res.Conversion.IsExplicit && res.Conversion.Method != null && res.Conversion.Method.Name != null && res.Conversion.Method.Name.Contains("Implicit"))
            //    isImplicit = true;
            if (conversion.IsMethodGroupConversion)
            {
            }
            else if (conversion.IsUserDefined)
            {
                ITypeDefinition typeDef;
                if (conversion.Method != null && conversion.Method.DeclaringType != null)
                {
                    typeDef = conversion.Method.DeclaringType.GetDefinitionOrArrayType();
                }
                else
                {
                    typeDef = conversionType.GetDefinitionOrArrayType();
                }
                var nativeOverloads = Sk.UseNativeOperatorOverloads(typeDef);
                if (nativeOverloads)
                {
                    return(Visit(input));
                }
                ////TODO: Check if OmitCalls is found on conversion method, if so - return Visit(input);
                //if (Sk.IsOmitCalls(conversion.Method))
                //{
                //}
                var fake  = conversion.Method.InvokeMethod(null, input);
                var node2 = Visit(fake);
                return(node2);
            }
            else if (conversion.IsTryCast || conversion.IsExplicit)
            {
                if (ForceIntegers && conversion.IsNumericConversion && IsInteger(conversionType))
                {
                    return(ForceInteger(Visit(input)));
                }

                //Skip enum casts
                if ((conversionType.Kind == TypeKind.Enum && IsInteger(input.Type)) || (input.Type.Kind == TypeKind.Enum && IsInteger(conversionType)))
                {
                    return(Visit(input));
                }

                var omitCasts = Sk.OmitCasts(conversionType);
                if (omitCasts)
                {
                    return(Visit(input));
                }
                if (Sk.NativeCasts(conversionType))
                {
                    var exp2  = VisitExpression(input);
                    var type2 = SkJs.EntityTypeRefToMember(conversionType);
                    if (conversion.IsTryCast)
                    {
                        var node2 = exp2.InstanceOf(type2).Conditional(exp2, Js.Null());
                        return(node2);
                    }
                    else
                    {
                        var node2 = Js.Conditional(exp2.InstanceOf(type2).Or(exp2.Equal(Js.Null())), exp2,
                                                   Js.Parentheses(Js.Function().Add(Js.ThrowNewError("InvalidCastException")).Invoke()));
                        //var node2 = Js.Parentheses(Js.Function().AddStatements(
                        //Js.If(exp2.InstanceOf(type2).Or(exp2.Equal(Js.Null())), Js.Return(exp2)),
                        //Js.ThrowNewError("InvalidCastException"))).Member("call").Invoke(Js.This());
                        return(node2);
                    }
                }
                else
                {
                    var cast  = conversion.IsTryCast ? "As" : "Cast";
                    var node2 = Js.Member(cast).Invoke(VisitExpression(input), SkJs.EntityTypeRefToMember(conversionType));
                    return(node2);
                }
            }
            return(Visit(input));
        }
Пример #30
0
 private JsInvocationExpression ExportDefault(IType type)
 {
     return(Js.Member("Default").Invoke(SkJs.EntityTypeRefToMember(type)));
 }