예제 #1
0
            public override SyntaxList <StatementSyntax> VisitSelectBlock(VBSyntax.SelectBlockSyntax node)
            {
                var expr = (ExpressionSyntax)node.SelectStatement.Expression.Accept(_nodesVisitor);
                var exprWithoutTrivia = expr.WithoutTrivia().WithoutAnnotations();
                var sections          = new List <SwitchSectionSyntax>();

                foreach (var block in node.CaseBlocks)
                {
                    var labels = new List <SwitchLabelSyntax>();
                    foreach (var c in block.CaseStatement.Cases)
                    {
                        if (c is VBSyntax.SimpleCaseClauseSyntax s)
                        {
                            var expressionSyntax = (ExpressionSyntax)s.Value.Accept(_nodesVisitor);
                            SwitchLabelSyntax caseSwitchLabelSyntax = SyntaxFactory.CaseSwitchLabel(expressionSyntax);
                            if (!_semanticModel.GetConstantValue(s.Value).HasValue)
                            {
                                caseSwitchLabelSyntax =
                                    WrapInCasePatternSwitchLabelSyntax(expressionSyntax);
                            }

                            labels.Add(caseSwitchLabelSyntax);
                        }
                        else if (c is VBSyntax.ElseCaseClauseSyntax)
                        {
                            labels.Add(SyntaxFactory.DefaultSwitchLabel());
                        }
                        else if (c is VBSyntax.RelationalCaseClauseSyntax relational)
                        {
                            var operatorKind     = VBasic.VisualBasicExtensions.Kind(relational);
                            var cSharpSyntaxNode = SyntaxFactory.BinaryExpression(operatorKind.ConvertToken(TokenContext.Local), exprWithoutTrivia, (ExpressionSyntax)relational.Value.Accept(_nodesVisitor));
                            labels.Add(WrapInCasePatternSwitchLabelSyntax(cSharpSyntaxNode));
                        }
                        else if (c is VBSyntax.RangeCaseClauseSyntax range)
                        {
                            var lowerBoundCheck = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression, (ExpressionSyntax)range.LowerBound.Accept(_nodesVisitor), exprWithoutTrivia);
                            var upperBoundCheck = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression, exprWithoutTrivia, (ExpressionSyntax)range.UpperBound.Accept(_nodesVisitor));
                            var withinBounds    = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalAndExpression, lowerBoundCheck, upperBoundCheck);
                            labels.Add(WrapInCasePatternSwitchLabelSyntax(withinBounds));
                        }
                        else
                        {
                            throw new NotSupportedException(c.Kind().ToString());
                        }
                    }

                    var csBlockStatements = block.Statements.SelectMany(s => s.Accept(CommentConvertingVisitor)).ToList();
                    if (csBlockStatements.LastOrDefault()
                        ?.IsKind(SyntaxKind.ReturnStatement) != true)
                    {
                        csBlockStatements.Add(SyntaxFactory.BreakStatement());
                    }
                    var list = SingleStatement(SyntaxFactory.Block(csBlockStatements));
                    sections.Add(SyntaxFactory.SwitchSection(SyntaxFactory.List(labels), list));
                }

                var switchStatementSyntax = SyntaxFactory.SwitchStatement(expr, SyntaxFactory.List(sections));

                return(SingleStatement(switchStatementSyntax));
            }
            public override SyntaxList <StatementSyntax> VisitExitStatement(VBSyntax.ExitStatementSyntax node)
            {
                switch (VBasic.VisualBasicExtensions.Kind(node.BlockKeyword))
                {
                case VBasic.SyntaxKind.SubKeyword:
                    return(SingleStatement(SyntaxFactory.ReturnStatement()));

                case VBasic.SyntaxKind.FunctionKeyword:
                    VBasic.VisualBasicSyntaxNode typeContainer = (VBasic.VisualBasicSyntaxNode)node.Ancestors().OfType <VBSyntax.LambdaExpressionSyntax>().FirstOrDefault()
                                                                 ?? node.Ancestors().OfType <VBSyntax.MethodBlockSyntax>().FirstOrDefault();
                    var info = typeContainer.TypeSwitch(
                        (VBSyntax.LambdaExpressionSyntax e) => _semanticModel.GetTypeInfo(e).Type.GetReturnType(),
                        (VBSyntax.MethodBlockSyntax e) => {
                        var type = (TypeSyntax)e.SubOrFunctionStatement.AsClause?.Type.Accept(_nodesVisitor) ?? SyntaxFactory.ParseTypeName("object");
                        return(_semanticModel.GetSymbolInfo(type).Symbol?.GetReturnType());
                    }
                        );
                    ExpressionSyntax expr;
                    if (HasReturnVariable)
                    {
                        expr = ReturnVariable;
                    }
                    else if (info == null)
                    {
                        expr = null;
                    }
                    else if (info.IsReferenceType)
                    {
                        expr = SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression);
                    }
                    else if (info.CanBeReferencedByName)
                    {
                        expr = SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(info.ToMinimalCSharpDisplayString(_semanticModel, node.SpanStart)));
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                    return(SingleStatement(SyntaxFactory.ReturnStatement(expr)));

                default:
                    return(SingleStatement(SyntaxFactory.BreakStatement()));
                }
            }
예제 #3
0
            private bool ConvertToSwitch(ExpressionSyntax expr, SyntaxList <VBSyntax.CaseBlockSyntax> caseBlocks, out SwitchStatementSyntax switchStatement)
            {
                switchStatement = null;

                var sections = new List <SwitchSectionSyntax>();

                foreach (var block in caseBlocks)
                {
                    var labels = new List <SwitchLabelSyntax>();
                    foreach (var c in block.CaseStatement.Cases)
                    {
                        if (c is VBSyntax.SimpleCaseClauseSyntax)
                        {
                            var s = (VBSyntax.SimpleCaseClauseSyntax)c;
                            labels.Add(SyntaxFactory.CaseSwitchLabel((ExpressionSyntax)s.Value.Accept(nodesVisitor)));
                        }
                        else if (c is VBSyntax.ElseCaseClauseSyntax)
                        {
                            labels.Add(SyntaxFactory.DefaultSwitchLabel());
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    var list = SingleStatement(SyntaxFactory.Block(block.Statements.SelectMany(s => s.Accept(this)).Concat(SyntaxFactory.BreakStatement())));
                    sections.Add(SyntaxFactory.SwitchSection(SyntaxFactory.List(labels), list));
                }
                switchStatement = SyntaxFactory.SwitchStatement(expr, SyntaxFactory.List(sections));
                return(true);
            }