forked from qt-creator/qt-creator
CppEditor: Consider symbol occurrences in comments
... when renaming. For local renaming, we consider only function parameters. Task-number: QTCREATORBUG-12051 Change-Id: I7948d69f11b97663c9bd747ae6241a82dd9bdd82 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -8,58 +8,35 @@
|
||||
#include <cplusplus/Overview.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/textutils.h>
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
QList<Token> commentsForDeclaration(const Symbol *symbol, const Snapshot &snapshot,
|
||||
const QTextDocument &textDoc)
|
||||
static QString nameFromSymbol(const Symbol *symbol)
|
||||
{
|
||||
// Set up cpp document.
|
||||
const Document::Ptr cppDoc = snapshot.preprocessedDocument(textDoc.toPlainText().toUtf8(),
|
||||
symbol->filePath());
|
||||
cppDoc->parse();
|
||||
TranslationUnit * const tu = cppDoc->translationUnit();
|
||||
if (!tu || !tu->isParsed())
|
||||
const QStringList symbolParts = Overview().prettyName(symbol->name())
|
||||
.split("::", Qt::SkipEmptyParts);
|
||||
if (symbolParts.isEmpty())
|
||||
return {};
|
||||
return symbolParts.last();
|
||||
}
|
||||
|
||||
// Find the symbol declaration's AST node.
|
||||
// We stop at the last declaration node that precedes the symbol, except:
|
||||
// - For parameter declarations, we just continue, because we are interested in the function.
|
||||
// - If the declaration node is preceded directly by another one, we choose that one instead,
|
||||
// because with nested declarations we want the outer one (e.g. templates).
|
||||
int line, column;
|
||||
tu->getTokenPosition(symbol->sourceLocation(), &line, &column);
|
||||
const QList<AST *> astPath = ASTPath(cppDoc)(line, column);
|
||||
if (astPath.isEmpty())
|
||||
return {};
|
||||
if (astPath.last()->firstToken() != symbol->sourceLocation())
|
||||
return {};
|
||||
const AST *declAst = nullptr;
|
||||
bool needsSymbolReference = false;
|
||||
bool isParameter = false;
|
||||
for (auto it = std::next(std::rbegin(astPath)); it != std::rend(astPath); ++it) {
|
||||
AST * const node = *it;
|
||||
if (node->asParameterDeclaration()) {
|
||||
needsSymbolReference = true;
|
||||
isParameter = true;
|
||||
continue;
|
||||
}
|
||||
if (node->asDeclaration()) {
|
||||
declAst = node;
|
||||
continue;
|
||||
}
|
||||
if (declAst)
|
||||
break;
|
||||
}
|
||||
if (!declAst)
|
||||
static QList<Token> commentsForDeclaration(
|
||||
const AST *decl, const QString &symbolName, const QTextDocument &textDoc,
|
||||
const Document::Ptr &cppDoc, bool isParameter)
|
||||
{
|
||||
if (symbolName.isEmpty())
|
||||
return {};
|
||||
|
||||
// Get the list of all tokens (including comments) and find the declaration start token there.
|
||||
const Token &declToken = tu->tokenAt(declAst->firstToken());
|
||||
TranslationUnit * const tu = cppDoc->translationUnit();
|
||||
QTC_ASSERT(tu && tu->isParsed(), return {});
|
||||
const Token &declToken = tu->tokenAt(decl->firstToken());
|
||||
std::vector<Token> allTokens = tu->allTokens();
|
||||
QTC_ASSERT(!allTokens.empty(), return {});
|
||||
int tokenPos = -1;
|
||||
@@ -86,6 +63,7 @@ QList<Token> commentsForDeclaration(const Symbol *symbol, const Snapshot &snapsh
|
||||
const auto blockForTokenEnd = [&](const Token &tok) {
|
||||
return textDoc.findBlock(tu->getTokenEndPositionInDocument(tok, &textDoc));
|
||||
};
|
||||
bool needsSymbolReference = isParameter;
|
||||
for (int i = tokenPos - 1; i >= 0; --i) {
|
||||
const Token &tok = allTokens.at(i);
|
||||
if (!tok.isComment())
|
||||
@@ -127,7 +105,6 @@ QList<Token> commentsForDeclaration(const Symbol *symbol, const Snapshot &snapsh
|
||||
return tokenList();
|
||||
|
||||
// b)
|
||||
const QString symbolName = Overview().prettyName(symbol->name());
|
||||
const Kind tokenKind = comments.first().token.kind();
|
||||
const bool isDoxygenComment = tokenKind == T_DOXY_COMMENT || tokenKind == T_CPP_DOXY_COMMENT;
|
||||
const QRegularExpression symbolRegExp(QString("%1\\b%2\\b").arg(
|
||||
@@ -142,4 +119,57 @@ QList<Token> commentsForDeclaration(const Symbol *symbol, const Snapshot &snapsh
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
QList<Token> commentsForDeclaration(const Symbol *symbol, const QTextDocument &textDoc,
|
||||
const Document::Ptr &cppDoc)
|
||||
{
|
||||
QTC_ASSERT(cppDoc->translationUnit() && cppDoc->translationUnit()->isParsed(), return {});
|
||||
Utils::Text::Position pos;
|
||||
cppDoc->translationUnit()->getTokenPosition(symbol->sourceLocation(), &pos.line, &pos.column);
|
||||
--pos.column;
|
||||
return commentsForDeclaration(nameFromSymbol(symbol), pos, textDoc, cppDoc);
|
||||
}
|
||||
|
||||
QList<Token> commentsForDeclaration(const QString &symbolName, const Utils::Text::Position &pos,
|
||||
const QTextDocument &textDoc, const Document::Ptr &cppDoc)
|
||||
{
|
||||
if (symbolName.isEmpty())
|
||||
return {};
|
||||
|
||||
// Find the symbol declaration's AST node.
|
||||
// We stop at the last declaration node that precedes the symbol, except:
|
||||
// - For parameter declarations, we just continue, because we are interested in the function.
|
||||
// - If the declaration node is preceded directly by another one, we choose that one instead,
|
||||
// because with nested declarations we want the outer one (e.g. templates).
|
||||
const QList<AST *> astPath = ASTPath(cppDoc)(pos.line, pos.column + 1);
|
||||
if (astPath.isEmpty())
|
||||
return {};
|
||||
const AST *declAst = nullptr;
|
||||
bool isParameter = false;
|
||||
for (auto it = std::next(std::rbegin(astPath)); it != std::rend(astPath); ++it) {
|
||||
AST * const node = *it;
|
||||
if (node->asParameterDeclaration()) {
|
||||
isParameter = true;
|
||||
continue;
|
||||
}
|
||||
if (node->asDeclaration()) {
|
||||
declAst = node;
|
||||
continue;
|
||||
}
|
||||
if (declAst)
|
||||
break;
|
||||
}
|
||||
if (!declAst)
|
||||
return {};
|
||||
|
||||
return commentsForDeclaration(declAst, symbolName, textDoc, cppDoc, isParameter);
|
||||
}
|
||||
|
||||
QList<Token> commentsForDeclaration(const Symbol *symbol, const AST *decl,
|
||||
const QTextDocument &textDoc, const Document::Ptr &cppDoc)
|
||||
{
|
||||
return commentsForDeclaration(decl, nameFromSymbol(symbol), textDoc, cppDoc,
|
||||
symbol->asArgument());
|
||||
}
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <cplusplus/Token.h>
|
||||
|
||||
#include <QList>
|
||||
@@ -11,11 +12,24 @@ QT_BEGIN_NAMESPACE
|
||||
class QTextDocument;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { namespace Text { class Position; } }
|
||||
|
||||
namespace CPlusPlus {
|
||||
class Snapshot;
|
||||
class AST;
|
||||
class Symbol;
|
||||
|
||||
QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const Symbol *symbol,
|
||||
const Snapshot &snapshot,
|
||||
const QTextDocument &textDoc);
|
||||
const QTextDocument &textDoc,
|
||||
const Document::Ptr &cppDoc);
|
||||
|
||||
QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const Symbol *symbol,
|
||||
const AST *decl,
|
||||
const QTextDocument &textDoc,
|
||||
const Document::Ptr &cppDoc);
|
||||
|
||||
QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const QString &symbolName,
|
||||
const Utils::Text::Position &pos,
|
||||
const QTextDocument &textDoc,
|
||||
const Document::Ptr &cppDoc);
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
Reference in New Issue
Block a user