Skip to content

Commit a506304

Browse files
committed
chore: Initial clean up of the Scope and Symbol classes
1 parent 70cec06 commit a506304

File tree

11 files changed

+178
-116
lines changed

11 files changed

+178
-116
lines changed

src/lsp/cxx/lsp/cxx_document.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ void CxxDocument::parse(std::string source) {
259259

260260
if (auto classType = type_cast<ClassType>(objectType)) {
261261
auto classSymbol = classType->symbol();
262-
for (auto member : classSymbol->members()) {
262+
for (auto member : classSymbol->scope()->symbols()) {
263263
if (!member->name()) continue;
264264
auto item = d->completionItems.emplace_back();
265265
item.label(to_string(member->name()));

src/parser/cxx/name_lookup.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ auto Lookup::lookupHelper(Scope* scope, const Name* name,
8383

8484
cache.insert(scope);
8585

86-
for (auto symbol : scope->get(name)) {
86+
for (auto symbol : scope->find(name)) {
8787
return symbol;
8888
}
8989

src/parser/cxx/parser.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <cxx/name_printer.h>
3030
#include <cxx/names.h>
3131
#include <cxx/scope.h>
32+
#include <cxx/symbol_chain_view.h>
3233
#include <cxx/symbol_instantiation.h>
3334
#include <cxx/symbols.h>
3435
#include <cxx/token.h>
@@ -754,7 +755,7 @@ struct Parser::DeclareSymbol {
754755

755756
void operator()(Symbol* symbol) {
756757
if (auto f = symbol_cast<FunctionSymbol>(symbol)) {
757-
for (Symbol* candidate : scope_->get(symbol->name())) {
758+
for (Symbol* candidate : scope_->find(symbol->name())) {
758759
if (auto currentFunction = symbol_cast<FunctionSymbol>(candidate)) {
759760
auto ovl =
760761
control()->newOverloadSetSymbol(candidate->enclosingScope(), {});
@@ -4561,8 +4562,8 @@ auto Parser::enterOrCreateNamespace(const Identifier* identifier,
45614562
if (!identifier) {
45624563
namespaceSymbol = parentNamespace->unnamedNamespace();
45634564
} else {
4564-
auto resolved =
4565-
parentScope->get(identifier) | std::views::filter(&Symbol::isNamespace);
4565+
auto resolved = parentScope->find(identifier) |
4566+
std::views::filter(&Symbol::isNamespace);
45664567
if (std::ranges::distance(resolved) == 1) {
45674568
namespaceSymbol =
45684569
symbol_cast<NamespaceSymbol>(*std::ranges::begin(resolved));
@@ -9309,7 +9310,7 @@ auto Parser::parse_class_head(ClassHead& classHead) -> bool {
93099310

93109311
if (id && !isTemplateSpecialization) {
93119312
for (auto previous :
9312-
scope_->get(id) | std::views::filter(&Symbol::isClass)) {
9313+
scope_->find(id) | std::views::filter(&Symbol::isClass)) {
93139314
if (auto previousClass = symbol_cast<ClassSymbol>(previous)) {
93149315
if (previousClass->isComplete()) {
93159316
parse_error(classHead.name->firstSourceLocation(),
@@ -11272,7 +11273,7 @@ auto Parser::convertName(UnqualifiedIdAST* id) -> const Name* {
1127211273
}
1127311274
auto Parser::getFunction(Scope* scope, const Name* name, const Type* type)
1127411275
-> FunctionSymbol* {
11275-
for (auto candidate : scope->get(name)) {
11276+
for (auto candidate : scope->find(name)) {
1127611277
if (auto function = symbol_cast<FunctionSymbol>(candidate)) {
1127711278
if (control_->is_same(function->type(), type)) {
1127811279
return function;

src/parser/cxx/scope.cc

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919
// SOFTWARE.
2020

21-
#include <cxx/names.h>
2221
#include <cxx/scope.h>
22+
23+
// cxx
24+
#include <cxx/names.h>
2325
#include <cxx/symbols.h>
2426

2527
#include <algorithm>
@@ -70,17 +72,6 @@ struct AddTemplateSymbol {
7072

7173
} // namespace
7274

73-
auto Scope::MemberIterator::operator++() -> MemberIterator& {
74-
symbol_ = symbol_->next();
75-
return *this;
76-
}
77-
78-
auto Scope::MemberIterator::operator++(int) -> MemberIterator {
79-
auto it = *this;
80-
symbol_ = symbol_->next();
81-
return it;
82-
}
83-
8475
Scope::Scope(Scope* parent) : parent_(parent) {}
8576

8677
Scope::~Scope() {}
@@ -163,25 +154,20 @@ void Scope::replaceSymbol(Symbol* symbol, Symbol* newSymbol) {
163154
}
164155
}
165156

166-
auto Scope::usingDirectives() const -> const std::vector<Scope*>& {
167-
return usingDirectives_;
168-
}
169-
170157
void Scope::addUsingDirective(Scope* scope) {
171158
usingDirectives_.push_back(scope);
172159
}
173160

174-
auto Scope::getHelper(const Name* name) const
175-
-> std::pair<MemberIterator, MemberIterator> {
161+
auto Scope::find(const Name* name) const -> SymbolChainView {
176162
if (!symbols_.empty()) {
177163
const auto h = std::hash<const void*>{}(name) % buckets_.size();
178164
for (auto symbol = buckets_[h]; symbol; symbol = symbol->link_) {
179165
if (symbol->name() == name) {
180-
return {MemberIterator{symbol}, MemberIterator{}};
166+
return SymbolChainView{symbol};
181167
}
182168
}
183169
}
184-
return {};
170+
return SymbolChainView{nullptr};
185171
}
186172

187173
} // namespace cxx

src/parser/cxx/scope.h

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,68 +21,46 @@
2121
#pragma once
2222

2323
#include <cxx/names_fwd.h>
24+
#include <cxx/symbol_chain_view.h>
25+
#include <cxx/symbols.h>
2426
#include <cxx/symbols_fwd.h>
2527
#include <cxx/types_fwd.h>
2628

27-
#include <ranges>
2829
#include <vector>
2930

3031
namespace cxx {
3132

33+
class SymbolChainView;
34+
3235
class Scope {
3336
public:
34-
class MemberIterator {
35-
public:
36-
using value_type = Symbol*;
37-
using difference_type = std::ptrdiff_t;
38-
39-
MemberIterator() = default;
40-
explicit MemberIterator(Symbol* symbol) : symbol_(symbol) {}
41-
42-
auto operator<=>(const MemberIterator&) const = default;
43-
44-
auto operator*() const -> Symbol* { return symbol_; }
45-
auto operator++() -> MemberIterator&;
46-
auto operator++(int) -> MemberIterator;
47-
48-
private:
49-
Symbol* symbol_ = nullptr;
50-
};
51-
5237
explicit Scope(Scope* parent);
5338
~Scope();
5439

5540
[[nodiscard]] auto isEnumScope() const -> bool;
5641
[[nodiscard]] auto isTemplateParametersScope() const -> bool;
57-
58-
[[nodiscard]] auto parent() const -> Scope* { return parent_; }
59-
void setParent(Scope* parent) { parent_ = parent; }
60-
6142
[[nodiscard]] auto enclosingNonTemplateParametersScope() const -> Scope*;
6243

44+
[[nodiscard]] auto parent() const -> Scope* { return parent_; }
6345
[[nodiscard]] auto owner() const -> ScopedSymbol* { return owner_; }
64-
void setOwner(ScopedSymbol* owner) { owner_ = owner; }
6546

66-
[[nodiscard]] auto symbols() const -> const std::vector<Symbol*>& {
67-
return symbols_;
68-
}
47+
[[nodiscard]] auto symbols() const { return std::views::all(symbols_); }
6948

70-
[[nodiscard]] auto get(const Name* name) const {
71-
auto [first, last] = getHelper(name);
72-
return std::ranges::subrange(first, last);
49+
[[nodiscard]] auto usingDirectives() const {
50+
return std::views::all(usingDirectives_);
7351
}
7452

75-
void addSymbol(Symbol* symbol);
76-
void replaceSymbol(Symbol* symbol, Symbol* newSymbol);
53+
[[nodiscard]] auto find(const Name* name) const -> SymbolChainView;
7754

78-
[[nodiscard]] auto usingDirectives() const -> const std::vector<Scope*>&;
55+
void setParent(Scope* parent) { parent_ = parent; }
56+
void setOwner(ScopedSymbol* owner) { owner_ = owner; }
7957

58+
void addSymbol(Symbol* symbol);
8059
void addUsingDirective(Scope* scope);
8160

82-
private:
83-
[[nodiscard]] auto getHelper(const Name* name) const
84-
-> std::pair<MemberIterator, MemberIterator>;
61+
void replaceSymbol(Symbol* symbol, Symbol* newSymbol);
8562

63+
private:
8664
void rehash();
8765

8866
private:
@@ -93,4 +71,41 @@ class Scope {
9371
std::vector<Scope*> usingDirectives_;
9472
};
9573

74+
namespace views {
75+
76+
constexpr auto class_or_namespaces =
77+
std::views::filter(&Symbol::isClassOrNamespace) |
78+
std::views::transform(
79+
[](Symbol* s) { return static_cast<ScopedSymbol*>(s); });
80+
81+
constexpr auto enum_or_scoped_enums =
82+
std::views::filter(&Symbol::isEnumOrScopedEnum) |
83+
std::views::transform(
84+
[](Symbol* s) { return static_cast<ScopedSymbol*>(s); });
85+
86+
constexpr const auto namespaces =
87+
std::views::filter(&Symbol::isNamespace) |
88+
std::views::transform(symbol_cast<NamespaceSymbol>);
89+
90+
constexpr auto concepts = std::views::filter(&Symbol::isConcept) |
91+
std::views::transform(symbol_cast<ConceptSymbol>);
92+
93+
constexpr auto classes = std::views::filter(&Symbol::isClass) |
94+
std::views::transform(symbol_cast<ClassSymbol>);
95+
96+
constexpr auto enums = std::views::filter(&Symbol::isEnum) |
97+
std::views::transform(symbol_cast<EnumSymbol>);
98+
99+
constexpr auto scoped_enums =
100+
std::views::filter(&Symbol::isScopedEnum) |
101+
std::views::transform(symbol_cast<ScopedEnumSymbol>);
102+
103+
constexpr auto functions = std::views::filter(&Symbol::isFunction) |
104+
std::views::transform(symbol_cast<FunctionSymbol>);
105+
106+
constexpr auto variables = std::views::filter(&Symbol::isVariable) |
107+
std::views::transform(symbol_cast<VariableSymbol>);
108+
109+
} // namespace views
110+
96111
} // namespace cxx
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2024 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include <cxx/symbol_chain_view.h>
22+
#include <cxx/symbols.h>
23+
24+
namespace cxx {
25+
26+
auto SymbolChainView::Generator::operator++() -> Generator& {
27+
symbol_ = symbol_->next();
28+
return *this;
29+
}
30+
31+
} // namespace cxx

src/parser/cxx/symbol_chain_view.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) 2024 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#pragma once
22+
23+
#include <cxx/symbols_fwd.h>
24+
25+
#include <ranges>
26+
27+
namespace cxx {
28+
29+
class SymbolChainView : public std::ranges::view_interface<SymbolChainView> {
30+
public:
31+
explicit SymbolChainView(Symbol* symbol) : symbol_{symbol} {}
32+
33+
auto begin() const { return Generator{symbol_}; }
34+
auto end() const { return std::default_sentinel; }
35+
36+
private:
37+
class Generator {
38+
public:
39+
using difference_type = std::ptrdiff_t;
40+
using value_type = Symbol*;
41+
42+
explicit Generator(Symbol* symbol) : symbol_(symbol) {}
43+
44+
auto operator*() const -> Symbol* { return symbol_; }
45+
46+
auto operator++() -> Generator&;
47+
48+
auto operator++(int) -> Generator {
49+
auto it = *this;
50+
++*this;
51+
return it;
52+
}
53+
54+
auto operator==(const std::default_sentinel_t&) const -> bool {
55+
return symbol_ == nullptr;
56+
}
57+
58+
private:
59+
Symbol* symbol_ = nullptr;
60+
};
61+
62+
private:
63+
Symbol* symbol_;
64+
};
65+
66+
} // namespace cxx

0 commit comments

Comments
 (0)