2017-06-15 05:32:23 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "query.h"
|
|
|
|
#include "working_files.h"
|
|
|
|
|
|
|
|
#include <optional.h>
|
|
|
|
|
2018-02-24 00:12:39 +00:00
|
|
|
Maybe<Use> GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym);
|
|
|
|
Maybe<Use> GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym);
|
2018-02-10 08:19:17 +00:00
|
|
|
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
2018-02-11 18:25:37 +00:00
|
|
|
SymbolIdx sym);
|
2018-02-09 05:11:35 +00:00
|
|
|
|
2018-02-23 23:27:21 +00:00
|
|
|
// Get defining declaration (if exists) or an arbitrary declaration (otherwise) for each id.
|
|
|
|
std::vector<Use> GetDeclarations(QueryDatabase* db, const std::vector<QueryFuncId>& ids);
|
|
|
|
std::vector<Use> GetDeclarations(QueryDatabase* db, const std::vector<QueryTypeId>& ids);
|
|
|
|
std::vector<Use> GetDeclarations(QueryDatabase* db, const std::vector<QueryVarId>& ids);
|
2018-02-10 20:53:18 +00:00
|
|
|
|
2018-02-23 23:27:21 +00:00
|
|
|
// Get non-defining declarations.
|
|
|
|
std::vector<Use> GetNonDefDeclarations(QueryDatabase* db, SymbolIdx sym);
|
2017-12-20 06:20:44 +00:00
|
|
|
|
2018-02-27 04:31:08 +00:00
|
|
|
std::vector<Use> GetUsesForAllBases(QueryDatabase* db, QueryFunc& root);
|
|
|
|
std::vector<Use> GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root);
|
2017-09-22 01:14:57 +00:00
|
|
|
optional<lsPosition> GetLsPosition(WorkingFile* working_file,
|
|
|
|
const Position& position);
|
2017-06-15 05:32:23 +00:00
|
|
|
optional<lsRange> GetLsRange(WorkingFile* working_file, const Range& location);
|
2017-09-22 01:14:57 +00:00
|
|
|
lsDocumentUri GetLsDocumentUri(QueryDatabase* db,
|
|
|
|
QueryFileId file_id,
|
|
|
|
std::string* path);
|
2017-06-15 05:32:23 +00:00
|
|
|
lsDocumentUri GetLsDocumentUri(QueryDatabase* db, QueryFileId file_id);
|
2018-02-09 05:11:35 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
|
|
|
WorkingFiles* working_files,
|
2018-02-12 04:22:47 +00:00
|
|
|
Use use);
|
2018-02-11 01:50:44 +00:00
|
|
|
optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
|
|
|
WorkingFiles* working_files,
|
|
|
|
Use use,
|
2018-02-21 04:26:17 +00:00
|
|
|
bool container);
|
|
|
|
std::vector<lsLocationEx> GetLsLocationExs(QueryDatabase* db,
|
|
|
|
WorkingFiles* working_files,
|
|
|
|
const std::vector<Use>& refs,
|
|
|
|
bool container,
|
|
|
|
int limit);
|
2017-06-15 05:32:23 +00:00
|
|
|
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
2017-09-22 01:14:57 +00:00
|
|
|
optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|
|
|
WorkingFiles* working_files,
|
2018-02-11 18:25:37 +00:00
|
|
|
SymbolIdx sym,
|
2017-12-19 05:31:19 +00:00
|
|
|
bool use_short_name);
|
2017-06-15 05:32:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|
|
|
QueryFile* file,
|
2017-12-20 06:20:44 +00:00
|
|
|
lsPosition position);
|
2017-12-24 01:30:52 +00:00
|
|
|
|
2018-02-20 23:40:31 +00:00
|
|
|
template <typename Fn>
|
2018-02-21 01:50:48 +00:00
|
|
|
void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) {
|
2018-02-20 23:40:31 +00:00
|
|
|
switch (sym.kind) {
|
|
|
|
case SymbolKind::Invalid:
|
|
|
|
case SymbolKind::File:
|
|
|
|
break;
|
|
|
|
case SymbolKind::Func:
|
2018-02-21 01:50:48 +00:00
|
|
|
fn(db->GetFunc(sym));
|
2018-02-20 23:40:31 +00:00
|
|
|
break;
|
|
|
|
case SymbolKind::Type:
|
2018-02-21 01:50:48 +00:00
|
|
|
fn(db->GetType(sym));
|
2018-02-20 23:40:31 +00:00
|
|
|
break;
|
|
|
|
case SymbolKind::Var:
|
2018-02-21 01:50:48 +00:00
|
|
|
fn(db->GetVar(sym));
|
2018-02-20 23:40:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-21 01:50:48 +00:00
|
|
|
template <typename Fn>
|
|
|
|
void EachEntityDef(QueryDatabase* db, SymbolIdx sym, Fn&& fn) {
|
|
|
|
WithEntity(db, sym, [&](const auto& entity) {
|
|
|
|
for (auto& def : entity.def)
|
|
|
|
if (!fn(def))
|
|
|
|
break;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Fn>
|
2018-02-23 23:27:21 +00:00
|
|
|
void EachOccurrence(QueryDatabase* db, SymbolIdx sym, bool include_decl, Fn&& fn) {
|
2018-02-21 01:50:48 +00:00
|
|
|
WithEntity(db, sym, [&](const auto& entity) {
|
|
|
|
for (Use use : entity.uses)
|
|
|
|
fn(use);
|
|
|
|
if (include_decl) {
|
|
|
|
for (auto& def : entity.def)
|
|
|
|
if (def.spell)
|
|
|
|
fn(*def.spell);
|
|
|
|
for (Use use : entity.declarations)
|
|
|
|
fn(use);
|
|
|
|
}
|
|
|
|
});
|
2018-02-04 00:20:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-07 08:29:53 +00:00
|
|
|
lsSymbolKind GetSymbolKind(QueryDatabase* db, SymbolIdx sym);
|
|
|
|
|
2018-03-07 03:07:54 +00:00
|
|
|
template <typename Fn>
|
|
|
|
void EachOccurrenceWithParent(QueryDatabase* db,
|
|
|
|
SymbolIdx sym,
|
|
|
|
bool include_decl,
|
|
|
|
Fn&& fn) {
|
|
|
|
WithEntity(db, sym, [&](const auto& entity) {
|
|
|
|
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
|
|
|
|
for (auto& def : entity.def)
|
|
|
|
if (def.spell) {
|
2018-03-07 08:29:53 +00:00
|
|
|
parent_kind = GetSymbolKind(db, sym);
|
2018-03-07 03:07:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
for (Use use : entity.uses)
|
|
|
|
fn(use, parent_kind);
|
|
|
|
if (include_decl) {
|
|
|
|
for (auto& def : entity.def)
|
|
|
|
if (def.spell)
|
|
|
|
fn(*def.spell, parent_kind);
|
|
|
|
for (Use use : entity.declarations)
|
|
|
|
fn(use, parent_kind);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-02-04 21:43:29 +00:00
|
|
|
template <typename Q, typename Fn>
|
2018-02-22 07:34:32 +00:00
|
|
|
void EachDefinedEntity(std::vector<Q>& collection,
|
|
|
|
const std::vector<Id<Q>>& ids,
|
|
|
|
Fn&& fn) {
|
2018-02-05 18:12:28 +00:00
|
|
|
for (Id<Q> x : ids) {
|
|
|
|
Q& obj = collection[x.id];
|
2018-02-21 01:50:48 +00:00
|
|
|
if (!obj.def.empty())
|
2018-02-05 18:12:28 +00:00
|
|
|
fn(obj);
|
2018-02-04 00:20:14 +00:00
|
|
|
}
|
|
|
|
}
|