Commit dec33024 authored by Simon Martens's avatar Simon Martens Committed by Ralf Habacker

Fixes for adding multiline c++ comment support

BUG:418970
FIXED-IN:2.31.1 (KDE releases 20.04.1)
parent b25c3c74
......@@ -1852,7 +1852,7 @@ template<class Type>
void Parser::eventuallyTakeComment(Type& ast)
{
int line = currentLine();
Comment c = m_commentStore.getCommentsInRange(line);
Comment c = m_commentStore.getCommentsInRange(line, true);
if (&(*ast) && c) {
ast->setComment(c);
......@@ -3133,12 +3133,25 @@ bool Parser::parseDeclarationInternal(DeclarationAST::Node& node)
if (parseInitDeclarator(declarator)) {
int endSignature = m_lexer->index();
Comment mcomment;
if (&(*declarator)) {
int endLine, endColumn;
declarator->getEndPosition(&endLine, &endColumn);
mcomment = m_commentStore.getCommentsInRange(endLine);
}
else {
mcomment = comment();
}
clearComment();
switch (m_lexer->lookAhead(0)) {
case ';': {
nextToken();
InitDeclaratorListAST::Node declarators = CreateNode<InitDeclaratorListAST>();
SimpleDeclarationAST::Node ast = CreateNode<SimpleDeclarationAST>();
// update declarators position
int startLine, startColumn, endLine, endColumn;
if (declarator.get()) {
......@@ -3146,10 +3159,16 @@ bool Parser::parseDeclarationInternal(DeclarationAST::Node& node)
declarator->getEndPosition(&endLine, &endColumn);
declarators->setStartPosition(startLine, startColumn);
declarators->setEndPosition(endLine, endColumn);
ast->setComment(mcomment);
preparseLineComments(endLine);
Comment c = m_commentStore.getCommentInRange(endLine);
if (c) {
ast->addComment(c);
}
}
declarators->addInitDeclarator(declarator);
SimpleDeclarationAST::Node ast = CreateNode<SimpleDeclarationAST>();
ast->setInitDeclaratorList(declarators);
if (hasFunSpec)
ast->setFunctionSpecifier(funSpec);
......@@ -3225,9 +3244,6 @@ start_decl:
return false;
}
Comment mcomment = comment();
clearComment();
TypeSpecifierAST::Node spec;
if (parseTypeSpecifier(spec)) {
if (!hasFunSpec)
......@@ -3253,6 +3269,17 @@ start_decl:
}
}
Comment mcomment;
if (&(*decl)) {
int line, col;
decl->getEndPosition(&line, &col);
mcomment = m_commentStore.getCommentsInRange(line);
}
else {
mcomment = comment();
}
clearComment();
int endSignature = m_lexer->index();
switch (m_lexer->lookAhead(0)) {
case ';': {
......@@ -3292,6 +3319,16 @@ start_decl:
FunctionDefinitionAST::Node ast = CreateNode<FunctionDefinitionAST>();
ast->setComment(mcomment);
if (&(*decl)) {
int line, col;
decl->getEndPosition(&line, &col);
preparseLineComments(line);
Comment c = m_commentStore.getCommentInRange(line);
if (c) {
ast->addComment(c);
}
}
ast->setWinDeclSpec(winDeclSpec);
ast->setStorageSpecifier(storageSpec);
......
......@@ -27,6 +27,7 @@
#include <QStringList>
#include <QList>
#include <set>
#include <vector>
#include <iostream>
struct ParserPrivateData;
......@@ -237,42 +238,46 @@ public:
/**
* Returns the comments between "end" (inclusive) and "start" and removes it
* @param end last line to return
* @param classInit protects against independent comments which are further away of the class
* @param start start line to return
* @return instance of class Comment with combined comment
*/
Comment getCommentsInRange(int end, int start = 0)
Comment getCommentsInRange(int end, bool classInit = false, int start = 0)
{
std::vector<Comment> tempStorage; // The vector is required in order to output the comments in the correct order since the iterator goes reverse
Comment ret;
if (m_comments.empty())
return ret;
// The following lines will look ahead if there is a independent comment.
CommentSet::iterator it = m_comments.begin();
CommentSet::iterator it = m_comments.end();
--it; // .end() points to an element behind the container, so it's safe to move it to the actual last element
int tempLine = (*it).line();
++it;
if(tempLine < (end-2) && classInit) { // protects against independent comments which are further away of the class
m_comments.clear();
return ret;
}
tempStorage.push_back(*it);
while (it != m_comments.end() && (*it).line() >= start && (*it).line() <= end) {
if(tempLine == ((*it).line() - 1)) {
tempLine++;
++it;
} else {
--it;
m_comments.erase(it); // The independent comment is deleted
while (it != m_comments.begin() && (*it).line() >= start && (*it).line() <= end) { // goes reverse through the comments because the required comments are at the end of m_comments
--it;
if(tempLine == ((*it).line() + 1)) {
tempLine--;
tempStorage.push_back(*it);
} else { // as soons as first independent comment is found the rest isn't interesting anymore (protects against multiline independent comments)
m_comments.clear();
break;
}
}
it = m_comments.begin(); // Redefines the beginning of the container
while (it != m_comments.end() && (*it).line() >= start && (*it).line() <= end) {
if (ret)
ret += *it;
else
ret = *it;
m_comments.erase(it);
++it;
for (auto it2 = tempStorage.rbegin(); it2 != tempStorage.rend(); ++it2) { // outputs the comments in the correct order
if(it2 == tempStorage.rbegin()) {
ret = (*it2);
}
else {
ret += (*it2);
}
}
return ret;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment