//This overload differs from the one for module declaration elements because we have to take care that we do not invalidate line labels or line numbers on the next line.
        protected static int FindStopTokenIndexForRemoval(VBAParser.BlockStmtContext blockStmt)
        {
            if (!blockStmt.TryGetFollowingContext <VBAParser.IndividualNonEOFEndOfStatementContext>(out var followingIndividualEndOfLineStatement))
            {
                return(blockStmt.Stop.TokenIndex);
            }

            //If the endOfStatement starts with a statement separator, it is safe to simply remove that.
            if (followingIndividualEndOfLineStatement.COLON() != null)
            {
                return(followingIndividualEndOfLineStatement.Stop.TokenIndex);
            }

            //Since there is no statement separator, the individual endOfStatement must contain an endOfLine.
            var endOfLine = followingIndividualEndOfLineStatement.endOfLine();

            //EndOfLines contain preceding comments. So, we cannot remove the line, if there is one.
            if (endOfLine.commentOrAnnotation() != null)
            {
                return(endOfLine.commentOrAnnotation().Start.TokenIndex - 1);
            }

            //There could be a statement label right after the individual endOfStatement.
            //In that case, removing the endOfStatement would break the code.
            if (followingIndividualEndOfLineStatement.TryGetFollowingContext <VBAParser.StatementLabelDefinitionContext>(out _))
            {
                return(blockStmt.Stop.TokenIndex);
            }

            return(followingIndividualEndOfLineStatement.Stop.TokenIndex);
        }
        private string PaddedDeclaration(string declarationText, VBAParser.BlockStmtContext blockStmtContext)
        {
            if (blockStmtContext.TryGetPrecedingContext(out VBAParser.IndividualNonEOFEndOfStatementContext precedingEndOfStatement))
            {
                if (precedingEndOfStatement.COLON() != null)
                {
                    //You have been asking for it!
                    return($"{declarationText} : ");
                }

                var labelContext = blockStmtContext.statementLabelDefinition();
                if (labelContext != null)
                {
                    var labelAsSpace = new string(' ', labelContext.GetText().Length);
                    return($"{labelAsSpace}{blockStmtContext.whiteSpace()?.GetText()}{declarationText}{Environment.NewLine}");
                }

                var precedingWhitespaces = precedingEndOfStatement.whiteSpace();
                if (precedingWhitespaces != null && precedingWhitespaces.Length > 0)
                {
                    return($"{declarationText}{Environment.NewLine}{precedingWhitespaces[0]?.GetText()}");
                }

                return($"{declarationText}{Environment.NewLine}");
            }
            //This is the very first statement. In the context of this refactoring, this should not happen since we move a declaration into or inside a method.
            //We will handle this edge-case nonetheless and return the result with the proper indentation for this special case.
            if (blockStmtContext.TryGetPrecedingContext(out VBAParser.WhiteSpaceContext startingWhitespace))
            {
                return($"{declarationText}{Environment.NewLine}{startingWhitespace?.GetText()}");
            }

            return($"{declarationText}{Environment.NewLine}");
        }
        private string FrontPadding(VBAParser.BlockStmtContext context)
        {
            var statementLabelContext = context.statementLabelDefinition();

            if (statementLabelContext == null)
            {
                return(string.Empty);
            }

            var statementLabelTextAsWhitespace = ReplaceNonWhitespaceWithSpace(statementLabelContext.GetText());
            var whitespaceContext = context.whiteSpace();

            return(statementLabelTextAsWhitespace + (whitespaceContext?.GetText() ?? string.Empty));
        }
        private string EndOfStatementText(VBAParser.BlockStmtContext context)
        {
            if (!context.TryGetPrecedingContext <VBAParser.IndividualNonEOFEndOfStatementContext>(out var individualEndOfStmtContext))
            {
                return(Environment.NewLine);
            }

            var endOfLine = individualEndOfStmtContext.endOfLine();

            if (endOfLine?.commentOrAnnotation() == null)
            {
                return(individualEndOfStmtContext.GetText());
            }

            //There is a comment inside the preceding endOfLine, which we do not want to duplicate.
            var whitespaceContext = individualEndOfStmtContext.whiteSpace(0);

            return(Environment.NewLine + (whitespaceContext?.GetText() ?? string.Empty));
        }
Beispiel #5
0
 public override void EnterBlockStmt([NotNull] VBAParser.BlockStmtContext context)
 {
     // there is a whitespace context here after the option of a statementLabel.
     // we need to account for that
     _results.Add(new CodeMetricsResult(0, 0, IndentationLevelFromWhitespace(context.whiteSpace())));
 }