data: refreshing with DB

* database stores modification time of files.
* FileManager updates internal state based on database info.
* reimplemented FileManager's check if a file is in project.
* implemented clearing data of updated or removed files before reparsing the updated and added files.
This commit is contained in:
malte_langkabel
2015-09-16 18:53:33 +02:00
parent 73b1b77ca8
commit 3d94b78b8c
22 changed files with 406 additions and 109 deletions
+120 -11
View File
@@ -2,6 +2,7 @@
#include "data/graph/Node.h"
#include "data/location/TokenLocation.h"
#include "utility/logging/logging.h"
SqliteStorage::SqliteStorage(const std::string& dbFilePath)
{
@@ -68,13 +69,13 @@ Id SqliteStorage::addNode(int type, Id nameId)
return id;
}
Id SqliteStorage::addFile(Id nameId, const std::string& filePath)
Id SqliteStorage::addFile(Id nameId, const std::string& filePath, const std::string& modificationTime)
{
Id id = addNode(Node::NODE_FILE, nameId);
m_database.execDML((
"INSERT INTO file(id, path) VALUES("
+ std::to_string(id) + ", '" + filePath + "');"
"INSERT INTO file(id, path, modification_time) VALUES("
+ std::to_string(id) + ", '" + filePath + "', '" + modificationTime + "');"
).c_str());
return id;
@@ -126,6 +127,59 @@ void SqliteStorage::removeNameHierarchyElement(Id id)
).c_str());
}
void SqliteStorage::removeElementsWithLocationInFile(Id fileId)
{
m_database.execDML((
"DELETE FROM element WHERE id IN (SELECT element_id FROM source_location WHERE source_location.file_node_id == " + std::to_string(fileId) + ");"
).c_str());
}
void SqliteStorage::removeFile(Id id)
{
if (isFile(id))
{
m_database.execDML((
"DELETE FROM element WHERE id == " + std::to_string(id) + ";"
).c_str());
}
else
{
LOG_WARNING("Removing file from DB failed since there is no file element with id " + std::to_string(id));
}
}
void SqliteStorage::removeUnusedNameHierarchyElements()
{
m_database.execDML(
"DELETE FROM name_hierarchy_element WHERE NOT EXISTS (SELECT * FROM node where node.name_id == name_hierarchy_element.id);"
);
}
std::vector<StorageNode> SqliteStorage::getAllNodes() const
{
std::vector<StorageNode> nodes;
CppSQLite3Query q = m_database.execQuery(
"SELECT id, type, name_id FROM node;"
);
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const int type = q.getIntField(1, -1);
const Id nameId = q.getIntField(2, 0);
if (id != 0 && type != -1 && nameId != 0)
{
nodes.push_back(StorageNode(id, type, nameId));
}
q.nextRow();
}
return nodes;
}
bool SqliteStorage::isEdge(Id elementId) const
{
int count = m_database.execScalar(("SELECT count(*) FROM edge WHERE id = " + std::to_string(elementId) + ";").c_str());
@@ -340,7 +394,7 @@ StorageNode SqliteStorage::getNodeByName(const std::string& nodeName) const
StorageFile SqliteStorage::getFileById(const Id id) const
{
return getFirstFile(
"SELECT node.id, node.name_id, file.path FROM node INNER JOIN file ON node.id = file.id "
"SELECT node.id, node.name_id, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"WHERE node.id == " + std::to_string(id) + ";"
);
}
@@ -349,12 +403,12 @@ StorageFile SqliteStorage::getFileByName(const std::string& fileName) const
{
Id nameId = getNameHierarchyElementIdByName(fileName);
StorageFile storageFile(0, 0, "");
StorageFile storageFile(0, 0, "", "");
if (nameId != 0)
{
storageFile = getFirstFile(
"SELECT node.id, node.name_id, file.path FROM node INNER JOIN file ON node.id = file.id "
"SELECT node.id, node.name_id, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id "
"WHERE node.name_id == " + std::to_string(nameId) + ";"
);
}
@@ -362,6 +416,11 @@ StorageFile SqliteStorage::getFileByName(const std::string& fileName) const
return storageFile;
}
std::vector<StorageFile> SqliteStorage::getAllFiles() const
{
return getAllFiles("SELECT file.id, node.name_id, file.path, file.modification_time FROM file INNER JOIN node ON file.id = node.id;");
}
void SqliteStorage::setNodeType(int type, Id nodeId)
{
m_database.execDML((
@@ -390,6 +449,31 @@ Id SqliteStorage::getNameHierarchyElementIdByNodeId(const Id nodeId) const
);
}
std::vector<StorageNameHierarchyElement> SqliteStorage::getAllNameHierarchyElements() const
{
std::vector<StorageNameHierarchyElement> ret;
CppSQLite3Query q = m_database.execQuery(
"SELECT * FROM name_hierarchy_element;"
);
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const std::string name = q.getStringField(1, "");
const Id parent_id = q.getIntField(2, 0);
if (id != 0 && name != "" && parent_id != 0)
{
ret.push_back(StorageNameHierarchyElement(id, name, parent_id));
}
q.nextRow();
}
return ret;
}
NameHierarchy SqliteStorage::getNameHierarchyById(const Id id) const
{
CppSQLite3Query q = m_database.execQuery((
@@ -554,6 +638,7 @@ void SqliteStorage::setupTables()
"CREATE TABLE IF NOT EXISTS file("
"id INTEGER NOT NULL, "
"path TEXT, "
"modification_time TEXT, "
"PRIMARY KEY(id), "
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
);
@@ -589,16 +674,40 @@ StorageFile SqliteStorage::getFirstFile(const std::string& query) const
if (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id nameId = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
const Id id = q.getIntField(0, 0);
const Id nameId = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
const std::string modificationTime = q.getStringField(3, "");
if (id != 0 && nameId != 0)
{
return StorageFile(id, nameId, filePath);
return StorageFile(id, nameId, filePath, modificationTime);
}
}
return StorageFile(0, 0, "");
return StorageFile(0, 0, "", "");
}
std::vector<StorageFile> SqliteStorage::getAllFiles(const std::string& query) const
{
std::vector<StorageFile> files;
CppSQLite3Query q = m_database.execQuery(query.c_str());
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id nameId = q.getIntField(1, 0);
const std::string filePath = q.getStringField(2, "");
const std::string modificationTime = q.getStringField(3, "");
if (id != 0 && nameId != 0)
{
files.push_back(StorageFile(id, nameId, filePath, modificationTime));
}
q.nextRow();
}
return files;
}
StorageSourceLocation SqliteStorage::getFirstSourceLocation(const std::string& query) const
+10 -1
View File
@@ -28,13 +28,18 @@ public:
Id addEdge(int type, Id sourceNodeId, Id targetNodeId);
Id addNode(int type, Id nameId);
Id addFile(Id nameId, const std::string& filePath);
Id addFile(Id nameId, const std::string& filePath, const std::string& modificationTime);
int addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope);
Id addNameHierarchyElement(const std::string& name);
Id addNameHierarchyElement(const std::string& name, Id parentId);
void removeElement(Id id);
void removeNameHierarchyElement(Id id);
void removeElementsWithLocationInFile(Id fileId);
void removeFile(Id id);
void removeUnusedNameHierarchyElements();
std::vector<StorageNode> getAllNodes() const;
bool isEdge(Id elementId) const;
bool isNode(Id elementId) const;
@@ -53,6 +58,7 @@ public:
StorageFile getFileById(const Id id) const;
StorageFile getFileByName(const std::string& fileName) const;
std::vector<StorageFile> getAllFiles() const;
void setNodeType(int type, Id nodeId);
@@ -61,6 +67,8 @@ public:
Id getNameHierarchyElementIdByNodeId(const Id nodeId) const;
std::vector<StorageNameHierarchyElement> getAllNameHierarchyElements() const;
NameHierarchy getNameHierarchyById(const Id id) const;
StorageSourceLocation getSourceLocationById(const Id id) const;
@@ -79,6 +87,7 @@ private:
void setupTables();
StorageFile getFirstFile(const std::string& query) const;
std::vector<StorageFile> getAllFiles(const std::string& query) const;
StorageSourceLocation getFirstSourceLocation(const std::string& query) const;
std::vector<StorageSourceLocation> getAllSourceLocations(const std::string& query) const;
+97 -20
View File
@@ -3,9 +3,10 @@
#include <sstream>
#include <queue>
#include "utility/file/FileSystem.h"
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
#include "utility/utility.h"
#include "utility/utilityString.h"
#include "data/graph/token_component/TokenComponentAggregation.h"
#include "data/graph/token_component/TokenComponentName.h"
@@ -38,15 +39,66 @@ void Storage::clear()
m_errorLocationCollection.clear();
}
void Storage::clearFileData(const std::set<FilePath>& filePaths)
void Storage::clearFileElements(const std::set<FilePath>& filePaths)
{
// TODO: Implement this one
for (const FilePath& filePath: filePaths)
{
clearFileElements(filePath);
}
}
std::set<FilePath> Storage::getDependingFilePathsAndRemoveFileNodes(const std::set<FilePath>& filePaths)
void Storage::clearFileElements(const FilePath& filePath)
{
// TODO: Implement this one
return std::set<FilePath>();
Id fileId = m_sqliteStorage.getFileByName(filePath.fileName()).id;
if (fileId != 0)
{
m_sqliteStorage.removeElementsWithLocationInFile(fileId);
m_sqliteStorage.removeFile(fileId);
}
}
std::set<FilePath> Storage::getDependingFilePaths(const std::set<FilePath>& filePaths)
{
std::set<FilePath> dependingFilePaths;
for (const FilePath& filePath: filePaths)
{
std::set<FilePath> dependingFilePathsSubset = getDependingFilePaths(filePath);
dependingFilePaths.insert(dependingFilePathsSubset.begin(), dependingFilePathsSubset.end());
}
return dependingFilePaths;
}
std::set<FilePath> Storage::getDependingFilePaths(const FilePath& filePath)
{
std::set<FilePath> dependingFilePaths;
Id fileNodeId = m_sqliteStorage.getFileByName(filePath.fileName()).id;
std::vector<StorageEdge> incomingEdges = m_sqliteStorage.getEdgesByTargetType(
fileNodeId, Edge::typeToInt(Edge::EDGE_INCLUDE)
);
for (StorageEdge incomingEdge: incomingEdges)
{
Id dependingFileId = incomingEdge.sourceNodeId;
FilePath dependingFilePath = FilePath(m_sqliteStorage.getFileById(dependingFileId).filePath);
dependingFilePaths.insert(dependingFilePath);
std::set<FilePath> dependingFilePathsSubset = getDependingFilePaths(dependingFilePath);
dependingFilePaths.insert(dependingFilePathsSubset.begin(), dependingFilePathsSubset.end());
}
return dependingFilePaths;
}
void Storage::removeUnusedNames()
{
m_sqliteStorage.removeUnusedNameHierarchyElements();
m_tokenIndex.clear();
for (StorageNode node: m_sqliteStorage.getAllNodes())
{
m_tokenIndex.addNode(m_sqliteStorage.getNameHierarchyById(node.nameId))->addTokenId(node.id);
}
}
void Storage::logGraph() const
@@ -399,7 +451,7 @@ Id Storage::onTemplateArgumentTypeParsed(
const NameHierarchy& templateNameHierarchy)
{
Id argumentNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, argumentNameHierarchy);
// TODO add location for arg
// does not need a source location because this type that is already defined (and therefore has a location).
Id templateNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateNameHierarchy);
@@ -413,7 +465,7 @@ Id Storage::onTemplateDefaultArgumentTypeParsed(
const NameHierarchy& templateArgumentTypeNameHierarchy // actually this is the template parameter???
){
Id defaultArgumentNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, defaultArgumentTypeUsage.dataType->getTypeNameHierarchy());
// TODO add location for defarg
// does not need a source location because this type that is already defined (and therefore has a location).
Id argumentNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateArgumentTypeNameHierarchy);
@@ -427,7 +479,7 @@ Id Storage::onTemplateRecordParameterTypeParsed(
const NameHierarchy& templateRecordNameHierarchy
){
Id parameterNodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy);
// TODO add location for param
addSourceLocation(parameterNodeId, location, false);
Id recordNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateRecordNameHierarchy);
@@ -447,7 +499,7 @@ Id Storage::onTemplateRecordSpecializationParsed(
}
Id specializedNodeId = addNodeHierarchy(specializedRecordNodeType, specializedRecordNameHierarchy);
// TODO add location for specialized
addSourceLocation(specializedNodeId, location, false);
Id recordNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, specializedFromNameHierarchy);
@@ -460,7 +512,7 @@ Id Storage::onTemplateFunctionParameterTypeParsed(
const ParseLocation& location, const NameHierarchy& templateParameterTypeNameHierarchy, const ParseFunction function
){
Id parameterNodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy);
// TODO add location for parameter
addSourceLocation(parameterNodeId, location, false);
Id functionNodeId = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, function);
@@ -473,7 +525,7 @@ Id Storage::onTemplateFunctionSpecializationParsed(
const ParseLocation& location, const ParseFunction specializedFunction, const ParseFunction templateFunction
){
Id specializedNodeId = addNodeHierarchyWithDistinctSignature(Node::NODE_FUNCTION, specializedFunction);
// TODO add location for specialized
addSourceLocation(specializedNodeId, location, false);
Id functionNodeId = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, templateFunction);
@@ -482,9 +534,9 @@ Id Storage::onTemplateFunctionSpecializationParsed(
return specializedNodeId;
}
Id Storage::onFileParsed(const std::string& filePath)
Id Storage::onFileParsed(const FileInfo& fileInfo)
{
const std::string fileName = FilePath(filePath).fileName();
const std::string fileName = fileInfo.path.fileName();
Id nameHierarchyElementId = m_sqliteStorage.getNameHierarchyElementIdByName(fileName);
if (nameHierarchyElementId == 0)
@@ -495,7 +547,11 @@ Id Storage::onFileParsed(const std::string& filePath)
Id fileNodeId = m_sqliteStorage.getFileByName(fileName).id;
if (fileNodeId == 0)
{
fileNodeId = m_sqliteStorage.addFile(nameHierarchyElementId, filePath);
fileNodeId = m_sqliteStorage.addFile(
nameHierarchyElementId,
fileInfo.path.str(),
utility::timeToString(fileInfo.lastWriteTime)
);
}
NameHierarchy nameHierarchy;
@@ -505,10 +561,10 @@ Id Storage::onFileParsed(const std::string& filePath)
return fileNodeId;
}
Id Storage::onFileIncludeParsed(const ParseLocation& location, const std::string& filePath, const std::string& includedPath)
Id Storage::onFileIncludeParsed(const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo)
{
const Id fileNodeId = onFileParsed(filePath);
const Id includedFileNodeId = onFileParsed(includedPath);
const Id fileNodeId = onFileParsed(fileInfo);
const Id includedFileNodeId = onFileParsed(includedFileInfo);
addEdge(fileNodeId, includedFileNodeId, Edge::EDGE_INCLUDE, location);
@@ -556,6 +612,27 @@ Id Storage::getIdForEdgeWithName(const std::string& name) const
return m_sqliteStorage.getEdgeBySourceTargetType(sourceId, targetId, type).id;
}
std::vector<FileInfo> Storage::getInfoOnAllFiles() const
{
std::vector<FileInfo> fileInfos;
std::vector<StorageFile> storageFiles = m_sqliteStorage.getAllFiles();
for (size_t i = 0; i < storageFiles.size(); i++)
{
boost::posix_time::ptime modificationTime = boost::posix_time::not_a_date_time;
if (storageFiles[i].modificationTime != "not-a-date-time")
{
modificationTime = boost::posix_time::time_from_string(storageFiles[i].modificationTime);
}
fileInfos.push_back(FileInfo(
FilePath(storageFiles[i].filePath),
modificationTime
));
}
return fileInfos;
}
std::string Storage::getNameForNodeWithId(Id nodeId) const
{
Id nameHierarchyElementId = m_sqliteStorage.getNameHierarchyElementIdByNodeId(nodeId);
@@ -1035,11 +1112,11 @@ int Storage::addSourceLocation(int elementNodeId, const ParseLocation& location,
}
else
{
Id fileNodeId = m_sqliteStorage.getFileByName(FilePath(location.filePath).fileName()).id;
Id fileNodeId = m_sqliteStorage.getFileByName(location.filePath.fileName()).id;
if (fileNodeId == 0)
{
LOG_ERROR("No filenode created for file: " + location.filePath.str());
fileNodeId = onFileParsed(location.filePath.str()); // TODO: make onFileParsed accept filePath
fileNodeId = onFileParsed(FileSystem::getFileInfoForPath(location.filePath));
}
int locationId = m_sqliteStorage.addSourceLocation(
elementNodeId, fileNodeId, location.startLineNumber, location.startColumnNumber,
+9 -4
View File
@@ -23,8 +23,11 @@ public:
virtual ~Storage();
void clear();
void clearFileData(const std::set<FilePath>& filePaths);
std::set<FilePath> getDependingFilePathsAndRemoveFileNodes(const std::set<FilePath>& filePaths);
void clearFileElements(const std::set<FilePath>& filePaths);
void clearFileElements(const FilePath& filePath);
std::set<FilePath> getDependingFilePaths(const std::set<FilePath>& filePaths);
std::set<FilePath> getDependingFilePaths(const FilePath& filePath);
void removeUnusedNames();
void logGraph() const;
void logLocations() const;
@@ -105,14 +108,16 @@ public:
virtual Id onTemplateFunctionSpecializationParsed(
const ParseLocation& location, const ParseFunction specializedFunction, const ParseFunction templateFunction);
virtual Id onFileParsed(const std::string& filePath);
virtual Id onFileParsed(const FileInfo& fileInfo);
virtual Id onFileIncludeParsed(
const ParseLocation& location, const std::string& filePath, const std::string& includedPath);
const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo);
// StorageAccess implementation
virtual Id getIdForNodeWithName(const std::string& fullName) const;
virtual Id getIdForEdgeWithName(const std::string& name) const;
virtual std::vector<FileInfo> getInfoOnAllFiles() const;
virtual std::string getNameForNodeWithId(Id nodeId) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
virtual std::vector<SearchMatch> getAutocompletionMatches(
+3 -2
View File
@@ -30,13 +30,14 @@ struct StorageNode
struct StorageFile
{
StorageFile(Id id, Id nameId, const std::string& filePath)
: id(id), nameId(nameId), filePath(filePath)
StorageFile(Id id, Id nameId, const std::string& filePath, const std::string& modificationTime)
: id(id), nameId(nameId), filePath(filePath), modificationTime(modificationTime)
{}
Id id;
Id nameId;
std::string filePath;
std::string modificationTime;
};
struct StorageNameHierarchyElement
+3
View File
@@ -11,6 +11,7 @@
#include "data/graph/Node.h"
#include "data/search/SearchMatch.h"
struct FileInfo;
class Graph;
class TokenLocation;
class TokenLocationCollection;
@@ -24,6 +25,8 @@ public:
virtual Id getIdForNodeWithName(const std::string& name) const = 0;
virtual Id getIdForEdgeWithName(const std::string& name) const = 0;
virtual std::vector<FileInfo> getInfoOnAllFiles() const = 0;
virtual std::string getNameForNodeWithId(Id id) const = 0;
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0;
virtual std::vector<SearchMatch> getAutocompletionMatches(
+13 -2
View File
@@ -1,11 +1,12 @@
#include "data/access/StorageAccessProxy.h"
#include "utility/logging/logging.h"
#include "data/graph/Graph.h"
#include "data/location/TokenLocationCollection.h"
#include "data/location/TokenLocationFile.h"
#include "utility/logging/logging.h"
#include "utility/file/FileInfo.h"
StorageAccessProxy::StorageAccessProxy()
: m_subject(nullptr)
{
@@ -51,6 +52,16 @@ Id StorageAccessProxy::getIdForEdgeWithName(const std::string& name) const
return 0;
}
std::vector<FileInfo> StorageAccessProxy::getInfoOnAllFiles() const
{
std::vector<FileInfo> fileInfos;
if (hasSubject())
{
fileInfos = m_subject->getInfoOnAllFiles();
}
return fileInfos;
}
Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const
{
if(hasSubject())
+2
View File
@@ -16,6 +16,8 @@ public:
virtual Id getIdForNodeWithName(const std::string& name) const;
virtual Id getIdForEdgeWithName(const std::string& name) const;
virtual std::vector<FileInfo> getInfoOnAllFiles() const;
virtual std::string getNameForNodeWithId(Id id) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
virtual std::vector<SearchMatch> getAutocompletionMatches(
+3 -2
View File
@@ -6,6 +6,7 @@
#include "utility/types.h"
#include "data/name/NameHierarchy.h"
#include "utility/file/FileInfo.h"
struct ParseFunction;
struct ParseLocation;
@@ -125,9 +126,9 @@ public:
virtual Id onTemplateFunctionSpecializationParsed(
const ParseLocation& location, const ParseFunction specializedFunction, const ParseFunction templateFunction) = 0;
virtual Id onFileParsed(const std::string& filePath) = 0;
virtual Id onFileParsed(const FileInfo& fileInfo) = 0;
virtual Id onFileIncludeParsed(
const ParseLocation& location, const std::string& filePath, const std::string& includedPath) = 0;
const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo) = 0;
};
#endif // PARSER_CLIENT_H
+15 -4
View File
@@ -345,16 +345,27 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
{
clang::ClassTemplateSpecializationDecl* specializationDecl = *it;
ParseLocation specializationLocation = getParseLocationForNamedDecl(*it);
if (specializationDecl->getSpecializationKind() == clang::TSK_ImplicitInstantiation)
{
specializationLocation = getParseLocation(specializationDecl->getPointOfInstantiation());
}
NameHierarchy specializedRecordNameHierarchy = utility::getDeclNameHierarchy(specializationDecl);
ParserClient::RecordType specializedRecordType = specializationDecl->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS;
// The specializationParent can be an indirect specialization of the ClassTemplate (by specializing a partial specialization).
NameHierarchy specializationParentNameHierarchy = utility::getTemplateSpecializationParentNameHierarchy(specializationDecl);
ParserClient::RecordType specializedRecordType = specializationDecl->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS;
NameHierarchy specializedRecordNameHierarchy = utility::getDeclNameHierarchy(specializationDecl);
m_client->onTemplateRecordSpecializationParsed(
getParseLocationForNamedDecl(*it), specializedRecordNameHierarchy, specializedRecordType, specializationParentNameHierarchy
specializationLocation,
specializedRecordNameHierarchy,
specializedRecordType,
specializationParentNameHierarchy
);
std::string specializationFilePath = getParseLocationForNamedDecl(specializationDecl).filePath.str();
std::string specializationFilePath = specializationLocation.filePath.str();
const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs();
for (size_t i = 0; i < argList.size(); i++)
@@ -26,7 +26,10 @@ void PreprocessorCallbacks::FileChanged(
const clang::FileEntry *fileEntry = m_sourceManager.getFileEntryForID(m_sourceManager.getFileID(location));
if (fileEntry && m_fileRegister->getFileManager()->hasFilePath(fileEntry->getName()))
{
m_client->onFileParsed(fileEntry->getName());
m_client->onFileParsed(FileInfo(
FilePath(fileEntry->getName()),
boost::posix_time::from_time_t(fileEntry->getModificationTime())
));
m_fileRegister->markIncludeFileParsing(fileEntry->getName());
}
}
@@ -40,12 +43,15 @@ void PreprocessorCallbacks::InclusionDirective(
if (fileEntry && baseFileEntry)
{
std::string baseFilePath = baseFileEntry->getName();
std::string filePath = fileEntry->getName();
std::string includedFilePath = fileEntry->getName();
if (m_fileRegister->getFileManager()->hasFilePath(baseFilePath) &&
m_fileRegister->getFileManager()->hasFilePath(filePath))
if (m_fileRegister->getFileManager()->hasFilePath(baseFilePath) && // check if file is in project
m_fileRegister->getFileManager()->hasFilePath(includedFilePath))
{
m_client->onFileIncludeParsed(getParseLocation(fileNameRange.getAsRange()), baseFilePath, filePath);
FileInfo baseFileInfo(baseFilePath, boost::posix_time::from_time_t(baseFileEntry->getModificationTime()));
FileInfo includedFileInfo(includedFilePath, boost::posix_time::from_time_t(fileEntry->getModificationTime()));
m_client->onFileIncludeParsed(getParseLocation(fileNameRange.getAsRange()), baseFileInfo, includedFileInfo);
}
}
}