コード例 #1
0
ファイル: JWriter.cs プロジェクト: wangchengqun/Cs2Java
 public void VisitBinaryExpression(JBinaryExpression node)
 {
     Visit(node.Left);
     Write(" ");
     Write(node.Operator);
     Write(" ");
     Visit(node.Right);
 }
コード例 #2
0
        private JNode VisitInvocationResolveResult(CSharpInvocationResolveResult res)
        {
            ////TODO: LET LINQ
            //var firstNode = res.GetFirstNode();
            //if (firstNode != null && firstNode is QueryLetClause)
            //{
            //    foreach (var arg in res.Arguments)
            //    {
            //        if (arg.GetInfo() == null)
            //            arg.SetInfo(new ResolveResultInfo { Nodes = { firstNode } });
            //    }
            //}
            var member = res.Member;
            var me     = member as IMethod;

            if (me == null)
            {
                var pe = member as IProperty;
                if (pe != null)
                {
                    me     = pe.Getter;
                    member = me;
                }
            }
            var att = me != null?JMeta.GetJMethodAttribute(me) : null;

            if (att != null && att.InlineCode != null)
            {
                return(J.Code(att.InlineCode));
            }
            //TODO: move defines locally
            var condAtt = me.GetMetadata <System.Diagnostics.ConditionalAttribute>();

            if (condAtt != null && Compiler != null && Compiler.Defines != null && !Compiler.Defines.Contains(condAtt.ConditionString))
            {
                return(null);
            }
            if (att != null && att.OmitCalls)
            {
                if (me.IsStatic() && !me.IsExtensionMethod)
                {
                    return(null);
                }
                if (me.IsExtensionMethod && !res.IsExtensionMethodInvocation)
                {
                    return(null);
                }
                if (res.Arguments.IsEmpty() && res.TargetResult != null)
                {
                    return(VisitExpression(res.TargetResult));
                }
                return(Visit(res.Arguments[0]));
            }
            var jsMember = JNaming.JAccess(member);

            if (res.TargetResult != null && !member.IsStatic() && member.SymbolKind != SymbolKind.Constructor) //TargetResult==null when ctor
            {
                var target = VisitExpression(res.TargetResult);
                if (jsMember.PreviousMember != null)
                {
                    throw new NotSupportedException();
                }
                jsMember.PreviousMember = target;
            }
            var bindings = res.GetArgumentsForCall2();

            if (JMeta.OmitOptionalParameters(me))
            {
                bindings.RemoveAll(t => t.ArgResult == null);
            }
            if (JMeta.IsNativeParams(me))
            {
                var binding = bindings.Where(t => t.Parameter.IsParams).FirstOrDefault();
                if (binding != null)
                {
                    if (binding.CallResult is ArrayCreateResolveResult)
                    {
                        var arrayRes = (ArrayCreateResolveResult)binding.CallResult;
                        bindings.Remove(binding);
                        if (arrayRes.InitializerElements.IsNotNullOrEmpty())
                        {
                            foreach (var init in arrayRes.InitializerElements)
                            {
                                var b = binding.Clone();
                                b.CallResult = init;
                                bindings.Add(b);
                            }
                        }
                    }
                    else
                    {
                        Log.Warn(res.GetFirstNode(), "Invalid params parameter passed to method with NativeParams=true");
                    }
                }
            }
            var        byRefs    = new List <ByReferenceResolveResult>();
            List <int> refToRefs = new List <int>();
            var        c         = 0;

            foreach (var binding in bindings)
            {
                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);
                c++;
            }
            var callArgs = bindings.Select(t => t.CallResult).ToList();
            var node2    = new JInvocationExpression
            {
                Member    = jsMember,
                Arguments = VisitExpressions(callArgs),
            };

            foreach (var i in refToRefs)
            {
                JMemberExpression jsmex = node2.Arguments[i] as JMemberExpression;
                if (jsmex != null)
                {
                    node2.Arguments[i] = jsmex.PreviousMember;//remove the .Value ref wrapper
                }
            }
            if (me != null && me.IsExtensionMethod && res.IsExtensionMethodInvocation && JMeta.ExtensionImplementedInInstance(me))
            {
                var arg = node2.Arguments[0];
                node2.Arguments.RemoveAt(0);
                if (jsMember.PreviousMember != null)
                {
                    throw new NotImplementedException();
                }
                jsMember.PreviousMember = arg;
            }

            TransformIntoBaseMethodCallIfNeeded(res, node2);
            if (att != null)
            {
                if (att.OmitParanthesis)
                {
                    node2.OmitParanthesis = true;
                }
                if (node2.Arguments == null)
                {
                    node2.Arguments = new List <JExpression>();
                }
                if (att.InsertArg2 != null)
                {
                    node2.Arguments.InsertOrAdd(2, new JCodeExpression {
                        Code = att.InsertArg2.ToString()
                    });
                }
                if (att.InsertArg1 != null)
                {
                    node2.Arguments.InsertOrAdd(1, new JCodeExpression {
                        Code = att.InsertArg1.ToString()
                    });
                }
                if (att.InsertArg0 != null)
                {
                    node2.Arguments.InsertOrAdd(0, new JCodeExpression {
                        Code = att.InsertArg0.ToString()
                    });
                }
                node2.OmitCommas      = att.OmitCommas;
                node2.ArgumentsPrefix = att.ArgumentsPrefix;
                node2.ArgumentsSuffix = att.ArgumentsSuffix;
                if (att.InstanceImplementedAsExtension)
                {
                    var ext = (JMemberExpression)node2.Member;
                    node2.Arguments.Insert(0, ext.PreviousMember);
                    ext.PreviousMember = null;
                }
            }


            //if (me != null && me is SpecializedMethod && !Sk.IgnoreGenericMethodArguments(me))
            //{
            //    List<JsExpression> genericArgs;
            //    if (me.IsConstructor)
            //    {
            //        var ce = me.DeclaringType as ParameterizedType;
            //        if (ce != null)
            //            genericArgs = ce.TypeArguments.Select(t => SkJs.EntityTypeRefToMember(t, true)).ToList();
            //        else
            //            genericArgs = new List<JsExpression>();
            //    }
            //    else
            //    {
            //        var sme = (SpecializedMethod)me;
            //        genericArgs = sme.TypeArguments.Select(t => SkJs.EntityTypeRefToMember(t, true)).ToList();
            //    }
            //    if (node2.Arguments == null)
            //        node2.Arguments = new List<JsExpression>(genericArgs);
            //    else
            //        node2.Arguments.InsertRange(0, genericArgs);
            //}
            if (att != null && att.OmitDotOperator)
            {
                if (node2.Member is JMemberExpression && node2.Arguments.Count == 1 && att.OmitParanthesis)
                {
                    var meNode = (JMemberExpression)node2.Member;
                    var node3  = new JBinaryExpression {
                        Left = meNode.PreviousMember, Operator = meNode.Name, Right = node2.Arguments[0]
                    };
                    return(node3);
                }
                else
                {
                    Log.Warn(res.GetFirstNode(), "TODO:OmitDotOperator is not supported in this syntax.");
                }
            }
            if (node2.Member is JMemberExpression)
            {
                var x = (JMemberExpression)node2.Member;
                if (x.Name.IsNullOrEmpty() && jsMember.PreviousMember != null)
                {
                    node2.Member = x.PreviousMember;
                }
            }
            if (res.Member.SymbolKind == SymbolKind.Indexer && JMeta.UseNativeIndexer((IProperty)res.Member))
            {
                var node3 = new JIndexerAccessExpression
                {
                    Member    = node2.Member,
                    Arguments = node2.Arguments,
                };

                return(node3);
            }

            if (byRefs.IsNotNullOrEmpty())
            {
                var func = J.Function();
                foreach (var byRef in byRefs)
                {
                    func.Add(J.Assign(VisitExpression(byRef), J.Json().Add("Value", VisitExpression(byRef))).Statement());
                }
                func.Add(J.Var("$res", res.Type.JAccess(), node2).Statement());
                foreach (var byRef in byRefs)
                {
                    func.Add(J.Assign(VisitExpression(byRef), VisitExpression(byRef).Member("Value")).Statement());
                }
                func.Add(J.Return(J.Member("$res")));
                var node5 = WrapFunctionAndInvoke(res, func.Block);
                return(node5);
            }


            return(node2);
        }
