private ExpressionSyntax CreateCast(ExpressionSyntax csNode, ITypeSymbol vbConvertedType)
        {
            var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType);

            if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName))
            {
                return(csNode);
            }

            return(ValidSyntaxFactory.CastExpression(typeName, csNode));
        }
 public static CS.Syntax.ExpressionSyntax SkipOutOfParens(this CS.Syntax.ExpressionSyntax expression)
 {
     if (expression == null)
     {
         return(null);
     }
     while (expression is CS.Syntax.ParenthesizedExpressionSyntax pes)
     {
         expression = pes.Parent as CS.Syntax.ExpressionSyntax;
     }
     return(expression);
 }
 public static ExpressionSyntax SkipParens(this ExpressionSyntax expression)
 {
     if (expression == null)
     {
         return(null);
     }
     while (expression != null && expression.IsKind(SyntaxKind.ParenthesizedExpression))
     {
         expression = ((ParenthesizedExpressionSyntax)expression).Expression;
     }
     return(expression);
 }
    private ExpressionSyntax AddTypeConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded, ITypeSymbol vbType, ITypeSymbol vbConvertedType)
    {
        switch (conversionKind)
        {
        case TypeConversionKind.FractionalNumberRoundThenCast:
            csNode = vbType.IsNullable() && vbConvertedType.IsNullable()
                    ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetMathRoundMemberAccess(), GetTypeSyntax(vbConvertedType))
                    : AddRoundInvocation(vbType.IsNullable() ? csNode.NullableGetValueExpression() : csNode);

            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType));

        case TypeConversionKind.EnumConversionThenCast:
            vbConvertedType.IsNullable(out var convertedNullableType);
            var underlyingEnumType = ((INamedTypeSymbol)(convertedNullableType ?? vbConvertedType)).EnumUnderlyingType;
            csNode = vbType.IsNullable() && convertedNullableType != null
                    ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetConversionsMemberAccess(underlyingEnumType), GetTypeSyntax(vbConvertedType))
                    : AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, vbType, underlyingEnumType);

            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType));

        case TypeConversionKind.EnumCastThenConversion:
            var enumUnderlyingType = ((INamedTypeSymbol)vbType).EnumUnderlyingType;
            csNode = AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, enumUnderlyingType);
            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, enumUnderlyingType, vbConvertedType));

        case TypeConversionKind.Unknown:
        case TypeConversionKind.Identity:
            return(addParenthesisIfNeeded ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode);

        case TypeConversionKind.DestructiveCast:
        case TypeConversionKind.NonDestructiveCast:
            return(CreateCast(csNode, vbConvertedType));

        case TypeConversionKind.Conversion:
            return(AddExplicitConvertTo(vbNode, csNode, vbType, vbConvertedType));

        case TypeConversionKind.NullableBool:
            return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode,
                                                  LiteralConversions.GetLiteralExpression(true)));

        case TypeConversionKind.StringToCharArray:
            var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray)));
            return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax,
                                                      SyntaxFactory.ArgumentList()));

        case TypeConversionKind.DelegateConstructor:
            return(SyntaxFactory.ObjectCreationExpression(GetCommonDelegateTypeOrNull(vbNode, vbConvertedType)).WithArgumentList(new[] { csNode }.CreateCsArgList()));

        default:
            throw new ArgumentOutOfRangeException(nameof(conversionKind), conversionKind, null);
        }
    }
    public ExpressionSyntax AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null)
    {
        if (csNode == null)
        {
            return(null);
        }
        var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceSourceType, forceTargetType);

        csNode = addParenthesisIfNeeded && conversionKind is TypeConversionKind.DestructiveCast or TypeConversionKind.NonDestructiveCast
            ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode)
            : csNode;
        return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, isConst, forceSourceType: forceSourceType, forceTargetType: forceTargetType).Expr);
    }
 public static Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax SkipParens(this Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression)
 {
     if (expression == null)
     {
         return(null);
     }
     while (expression is Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedExpressionSyntax pes)
     {
         expression = pes.Expression;
     }
     return(expression);
 }
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false)
        {
            var vbConvertedType = ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType;

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.DestructiveCast:
            case TypeConversionKind.NonDestructiveCast:
                return(CreateCast(csNode, vbConvertedType));

            case TypeConversionKind.Conversion:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool alwaysExplicit = false)
        {
            var conversionKind = AnalyzeConversion(vbNode, alwaysExplicit);

            csNode = addParenthesisIfNeeded && (conversionKind == TypeConversionKind.DestructiveCast || conversionKind == TypeConversionKind.NonDestructiveCast)
                ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode)
                : csNode;
            return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded));
        }
        public ExpressionSyntax AddExplicitConvertTo(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, ITypeSymbol type)
        {
            var displayType = type.ToMinimalDisplayString(_semanticModel, vbNode.SpanStart);

            if (csNode is InvocationExpressionSyntax invoke &&
                invoke.Expression is MemberAccessExpressionSyntax expr &&
                expr.Expression is IdentifierNameSyntax name && name.Identifier.ValueText == "Conversions" &&
                expr.Name.Identifier.ValueText == $"To{displayType}")
            {
                return(csNode);
            }

            if (!ConversionsTypeFullNames.TryGetValue(type.GetFullMetadataName(), out var methodId))
            {
                return(CreateCast(csNode, type));
            }

            // Need to use Conversions rather than Convert to match what VB does, eg. True -> -1
            _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices");
            var memberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                    SyntaxFactory.IdentifierName("Conversions"), SyntaxFactory.IdentifierName(methodId));
            var arguments = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(csNode)));

            return(SyntaxFactory.InvocationExpression(memberAccess, arguments));
        }
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, ITypeSymbol forceTargetType = null)
        {
            var vbConvertedType = forceTargetType ?? ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType;

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.DestructiveCast:
            case TypeConversionKind.NonDestructiveCast:
                return(CreateCast(csNode, vbConvertedType));

            case TypeConversionKind.Conversion:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            case TypeConversionKind.ConstConversion:
                return(ConstantFold(vbNode, vbConvertedType));

            case TypeConversionKind.NullableBool:
                return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode,
                                                      LiteralConversions.GetLiteralExpression(true)));

            case TypeConversionKind.StringToCharArray:
                var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray)));
                return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax,
                                                          SyntaxFactory.ArgumentList()));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceTargetType = null)
        {
            if (csNode == null)
            {
                return(null);
            }
            var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceTargetType);

            csNode = addParenthesisIfNeeded && (conversionKind == TypeConversionKind.DestructiveCast || conversionKind == TypeConversionKind.NonDestructiveCast)
                ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode)
                : csNode;
            return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, forceTargetType: forceTargetType));
        }
    public (ExpressionSyntax Expr, bool IsConst) AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, bool requiresConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null)
    {
        var(vbType, vbConvertedType) = GetTypeInfo(vbNode, forceSourceType, forceTargetType);
        bool resultConst = false;

        if (requiresConst)
        {
            var(constExpression, isCorrectType) = _expressionEvaluator.GetConstantOrNull(vbNode, vbConvertedType, conversionKind, csNode);
            if (isCorrectType)
            {
                return(constExpression, true);
            }
            if (constExpression != null)
            {
                csNode      = constExpression ?? csNode;
                resultConst = true;
            }
        }

        var typeConvertedResult = AddTypeConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, vbType, vbConvertedType);

        return(typeConvertedResult, resultConst);
    }
