Пример #1
0
            public ConditionalAccessInfo(SemanticModel semanticModel, ConditionalAccessExpressionSyntax node)
            {
                Node = node;

                var expressionType = semanticModel.GetTypeInfo(node.Expression).Type;

                ExpressionType = SyntaxFactory.ParseTypeName(expressionType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start));

                var resultType = semanticModel.GetTypeInfo(node).Type;

                ResultType = SyntaxFactory.ParseTypeName(resultType.ToMinimalDisplayString(semanticModel, node.GetLocation().SourceSpan.Start));

                IsResultVoid = resultType.SpecialType == SpecialType.System_Void;
                IsComplex    = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(semanticModel, node.Expression);
            }
Пример #2
0
            public ConditionalAccessInfo(SemanticModel semanticModel, ConditionalAccessExpressionSyntax node)
            {
                Node = node;

                var expressionType = semanticModel.GetTypeInfo(node.Expression).Type;

                ExpressionType  = SyntaxFactory.ParseTypeName(expressionType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start));
                this.IsNullable = expressionType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T;

                if (this.IsNullable)
                {
                    UnderlyingNullableType = ((INamedTypeSymbol)expressionType).TypeArguments[0];
                    ExpressionType         = SyntaxFactory.ParseTypeName(UnderlyingNullableType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start));
                }

                var resultType = semanticModel.GetTypeInfo(node).Type;

                ResultType = SyntaxFactory.ParseTypeName(resultType.ToMinimalDisplayString(semanticModel, node.GetLocation().SourceSpan.Start));

                IsResultVoid = resultType.SpecialType == SpecialType.System_Void;
                IsComplex    = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(semanticModel, node.Expression);
            }
Пример #3
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model)
        {
            var switches = root.DescendantNodes().OfType <SwitchStatementSyntax>().Where(sw => {
                return(sw.Sections.Any(s => s.Labels.Any(l => l is CasePatternSwitchLabelSyntax || l is CaseSwitchLabelSyntax csl && csl.Value is CastExpressionSyntax ce && ce.Expression.Kind() == SyntaxKind.DefaultLiteralExpression)));
            });

            var tempKey = 0;

            root = root.ReplaceNodes(switches, (s1, sw) =>
            {
                try
                {
                    var ifNodes = new List <IfStatementSyntax>();
                    BlockSyntax defaultBlock = null;
                    var isComplex            = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(model, s1.Expression);
                    var switchExpression     = sw.Expression;
                    StatementSyntax switchConditionVariable = null;

                    var iType          = model.GetTypeInfo(s1.Expression).Type;
                    var expressionType = SyntaxFactory.ParseTypeName(iType.ToMinimalDisplayString(model, s1.Expression.GetLocation().SourceSpan.Start));

                    if (isComplex)
                    {
                        var key              = tempKey++;
                        var keyArg           = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("case_pattern" + key));
                        var methodIdentifier = SyntaxFactory.IdentifierName("global::Bridge.Script.ToTemp");

                        var toTemp = SyntaxFactory.InvocationExpression(methodIdentifier,
                                                                        SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg), SyntaxFactory.Argument(switchExpression) })));

                        switchConditionVariable = SyntaxFactory.ExpressionStatement(toTemp).NormalizeWhitespace();

                        var parentMethodIdentifier = SyntaxFactory.GenericName(SyntaxFactory.Identifier("global::Bridge.Script.FromTemp"),
                                                                               SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(new[] { expressionType })));
                        switchExpression = SyntaxFactory.InvocationExpression(parentMethodIdentifier,
                                                                              SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg) })));
                    }

                    foreach (var section in sw.Sections)
                    {
                        // This should catch most (if not all) unhandled yet natively supported syntax usage
                        try
                        {
                            var tuple     = CollectCondition(switchExpression, section.Labels, expressionType);
                            var condition = tuple.Item1;
                            var variables = tuple.Item2;
                            var whens     = tuple.Item3;

                            var body     = SyntaxFactory.Block();
                            var whenBody = SyntaxFactory.Block();

                            foreach (var variable in variables)
                            {
                                body = body.WithStatements(body.Statements.Add(SyntaxFactory.LocalDeclarationStatement(variable)));
                            }

                            foreach (var statement in section.Statements)
                            {
                                if (whens.Count > 0)
                                {
                                    whenBody = whenBody.WithStatements(whenBody.Statements.Add(statement));
                                }
                                else
                                {
                                    body = body.WithStatements(body.Statements.Add(statement));
                                }
                            }

                            if (whens.Count > 0)
                            {
                                ExpressionSyntax whenCondition = whens[0];
                                for (int i = 1; i < whens.Count; ++i)
                                {
                                    whenCondition = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalOrExpression, whenCondition, whens[i]);
                                }

                                body = body.WithStatements(body.Statements.Add(SyntaxFactory.IfStatement(whenCondition, whenBody)));
                            }

                            if (condition == null)
                            {
                                defaultBlock = body
                                               .WithLeadingTrivia(section.GetLeadingTrivia())
                                               .WithTrailingTrivia(section.GetTrailingTrivia());
                                break;
                            }

                            ifNodes.Add(SyntaxFactory.IfStatement(condition, body).WithLeadingTrivia(section.GetLeadingTrivia()));
                        }
                        catch (Exception e)
                        {
                            throw new ReplacerException(section, e);
                        }
                    }

                    var doBlock = SyntaxFactory.Block();
                    if (switchConditionVariable != null)
                    {
                        doBlock = doBlock.WithStatements(doBlock.Statements.Add(switchConditionVariable));
                    }

                    doBlock = doBlock.WithStatements(doBlock.Statements.AddRange(ifNodes));

                    if (defaultBlock != null)
                    {
                        doBlock = doBlock.WithStatements(doBlock.Statements.Add(defaultBlock));
                    }

                    var doStatement = SyntaxFactory.DoStatement(doBlock, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));

                    doStatement = doStatement.WithLeadingTrivia(sw.GetLeadingTrivia().Concat(doStatement.GetLeadingTrivia())).WithTrailingTrivia(sw.GetTrailingTrivia());
                    return(doStatement.NormalizeWhitespace());
                }
                catch (Exception e)
                {
                    throw new ReplacerException(sw, e);
                }
            });

            return(root);
        }