Try to keep semantic highlighting colors stable across open files.

This commit is contained in:
Jacob Dufault 2017-12-22 07:29:13 -08:00
parent 043e9a4d44
commit d7a183c796
3 changed files with 72 additions and 18 deletions

View File

@ -24,6 +24,11 @@ struct LruCache {
// Inserts an entry. Evicts the oldest unused entry if there is no space.
void Insert(const TKey& key, const std::shared_ptr<TValue>& value);
// Call |func| on existing entries. If |func| returns false iteration
// temrinates early.
template <typename TFunc>
void IterateValues(TFunc func);
private:
// There is a global score counter, when we access an element we increase
// its score to the current global value, so it has the highest overall
@ -113,6 +118,15 @@ void LruCache<TKey, TValue>::Insert(const TKey& key,
entries_.push_back(entry);
}
template <typename TKey, typename TValue>
template <typename TFunc>
void LruCache<TKey, TValue>::IterateValues(TFunc func) {
for (Entry& entry : entries_) {
if (!func(entry.value))
break;
}
}
template <typename TKey, typename TValue>
void LruCache<TKey, TValue>::IncrementScore() {
next_score_ += 1;

View File

@ -1,31 +1,60 @@
#include "semantic_highlight_symbol_cache.h"
SemanticHighlightSymbolCache::Entry::Entry(const std::string& path)
: path(path) {}
SemanticHighlightSymbolCache::Entry::Entry(
SemanticHighlightSymbolCache* all_caches,
const std::string& path)
: all_caches_(all_caches), path(path) {}
optional<int> SemanticHighlightSymbolCache::Entry::TryGetStableId(
SymbolKind kind,
const std::string& detailed_name) {
TNameToId* map = GetMapForSymbol_(kind);
auto it = map->find(detailed_name);
if (it != map->end())
return it->second;
return nullopt;
}
int SemanticHighlightSymbolCache::Entry::GetStableId(
SymbolKind kind,
const std::string& detailed_name) {
TNameToId* map = nullptr;
optional<int> id = TryGetStableId(kind, detailed_name);
if (id)
return *id;
// Create a new id. First try to find a key in another map.
all_caches_->cache_.IterateValues([&](const std::shared_ptr<Entry>& entry) {
optional<int> other_id = entry->TryGetStableId(kind, detailed_name);
if (other_id) {
id = other_id;
return false;
}
return true;
});
// Create a new id.
TNameToId* map = GetMapForSymbol_(kind);
if (!id)
id = all_caches_->next_stable_id_++;
return (*map)[detailed_name] = *id;
}
SemanticHighlightSymbolCache::Entry::TNameToId*
SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) {
switch (kind) {
case SymbolKind::Type:
map = &detailed_type_name_to_stable_id;
break;
return &detailed_type_name_to_stable_id;
case SymbolKind::Func:
map = &detailed_func_name_to_stable_id;
break;
return &detailed_func_name_to_stable_id;
case SymbolKind::Var:
map = &detailed_var_name_to_stable_id;
return &detailed_var_name_to_stable_id;
case SymbolKind::File:
case SymbolKind::Invalid:
break;
default:
assert(false);
return 0;
}
assert(map);
auto it = map->find(detailed_name);
if (it != map->end())
return it->second;
return (*map)[detailed_name] = map->size();
assert(false);
return nullptr;
}
SemanticHighlightSymbolCache::SemanticHighlightSymbolCache()
@ -33,5 +62,6 @@ SemanticHighlightSymbolCache::SemanticHighlightSymbolCache()
std::shared_ptr<SemanticHighlightSymbolCache::Entry>
SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) {
return cache_.Get(path, [&]() { return std::make_shared<Entry>(path); });
return cache_.Get(
path, [&, this]() { return std::make_shared<Entry>(this, path); });
}

View File

@ -6,10 +6,15 @@
#include <string>
#include <unordered_map>
using std::experimental::nullopt;
using std::experimental::optional;
// Caches symbols for a single file for semantic highlighting to provide
// relatively stable ids. Only supports xxx files at a time.
struct SemanticHighlightSymbolCache {
struct Entry {
SemanticHighlightSymbolCache* all_caches_ = nullptr;
// The path this cache belongs to.
std::string path;
// Detailed symbol name to stable id.
@ -18,13 +23,18 @@ struct SemanticHighlightSymbolCache {
TNameToId detailed_func_name_to_stable_id;
TNameToId detailed_var_name_to_stable_id;
explicit Entry(const std::string& path);
Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path);
optional<int> TryGetStableId(SymbolKind kind,
const std::string& detailed_name);
int GetStableId(SymbolKind kind, const std::string& detailed_name);
TNameToId* GetMapForSymbol_(SymbolKind kind);
};
constexpr static int kCacheSize = 10;
LruCache<std::string, Entry> cache_;
uint32_t next_stable_id_ = 0;
SemanticHighlightSymbolCache();