private static IEnumerable <SyntaxTrivia> ConvertVBTrivia(SyntaxTrivia t)
    {
        if (t.IsKind(VBSyntaxKind.CommentTrivia))
        {
            yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, $"// {t.GetCommentText()}"));

            yield break;
        }
        if (t.IsKind(VBSyntaxKind.DocumentationCommentTrivia))
        {
            var previousWhitespace = t.GetPreviousTrivia(t.SyntaxTree, CancellationToken.None).ToString().Trim('\r', '\n');
            var commentTextLines   = t.GetCommentText().Replace("\r\n", "\n").Replace("\r", "\n").Split('\n');
            var outputCommentText  = "/// " + String.Join($"\r\n{previousWhitespace}/// ", commentTextLines);
            yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, outputCommentText)); //It's always single line...even when it has multiple lines

            yield return(_endOfLine);

            yield break;
        }

        if (t.IsKind(VBSyntaxKind.WhitespaceTrivia))
        {
            yield return(SyntaxFactory.ElasticWhitespace(t.ToString()));

            yield break;
        }

        if (t.IsKind(VBSyntaxKind.EndOfLineTrivia))
        {
            yield return(SyntaxFactory.EndOfLine(t.ToString()));

            yield break;
        }

        if (t.HasStructure)
        {
            bool wasConverted = false;
            foreach (var converted in ConvertStructuredVBTrivia(t))
            {
                yield return(converted);

                wasConverted = true;
            }
            if (wasConverted)
            {
                yield break;
            }
        }

        //Each of these would need its own method to recreate for C# with the right structure probably so let's just warn about them for now.
        var convertedKind = t.GetCSKind();

        yield return(convertedKind.HasValue
            ? SyntaxFactory.Comment(@$ "/* TODO ERROR: Skipped {convertedKind.Value}
{t.ToFullString()}*/")
            : default(SyntaxTrivia));
    }
        private static Document ClassDeclWithCommentAtOpeningBrace(
            Document document,
            SyntaxNode root,
            ClassDeclarationSyntax type,
            string errorMessage)
        {
            var explanatoryCommentTrivia = SF.Comment("//" + errorMessage);
            var endOfLineTrivia          = SF.EndOfLine("\r\n");
            var leadingTrivia            = @type.OpenBraceToken.LeadingTrivia;

            var typeUpdatedWithExplanatoryComment = @type.WithOpenBraceToken(
                SF.Token(
                    leadingTrivia,
                    SyntaxKind.OpenBraceToken,
                    SF.TriviaList(
                        explanatoryCommentTrivia,
                        endOfLineTrivia)));

            var newDocumentRoot = root.ReplaceNode(@type, typeUpdatedWithExplanatoryComment);
            var newDocument     = document.WithSyntaxRoot(newDocumentRoot);

            return(newDocument);
        }
Exemple #3
0
        private static IEnumerable <SyntaxTrivia> ConvertVBTrivia(SyntaxTrivia t)
        {
            var endOfLine = SyntaxFactory.EndOfLine(Environment.NewLine);

            if (t.IsKind(VBSyntaxKind.CommentTrivia))
            {
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, $"// {t.GetCommentText()}"));

                yield break;
            }
            if (t.IsKind(VBSyntaxKind.DocumentationCommentTrivia))
            {
                var previousWhitespace = t.GetPreviousTrivia(t.SyntaxTree, CancellationToken.None).ToString().Trim('\r', '\n');
                var commentTextLines   = t.GetCommentText().Replace("\r\n", "\n").Replace("\r", "\n").Split('\n');
                var outputCommentText  = "/// " + String.Join($"\r\n{previousWhitespace}/// ", commentTextLines) + Environment.NewLine;
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, outputCommentText)); //It's always single line...even when it has multiple lines

                yield break;
            }

            if (t.IsKind(VBSyntaxKind.WhitespaceTrivia))
            {
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.WhitespaceTrivia, t.ToString()));

                yield break;
            }

            if (t.IsKind(VBSyntaxKind.EndOfLineTrivia))
            {
                // Mapping one to one here leads to newlines appearing where the natural line-end was in VB.
                // e.g. ToString\r\n()
                // Because C Sharp needs those brackets. Handling each possible case of this is far more effort than it's worth.
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.EndOfLineTrivia, t.ToString()));

                yield break;
            }

            if (t.HasStructure && t.GetStructure() is VBSyntax.RegionDirectiveTriviaSyntax rdts)
            {
                var regionDirective     = SyntaxFactory.RegionDirectiveTrivia(true);
                var regionKeyword       = regionDirective.RegionKeyword.WithTrailingTrivia(SyntaxFactory.Space);
                var endOfDirectiveToken = regionDirective.EndOfDirectiveToken.WithLeadingTrivia(SyntaxFactory.PreprocessingMessage(rdts.Name.Text.Trim('"'))).WithTrailingTrivia(endOfLine);
                yield return(SyntaxFactory.Trivia(regionDirective.WithRegionKeyword(regionKeyword).WithEndOfDirectiveToken(endOfDirectiveToken)));

                yield break;
            }

            if (t.IsKind(VBSyntaxKind.EndRegionDirectiveTrivia))
            {
                yield return(SyntaxFactory.Trivia(SyntaxFactory.EndRegionDirectiveTrivia(true).WithTrailingTrivia(endOfLine)));

                yield break;
            }

            //Each of these would need its own method to recreate for C# with the right structure probably so let's just warn about them for now.
            var convertedKind = t.GetCSKind();

            yield return(convertedKind.HasValue
                ? SyntaxFactory.Comment($"/* TODO ERROR: Skipped {convertedKind.Value} */")
                : default(SyntaxTrivia));
        }