Esempio n. 13
0
        static void CompileExpression(CompileContext context, Neo.ASML.Node.ASMFunction func, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, string comment = null)
        {
            if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax)
            {
                var lit = expression as Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax;
                var v   = lit.Token.ValueText;
                func.nodes.Add(new Neo.ASML.Node.ASMInstruction()
                {
                    opcode = Neo.ASML.Node.ASMOpCode.CreatePush(), valuetext = v, commentRight = comment
                });
                return;
            }
            else if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.BinaryExpressionSyntax)
            {
                var binary = expression as Microsoft.CodeAnalysis.CSharp.Syntax.BinaryExpressionSyntax;
                if (comment != null)
                {
                    func.nodes.Add(new Neo.ASML.Node.ASMComment()
                    {
                        text = comment
                    });
                }

                CompileExpression(context, func, binary.Left);
                CompileExpression(context, func, binary.Right);

                Neo.VM.OpCode opcode = Neo.VM.OpCode.NOP;
                if (binary.OperatorToken.ValueText == "+")
                {
                    opcode = Neo.VM.OpCode.ADD;
                }
                else if (binary.OperatorToken.ValueText == "-")
                {
                    opcode = Neo.VM.OpCode.DEC;
                }
                if (binary.OperatorToken.ValueText == "*")
                {
                    opcode = Neo.VM.OpCode.MUL;
                }
                if (binary.OperatorToken.ValueText == "/")
                {
                    opcode = Neo.VM.OpCode.DIV;
                }

                func.nodes.Add(new Neo.ASML.Node.ASMInstruction()
                {
                    opcode = Neo.ASML.Node.ASMOpCode.Create(opcode)
                });
            }
            else if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax)
            {
                var id       = expression as Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax;
                var varname  = id.Identifier.ValueText;
                var varindex = context.variables.IndexOf(varname);
                if (varindex >= 0)
                {
                    //this is a LDLoc op
                    func.nodes.Add(new Neo.ASML.Node.ASMComment()
                    {
                        text = "//" + varname
                    });
                    //push setitem
                    func.nodes.Add(new Neo.ASML.Node.ASMInstruction()
                    {
                        opcode = Neo.ASML.Node.ASMOpCode.Create(Neo.VM.OpCode.DUPFROMALTSTACK), commentRight = "//variables array"
                    });
                    func.nodes.Add(new Neo.ASML.Node.ASMInstruction()
                    {
                        opcode = Neo.ASML.Node.ASMOpCode.CreatePush(), valuetext = varindex.ToString(), commentRight = "//index"
                    });
                    func.nodes.Add(new Neo.ASML.Node.ASMInstruction()
                    {
                        opcode = Neo.ASML.Node.ASMOpCode.Create(Neo.VM.OpCode.PICKITEM)
                    });
                }
            }
            else
            {
                var type = expression.GetType().ToString();
                throw new Exception("not support type:" + type);
            }
        }
Esempio n. 14
0
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false)
        {
            var vbConvertedType = ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType;

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.DestructiveCast:
            case TypeConversionKind.NonDestructiveCast:
                var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType);
                if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName))
                {
                    return(csNode);
                }
                return(ValidSyntaxFactory.CastExpression(typeName, csNode));

            case TypeConversionKind.Conversion:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }