data, ui: comment handling

* CodeView displays comments as atomic regions. They are either displayed as a whole or not at all. Do nothing halfway!
* added CommentHandler that handles comments detected by clang.
* stored CommentLocations in database.
This commit is contained in:
malte_langkabel
2015-11-06 14:03:20 +01:00
parent e186eefdff
commit 50bc970c30
17 changed files with 282 additions and 31 deletions
+55
View File
@@ -164,6 +164,18 @@ Id SqliteStorage::addSignature(Id nodeId, const std::string& signature)
return m_database.lastRowId();
}
Id SqliteStorage::addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol)
{
m_database.execDML((
"INSERT INTO comment_location(id, file_node_id, start_line, start_column, end_line, end_column) "
"VALUES(NULL, " + std::to_string(fileNodeId) + ", "
+ std::to_string(startLine) + ", " + std::to_string(startCol) + ", "
+ std::to_string(endLine) + ", " + std::to_string(endCol) + ");"
).c_str());
return m_database.lastRowId();
}
Id SqliteStorage::addError(const std::string& message, const std::string& filePath, uint lineNumber, uint columnNumber)
{
std::string sanitizedMessage = utility::replace(message, "'", "''");
@@ -727,6 +739,36 @@ Id SqliteStorage::getNodeIdBySignature(const std::string& signature) const
return 0;
}
std::vector<StorageCommentLocation> SqliteStorage::getCommentLocationsInFile(const FilePath& filePath) const
{
Id fileNodeId = getFileByPath(filePath.str()).id;
CppSQLite3Query q = m_database.execQuery((
"SELECT id, file_node_id, start_line, start_column, end_line, end_column FROM comment_location "
"WHERE file_node_id == " + std::to_string(fileNodeId) + ";"
).c_str());
std::vector<StorageCommentLocation> commentLocations;
while (!q.eof())
{
const Id id = q.getIntField(0, 0);
const Id fileNodeId = q.getIntField(1, 0);
const int startLineNumber = q.getIntField(2, -1);
const int startColNumber = q.getIntField(3, -1);
const int endLineNumber = q.getIntField(4, -1);
const int endColNumber = q.getIntField(5, -1);
if (id != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1)
{
commentLocations.push_back(StorageCommentLocation(
id, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber
));
}
q.nextRow();
}
return commentLocations;
}
std::vector<StorageError> SqliteStorage::getAllErrors() const
{
CppSQLite3Query q = m_database.execQuery(
@@ -777,6 +819,7 @@ int SqliteStorage::getSourceLocationCount() const
void SqliteStorage::clearTables()
{
m_database.execDML("DROP TABLE IF EXISTS main.error;");
m_database.execDML("DROP TABLE IF EXISTS main.comment_location;");
m_database.execDML("DROP TABLE IF EXISTS main.function_signature;");
m_database.execDML("DROP TABLE IF EXISTS main.component_access;");
m_database.execDML("DROP TABLE IF EXISTS main.source_location;");
@@ -878,6 +921,18 @@ void SqliteStorage::setupTables()
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS comment_location("
"id INTEGER NOT NULL, "
"file_node_id INTEGER, "
"start_line INTEGER, "
"start_column INTEGER, "
"end_line INTEGER, "
"end_column INTEGER, "
"PRIMARY KEY(id), "
"FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE);"
);
m_database.execDML(
"CREATE TABLE IF NOT EXISTS error("
"id INTEGER NOT NULL, "
+3
View File
@@ -42,6 +42,7 @@ public:
Id addComponentAccess(Id memberEdgeId, int type);
Id addSignature(Id nodeId, const std::string& signature);
Id addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
Id addError(const std::string& message, const std::string& filePath, uint lineNumber, uint columnNumber);
void removeElement(Id id);
@@ -51,6 +52,7 @@ public:
void removeFiles(const std::vector<Id>& fileIds);
void removeUnusedNameHierarchyElements();
void removeCommentLocationsInFiles(const std::vector<FilePath>& filePaths);
void removeErrorsInFiles(const std::vector<FilePath>& filePaths);
StorageNode getFirstNode() const;
@@ -105,6 +107,7 @@ public:
std::vector<StorageComponentAccess> getComponentAccessByMemberEdgeIds(const std::vector<Id>& memberEdgeIds) const;
Id getNodeIdBySignature(const std::string& signature) const;
std::vector<StorageCommentLocation> getCommentLocationsInFile(const FilePath& filePath) const;
std::vector<StorageError> getAllErrors() const;
int getNodeCount() const;
+37 -1
View File
@@ -713,6 +713,22 @@ Id Storage::onMacroExpandParsed(const ParseLocation &location, const NameHierarc
return edgeId;
}
Id Storage::onCommentParsed(const ParseLocation& location)
{
log("comment", "no name", location);
Id fileNodeId = m_sqliteStorage.getFileByPath(location.filePath.str()).id;
Id commentId = m_sqliteStorage.addCommentLocation(
fileNodeId,
location.startLineNumber,
location.startColumnNumber,
location.endLineNumber,
location.endColumnNumber
);
return commentId;
}
Id Storage::getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const
{
Id currentId = 0;
@@ -1167,7 +1183,7 @@ std::shared_ptr<TokenLocationFile> Storage::getTokenLocationOfParentScope(const
const TokenLocation* parent = child;
const FilePath filePath = child->getFilePath();
std::shared_ptr<TokenLocationFile> locationFile = m_sqliteStorage.getTokenLocationsForFile(filePath);
std::shared_ptr<TokenLocationFile> locationFile = m_sqliteStorage.getTokenLocationsForFile(filePath); // TODO: sqlite should not know TokenLocationFile!
locationFile->forEachStartTokenLocation(
[&](TokenLocation* tokenLocation) -> void
{
@@ -1197,6 +1213,26 @@ std::shared_ptr<TokenLocationFile> Storage::getTokenLocationOfParentScope(const
return file;
}
std::shared_ptr<TokenLocationFile> Storage::getCommentLocationsInFile(const FilePath& filePath) const
{
std::shared_ptr<TokenLocationFile> file = std::make_shared<TokenLocationFile>(filePath);
std::vector<StorageCommentLocation> storageLocations = m_sqliteStorage.getCommentLocationsInFile(filePath);
for (size_t i = 0; i < storageLocations.size(); i++)
{
TokenLocation* loc = file->addTokenLocation(
storageLocations[i].id,
0, // comment token location has no element.
storageLocations[i].startLine,
storageLocations[i].startCol,
storageLocations[i].endLine,
storageLocations[i].endCol
);
}
return file;
}
std::shared_ptr<TextAccess> Storage::getFileContent(const FilePath& filePath) const
{
return m_sqliteStorage.getFileContentByPath(filePath.str());
+3
View File
@@ -127,6 +127,8 @@ public:
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation);
virtual Id onMacroExpandParsed(const ParseLocation& location, const NameHierarchy& macroNameHierarchy);
virtual Id onCommentParsed(const ParseLocation& location);
// StorageAccess implementation
virtual Id getIdForNodeWithNameHierarchy(const NameHierarchy& nameHierarchy) const;
virtual Id getIdForEdge(
@@ -160,6 +162,7 @@ public:
virtual TokenLocationCollection getErrorTokenLocations(std::vector<std::string>* errorMessages) const;
virtual std::shared_ptr<TokenLocationFile> getTokenLocationOfParentScope(const TokenLocation* child) const;
virtual std::shared_ptr<TokenLocationFile> getCommentLocationsInFile(const FilePath& filePath) const;
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
virtual TimePoint getFileModificationTime(const FilePath& filePath) const;
+39 -5
View File
@@ -8,7 +8,10 @@
struct StorageEdge
{
StorageEdge(Id id, int type, Id sourceNodeId, Id targetNodeId)
: id(id), type(type), sourceNodeId(sourceNodeId), targetNodeId(targetNodeId)
: id(id)
, type(type)
, sourceNodeId(sourceNodeId)
, targetNodeId(targetNodeId)
{}
Id id;
@@ -20,7 +23,10 @@ struct StorageEdge
struct StorageNode
{
StorageNode(Id id, int type, Id nameId, bool defined)
: id(id), type(type), nameId(nameId), defined(defined)
: id(id)
, type(type)
, nameId(nameId)
, defined(defined)
{}
Id id;
@@ -32,7 +38,10 @@ struct StorageNode
struct StorageFile
{
StorageFile(Id id, Id nameId, const std::string& filePath, const std::string& modificationTime)
: id(id), nameId(nameId), filePath(filePath), modificationTime(modificationTime)
: id(id)
, nameId(nameId)
, filePath(filePath)
, modificationTime(modificationTime)
{}
Id id;
@@ -55,8 +64,14 @@ struct StorageNameHierarchyElement
struct StorageSourceLocation
{
StorageSourceLocation(Id id, Id elementId, Id fileNodeId, int startLine, int startCol, int endLine, int endCol, bool isScope)
: id(id), elementId(elementId), fileNodeId(fileNodeId)
, startLine(startLine), startCol(startCol), endLine(endLine), endCol(endCol), isScope(isScope)
: id(id)
, elementId(elementId)
, fileNodeId(fileNodeId)
, startLine(startLine)
, startCol(startCol)
, endLine(endLine)
, endCol(endCol)
, isScope(isScope)
{}
Id id;
@@ -80,6 +95,25 @@ struct StorageComponentAccess
int type;
};
struct StorageCommentLocation
{
StorageCommentLocation(Id id, Id fileNodeId, int startLine, int startCol, int endLine, int endCol)
: id(id)
, fileNodeId(fileNodeId)
, startLine(startLine)
, startCol(startCol)
, endLine(endLine)
, endCol(endCol)
{}
Id id;
Id fileNodeId;
int startLine;
int startCol;
int endLine;
int endCol;
};
struct StorageError
{
StorageError(const std::string& message, const std::string& filePath, uint lineNumber, uint columnNumber)
+1
View File
@@ -55,6 +55,7 @@ public:
virtual TokenLocationCollection getErrorTokenLocations(std::vector<std::string>* errorMessages) const = 0;
virtual std::shared_ptr<TokenLocationFile> getTokenLocationOfParentScope(const TokenLocation* child) const = 0;
virtual std::shared_ptr<TokenLocationFile> getCommentLocationsInFile(const FilePath& filePath) const = 0;
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const = 0;
virtual TimePoint getFileModificationTime(const FilePath& filePath) const = 0;
@@ -235,6 +235,16 @@ std::shared_ptr<TokenLocationFile> StorageAccessProxy::getTokenLocationOfParentS
return std::make_shared<TokenLocationFile>("");
}
std::shared_ptr<TokenLocationFile> StorageAccessProxy::getCommentLocationsInFile(const FilePath& filePath) const
{
if (hasSubject())
{
return m_subject->getCommentLocationsInFile(filePath);
}
return std::make_shared<TokenLocationFile>("");
}
std::shared_ptr<TextAccess> StorageAccessProxy::getFileContent(const FilePath& filePath) const
{
if (hasSubject())
+1
View File
@@ -45,6 +45,7 @@ public:
virtual TokenLocationCollection getErrorTokenLocations(std::vector<std::string>* errorMessages) const;
virtual std::shared_ptr<TokenLocationFile> getTokenLocationOfParentScope(const TokenLocation* child) const;
virtual std::shared_ptr<TokenLocationFile> getCommentLocationsInFile(const FilePath& filePath) const;
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
virtual TimePoint getFileModificationTime(const FilePath& filePath) const;
+2
View File
@@ -145,6 +145,8 @@ public:
const ParseLocation& location, const NameHierarchy& macroNameHierarchy, const ParseLocation& scopeLocation) = 0;
virtual Id onMacroExpandParsed(
const ParseLocation& location, const NameHierarchy& macroNameHierarchy) = 0;
virtual Id onCommentParsed(const ParseLocation& location) = 0;
};
#endif // PARSER_CLIENT_H
+3 -1
View File
@@ -2,11 +2,13 @@
#include "clang/Lex/Preprocessor.h"
#include "data/parser/cxx/CommentHandler.h"
#include "data/parser/cxx/PreprocessorCallbacks.h"
ASTAction::ASTAction(ParserClient* client, FileRegister* fileRegister)
: m_client(client)
, m_fileRegister(fileRegister)
, m_commentHandler(client)
{
}
@@ -24,7 +26,7 @@ bool ASTAction::BeginSourceFileAction(clang::CompilerInstance& compiler, llvm::S
clang::Preprocessor& preprocessor = compiler.getPreprocessor();
preprocessor.addPPCallbacks(
llvm::make_unique<PreprocessorCallbacks>(compiler.getSourceManager(), m_client, m_fileRegister));
preprocessor.addCommentHandler(&m_commentHandler);
return true;
}
+3
View File
@@ -5,6 +5,7 @@
#include "clang/Frontend/FrontendAction.h"
#include "data/parser/cxx/ASTConsumer.h"
#include "data/parser/cxx/CommentHandler.h"
#include "utility/file/FileRegister.h"
class ASTAction : public clang::ASTFrontendAction
@@ -22,6 +23,8 @@ protected:
private:
ParserClient* m_client;
FileRegister* m_fileRegister;
CommentHandler m_commentHandler;
};
#endif // AST_ACTION_H
@@ -0,0 +1,28 @@
#include "data/parser/cxx/CommentHandler.h"
#include "data/parser/ParserClient.h"
CommentHandler::CommentHandler(ParserClient* client)
: m_client(client)
{
}
CommentHandler::~CommentHandler()
{
}
bool CommentHandler::HandleComment(clang::Preprocessor& preprocessor, clang::SourceRange sourceRange)
{
clang::SourceManager& sourceManager = preprocessor.getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(sourceRange.getBegin(), false);
const clang::PresumedLoc& presumedEnd = sourceManager.getPresumedLoc(sourceRange.getEnd(), false);
m_client->onCommentParsed(ParseLocation(
presumedBegin.getFilename(),
presumedBegin.getLine(),
presumedBegin.getColumn(),
presumedEnd.getLine(),
presumedEnd.getColumn()
));
return false;
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef COMMENT_HANDLER_H
#define COMMENT_HANDLER_H
#include "clang/Lex/Preprocessor.h"
class ParserClient;
class CommentHandler
: public clang::CommentHandler
{
public:
CommentHandler(ParserClient* client);
virtual ~CommentHandler();
virtual bool HandleComment(clang::Preprocessor& preprocessor, clang::SourceRange sourceRange);
private:
ParserClient* m_client;
};
#endif // COMMENT_HANDLER_H