Exemple #4
0
        private MethodDeclarationSyntax AddReturnLogging(MethodDeclarationSyntax methodDecl)
        {
            var returnType = methodDecl.ReturnType;
            MethodDeclarationSyntax newMethod = methodDecl;

            var isVoid = returnType.ChildTokens().Any(x => x.Kind() == SyntaxKind.VoidKeyword);

            var returnStatements = methodDecl
                                   .Body
                                   .DescendantNodes()
                                   .OfType <ReturnStatementSyntax>()
                                   .Where(node => methodDecl.DirectlyContains(node))
                                   .ToArray();

            newMethod = newMethod.TrackNodes(returnStatements);

            if (isVoid)
            {
                var loggingInvocation = GetLoggingStatementWithDictionaryState(methodDecl, LogMethodReturnName);

                loggingInvocation = loggingInvocation.WithTrailingTrivia(SF.LineFeed);

                foreach (var statement in returnStatements)
                {
                    newMethod = newMethod.WithTracking(x => x.InsertNodesBefore, statement, new[] { loggingInvocation });
                }

                return(newMethod);
            }

            var resultBuffVarBame      = "result";
            var isResultBuffVarCreated = false;

            foreach (var statement in returnStatements)
            {
                switch (statement.Expression)
                {
                case IdentifierNameSyntax id:
                    var loggingInvocation = GetLoggingStatementWithSingleStateWithoutName(
                        methodDecl,
                        LogMethodReturnName,
                        id.ChildTokens().Single());

                    loggingInvocation = loggingInvocation
                                        .WithLeadingTrivia(SF.LineFeed)
                                        .WithTrailingTrivia(SF.LineFeed);

                    newMethod = newMethod.WithTracking(x => x.InsertNodesBefore, statement, new[] { loggingInvocation });
                    break;

                default:
                    if (isResultBuffVarCreated == false)
                    {
                        var declaration = LocalVariableExtensions
                                          .LocalVairableDeclaration(
                            methodDecl.ReturnType,
                            resultBuffVarBame,
                            statement.Expression)
                                          .WithTrailingTrivia(SF.EndOfLine("\r\n"));

                        newMethod = newMethod.WithTracking(x => x.InsertNodesBefore, statement, new[] { declaration });
                        isResultBuffVarCreated = true;
                    }
                    else
                    {
                        var assignment = SF.ExpressionStatement(
                            SF.AssignmentExpression(
                                SyntaxKind.SimpleAssignmentExpression,
                                SF.IdentifierName(resultBuffVarBame),
                                statement.Expression))
                                         .WithTrailingTrivia(SF.EndOfLine("\r\n"));

                        newMethod = newMethod.WithTracking(x => x.InsertNodesBefore, statement, new[] { assignment });
                    }

                    var logExpression = GetLoggingStatementWithSingleStateWithoutName(
                        methodDecl,
                        LogMethodReturnName,
                        SF.Identifier(resultBuffVarBame))
                                        .WithTrailingTrivia(SF.EndOfLine("\r\n"));

                    newMethod = newMethod.WithTracking(x => x.InsertNodesBefore, statement, new[] { logExpression });
                    var newReturn = SF.ReturnStatement(SF.IdentifierName(" result"));

                    newMethod = newMethod.WithTracking(x => x.ReplaceNode, statement, new[] { newReturn });
                    break;
                }
            }

            return(newMethod);
        }