|
67 | 67 | #include "llvm/Support/Error.h" |
68 | 68 | #include "llvm/Support/MemoryBuffer.h" |
69 | 69 | #include <cassert> |
| 70 | +#include <cctype> |
70 | 71 | #include <cstddef> |
71 | 72 | #include <iterator> |
72 | 73 | #include <memory> |
@@ -401,6 +402,48 @@ filterFastTidyChecks(const tidy::ClangTidyCheckFactories &All, |
401 | 402 |
|
402 | 403 | } // namespace |
403 | 404 |
|
| 405 | +std::vector<Fix> |
| 406 | +clangTidyNoLintFixes(const clang::tidy::ClangTidyContext &CTContext, |
| 407 | + const clang::Diagnostic &Info, const Diag &Diag) { |
| 408 | + auto RuleName = CTContext.getCheckName(Info.getID()); |
| 409 | + if (RuleName.empty()) { |
| 410 | + return {}; |
| 411 | + } |
| 412 | + if (!Diag.InsideMainFile) { |
| 413 | + return {}; |
| 414 | + } |
| 415 | + auto &SrcMgr = Info.getSourceManager(); |
| 416 | + auto &DiagLoc = Info.getLocation(); |
| 417 | + |
| 418 | + auto F = Fix{}; |
| 419 | + F.Message = llvm::formatv("ignore [{0}] for this line", RuleName); |
| 420 | + auto &E = F.Edits.emplace_back(); |
| 421 | + |
| 422 | + auto File = SrcMgr.getFileID(DiagLoc); |
| 423 | + auto CodeTilDiag = toSourceCode( |
| 424 | + SrcMgr, SourceRange(SrcMgr.getLocForStartOfFile(File), DiagLoc)); |
| 425 | + |
| 426 | + auto StartCurLine = CodeTilDiag.find_last_of('\n') + 1; |
| 427 | + auto CurLine = CodeTilDiag.substr(StartCurLine); |
| 428 | + elog("CurLine: '{0}'", CurLine); |
| 429 | + auto Indent = CurLine.take_while([](char C) { return std::isspace(C); }); |
| 430 | + |
| 431 | + if (StartCurLine > 0) { |
| 432 | + auto StartPrevLine = CodeTilDiag.find_last_of('\n', StartCurLine - 1) + 1; |
| 433 | + auto PrevLine = |
| 434 | + CodeTilDiag.substr(StartPrevLine, StartCurLine - StartPrevLine - 1); |
| 435 | + elog("PrevLine: '{0}'", PrevLine); |
| 436 | + } |
| 437 | + |
| 438 | + E.newText = llvm::formatv("{0}// NOLINTNEXTLINE({1})\n", Indent, RuleName); |
| 439 | + |
| 440 | + auto InsertPos = sourceLocToPosition(SrcMgr, DiagLoc); |
| 441 | + InsertPos.character = 0; |
| 442 | + E.range = {InsertPos, InsertPos}; |
| 443 | + |
| 444 | + return {F}; |
| 445 | +} |
| 446 | + |
404 | 447 | std::optional<ParsedAST> |
405 | 448 | ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, |
406 | 449 | std::unique_ptr<clang::CompilerInvocation> CI, |
@@ -655,10 +698,16 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, |
655 | 698 | : Symbol::Include; |
656 | 699 | FixIncludes.emplace(Filename, Inserter, *Inputs.Index, |
657 | 700 | /*IndexRequestLimit=*/5, Directive); |
658 | | - ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl, |
659 | | - const clang::Diagnostic &Info) { |
660 | | - return FixIncludes->fix(DiagLevl, Info); |
661 | | - }); |
| 701 | + ASTDiags.contributeFixes( |
| 702 | + [&FixIncludes, &CTContext](const Diag &Diag, |
| 703 | + const clang::Diagnostic &Info) { |
| 704 | + auto Fixes = std::vector<Fix>(); |
| 705 | + auto NoLintFixes = clangTidyNoLintFixes(*CTContext, Info, Diag); |
| 706 | + Fixes.insert(Fixes.end(), NoLintFixes.begin(), NoLintFixes.end()); |
| 707 | + auto IncludeFixes = FixIncludes->fix(Diag.Severity, Info); |
| 708 | + Fixes.insert(Fixes.end(), IncludeFixes.begin(), IncludeFixes.end()); |
| 709 | + return Fixes; |
| 710 | + }); |
662 | 711 | Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder()); |
663 | 712 | } |
664 | 713 | } |
|
0 commit comments