Skip to content

Commit 445195b

Browse files
[clangd] Have visibleNamespaces() and getEligiblePoints() take a LangOptions rather than a FormatStyle
Summary: These functions only use the FormatStyle to obtain a LangOptions via format::getFormattingLangOpts(), and some callers can more easily obtain a LangOptions more directly. Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75716
1 parent 484402a commit 445195b

File tree

5 files changed

+128
-127
lines changed

5 files changed

+128
-127
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,8 +1373,8 @@ class CodeCompleteFlow {
13731373
// - accessible scopes are determined heuristically.
13741374
// - all-scopes query if no qualifier was typed (and it's allowed).
13751375
SpecifiedScope Scopes;
1376-
Scopes.AccessibleScopes =
1377-
visibleNamespaces(Content.take_front(Offset), Style);
1376+
Scopes.AccessibleScopes = visibleNamespaces(
1377+
Content.take_front(Offset), format::getFormattingLangOpts(Style));
13781378
for (std::string &S : Scopes.AccessibleScopes)
13791379
if (!S.empty())
13801380
S.append("::"); // visibleNamespaces doesn't include trailing ::.

clang-tools-extra/clangd/SourceCode.cpp

Lines changed: 111 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,7 @@ struct NamespaceEvent {
654654
Position Pos;
655655
};
656656
// Scans C++ source code for constructs that change the visible namespaces.
657-
void parseNamespaceEvents(llvm::StringRef Code,
658-
const format::FormatStyle &Style,
657+
void parseNamespaceEvents(llvm::StringRef Code, const LangOptions &LangOpts,
659658
llvm::function_ref<void(NamespaceEvent)> Callback) {
660659

661660
// Stack of enclosing namespaces, e.g. {"clang", "clangd"}
@@ -674,114 +673,113 @@ void parseNamespaceEvents(llvm::StringRef Code,
674673
std::string NSName;
675674

676675
NamespaceEvent Event;
677-
lex(Code, format::getFormattingLangOpts(Style),
678-
[&](const syntax::Token &Tok, const SourceManager &SM) {
679-
Event.Pos = sourceLocToPosition(SM, Tok.location());
680-
switch (Tok.kind()) {
681-
case tok::kw_using:
682-
State = State == Default ? Using : Default;
683-
break;
684-
case tok::kw_namespace:
685-
switch (State) {
686-
case Using:
687-
State = UsingNamespace;
688-
break;
689-
case Default:
690-
State = Namespace;
691-
break;
692-
default:
693-
State = Default;
694-
break;
695-
}
696-
break;
697-
case tok::identifier:
698-
switch (State) {
699-
case UsingNamespace:
700-
NSName.clear();
701-
LLVM_FALLTHROUGH;
702-
case UsingNamespaceName:
703-
NSName.append(Tok.text(SM).str());
704-
State = UsingNamespaceName;
705-
break;
706-
case Namespace:
707-
NSName.clear();
708-
LLVM_FALLTHROUGH;
709-
case NamespaceName:
710-
NSName.append(Tok.text(SM).str());
711-
State = NamespaceName;
712-
break;
713-
case Using:
714-
case Default:
715-
State = Default;
716-
break;
717-
}
718-
break;
719-
case tok::coloncolon:
720-
// This can come at the beginning or in the middle of a namespace
721-
// name.
722-
switch (State) {
723-
case UsingNamespace:
724-
NSName.clear();
725-
LLVM_FALLTHROUGH;
726-
case UsingNamespaceName:
727-
NSName.append("::");
728-
State = UsingNamespaceName;
729-
break;
730-
case NamespaceName:
731-
NSName.append("::");
732-
State = NamespaceName;
733-
break;
734-
case Namespace: // Not legal here.
735-
case Using:
736-
case Default:
737-
State = Default;
738-
break;
739-
}
740-
break;
741-
case tok::l_brace:
742-
// Record which { started a namespace, so we know when } ends one.
743-
if (State == NamespaceName) {
744-
// Parsed: namespace <name> {
745-
BraceStack.push_back(true);
746-
Enclosing.push_back(NSName);
747-
Event.Trigger = NamespaceEvent::BeginNamespace;
748-
Event.Payload = llvm::join(Enclosing, "::");
749-
Callback(Event);
750-
} else {
751-
// This case includes anonymous namespaces (State = Namespace).
752-
// For our purposes, they're not namespaces and we ignore them.
753-
BraceStack.push_back(false);
754-
}
755-
State = Default;
756-
break;
757-
case tok::r_brace:
758-
// If braces are unmatched, we're going to be confused, but don't
759-
// crash.
760-
if (!BraceStack.empty()) {
761-
if (BraceStack.back()) {
762-
// Parsed: } // namespace
763-
Enclosing.pop_back();
764-
Event.Trigger = NamespaceEvent::EndNamespace;
765-
Event.Payload = llvm::join(Enclosing, "::");
766-
Callback(Event);
767-
}
768-
BraceStack.pop_back();
769-
}
770-
break;
771-
case tok::semi:
772-
if (State == UsingNamespaceName) {
773-
// Parsed: using namespace <name> ;
774-
Event.Trigger = NamespaceEvent::UsingDirective;
775-
Event.Payload = std::move(NSName);
776-
Callback(Event);
777-
}
778-
State = Default;
779-
break;
780-
default:
781-
State = Default;
782-
break;
676+
lex(Code, LangOpts, [&](const syntax::Token &Tok, const SourceManager &SM) {
677+
Event.Pos = sourceLocToPosition(SM, Tok.location());
678+
switch (Tok.kind()) {
679+
case tok::kw_using:
680+
State = State == Default ? Using : Default;
681+
break;
682+
case tok::kw_namespace:
683+
switch (State) {
684+
case Using:
685+
State = UsingNamespace;
686+
break;
687+
case Default:
688+
State = Namespace;
689+
break;
690+
default:
691+
State = Default;
692+
break;
693+
}
694+
break;
695+
case tok::identifier:
696+
switch (State) {
697+
case UsingNamespace:
698+
NSName.clear();
699+
LLVM_FALLTHROUGH;
700+
case UsingNamespaceName:
701+
NSName.append(Tok.text(SM).str());
702+
State = UsingNamespaceName;
703+
break;
704+
case Namespace:
705+
NSName.clear();
706+
LLVM_FALLTHROUGH;
707+
case NamespaceName:
708+
NSName.append(Tok.text(SM).str());
709+
State = NamespaceName;
710+
break;
711+
case Using:
712+
case Default:
713+
State = Default;
714+
break;
715+
}
716+
break;
717+
case tok::coloncolon:
718+
// This can come at the beginning or in the middle of a namespace
719+
// name.
720+
switch (State) {
721+
case UsingNamespace:
722+
NSName.clear();
723+
LLVM_FALLTHROUGH;
724+
case UsingNamespaceName:
725+
NSName.append("::");
726+
State = UsingNamespaceName;
727+
break;
728+
case NamespaceName:
729+
NSName.append("::");
730+
State = NamespaceName;
731+
break;
732+
case Namespace: // Not legal here.
733+
case Using:
734+
case Default:
735+
State = Default;
736+
break;
737+
}
738+
break;
739+
case tok::l_brace:
740+
// Record which { started a namespace, so we know when } ends one.
741+
if (State == NamespaceName) {
742+
// Parsed: namespace <name> {
743+
BraceStack.push_back(true);
744+
Enclosing.push_back(NSName);
745+
Event.Trigger = NamespaceEvent::BeginNamespace;
746+
Event.Payload = llvm::join(Enclosing, "::");
747+
Callback(Event);
748+
} else {
749+
// This case includes anonymous namespaces (State = Namespace).
750+
// For our purposes, they're not namespaces and we ignore them.
751+
BraceStack.push_back(false);
752+
}
753+
State = Default;
754+
break;
755+
case tok::r_brace:
756+
// If braces are unmatched, we're going to be confused, but don't
757+
// crash.
758+
if (!BraceStack.empty()) {
759+
if (BraceStack.back()) {
760+
// Parsed: } // namespace
761+
Enclosing.pop_back();
762+
Event.Trigger = NamespaceEvent::EndNamespace;
763+
Event.Payload = llvm::join(Enclosing, "::");
764+
Callback(Event);
783765
}
784-
});
766+
BraceStack.pop_back();
767+
}
768+
break;
769+
case tok::semi:
770+
if (State == UsingNamespaceName) {
771+
// Parsed: using namespace <name> ;
772+
Event.Trigger = NamespaceEvent::UsingDirective;
773+
Event.Payload = std::move(NSName);
774+
Callback(Event);
775+
}
776+
State = Default;
777+
break;
778+
default:
779+
State = Default;
780+
break;
781+
}
782+
});
785783
}
786784

787785
// Returns the prefix namespaces of NS: {"" ... NS}.
@@ -797,12 +795,12 @@ llvm::SmallVector<llvm::StringRef, 8> ancestorNamespaces(llvm::StringRef NS) {
797795
} // namespace
798796

799797
std::vector<std::string> visibleNamespaces(llvm::StringRef Code,
800-
const format::FormatStyle &Style) {
798+
const LangOptions &LangOpts) {
801799
std::string Current;
802800
// Map from namespace to (resolved) namespaces introduced via using directive.
803801
llvm::StringMap<llvm::StringSet<>> UsingDirectives;
804802

805-
parseNamespaceEvents(Code, Style, [&](NamespaceEvent Event) {
803+
parseNamespaceEvents(Code, LangOpts, [&](NamespaceEvent Event) {
806804
llvm::StringRef NS = Event.Payload;
807805
switch (Event.Trigger) {
808806
case NamespaceEvent::BeginNamespace:
@@ -956,14 +954,14 @@ llvm::Error reformatEdit(Edit &E, const format::FormatStyle &Style) {
956954

957955
EligibleRegion getEligiblePoints(llvm::StringRef Code,
958956
llvm::StringRef FullyQualifiedName,
959-
const format::FormatStyle &Style) {
957+
const LangOptions &LangOpts) {
960958
EligibleRegion ER;
961959
// Start with global namespace.
962960
std::vector<std::string> Enclosing = {""};
963961
// FIXME: In addition to namespaces try to generate events for function
964962
// definitions as well. One might use a closing parantheses(")" followed by an
965963
// opening brace "{" to trigger the start.
966-
parseNamespaceEvents(Code, Style, [&](NamespaceEvent Event) {
964+
parseNamespaceEvents(Code, LangOpts, [&](NamespaceEvent Event) {
967965
// Using Directives only introduces declarations to current scope, they do
968966
// not change the current namespace, so skip them.
969967
if (Event.Trigger == NamespaceEvent::UsingDirective)

clang-tools-extra/clangd/SourceCode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ llvm::StringSet<> collectWords(llvm::StringRef Content);
250250
///
251251
/// visibleNamespaces are {"foo::", "", "a::", "b::", "foo::b::"}, not "a::b::".
252252
std::vector<std::string> visibleNamespaces(llvm::StringRef Code,
253-
const format::FormatStyle &Style);
253+
const LangOptions &LangOpts);
254254

255255
/// Represents locations that can accept a definition.
256256
struct EligibleRegion {
@@ -271,7 +271,7 @@ struct EligibleRegion {
271271
/// \p FullyQualifiedName should not contain anonymous namespaces.
272272
EligibleRegion getEligiblePoints(llvm::StringRef Code,
273273
llvm::StringRef FullyQualifiedName,
274-
const format::FormatStyle &Style);
274+
const LangOptions &LangOpts);
275275

276276
struct DefinedMacro {
277277
llvm::StringRef Name;

clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,10 @@ struct InsertionPoint {
284284
// should also try to follow ordering of declarations. For example, if decls
285285
// come in order `foo, bar, baz` then this function should return some point
286286
// between foo and baz for inserting bar.
287-
llvm::Expected<InsertionPoint>
288-
getInsertionPoint(llvm::StringRef Contents, llvm::StringRef QualifiedName,
289-
const format::FormatStyle &Style) {
290-
auto Region = getEligiblePoints(Contents, QualifiedName, Style);
287+
llvm::Expected<InsertionPoint> getInsertionPoint(llvm::StringRef Contents,
288+
llvm::StringRef QualifiedName,
289+
const LangOptions &LangOpts) {
290+
auto Region = getEligiblePoints(Contents, QualifiedName, LangOpts);
291291

292292
assert(!Region.EligiblePoints.empty());
293293
// FIXME: This selection can be made smarter by looking at the definition
@@ -416,9 +416,10 @@ class DefineOutline : public Tweak {
416416
return llvm::createStringError(Buffer.getError(),
417417
Buffer.getError().message());
418418
auto Contents = Buffer->get()->getBuffer();
419-
auto InsertionPoint =
420-
getInsertionPoint(Contents, Source->getQualifiedNameAsString(),
421-
getFormatStyleForFile(*CCFile, Contents, &FS));
419+
auto LangOpts = format::getFormattingLangOpts(
420+
getFormatStyleForFile(*CCFile, Contents, &FS));
421+
auto InsertionPoint = getInsertionPoint(
422+
Contents, Source->getQualifiedNameAsString(), LangOpts);
422423
if (!InsertionPoint)
423424
return InsertionPoint.takeError();
424425

clang-tools-extra/clangd/unittests/SourceCodeTests.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,8 @@ TEST(SourceCodeTests, VisibleNamespaces) {
416416
};
417417
for (const auto &Case : Cases) {
418418
EXPECT_EQ(Case.second,
419-
visibleNamespaces(Case.first, format::getLLVMStyle()))
419+
visibleNamespaces(Case.first, format::getFormattingLangOpts(
420+
format::getLLVMStyle())))
420421
<< Case.first;
421422
}
422423
}
@@ -639,8 +640,9 @@ TEST(SourceCodeTests, GetEligiblePoints) {
639640
for (auto Case : Cases) {
640641
Annotations Test(Case.Code);
641642

642-
auto Res = getEligiblePoints(Test.code(), Case.FullyQualifiedName,
643-
format::getLLVMStyle());
643+
auto Res = getEligiblePoints(
644+
Test.code(), Case.FullyQualifiedName,
645+
format::getFormattingLangOpts(format::getLLVMStyle()));
644646
EXPECT_THAT(Res.EligiblePoints, testing::ElementsAreArray(Test.points()))
645647
<< Test.code();
646648
EXPECT_EQ(Res.EnclosingNamespace, Case.EnclosingNamespace) << Test.code();

0 commit comments

Comments
 (0)