private static VBAParser.EndOfLineContext PreviousEndOfLine(ParserRuleContext context) { var moduleContext = context.GetAncestor <VBAParser.ModuleContext>(); var endOfLineListener = new EndOfLineListener(); ParseTreeWalker.Default.Walk(endOfLineListener, moduleContext); var previousEol = endOfLineListener.Contexts .OrderBy(eol => eol.Start.TokenIndex) .LastOrDefault(eol => eol.stop.TokenIndex < context.start.TokenIndex); return(previousEol); }
public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var annotationText = $"'@Ignore {result.Inspection.AnnotationName}"; int annotationLine; //TODO: Make this use the parse tree instead of the code module. var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName); using (var module = component.CodeModule) { annotationLine = result.QualifiedSelection.Selection.StartLine; while (annotationLine != 1 && module.GetLines(annotationLine - 1, 1).EndsWith(" _")) { annotationLine--; } } RuleContext treeRoot = result.Context; while (treeRoot.Parent != null) { treeRoot = treeRoot.Parent; } var listener = new CommentOrAnnotationListener(); ParseTreeWalker.Default.Walk(listener, treeRoot); var commentContext = listener.Contexts.LastOrDefault(i => i.Stop.TokenIndex <= result.Context.Start.TokenIndex); var commented = commentContext?.Stop.Line + 1 == annotationLine; var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); if (commented) { var annotation = commentContext.annotationList()?.annotation(0); if (annotation != null && annotation.GetText().StartsWith("Ignore")) { rewriter.InsertAfter(annotation.annotationName().Stop.TokenIndex, $" {result.Inspection.AnnotationName},"); } else { var indent = new string(Enumerable.Repeat(' ', commentContext.Start.Column).ToArray()); rewriter.InsertAfter(commentContext.Stop.TokenIndex, $"{indent}{annotationText}{Environment.NewLine}"); } } else { int insertIndex; // this value is used when the annotation should be on line 1--we need to insert before token index 0 if (annotationLine == 1) { insertIndex = 0; annotationText += Environment.NewLine; } else { var eol = new EndOfLineListener(); ParseTreeWalker.Default.Walk(eol, treeRoot); // we subtract 2 here to get the insertion index to A) account for VBE's one-based indexing // and B) to get the newline token that introduces that line var eolContext = eol.Contexts.OrderBy(o => o.Start.TokenIndex).ElementAt(annotationLine - 2); insertIndex = eolContext.Start.TokenIndex; annotationText = Environment.NewLine + annotationText; } rewriter.InsertBefore(insertIndex, annotationText); } }