Exemple #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));
            }
            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);
            }
Exemple #3
0
        /// <summary>
        /// Returns syntax for dispatching <paramref name="event"/> to <paramref name="method"/>.
        /// </summary>
        /// <param name="event">
        /// The event.
        /// </param>
        /// <param name="method">
        /// The actor description.
        /// </param>
        /// <returns>
        /// Syntax for dispatching <paramref name="event"/> to <paramref name="method"/>.
        /// </returns>
        private static SwitchSectionSyntax GetMethodSwitchCase(ExpressionSyntax @event, ActorMethodDescription method)
        {
            var label =
                SF.CaseSwitchLabel(SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal(method.Name)));

            return
                (SF.SwitchSection()
                 .AddLabels(label)
                 .AddStatements(
                     GenerateMethodDispatcher(@event, SF.IdentifierName("grain"), method.MethodInfo)));
        }
Exemple #4
0
        /// <summary>
        /// Returns syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
        /// </summary>
        /// <param name="actor">
        /// The actor description.
        /// </param>
        /// <param name="event">
        /// The event.
        /// </param>
        /// <returns>
        /// Syntax for dispatching <paramref name="event"/> to <paramref name="actor"/>.
        /// </returns>
        private static SwitchSectionSyntax GetActorSwitch(
            ActorDescription actor,
            ExpressionSyntax @event)
        {
            var label =
                SF.CaseSwitchLabel(SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal(actor.Kind)));

            return
                (SF.SwitchSection()
                 .AddLabels(label)
                 .AddStatements(GenerateActorBlock(@event, actor)));
        }
 /// <summary>
 /// Generates switch cases for the provided actor.
 /// </summary>
 /// <param name="actor">
 /// The actor.
 /// </param>
 /// <param name="generateSwitchBlock">
 /// The function used to generate switch block statements for each method.
 /// </param>
 /// <returns>
 /// The switch cases for the provided actor.
 /// </returns>
 private static IEnumerable <SwitchSectionSyntax> GenerateSwitchCases(ActorDescription actor, Func <ActorMethodDescription, StatementSyntax> generateSwitchBlock)
 {
     return(actor.Methods.Values.Select(
                m =>
     {
         var label =
             SF.CaseSwitchLabel(SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal(m.Name)));
         return
         SF.SwitchSection()
         .AddLabels(label)
         .AddStatements(generateSwitchBlock(m));
     }));
 }
Exemple #6
0
        /// <summary>
        /// Generates switch cases for the provided grain type.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="methodIdArgument">
        /// The method id argument, which is used to select the correct switch label.
        /// </param>
        /// <param name="generateMethodHandler">
        /// The function used to generate switch block statements for each method.
        /// </param>
        /// <returns>
        /// The switch cases for the provided grain type.
        /// </returns>
        public static SwitchSectionSyntax[] GenerateGrainInterfaceAndMethodSwitch(
            Type grainType,
            IdentifierNameSyntax methodIdArgument,
            Func <MethodInfo, StatementSyntax[]> generateMethodHandler)
        {
            var interfaces = GrainInterfaceData.GetRemoteInterfaces(grainType);

            interfaces[GrainInterfaceData.GetGrainInterfaceId(grainType)] = grainType;

            // Switch on interface id.
            var interfaceCases = new List <SwitchSectionSyntax>();

            foreach (var @interface in interfaces)
            {
                var interfaceType = @interface.Value;
                var interfaceId   = @interface.Key;
                var methods       = GrainInterfaceData.GetMethods(interfaceType);

                var methodCases = new List <SwitchSectionSyntax>();

                // Switch on method id.
                foreach (var method in methods)
                {
                    // Generate switch case.
                    var methodId   = GrainInterfaceData.ComputeMethodId(method);
                    var methodType = method;

                    // Generate the switch label for this interface id.
                    var methodIdSwitchLabel =
                        SF.CaseSwitchLabel(
                            SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                    // Generate the switch body.
                    var methodInvokeStatement = generateMethodHandler(methodType);

                    methodCases.Add(
                        SF.SwitchSection().AddLabels(methodIdSwitchLabel).AddStatements(methodInvokeStatement));
                }

                // Generate the switch label for this interface id.
                var interfaceIdSwitchLabel =
                    SF.CaseSwitchLabel(
                        SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)));

                // Generate the default case, which will throw a NotImplementedException.
                var errorMessage = SF.BinaryExpression(
                    SyntaxKind.AddExpression,
                    "interfaceId=".GetLiteralExpression(),
                    SF.BinaryExpression(
                        SyntaxKind.AddExpression,
                        SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)),
                        SF.BinaryExpression(
                            SyntaxKind.AddExpression,
                            ",methodId=".GetLiteralExpression(),
                            methodIdArgument)));
                var throwStatement =
                    SF.ThrowStatement(
                        SF.ObjectCreationExpression(typeof(NotImplementedException).GetTypeSyntax())
                        .AddArgumentListArguments(SF.Argument(errorMessage)));
                var defaultCase = SF.SwitchSection().AddLabels(SF.DefaultSwitchLabel()).AddStatements(throwStatement);

                // Generate switch statements for the methods in this interface.
                var methodSwitchStatements =
                    SF.SwitchStatement(methodIdArgument).AddSections(methodCases.ToArray()).AddSections(defaultCase);

                // Generate the switch section for this interface.
                interfaceCases.Add(
                    SF.SwitchSection().AddLabels(interfaceIdSwitchLabel).AddStatements(methodSwitchStatements));
            }

            return(interfaceCases.ToArray());
        }