[clang-tools-extra] 3b4936b - [clangd] Add --check-lines to restrict --check to specific lines
Adam Czachorowski via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 9 04:53:37 PDT 2021
Author: Adam Czachorowski
Date: 2021-04-09T13:47:20+02:00
New Revision: 3b4936ba290594cda4e53169958fe11c83119657
URL: https://github.com/llvm/llvm-project/commit/3b4936ba290594cda4e53169958fe11c83119657
DIFF: https://github.com/llvm/llvm-project/commit/3b4936ba290594cda4e53169958fe11c83119657.diff
LOG: [clangd] Add --check-lines to restrict --check to specific lines
This will allow us to add code completion, which is too expensive at
every token, to --check too.
Differential Revision: https://reviews.llvm.org/D98970
Added:
clang-tools-extra/clangd/test/check-lines.test
Modified:
clang-tools-extra/clangd/tool/Check.cpp
clang-tools-extra/clangd/tool/ClangdMain.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/test/check-lines.test b/clang-tools-extra/clangd/test/check-lines.test
new file mode 100644
index 000000000000..bfd30dd6104f
--- /dev/null
+++ b/clang-tools-extra/clangd/test/check-lines.test
@@ -0,0 +1,15 @@
+// RUN: cp %s %t.cpp
+// RUN: not clangd -check=%t.cpp -check-lines=6-14 2>&1 | FileCheck -strict-whitespace %s
+// RUN: not clangd -check=%t.cpp -check-lines=14 2>&1 | FileCheck -strict-whitespace %s
+
+// CHECK: Testing on source file {{.*}}check-lines.test
+// CHECK: internal (cc1) args are: -cc1
+// CHECK: Building preamble...
+// CHECK: Building AST...
+// CHECK: Testing features at each token
+// CHECK: tweak: ExpandAutoType ==> FAIL
+// CHECK: All checks completed, 1 errors
+
+void fun();
+auto x = fun; // This line is tested
+auto y = fun; // This line is not tested
diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp
index 20b86daff8af..0138ae3eb13b 100644
--- a/clang-tools-extra/clangd/tool/Check.cpp
+++ b/clang-tools-extra/clangd/tool/Check.cpp
@@ -192,14 +192,19 @@ class Checker {
}
// Run AST-based features at each token in the file.
- void testLocationFeatures() {
+ void testLocationFeatures(
+ llvm::function_ref<bool(const Position &)> ShouldCheckLine) {
log("Testing features at each token (may be slow in large files)");
- auto SpelledTokens =
- AST->getTokens().spelledTokens(AST->getSourceManager().getMainFileID());
+ auto &SM = AST->getSourceManager();
+ auto SpelledTokens = AST->getTokens().spelledTokens(SM.getMainFileID());
for (const auto &Tok : SpelledTokens) {
unsigned Start = AST->getSourceManager().getFileOffset(Tok.location());
unsigned End = Start + Tok.length();
Position Pos = offsetToPosition(Inputs.Contents, Start);
+
+ if (!ShouldCheckLine(Pos))
+ continue;
+
// FIXME: dumping the tokens may leak sensitive code into bug reports.
// Add an option to turn this off, once we decide how options work.
vlog(" {0} {1}", Pos, Tok.text(AST->getSourceManager()));
@@ -229,8 +234,9 @@ class Checker {
} // namespace
-bool check(llvm::StringRef File, const ThreadsafeFS &TFS,
- const ClangdLSPServer::Options &Opts) {
+bool check(llvm::StringRef File,
+ llvm::function_ref<bool(const Position &)> ShouldCheckLine,
+ const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts) {
llvm::SmallString<0> FakeFile;
llvm::Optional<std::string> Contents;
if (File.empty()) {
@@ -254,7 +260,7 @@ bool check(llvm::StringRef File, const ThreadsafeFS &TFS,
if (!C.buildCommand(TFS) || !C.buildInvocation(TFS, Contents) ||
!C.buildAST())
return false;
- C.testLocationFeatures();
+ C.testLocationFeatures(ShouldCheckLine);
log("All checks completed, {0} errors", C.ErrCount);
return C.ErrCount == 0;
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index c48821cba2c7..6dd13a503887 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -60,8 +60,9 @@ namespace clang {
namespace clangd {
// Implemented in Check.cpp.
-bool check(const llvm::StringRef File, const ThreadsafeFS &TFS,
- const ClangdLSPServer::Options &Opts);
+bool check(const llvm::StringRef File,
+ llvm::function_ref<bool(const Position &)> ShouldCheckLine,
+ const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts);
namespace {
@@ -347,6 +348,17 @@ opt<Path> CheckFile{
ValueOptional,
};
+opt<std::string> CheckFileLines{
+ "check-lines",
+ cat(Misc),
+ desc("If specified, limits the range of tokens in -check file on which "
+ "various features are tested. Example --check-lines=3-7 restricts "
+ "testing to lines 3 to 7 (inclusive) or --check-lines=5 to restrict "
+ "to one line. Default is testing entire file."),
+ init(""),
+ ValueOptional,
+};
+
enum PCHStorageFlag { Disk, Memory };
opt<PCHStorageFlag> PCHStorage{
"pch-storage",
@@ -883,10 +895,33 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
llvm::SmallString<256> Path;
llvm::sys::fs::real_path(CheckFile, Path, /*expand_tilde=*/true);
log("Entering check mode (no LSP server)");
- return check(Path, TFS, Opts)
+ uint32_t Begin = 0, End = std::numeric_limits<uint32_t>::max();
+ if (!CheckFileLines.empty()) {
+ StringRef RangeStr(CheckFileLines);
+ bool ParseError = RangeStr.consumeInteger(0, Begin);
+ if (RangeStr.empty()) {
+ End = Begin;
+ } else {
+ ParseError |= !RangeStr.consume_front("-");
+ ParseError |= RangeStr.consumeInteger(0, End);
+ }
+ if (ParseError || !RangeStr.empty()) {
+ elog("Invalid --check-line specified. Use Begin-End format, e.g. 3-17");
+ return 1;
+ }
+ }
+ auto ShouldCheckLine = [&](const Position &Pos) {
+ uint32_t Line = Pos.line + 1; // Position::line is 0-based.
+ return Line >= Begin && Line <= End;
+ };
+ return check(Path, ShouldCheckLine, TFS, Opts)
? 0
: static_cast<int>(ErrorResultCode::CheckFailed);
}
+ if (!CheckFileLines.empty()) {
+ elog("--check-lines requires --check");
+ return 1;
+ }
// Initialize and run ClangdLSPServer.
// Change stdin to binary to not lose \r\n on windows.
More information about the cfe-commits
mailing list