Skip to content

Commit

Permalink
Fix a dependency node issue that I was able to reproduce like this:
Browse files Browse the repository at this point in the history
source.cpp:

int foo()
{
    return Foo;
}
forward.h:

header.h:

enum { Foo = 1 };

CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
include_directories(${CMAKE_CURRENT_LIST_DIR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
add_library(app source.cpp)

rc -W $PWD; rc -w "indexing project. all good"; sleep 1; rc -J; sleep 1; rc -w "moving file away"; sleep 1; mv forward.h /tmp/; sleep 1; touch source.cpp ; sleep 1; rc -w "moving file back"; sleep 1; mv /tmp/forward.h .; sleep 1
; touch source.cpp; rc -w "touching header.h should reindex"; touch header.h
  • Loading branch information
Andersbakken committed May 26, 2017
1 parent 09939bc commit 3b3ace9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
18 changes: 1 addition & 17 deletions src/IndexDataMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ class IndexDataMessage : public RTagsMessage

size_t bytesWritten() const { return mBytesWritten; }
void setBytesWritten(size_t bytes) { mBytesWritten = bytes; }

SourceList sources() const { return mSources; }
void setSources(const SourceList &srcs) { mSources = srcs; }
private:
Path mProject;
uint64_t mParseTime, mId;
Expand All @@ -112,7 +109,6 @@ class IndexDataMessage : public RTagsMessage
Hash<uint32_t, Flags<FileFlag> > mFiles;
Flags<Flag> mFlags;
size_t mBytesWritten;
SourceList mSources;
};

RCT_FLAGS(IndexDataMessage::Flag);
Expand All @@ -121,25 +117,13 @@ RCT_FLAGS(IndexDataMessage::FileFlag);
inline void IndexDataMessage::encode(Serializer &serializer) const
{
serializer << mProject << mParseTime << mId << mIndexerJobFlags << mMessage
<< mFixIts << mIncludes << mDiagnostics << mFiles << mFlags << mBytesWritten
<< static_cast<uint32_t>(mSources.size());
for (const Source &source : mSources) {
source.encode(serializer, Source::IgnoreSandbox);
}
<< mFixIts << mIncludes << mDiagnostics << mFiles << mFlags << mBytesWritten;
}

inline void IndexDataMessage::decode(Deserializer &deserializer)
{
deserializer >> mProject >> mParseTime >> mId >> mIndexerJobFlags >> mMessage
>> mFixIts >> mIncludes >> mDiagnostics >> mFiles >> mFlags >> mBytesWritten;

uint32_t size;
deserializer >> size;
mSources.resize(size);
for (Source &source : mSources) {
source.decode(deserializer, Source::IgnoreSandbox);
}

}

#endif
45 changes: 36 additions & 9 deletions src/Project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ void Project::onJobFinished(const std::shared_ptr<IndexerJob> &job, const std::s

Set<uint32_t> visited = msg->visitedFiles();
updateFixIts(visited, msg->fixIts());
updateDependencies(msg);
updateDependencies(fileId, msg);
if (success) {
forEachSources([&msg, fileId](Sources &sources) -> VisitResult {
// error() << "finished with" << Location::path(fileId) << sources.contains(fileId) << msg->parseTime();
Expand Down Expand Up @@ -1027,6 +1027,7 @@ bool Project::dependsOn(uint32_t source, uint32_t header) const

void Project::removeDependencies(uint32_t fileId)
{
// error() << "removeDependencies" << Location::path(fileId);
if (DependencyNode *node = mDependencies.take(fileId)) {
for (auto it : node->includes)
it.second->dependents.remove(fileId);
Expand All @@ -1036,37 +1037,46 @@ void Project::removeDependencies(uint32_t fileId)
}
}

void Project::updateDependencies(const std::shared_ptr<IndexDataMessage> &msg)
void Project::updateDependencies(uint32_t fileId, const std::shared_ptr<IndexDataMessage> &msg)
{
// error() << "updateDependencies" << Location::path(fileId);
static_cast<void>(fileId);
const bool prune = !(msg->flags() & (IndexDataMessage::InclusionError|IndexDataMessage::ParseFailure));
// error() << "updateDependencies" << Location::path(fileId) << prune;
Set<uint32_t> includeErrors, dirty;
for (auto pair : msg->files()) {
assert(pair.first);
DependencyNode *&node = mDependencies[pair.first];
// error() << "checking deps" << Location::path(pair.first) << node;
if (!node) {
node = new DependencyNode(pair.first);
}

if (pair.second & IndexDataMessage::Visited) {
if (prune) {
for (auto it : node->includes)
it.second->dependents.remove(pair.first);
node->includes.clear();
}
if (pair.second & IndexDataMessage::IncludeError) {
node->flags |= DependencyNode::Flag_IncludeError;
includeErrors.insert(pair.first);
// error() << "got include error for" << Location::path(pair.first);
} else if (node->flags & DependencyNode::Flag_IncludeError) {
// error() << "used to have include error for" << Location::path(pair.first);
// error() << "used to have include error for" << Location::path(pair.first) << node->includes.size();
node->flags &= ~DependencyNode::Flag_IncludeError;
dirty.insert(pair.first);
// for (auto dep : node->includes) {
// dirty.insert(dep.first);
// // error() << "dirty" << Location::path(dep.first);
// }
for (auto dep : node->dependents) {
dirty.insert(dep.first);
// error() << "dirty" << Location::path(dep.first);
}
}
if (prune) {
for (auto it : node->includes) {
it.second->dependents.remove(pair.first);
// error() << "removing" << Location::path(pair.first) << "from" << Location::path(it.first);
}
error() << "Removing all includes for" << Location::path(pair.first) << node->includes.size();
node->includes.clear();
}
}
watchFile(pair.first);
}
Expand All @@ -1077,6 +1087,7 @@ void Project::updateDependencies(const std::shared_ptr<IndexDataMessage> &msg)
assert(it.second);
DependencyNode *&includer = mDependencies[it.first];
DependencyNode *&inclusiary = mDependencies[it.second];
// error() << "adding include for" << Location::path(it.first) << Location::path(it.second);
if (!includer)
includer = new DependencyNode(it.first);
if (!inclusiary)
Expand All @@ -1100,6 +1111,18 @@ void Project::updateDependencies(const std::shared_ptr<IndexDataMessage> &msg)
simple.init(shared_from_this(), dirty);
startDirtyJobs(&simple, IndexerJob::Dirty);
}
// for (auto node : mDependencies) {
// for (auto inc : node.second->includes) {
// if (!inc.second->dependents.contains(node.first)) {
// error() << "SHIT SHIT SHIT" << Location::path(inc.first) << "doesn't have" << Location::path(node.first) << "in its dependents";
// }
// }
// for (auto inc : node.second->dependents) {
// if (!inc.second->includes.contains(node.first)) {
// error() << "SHIT SHIT SHIT" << Location::path(inc.first) << "doesn't have" << Location::path(node.first) << "in its includes";
// }
// }
// }
}

int Project::reindex(const Match &match,
Expand Down Expand Up @@ -2748,6 +2771,10 @@ void Project::removeSource(uint32_t fileId)
releaseFileIds(job->visited);
Server::instance()->jobScheduler()->abort(job);
}
Set<uint32_t> file;
file.insert(fileId);
dirty(fileId);
releaseFileIds(file);
removeDependencies(fileId);
Path::rmdir(sourceFilePath(fileId));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Project.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class Project : public std::enable_shared_from_this<Project>
};
bool validate(uint32_t fileId, ValidateMode mode, String *error = 0) const;
void removeDependencies(uint32_t fileId);
void updateDependencies(const std::shared_ptr<IndexDataMessage> &msg);
void updateDependencies(uint32_t fileId, const std::shared_ptr<IndexDataMessage> &msg);
void loadFailed(uint32_t fileId);
void updateFixIts(const Set<uint32_t> &visited, FixIts &fixIts);
Diagnostics updateDiagnostics(const Diagnostics &diagnostics);
Expand Down

0 comments on commit 3b3ace9

Please sign in to comment.