forked from OSchip/llvm-project
[clangd] Add metrics for selection tree and recovery expressions.
Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D79701
This commit is contained in:
parent
58f1417ebc
commit
774acdfb8c
|
@ -9,6 +9,7 @@
|
|||
#include "Selection.h"
|
||||
#include "SourceCode.h"
|
||||
#include "support/Logger.h"
|
||||
#include "support/Trace.h"
|
||||
#include "clang/AST/ASTTypeTraits.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
@ -35,6 +36,21 @@ namespace {
|
|||
using Node = SelectionTree::Node;
|
||||
using ast_type_traits::DynTypedNode;
|
||||
|
||||
// Measure the fraction of selections that were enabled by recovery AST.
|
||||
void recordMetrics(const SelectionTree &S) {
|
||||
static constexpr trace::Metric SelectionUsedRecovery(
|
||||
"selection_recovery", trace::Metric::Distribution);
|
||||
const auto *Common = S.commonAncestor();
|
||||
for (const auto *N = Common; N; N = N->Parent) {
|
||||
if (N->ASTNode.get<RecoveryExpr>()) {
|
||||
SelectionUsedRecovery.record(1); // used recovery ast.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Common)
|
||||
SelectionUsedRecovery.record(0); // unused.
|
||||
}
|
||||
|
||||
// An IntervalSet maintains a set of disjoint subranges of an array.
|
||||
//
|
||||
// Initially, it contains the entire array.
|
||||
|
@ -774,6 +790,7 @@ SelectionTree::SelectionTree(ASTContext &AST, const syntax::TokenBuffer &Tokens,
|
|||
.printToString(SM));
|
||||
Nodes = SelectionVisitor::collect(AST, Tokens, PrintPolicy, Begin, End, FID);
|
||||
Root = Nodes.empty() ? nullptr : &Nodes.front();
|
||||
recordMetrics(*this);
|
||||
dlog("Built selection tree\n{0}", *this);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Selection.h"
|
||||
#include "SourceCode.h"
|
||||
#include "TestTU.h"
|
||||
#include "support/TestTracer.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "gmock/gmock.h"
|
||||
|
@ -390,6 +391,7 @@ TEST(SelectionTest, CommonAncestor) {
|
|||
)cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
|
||||
};
|
||||
for (const Case &C : Cases) {
|
||||
trace::TestTracer Tracer;
|
||||
Annotations Test(C.Code);
|
||||
|
||||
TestTU TU;
|
||||
|
@ -407,6 +409,7 @@ TEST(SelectionTest, CommonAncestor) {
|
|||
if (Test.ranges().empty()) {
|
||||
// If no [[range]] is marked in the example, there should be no selection.
|
||||
EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T;
|
||||
EXPECT_THAT(Tracer.takeMetric("selection_recovery"), testing::IsEmpty());
|
||||
} else {
|
||||
// If there is an expected selection, common ancestor should exist
|
||||
// with the appropriate node type.
|
||||
|
@ -422,6 +425,8 @@ TEST(SelectionTest, CommonAncestor) {
|
|||
// and no nodes outside it are selected.
|
||||
EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
|
||||
<< C.Code;
|
||||
EXPECT_THAT(Tracer.takeMetric("selection_recovery"),
|
||||
testing::ElementsAreArray({0}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,6 +441,20 @@ TEST(SelectionTest, InjectedClassName) {
|
|||
EXPECT_FALSE(D->isInjectedClassName());
|
||||
}
|
||||
|
||||
TEST(SelectionTree, Metrics) {
|
||||
const char *Code = R"cpp(
|
||||
// error-ok: testing behavior on recovery expression
|
||||
int foo();
|
||||
int foo(int, int);
|
||||
int x = fo^o(42);
|
||||
)cpp";
|
||||
auto AST = TestTU::withCode(Annotations(Code).code()).build();
|
||||
trace::TestTracer Tracer;
|
||||
auto T = makeSelectionTree(Code, AST);
|
||||
EXPECT_THAT(Tracer.takeMetric("selection_recovery"),
|
||||
testing::ElementsAreArray({1}));
|
||||
}
|
||||
|
||||
// FIXME: Doesn't select the binary operator node in
|
||||
// #define FOO(X) X + 1
|
||||
// int a, b = [[FOO(a)]];
|
||||
|
|
Loading…
Reference in New Issue