Ejemplo n.º 1
0
 private JNode 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)
     {
         var me      = conversion.Method;
         var delType = conversionType;
         var exp     = me.JAccess().Invoke(me.Parameters.Select(t => J.Member(t.Name)).ToArray());
         var st      = J.Return(exp);
         var block   = J.Block().Add(st);
         var del2    = CreateDelegate(delType, me.Parameters, me.ReturnType, block);
         return(del2);
         //J.CreateDelegate(conversionType.JAccess(), me.Parameters.Select(t=>t.Acc
         //TODO:  J.CreateDelegate(conversionType.JAccess(),
     }
     else if (conversion.IsUserDefined)
     {
         ITypeDefinition typeDef;
         if (conversion.Method != null && conversion.Method.DeclaringType != null)
         {
             typeDef = conversion.Method.DeclaringType.GetDefinitionOrArrayType(Compiler);
         }
         else
         {
             typeDef = conversionType.GetDefinitionOrArrayType(Compiler);
         }
         var nativeOverloads = JMeta.UseNativeOperatorOverloads(typeDef);
         if (nativeOverloads)
         {
             return(Visit(input));
         }
         var fake  = conversion.Method.InvokeMethod(null, input);
         var node2 = Visit(fake);
         return(node2);
     }
     else if (conversion.IsTryCast || conversion.IsExplicit)
     {
         var typeDef   = conversionType.GetDefinitionOrArrayType(Compiler);
         var omitCasts = JMeta.OmitCasts(typeDef, Project);
         if (omitCasts)
         {
             return(Visit(input));
         }
         if (true)//Sk.NativeCasts(typeDef))
         {
             var exp2  = VisitExpression(input);
             var type2 = JNaming.JAccess(conversionType);
             if (conversion.IsTryCast)
             {
                 var node2 = exp2.InstanceOf(type2).Conditional(exp2, J.Null());
                 return(node2);
             }
             else
             {
                 return(J.Cast(exp2, type2));
             }
         }
         //else
         //{
         //    var cast = conversion.IsTryCast ? "As" : "Cast";
         //    var node2 = J.Member(cast).Invoke(VisitExpression(input), JNaming.JAccess(conversionType));
         //    return node2;
         //}
     }
     return(Visit(input));
 }
Ejemplo n.º 2
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();
            }
        }