Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from llvm:master #38

Merged
merged 2 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export class SemanticHighlightingFeature implements vscodelc.StaticFeature {
// highlighter being created.
this.highlighter = new Highlighter(this.scopeLookupTable);
this.subscriptions.push(vscode.Disposable.from(this.highlighter));
// Adds a listener to reload the theme when it changes.
this.subscriptions.push(
vscode.workspace.onDidChangeConfiguration((conf) => {
if (!conf.affectsConfiguration('workbench.colorTheme'))
return;
this.loadCurrentTheme();
}));
this.loadCurrentTheme();
// Event handling for handling with TextDocuments/Editors lifetimes.
this.subscriptions.push(vscode.window.onDidChangeVisibleTextEditors(
Expand Down
167 changes: 33 additions & 134 deletions clang-tools-extra/clangd/unittests/TweakTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#include "gtest/gtest.h"
#include <cassert>

using llvm::Failed;
using llvm::Succeeded;
using ::testing::AllOf;
using ::testing::HasSubstr;
using ::testing::StartsWith;
Expand All @@ -33,100 +31,6 @@ namespace clang {
namespace clangd {
namespace {

// FIXME(sammccall): migrate the rest of the tests to use TweakTesting.h and
// remove these helpers.
std::string markRange(llvm::StringRef Code, Range R) {
size_t Begin = llvm::cantFail(positionToOffset(Code, R.start));
size_t End = llvm::cantFail(positionToOffset(Code, R.end));
assert(Begin <= End);
if (Begin == End) // Mark a single point.
return (Code.substr(0, Begin) + "^" + Code.substr(Begin)).str();
// Mark a range.
return (Code.substr(0, Begin) + "[[" + Code.substr(Begin, End - Begin) +
"]]" + Code.substr(End))
.str();
}

void checkAvailable(StringRef ID, llvm::StringRef Input, bool Available) {
Annotations Code(Input);
ASSERT_TRUE(0 < Code.points().size() || 0 < Code.ranges().size())
<< "no points of interest specified";
TestTU TU;
TU.Filename = "foo.cpp";
TU.Code = Code.code();

ParsedAST AST = TU.build();

auto CheckOver = [&](Range Selection) {
unsigned Begin = cantFail(positionToOffset(Code.code(), Selection.start));
unsigned End = cantFail(positionToOffset(Code.code(), Selection.end));
auto T = prepareTweak(ID, Tweak::Selection(AST, Begin, End));
if (Available)
EXPECT_THAT_EXPECTED(T, Succeeded())
<< "code is " << markRange(Code.code(), Selection);
else
EXPECT_THAT_EXPECTED(T, Failed())
<< "code is " << markRange(Code.code(), Selection);
};
for (auto P : Code.points())
CheckOver(Range{P, P});
for (auto R : Code.ranges())
CheckOver(R);
}

/// Checks action is available at every point and range marked in \p Input.
void checkAvailable(StringRef ID, llvm::StringRef Input) {
return checkAvailable(ID, Input, /*Available=*/true);
}

/// Same as checkAvailable, but checks the action is not available.
void checkNotAvailable(StringRef ID, llvm::StringRef Input) {
return checkAvailable(ID, Input, /*Available=*/false);
}

llvm::Expected<Tweak::Effect> apply(StringRef ID, llvm::StringRef Input) {
Annotations Code(Input);
Range SelectionRng;
if (Code.points().size() != 0) {
assert(Code.ranges().size() == 0 &&
"both a cursor point and a selection range were specified");
SelectionRng = Range{Code.point(), Code.point()};
} else {
SelectionRng = Code.range();
}
TestTU TU;
TU.Filename = "foo.cpp";
TU.Code = Code.code();

ParsedAST AST = TU.build();
unsigned Begin = cantFail(positionToOffset(Code.code(), SelectionRng.start));
unsigned End = cantFail(positionToOffset(Code.code(), SelectionRng.end));
Tweak::Selection S(AST, Begin, End);

auto T = prepareTweak(ID, S);
if (!T)
return T.takeError();
return (*T)->apply(S);
}

llvm::Expected<std::string> applyEdit(StringRef ID, llvm::StringRef Input) {
auto Effect = apply(ID, Input);
if (!Effect)
return Effect.takeError();
if (!Effect->ApplyEdit)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"No replacements");
Annotations Code(Input);
return applyAllReplacements(Code.code(), *Effect->ApplyEdit);
}

void checkTransform(llvm::StringRef ID, llvm::StringRef Input,
std::string Output) {
auto Result = applyEdit(ID, Input);
ASSERT_TRUE(bool(Result)) << llvm::toString(Result.takeError()) << Input;
EXPECT_EQ(Output, std::string(*Result)) << Input;
}

TWEAK_TEST(SwapIfBranches);
TEST_F(SwapIfBranchesTest, Test) {
Context = Function;
Expand Down Expand Up @@ -215,9 +119,9 @@ TEST_F(DumpRecordLayoutTest, Test) {
AllOf(StartsWith("message:"), HasSubstr("0 | int x")));
}

TEST(TweaksTest, ExtractVariable) {
llvm::StringLiteral ID = "ExtractVariable";
checkAvailable(ID, R"cpp(
TWEAK_TEST(ExtractVariable);
TEST_F(ExtractVariableTest, Test) {
const char *AvailableCases = R"cpp(
int xyz(int a = 1) {
struct T {
int bar(int a = 1);
Expand Down Expand Up @@ -255,16 +159,19 @@ TEST(TweaksTest, ExtractVariable) {
a = [[1]];
while(a < [[3]]);
}
)cpp");
// Should not crash.
checkNotAvailable(ID, R"cpp(
)cpp";
EXPECT_AVAILABLE(AvailableCases);

const char *NoCrashCases = R"cpp(
template<typename T, typename ...Args>
struct Test<T, Args...> {
Test(const T &v) :val[[(^]]) {}
T val;
};
)cpp");
checkNotAvailable(ID, R"cpp(
)cpp";
EXPECT_UNAVAILABLE(NoCrashCases);

const char *UnavailableCases = R"cpp(
int xyz(int a = [[1]]) {
struct T {
int bar(int a = [[1]]);
Expand Down Expand Up @@ -306,7 +213,9 @@ TEST(TweaksTest, ExtractVariable) {
label:
a = [[1]];
}
)cpp");
)cpp";
EXPECT_UNAVAILABLE(UnavailableCases);

// vector of pairs of input and output strings
const std::vector<std::pair<llvm::StringLiteral, llvm::StringLiteral>>
InputOutputs = {
Expand Down Expand Up @@ -482,38 +391,28 @@ TEST(TweaksTest, ExtractVariable) {
})cpp"},
};
for (const auto &IO : InputOutputs) {
checkTransform(ID, IO.first, IO.second);
EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
}
}

TEST(TweaksTest, AnnotateHighlightings) {
llvm::StringLiteral ID = "AnnotateHighlightings";
checkAvailable(ID, "^vo^id^ ^f(^) {^}^"); // available everywhere.
checkAvailable(ID, "[[int a; int b;]]");
const char *Input = "void ^f() {}";
const char *Output = "/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f() {}";
checkTransform(ID, Input, Output);

checkTransform(ID,
R"cpp(
[[void f1();
void f2();]]
)cpp",
R"cpp(
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f1();
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f2();
)cpp");

checkTransform(ID,
R"cpp(
void f1();
void f2() {^};
)cpp",

R"cpp(
void f1();
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f2() {};
)cpp");
TWEAK_TEST(AnnotateHighlightings);
TEST_F(AnnotateHighlightingsTest, Test) {
EXPECT_AVAILABLE("^vo^id^ ^f(^) {^}^"); // available everywhere.
EXPECT_AVAILABLE("[[int a; int b;]]");
EXPECT_EQ("/* storage.type.primitive.cpp */void "
"/* entity.name.function.cpp */f() {}",
apply("void ^f() {}"));

EXPECT_EQ(apply("[[void f1(); void f2();]]"),
"/* storage.type.primitive.cpp */void "
"/* entity.name.function.cpp */f1(); "
"/* storage.type.primitive.cpp */void "
"/* entity.name.function.cpp */f2();");

EXPECT_EQ(apply("void f1(); void f2() {^}"),
"void f1(); "
"/* storage.type.primitive.cpp */void "
"/* entity.name.function.cpp */f2() {}");
}

TWEAK_TEST(ExpandMacro);
Expand Down