Skip to content

Commit

Permalink
Fix removing of disappeared sources from compile_commands.json
Browse files Browse the repository at this point in the history
  • Loading branch information
Andersbakken committed Apr 12, 2016
1 parent 9e21544 commit f191aae
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 127 deletions.
3 changes: 2 additions & 1 deletion src/IndexMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class IndexMessage : public RTagsMessage
void setArguments(const String &arguments) { mArgs = arguments; }
enum Flag {
None = 0x0,
GuessFlags = 0x1
GuessFlags = 0x1,
ReloadCompilationDatabase = 0x2
};
Flags<Flag> flags() const { return mFlags; }
void setFlags(Flags<Flag> flags) { mFlags = flags; }
Expand Down
54 changes: 22 additions & 32 deletions src/Project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static void saveDependencies(DataFile &file, const Dependencies &dependencies)

Project::Project(const Path &path)
: mPath(path), mSourceFilePathBase(RTags::encodeSourceFilePath(Server::instance()->options().dataDir, path)),
mJobCounter(0), mJobsStarted(0), mMarkSources(0)
mJobCounter(0), mJobsStarted(0)
{
Path srcPath = mPath;
RTags::encodePath(srcPath);
Expand Down Expand Up @@ -796,8 +796,6 @@ void Project::index(const std::shared_ptr<IndexerJob> &job)
} else {
auto cur = mSources.find(key);
if (cur != mSources.end()) {
if (mMarkSources)
mMarkSources->insert(key);
if (!(cur->second.flags & Source::Active))
markActive(mSources.lower_bound(Source::key(job->source.fileId, 0)), cur->second.buildRootId, mSources.end());
if (cur->second.compareArguments(job->source)) {
Expand All @@ -815,9 +813,6 @@ void Project::index(const std::shared_ptr<IndexerJob> &job)
if (f != job->source.fileId)
break;

if (mMarkSources)
mMarkSources->insert(it->first);

if (it->second.compareArguments(job->source)) {
markActive(start, b, mSources.end());
// no updates
Expand All @@ -837,8 +832,6 @@ void Project::index(const std::shared_ptr<IndexerJob> &job)
}
}

if (mMarkSources)
mMarkSources->insert(key);
Source &src = mSources[key];
src = job->source;
src.flags |= Source::Active;
Expand Down Expand Up @@ -2296,13 +2289,28 @@ String Project::estimateMemory() const

void Project::setCompilationDatabaseInfo(const Path &dir,
const List<Path> &pathEnvironment,
Flags<IndexMessage::Flag> flags)
Flags<IndexMessage::Flag> flags,
const Set<uint64_t> &indexed)
{
if (!mCompilationDatabaseInfo.dir.isEmpty())
unwatch(mCompilationDatabaseInfo.dir, Watch_CompilationDatabase);
mCompilationDatabaseInfo = {
dir, Path(dir + "compile_commands.json").lastModifiedMs(), pathEnvironment, flags
dir,
Path(dir + "compile_commands.json").lastModifiedMs(),
pathEnvironment,
flags | IndexMessage::ReloadCompilationDatabase
};
if (flags & IndexMessage::ReloadCompilationDatabase) {
Sources::iterator it = mSources.begin();
while (it != mSources.end()) {
if (!indexed.contains(it->first)) {
error() << it->second.sourceFile() << "is no longer in compile_commands.json, removing";
removeSource(it++);
} else {
++it;
}
}
}
if (!mCompilationDatabaseInfo.dir.isEmpty())
watch(mCompilationDatabaseInfo.dir, Watch_CompilationDatabase);
save();
Expand All @@ -2311,29 +2319,11 @@ void Project::setCompilationDatabaseInfo(const Path &dir,
void Project::reloadCompilationDatabase()
{
if (!mCompilationDatabaseInfo.dir.isEmpty() && !Server::instance()->suspended() ) {
const uint64_t lastModified = Path(mCompilationDatabaseInfo.dir + "compile_commands.json").lastModifiedMs();
const Path file(mCompilationDatabaseInfo.dir + "compile_commands.json");
const uint64_t lastModified = file.lastModifiedMs();
if (lastModified && lastModified != mCompilationDatabaseInfo.lastModified) {
// error() << lastModified << mCompilationDatabaseInfo.lastModified;
std::shared_ptr<IndexMessage> msg(new IndexMessage);
msg->setProjectRoot(mPath);
msg->setCompilationDatabaseDir(mCompilationDatabaseInfo.dir);
msg->setPathEnvironment(mCompilationDatabaseInfo.pathEnvironment);
msg->setFlags(mCompilationDatabaseInfo.indexFlags);
error() << (mCompilationDatabaseInfo.dir + "compile_commands.json modified, reloading") << mPath;
assert(!mMarkSources);
Set<uint64_t> markSources;
mMarkSources = &markSources;
Server::instance()->onNewMessage(msg, std::shared_ptr<Connection>());
mMarkSources = 0;
Sources::iterator it = mSources.begin();
while (it != mSources.end()) {
if (!markSources.contains(it->first)) {
error() << it->second.sourceFile() << "is no longer in compile_commands.json, removing";
removeSource(it++);
} else {
++it;
}
}
RTags::loadCompileCommands(mCompilationDatabaseInfo.dir, mCompilationDatabaseInfo.pathEnvironment,
mCompilationDatabaseInfo.indexFlags, mPath);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Project.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ class Project : public std::enable_shared_from_this<Project>
Path path() const { return mPath; }
void setCompilationDatabaseInfo(const Path &dir,
const List<Path> &pathEnvironment,
Flags<IndexMessage::Flag> flags);
Flags<IndexMessage::Flag> flags,
const Set<uint64_t> &indexed = Set<uint64_t>());

bool match(const Match &match, bool *indexed = 0) const;

Expand Down Expand Up @@ -374,7 +375,6 @@ class Project : public std::enable_shared_from_this<Project>
StopWatch mTimer;
FileSystemWatcher mWatcher;
Sources mSources;
Set<uint64_t> *mMarkSources;
Hash<Path, Flags<WatchMode> > mWatchedPaths;
std::shared_ptr<FileManager> mFileManager;
FixIts mFixIts;
Expand Down
101 changes: 100 additions & 1 deletion src/RTags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@
#endif

#include "IndexDataMessage.h"
#include "IndexMessage.h"
#include "LogOutputMessage.h"
#include "QueryMessage.h"
#include "rct/Rct.h"
#include "rct/StopWatch.h"
#include "Server.h"
#include "Project.h"
#include "VisitFileMessage.h"
#include "VisitFileResponseMessage.h"

#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR > 3)
#include <clang-c/CXCompilationDatabase.h>
#endif

namespace RTags {

Path encodeSourceFilePath(const Path &dataDir, const Path &project, uint32_t fileId)
Expand Down Expand Up @@ -811,4 +815,99 @@ String typeString(const CXType &type)
ret.chop(1);
return ret;
}

class CompileCommandsOperation
{
public:
CompileCommandsOperation(const Path &d,
const List<Path> &pathEnv,
Flags<IndexMessage::Flag> f,
const Path &proot)
: dir(d), pathEnvironment(pathEnv), flags(f), projectRootOverride(proot), indexIndex(0)
{}
~CompileCommandsOperation()
{
if (project) {
project->setCompilationDatabaseInfo(dir, pathEnvironment, flags, indexed);
}
}

struct Index {
String args;
Path dir;
};


void work()
{
Server *server = Server::instance();
if (!server) {
delete this;
return;
}
const size_t max = std::min(indexIndex + 5, indexes.size());
while (indexIndex < max) {
server->index(indexes.at(indexIndex).args,
indexes.at(indexIndex).dir,
pathEnvironment,
projectRootOverride,
flags,
&project,
&indexed);
++indexIndex;
}
if (max == indexes.size()) {
EventLoop::deleteLater(this);
} else {
EventLoop::eventLoop()->callLater(std::bind(&CompileCommandsOperation::work, this));
}
}
const Path dir;
const List<Path> pathEnvironment;
const Flags<IndexMessage::Flag> flags;
const Path projectRootOverride;
Set<uint64_t> indexed;
std::shared_ptr<Project> project;
List<Index> indexes;
size_t indexIndex;
};

bool loadCompileCommands(const Path &dir,
const List<Path> &pathEnvironment,
Flags<IndexMessage::Flag> flags,
const Path &projectRootOverride)
{
#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR > 3)
CXCompilationDatabase_Error err;
CXCompilationDatabase db = clang_CompilationDatabase_fromDirectory(dir.constData(), &err);
if (err == CXCompilationDatabase_NoError) {
CXCompileCommands cmds = clang_CompilationDatabase_getAllCompileCommands(db);
const unsigned int sz = clang_CompileCommands_getSize(cmds);
CompileCommandsOperation *op = new CompileCommandsOperation(dir, pathEnvironment,
flags, projectRootOverride);
op->indexes.reserve(sz);
for (unsigned int i = 0; i < sz; ++i) {
CXCompileCommand cmd = clang_CompileCommands_getCommand(cmds, i);
String args;
CXString str = clang_CompileCommand_getDirectory(cmd);
const Path dir = clang_getCString(str);
clang_disposeString(str);
const unsigned int num = clang_CompileCommand_getNumArgs(cmd);
for (unsigned int j = 0; j < num; ++j) {
str = clang_CompileCommand_getArg(cmd, j);
args += clang_getCString(str);
clang_disposeString(str);
if (j < num - 1)
args += ' ';
}
op->indexes.push_back(CompileCommandsOperation::Index { args, dir.ensureTrailingSlash() } );
}
EventLoop::eventLoop()->callLater(std::bind(&CompileCommandsOperation::work, op));
clang_CompileCommands_dispose(cmds);
clang_CompilationDatabase_dispose(db);
return true;
}
#endif
return false;
}
}
5 changes: 5 additions & 0 deletions src/RTags.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "rct/Path.h"
#include "rct/Set.h"
#include "rct/String.h"
#include "IndexMessage.h"

class Database;
class Project;
Expand Down Expand Up @@ -531,6 +532,10 @@ enum FindAncestorFlag {
RCT_FLAGS(FindAncestorFlag);
Path findAncestor(Path path, const char *fn, Flags<FindAncestorFlag> flags);
Map<String, String> rtagsConfig(const Path &path);
bool loadCompileCommands(const Path &dir,
const List<Path> &pathEnv,
Flags<IndexMessage::Flag> f,
const Path &proot);

enum { DefinitionBit = 0x1000 };
inline CXCursorKind targetsValueKind(uint16_t val)
Expand Down
Loading

0 comments on commit f191aae

Please sign in to comment.