mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 09:31:59 +00:00
Add Maybe<T> and change definition_{spelling,extent} from optional to Maybe
sizeof(db->funcs[0].def) decreases from 248 to 232 sizeof(db->types[0].def) decreases from 272 to 256 sizeof(db->vars[0].def) decreases from 184 to 168
This commit is contained in:
parent
74f9be1d6f
commit
392cd79d04
@ -8,6 +8,7 @@
|
||||
#include "file_consumer.h"
|
||||
#include "file_contents.h"
|
||||
#include "language_server_api.h"
|
||||
#include "maybe.h"
|
||||
#include "performance.h"
|
||||
#include "position.h"
|
||||
#include "serializer.h"
|
||||
@ -165,8 +166,8 @@ struct TypeDefDefinitionData {
|
||||
// It's also difficult to identify a `class Foo;` statement with the clang
|
||||
// indexer API (it's doable using cursor AST traversal), so we don't bother
|
||||
// supporting the feature.
|
||||
optional<Range> definition_spelling;
|
||||
optional<Range> definition_extent;
|
||||
Maybe<Range> definition_spelling;
|
||||
Maybe<Range> definition_extent;
|
||||
|
||||
// If set, then this is the same underlying type as the given value (ie, this
|
||||
// type comes from a using or typedef statement).
|
||||
@ -264,8 +265,8 @@ struct FuncDefDefinitionData {
|
||||
std::string detailed_name;
|
||||
std::string hover;
|
||||
std::string comments;
|
||||
optional<Range> definition_spelling;
|
||||
optional<Range> definition_extent;
|
||||
Maybe<Range> definition_spelling;
|
||||
Maybe<Range> definition_extent;
|
||||
|
||||
// Type which declares this one (ie, it is a method)
|
||||
optional<TypeId> declaring_type;
|
||||
@ -390,8 +391,8 @@ struct VarDefDefinitionData {
|
||||
std::string comments;
|
||||
// TODO: definitions should be a list of ranges, since there can be more
|
||||
// than one - when??
|
||||
optional<Range> definition_spelling;
|
||||
optional<Range> definition_extent;
|
||||
Maybe<Range> definition_spelling;
|
||||
Maybe<Range> definition_extent;
|
||||
|
||||
// Type of the variable.
|
||||
optional<TypeId> variable_type;
|
||||
|
44
src/maybe.h
Normal file
44
src/maybe.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
template <typename T>
|
||||
class Maybe {
|
||||
T storage;
|
||||
|
||||
public:
|
||||
constexpr Maybe() = default;
|
||||
Maybe(const Maybe&) = default;
|
||||
Maybe(const T& x) : storage(x) {}
|
||||
Maybe(T&& x) : storage(std::forward<T>(x)) {}
|
||||
|
||||
Maybe& operator=(const Maybe&) = default;
|
||||
Maybe& operator=(const T& x) {
|
||||
storage = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T *operator->() const { return &storage; }
|
||||
T *operator->() { return &storage; }
|
||||
const T& operator*() const { return storage; }
|
||||
T& operator*() { return storage; }
|
||||
|
||||
bool has_value() const;
|
||||
explicit operator bool() const { return has_value(); }
|
||||
operator optional<T>() const {
|
||||
if (has_value())
|
||||
return storage;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
void operator=(optional<T>&& o) {
|
||||
storage = o ? *o : T();
|
||||
}
|
||||
|
||||
// Does not test if has_value()
|
||||
bool operator==(const Maybe& o) const {
|
||||
return storage == o.storage;
|
||||
}
|
||||
};
|
@ -11,7 +11,7 @@ const char* SkipAfter(const char* input, char skip_after) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Position::Position() : line(0), column(0) {}
|
||||
Position::Position() : line(-1), column(-1) {}
|
||||
|
||||
Position::Position(int16_t line, int16_t column) : line(line), column(column) {}
|
||||
|
||||
@ -146,6 +146,16 @@ bool Range::operator<(const Range& that) const {
|
||||
return end < that.end;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Maybe<Position>::has_value() const {
|
||||
return storage.line >= 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Maybe<Range>::has_value() const {
|
||||
return storage.start.line >= 0;
|
||||
}
|
||||
|
||||
// Position
|
||||
void Reflect(Reader& visitor, Position& value) {
|
||||
if (visitor.Format() == SerializeFormat::Json) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "maybe.h"
|
||||
#include "serializer.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
struct Position {
|
||||
int16_t line;
|
||||
int16_t column;
|
||||
@ -49,6 +49,11 @@ struct Range {
|
||||
};
|
||||
MAKE_HASHABLE(Range, t.start, t.end);
|
||||
|
||||
template <>
|
||||
bool Maybe<Position>::has_value() const;
|
||||
template <>
|
||||
bool Maybe<Range>::has_value() const;
|
||||
|
||||
// Reflection
|
||||
void Reflect(Reader& visitor, Position& value);
|
||||
void Reflect(Writer& visitor, Position& value);
|
||||
|
17
src/query.cc
17
src/query.cc
@ -233,18 +233,18 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
||||
for (const IndexType& type : indexed.types) {
|
||||
if (type.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Definition,
|
||||
type.def.definition_spelling.value());
|
||||
*type.def.definition_spelling);
|
||||
if (type.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(type.id), type.def.definition_extent.value());
|
||||
add_outline(id_map.ToSymbol(type.id), *type.def.definition_extent);
|
||||
for (const Range& use : type.uses)
|
||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Reference, use);
|
||||
}
|
||||
for (const IndexFunc& func : indexed.funcs) {
|
||||
if (func.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Definition,
|
||||
func.def.definition_spelling.value());
|
||||
*func.def.definition_spelling);
|
||||
if (func.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(func.id), func.def.definition_extent.value());
|
||||
add_outline(id_map.ToSymbol(func.id), *func.def.definition_extent);
|
||||
for (const IndexFunc::Declaration& decl : func.declarations) {
|
||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration,
|
||||
decl.spelling);
|
||||
@ -271,9 +271,9 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
||||
for (const IndexVar& var : indexed.vars) {
|
||||
if (var.def.definition_spelling.has_value())
|
||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Definition,
|
||||
var.def.definition_spelling.value());
|
||||
*var.def.definition_spelling);
|
||||
if (var.def.definition_extent.has_value())
|
||||
add_outline(id_map.ToSymbol(var.id), var.def.definition_extent.value());
|
||||
add_outline(id_map.ToSymbol(var.id), *var.def.definition_extent);
|
||||
for (const Range& decl : var.declarations) {
|
||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
|
||||
add_outline(id_map.ToSymbol(var.id), decl);
|
||||
@ -357,6 +357,11 @@ inline optional<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
|
||||
|
||||
} // namespace
|
||||
|
||||
template <>
|
||||
bool Maybe<QueryLocation>::has_value() const {
|
||||
return storage.range.start.line >= 0;
|
||||
}
|
||||
|
||||
optional<QueryFileId> QueryDatabase::GetQueryFileIdFromPath(
|
||||
const std::string& path) {
|
||||
return ::GetQueryFileIdFromPath(this, path, false);
|
||||
|
@ -57,6 +57,9 @@ struct hash<::SymbolKind> {
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
template <>
|
||||
bool Maybe<QueryLocation>::has_value() const;
|
||||
|
||||
struct SymbolIdx {
|
||||
SymbolKind kind;
|
||||
size_t idx;
|
||||
|
@ -45,7 +45,7 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
case SymbolKind::Type: {
|
||||
QueryType& type = db->types[symbol.idx];
|
||||
if (type.def)
|
||||
return type.def->definition_spelling;
|
||||
return *type.def->definition_spelling;
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "maybe.h"
|
||||
#include "port.h"
|
||||
|
||||
#include <macro_map.h>
|
||||
@ -211,6 +212,26 @@ void Reflect(Writer& visitor, optional<T>& value) {
|
||||
else
|
||||
visitor.Null();
|
||||
}
|
||||
|
||||
// The same as std::optional
|
||||
template <typename T>
|
||||
void Reflect(Reader& visitor, Maybe<T>& value) {
|
||||
if (visitor.IsNull()) {
|
||||
visitor.GetNull();
|
||||
return;
|
||||
}
|
||||
T real_value;
|
||||
Reflect(visitor, real_value);
|
||||
value = real_value;
|
||||
}
|
||||
template <typename T>
|
||||
void Reflect(Writer& visitor, Maybe<T>& value) {
|
||||
if (value)
|
||||
Reflect(visitor, *value);
|
||||
else
|
||||
visitor.Null();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
|
||||
// For TypeScript optional property key?: value in the spec,
|
||||
@ -222,6 +243,15 @@ void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
|
||||
}
|
||||
}
|
||||
|
||||
// The same as std::optional
|
||||
template <typename T>
|
||||
void ReflectMember(Writer& visitor, const char* name, Maybe<T>& value) {
|
||||
if (value.has_value() || visitor.Format() != SerializeFormat::Json) {
|
||||
visitor.Key(name);
|
||||
Reflect(visitor, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Backport C++17 std::disjunction
|
||||
namespace {
|
||||
template <typename B0, typename... Bs>
|
||||
|
Loading…
Reference in New Issue
Block a user