mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 17:41:58 +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_consumer.h"
|
||||||
#include "file_contents.h"
|
#include "file_contents.h"
|
||||||
#include "language_server_api.h"
|
#include "language_server_api.h"
|
||||||
|
#include "maybe.h"
|
||||||
#include "performance.h"
|
#include "performance.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
@ -165,8 +166,8 @@ struct TypeDefDefinitionData {
|
|||||||
// It's also difficult to identify a `class Foo;` statement with the clang
|
// 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
|
// indexer API (it's doable using cursor AST traversal), so we don't bother
|
||||||
// supporting the feature.
|
// supporting the feature.
|
||||||
optional<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
optional<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
// If set, then this is the same underlying type as the given value (ie, this
|
// If set, then this is the same underlying type as the given value (ie, this
|
||||||
// type comes from a using or typedef statement).
|
// type comes from a using or typedef statement).
|
||||||
@ -264,8 +265,8 @@ struct FuncDefDefinitionData {
|
|||||||
std::string detailed_name;
|
std::string detailed_name;
|
||||||
std::string hover;
|
std::string hover;
|
||||||
std::string comments;
|
std::string comments;
|
||||||
optional<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
optional<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
// Type which declares this one (ie, it is a method)
|
// Type which declares this one (ie, it is a method)
|
||||||
optional<TypeId> declaring_type;
|
optional<TypeId> declaring_type;
|
||||||
@ -390,8 +391,8 @@ struct VarDefDefinitionData {
|
|||||||
std::string comments;
|
std::string comments;
|
||||||
// TODO: definitions should be a list of ranges, since there can be more
|
// TODO: definitions should be a list of ranges, since there can be more
|
||||||
// than one - when??
|
// than one - when??
|
||||||
optional<Range> definition_spelling;
|
Maybe<Range> definition_spelling;
|
||||||
optional<Range> definition_extent;
|
Maybe<Range> definition_extent;
|
||||||
|
|
||||||
// Type of the variable.
|
// Type of the variable.
|
||||||
optional<TypeId> variable_type;
|
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
|
} // 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) {}
|
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;
|
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
|
// Position
|
||||||
void Reflect(Reader& visitor, Position& value) {
|
void Reflect(Reader& visitor, Position& value) {
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
if (visitor.Format() == SerializeFormat::Json) {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include "maybe.h"
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
struct Position {
|
struct Position {
|
||||||
int16_t line;
|
int16_t line;
|
||||||
int16_t column;
|
int16_t column;
|
||||||
@ -49,6 +49,11 @@ struct Range {
|
|||||||
};
|
};
|
||||||
MAKE_HASHABLE(Range, t.start, t.end);
|
MAKE_HASHABLE(Range, t.start, t.end);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool Maybe<Position>::has_value() const;
|
||||||
|
template <>
|
||||||
|
bool Maybe<Range>::has_value() const;
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
void Reflect(Reader& visitor, Position& value);
|
void Reflect(Reader& visitor, Position& value);
|
||||||
void Reflect(Writer& 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) {
|
for (const IndexType& type : indexed.types) {
|
||||||
if (type.def.definition_spelling.has_value())
|
if (type.def.definition_spelling.has_value())
|
||||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Definition,
|
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())
|
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)
|
for (const Range& use : type.uses)
|
||||||
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Reference, use);
|
add_all_symbols(id_map.ToSymbol(type.id), SymbolRole::Reference, use);
|
||||||
}
|
}
|
||||||
for (const IndexFunc& func : indexed.funcs) {
|
for (const IndexFunc& func : indexed.funcs) {
|
||||||
if (func.def.definition_spelling.has_value())
|
if (func.def.definition_spelling.has_value())
|
||||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Definition,
|
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())
|
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) {
|
for (const IndexFunc::Declaration& decl : func.declarations) {
|
||||||
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration,
|
add_all_symbols(id_map.ToSymbol(func.id), SymbolRole::Declaration,
|
||||||
decl.spelling);
|
decl.spelling);
|
||||||
@ -271,9 +271,9 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
|||||||
for (const IndexVar& var : indexed.vars) {
|
for (const IndexVar& var : indexed.vars) {
|
||||||
if (var.def.definition_spelling.has_value())
|
if (var.def.definition_spelling.has_value())
|
||||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Definition,
|
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())
|
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) {
|
for (const Range& decl : var.declarations) {
|
||||||
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
|
add_all_symbols(id_map.ToSymbol(var.id), SymbolRole::Declaration, decl);
|
||||||
add_outline(id_map.ToSymbol(var.id), decl);
|
add_outline(id_map.ToSymbol(var.id), decl);
|
||||||
@ -357,6 +357,11 @@ inline optional<QueryVarId> GetQueryVarIdFromUsr(QueryDatabase* query_db,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool Maybe<QueryLocation>::has_value() const {
|
||||||
|
return storage.range.start.line >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
optional<QueryFileId> QueryDatabase::GetQueryFileIdFromPath(
|
optional<QueryFileId> QueryDatabase::GetQueryFileIdFromPath(
|
||||||
const std::string& path) {
|
const std::string& path) {
|
||||||
return ::GetQueryFileIdFromPath(this, path, false);
|
return ::GetQueryFileIdFromPath(this, path, false);
|
||||||
|
@ -57,6 +57,9 @@ struct hash<::SymbolKind> {
|
|||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool Maybe<QueryLocation>::has_value() const;
|
||||||
|
|
||||||
struct SymbolIdx {
|
struct SymbolIdx {
|
||||||
SymbolKind kind;
|
SymbolKind kind;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
|
@ -45,7 +45,7 @@ optional<QueryLocation> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = db->types[symbol.idx];
|
||||||
if (type.def)
|
if (type.def)
|
||||||
return type.def->definition_spelling;
|
return *type.def->definition_spelling;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "maybe.h"
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
#include <macro_map.h>
|
#include <macro_map.h>
|
||||||
@ -211,6 +212,26 @@ void Reflect(Writer& visitor, optional<T>& value) {
|
|||||||
else
|
else
|
||||||
visitor.Null();
|
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>
|
template <typename T>
|
||||||
void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
|
void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
|
||||||
// For TypeScript optional property key?: value in the spec,
|
// 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
|
// Backport C++17 std::disjunction
|
||||||
namespace {
|
namespace {
|
||||||
template <typename B0, typename... Bs>
|
template <typename B0, typename... Bs>
|
||||||
|
Loading…
Reference in New Issue
Block a user