コード例 #3
0
        public JNode VisitOperatorResolveResult(OperatorResolveResult res)
        {
            if (res.Operands.Count == 1)
            {
                if (res.UserDefinedOperatorMethod != null && !JMeta.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition))
                {
                    var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0]);
                    return(Visit(fake));
                }

                var isProperty = false;
                var meRes      = res.Operands[0] as MemberResolveResult;
                if (meRes != null && meRes.Member != null && IsEntityFunctionProperty(meRes.Member, res))
                {
                    isProperty = true;
                }

                JExpression node2;
                if (res.OperatorType == System.Linq.Expressions.ExpressionType.Negate ||
                    res.OperatorType == System.Linq.Expressions.ExpressionType.PreDecrementAssign ||
                    res.OperatorType == System.Linq.Expressions.ExpressionType.PreIncrementAssign ||
                    res.OperatorType == System.Linq.Expressions.ExpressionType.Not ||
                    res.OperatorType == System.Linq.Expressions.ExpressionType.OnesComplement)
                {
                    var simpler = res.OperatorType.ExtractCompoundAssignment();
                    if (isProperty && simpler != null)
                    {
                        var fakeCs = meRes.Member.AccessSelf().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type);
                        node2 = VisitExpression(fakeCs);
                    }
                    else
                    {
                        node2 = new JPreUnaryExpression {
                            Operator = Visit(res.OperatorType), Right = VisitExpression(res.Operands[0])
                        };
                    }
                }
                else if (res.OperatorType == System.Linq.Expressions.ExpressionType.PostIncrementAssign ||
                         res.OperatorType == System.Linq.Expressions.ExpressionType.PostDecrementAssign ||
                         res.OperatorType == System.Linq.Expressions.ExpressionType.PreIncrementAssign ||
                         res.OperatorType == System.Linq.Expressions.ExpressionType.PreDecrementAssign)
                {
                    if (isProperty)
                    {
                        var simpler = res.OperatorType.ExtractCompoundAssignment();
                        var fakeCs  = meRes.Member.AccessSelf().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type);
                        node2 = VisitExpression(fakeCs);
                    }
                    else
                    {
                        node2 = new JPostUnaryExpression {
                            Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0])
                        };
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
                return(node2);
            }
            else if (res.Operands.Count == 2)
            {
                if (res.UserDefinedOperatorMethod != null && !JMeta.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition))
                {
                    var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0], res.Operands[1]);
                    return(Visit(fake));
                }

                if (res.OperatorType == System.Linq.Expressions.ExpressionType.Coalesce)
                {
                    var fake  = Cs.Conditional(res.Operands[0].NotEqual(Cs.Null(), Project), res.Operands[0], res.Operands[1], res.Type);
                    var fake2 = Visit(fake);
                    fake2 = new JParenthesizedExpression {
                        Expression = (JExpression)fake2
                    };
                    return(fake2);
                }
                var mrrOp0 = res.Operands[0] as MemberResolveResult;
                if (mrrOp0 != null && mrrOp0.Member.SymbolKind == SymbolKind.Event)
                {
                    var pe = (IEvent)mrrOp0.Member;
                    if (res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.SubtractAssign)
                    {
                        var accessor = res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign ? pe.AddAccessor : pe.RemoveAccessor;
                        var fake     = new CSharpInvocationResolveResult(mrrOp0.TargetResult, accessor, new List <ResolveResult>
                        {
                            res.Operands[1]
                        });
                        var node6 = Visit(fake);
                        return(node6);
                    }
                }
                if (mrrOp0 != null && IsEntityFunctionProperty(mrrOp0.Member, res))
                {
                    var compOpType = res.OperatorType.ExtractCompoundAssignment();

                    var pe = (IProperty)mrrOp0.Member;
                    if (compOpType != null)
                    {
                        var fake = new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Setter, new List <ResolveResult>
                        {
                            new OperatorResolveResult(res.Type, compOpType.Value, new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Getter, null), res.Operands[1])
                        });
                        var node6 = Visit(fake);
                        return(node6);
                    }
                    else if (res.OperatorType == System.Linq.Expressions.ExpressionType.Assign)
                    {
                        var args = new List <ResolveResult>();
                        if (pe.IsIndexer)
                        {
                            var irrOp0 = (CSharpInvocationResolveResult)res.Operands[0];
                            args.AddRange(irrOp0.Arguments);
                        }
                        args.Add(res.Operands[1]);
                        var fake  = new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Setter, args).AssociateWithOriginal(res);
                        var node6 = Visit(fake);
                        node6 = WrapSetterToReturnValueIfNeeded(res, node6);
                        return(node6);
                    }
                }
                if (res.Operands[0] is ConversionResolveResult && res.Operands[1] is ConstantResolveResult)
                {
                    var leftConv   = (ConversionResolveResult)res.Operands[0];
                    var rightConst = (ConstantResolveResult)res.Operands[1];
                    if (leftConv.Conversion.IsNumericConversion && leftConv.Input.Type == Cs.CharType(Project))
                    {
                        var value = ((char)(int)rightConst.ConstantValue).ToString();
                        var fake  = Cs.Binary(leftConv.Input, res.OperatorType, Cs.Value(value, Project), leftConv.Input.Type);
                        return(Visit(fake));
                    }
                }
                if (res.Operands[0].Type.Kind == TypeKind.Delegate && res.Operands[1].Type.Kind == TypeKind.Delegate)
                {
                    if (res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.SubtractAssign)
                    {
                        var op    = res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign ? System.Linq.Expressions.ExpressionType.Add : System.Linq.Expressions.ExpressionType.Subtract;
                        var fake  = Cs.Assign(res.Operands[0], Cs.Binary(res.Operands[0], op, res.Operands[1], res.Type));
                        var node6 = Visit(fake);
                        return(node6);
                    }
                    else if (res.OperatorType == System.Linq.Expressions.ExpressionType.Add || res.OperatorType == System.Linq.Expressions.ExpressionType.Subtract)
                    {
                        var combineMethod = Compiler.Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Combine").FirstOrDefault();
                        var removeMethod  = Compiler.Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Remove").FirstOrDefault();

                        var meOp = res.OperatorType == System.Linq.Expressions.ExpressionType.Add ? combineMethod : removeMethod;

                        var fake  = Cs.Member(null, meOp).Invoke(res.Operands[0], res.Operands[1]);
                        var node6 = Visit(fake);
                        return(node6);
                    }
                }

                var node5 = new JBinaryExpression {
                    Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]), Right = VisitExpression(res.Operands[1])
                };

                if (res.OperatorType == System.Linq.Expressions.ExpressionType.Equal && node5.Operator == "==")
                {
                    var att = JMeta.GetJsExportAttribute(Project.Compilation.MainAssembly);
                    if (att != null && att.UseExactEquals)
                    {
                        node5.Operator = "===";
                    }
                }
                if (res.OperatorType == System.Linq.Expressions.ExpressionType.NotEqual && node5.Operator == "!=")
                {
                    var att = JMeta.GetJsExportAttribute(Project.Compilation.MainAssembly);
                    if (att != null && att.UseExactEquals)
                    {
                        node5.Operator = "!==";
                    }
                }

                return(node5);
            }
            else if (res.Operands.Count == 3)
            {
                if (res.OperatorType == System.Linq.Expressions.ExpressionType.Conditional)
                {
                    var node5 = new JConditionalExpression {
                        Condition = VisitExpression(res.Operands[0]), TrueExpression = VisitExpression(res.Operands[1]), FalseExpression = VisitExpression(res.Operands[2])
                    };
                    return(node5);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }