forked from qt-creator/qt-creator
C++ function link: Disable function links on name change.
Change-Id: Ib5e3a3a381568347a7a465f956f7daad15f10ab0 Reviewed-on: http://codereview.qt.nokia.com/3596 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
@@ -2161,10 +2161,11 @@ void CPPEditorWidget::updateFunctionDeclDefLink()
|
||||
{
|
||||
const int pos = textCursor().selectionStart();
|
||||
|
||||
// if there's already a link, abort it if the cursor is outside
|
||||
// if there's already a link, abort it if the cursor is outside or the name changed
|
||||
if (m_declDefLink
|
||||
&& (pos < m_declDefLink->linkSelection.selectionStart()
|
||||
|| pos > m_declDefLink->linkSelection.selectionEnd())) {
|
||||
|| pos > m_declDefLink->linkSelection.selectionEnd()
|
||||
|| m_declDefLink->nameSelection.selectedText() != m_declDefLink->nameInitial)) {
|
||||
abortDeclDefLink();
|
||||
return;
|
||||
}
|
||||
|
@@ -64,9 +64,14 @@ FunctionDeclDefLinkFinder::FunctionDeclDefLinkFinder(QObject *parent)
|
||||
void FunctionDeclDefLinkFinder::onFutureDone()
|
||||
{
|
||||
QSharedPointer<FunctionDeclDefLink> link = m_watcher.result();
|
||||
if (link)
|
||||
if (link) {
|
||||
link->linkSelection = m_scannedSelection;
|
||||
link->nameSelection = m_nameSelection;
|
||||
if (m_nameSelection.selectedText() != link->nameInitial)
|
||||
link.clear();
|
||||
}
|
||||
m_scannedSelection = QTextCursor();
|
||||
m_nameSelection = QTextCursor();
|
||||
if (link)
|
||||
emit foundLink(link);
|
||||
}
|
||||
@@ -79,7 +84,8 @@ QTextCursor FunctionDeclDefLinkFinder::scannedSelection() const
|
||||
// parent is either a FunctionDefinitionAST or a SimpleDeclarationAST
|
||||
// line and column are 1-based
|
||||
static bool findDeclOrDef(const Document::Ptr &doc, int line, int column,
|
||||
DeclarationAST **parent, FunctionDeclaratorAST **funcDecl)
|
||||
DeclarationAST **parent, DeclaratorAST **decl,
|
||||
FunctionDeclaratorAST **funcDecl)
|
||||
{
|
||||
QList<AST *> path = ASTPath(doc)(line, column);
|
||||
|
||||
@@ -89,29 +95,29 @@ static bool findDeclOrDef(const Document::Ptr &doc, int line, int column,
|
||||
// with a FunctionDeclarator postfix
|
||||
FunctionDefinitionAST *funcDef = 0;
|
||||
SimpleDeclarationAST *simpleDecl = 0;
|
||||
DeclaratorAST *decl = 0;
|
||||
*decl = 0;
|
||||
for (int i = path.size() - 1; i > 0; --i) {
|
||||
AST *ast = path.at(i);
|
||||
if (ast->asCompoundStatement() || ast->asCtorInitializer())
|
||||
break;
|
||||
if ((funcDef = ast->asFunctionDefinition()) != 0) {
|
||||
*parent = funcDef;
|
||||
decl = funcDef->declarator;
|
||||
*decl = funcDef->declarator;
|
||||
break;
|
||||
}
|
||||
if ((simpleDecl = ast->asSimpleDeclaration()) != 0) {
|
||||
*parent = simpleDecl;
|
||||
if (!simpleDecl->declarator_list || !simpleDecl->declarator_list->value)
|
||||
break;
|
||||
decl = simpleDecl->declarator_list->value;
|
||||
*decl = simpleDecl->declarator_list->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*parent || !decl)
|
||||
if (!*parent || !*decl)
|
||||
return false;
|
||||
if (!decl->postfix_declarator_list || !decl->postfix_declarator_list->value)
|
||||
if (!(*decl)->postfix_declarator_list || !(*decl)->postfix_declarator_list->value)
|
||||
return false;
|
||||
*funcDecl = decl->postfix_declarator_list->value->asFunctionDeclarator();
|
||||
*funcDecl = (*decl)->postfix_declarator_list->value->asFunctionDeclarator();
|
||||
return *funcDecl;
|
||||
}
|
||||
|
||||
@@ -130,6 +136,19 @@ static void declDefLinkStartEnd(const CppTools::CppRefactoringFileConstPtr &file
|
||||
*end = file->endOf(funcDecl->rparen_token);
|
||||
}
|
||||
|
||||
static DeclaratorIdAST *getDeclaratorId(DeclaratorAST *declarator)
|
||||
{
|
||||
if (!declarator || !declarator->core_declarator)
|
||||
return 0;
|
||||
if (DeclaratorIdAST *id = declarator->core_declarator->asDeclaratorId()) {
|
||||
return id;
|
||||
}
|
||||
if (NestedDeclaratorAST *nested = declarator->core_declarator->asNestedDeclarator()) {
|
||||
return getDeclaratorId(nested->declarator);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<FunctionDeclDefLink> link, CppTools::CppRefactoringChanges changes)
|
||||
{
|
||||
QSharedPointer<FunctionDeclDefLink> noResult;
|
||||
@@ -160,8 +179,9 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio
|
||||
|
||||
DeclarationAST *targetParent = 0;
|
||||
FunctionDeclaratorAST *targetFuncDecl = 0;
|
||||
DeclaratorAST *targetDeclarator = 0;
|
||||
if (!findDeclOrDef(targetFile->cppDocument(), target->line(), target->column(),
|
||||
&targetParent, &targetFuncDecl))
|
||||
&targetParent, &targetDeclarator, &targetFuncDecl))
|
||||
return noResult;
|
||||
|
||||
// the parens are necessary for finding good places for changes
|
||||
@@ -191,7 +211,9 @@ void FunctionDeclDefLinkFinder::startFindLinkAt(
|
||||
// check if cursor is on function decl/def
|
||||
DeclarationAST *parent = 0;
|
||||
FunctionDeclaratorAST *funcDecl = 0;
|
||||
if (!findDeclOrDef(doc, cursor.blockNumber() + 1, cursor.columnNumber() + 1, &parent, &funcDecl))
|
||||
DeclaratorAST *declarator = 0;
|
||||
if (!findDeclOrDef(doc, cursor.blockNumber() + 1, cursor.columnNumber() + 1,
|
||||
&parent, &declarator, &funcDecl))
|
||||
return;
|
||||
|
||||
// find the start/end offsets
|
||||
@@ -214,8 +236,16 @@ void FunctionDeclDefLinkFinder::startFindLinkAt(
|
||||
m_scannedSelection.setPosition(start, QTextCursor::KeepAnchor);
|
||||
m_scannedSelection.setKeepPositionOnInsert(true);
|
||||
|
||||
// build selection for the name
|
||||
DeclaratorIdAST *declId = getDeclaratorId(declarator);
|
||||
m_nameSelection = cursor;
|
||||
m_nameSelection.setPosition(sourceFile->endOf(declId));
|
||||
m_nameSelection.setPosition(sourceFile->startOf(declId), QTextCursor::KeepAnchor);
|
||||
m_nameSelection.setKeepPositionOnInsert(true);
|
||||
|
||||
// set up a base result
|
||||
QSharedPointer<FunctionDeclDefLink> result(new FunctionDeclDefLink);
|
||||
result->nameInitial = m_nameSelection.selectedText();
|
||||
result->sourceDocument = doc;
|
||||
result->sourceFunction = funcDecl->symbol;
|
||||
result->sourceDeclaration = parent;
|
||||
@@ -255,19 +285,6 @@ static bool namesEqual(const Name *n1, const Name *n2)
|
||||
return n1 == n2 || (n1 && n2 && n1->isEqualTo(n2));
|
||||
}
|
||||
|
||||
static DeclaratorIdAST *getDeclaratorId(DeclaratorAST *declarator)
|
||||
{
|
||||
if (!declarator || !declarator->core_declarator)
|
||||
return 0;
|
||||
if (DeclaratorIdAST *id = declarator->core_declarator->asDeclaratorId()) {
|
||||
return id;
|
||||
}
|
||||
if (NestedDeclaratorAST *nested = declarator->core_declarator->asNestedDeclarator()) {
|
||||
return getDeclaratorId(nested->declarator);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FunctionDeclDefLink::apply(CPPEditorWidget *editor, bool jumpToMatch)
|
||||
{
|
||||
Snapshot snapshot = editor->semanticInfo().snapshot;
|
||||
|
@@ -71,6 +71,7 @@ private slots:
|
||||
|
||||
private:
|
||||
QTextCursor m_scannedSelection;
|
||||
QTextCursor m_nameSelection;
|
||||
QFutureWatcher<QSharedPointer<FunctionDeclDefLink> > m_watcher;
|
||||
};
|
||||
|
||||
@@ -92,6 +93,11 @@ public:
|
||||
Utils::ChangeSet changes(const CPlusPlus::Snapshot &snapshot, int targetOffset = -1);
|
||||
|
||||
QTextCursor linkSelection;
|
||||
|
||||
// stored to allow aborting when the name is changed
|
||||
QTextCursor nameSelection;
|
||||
QString nameInitial;
|
||||
|
||||
// 1-based line and column
|
||||
unsigned targetLine;
|
||||
unsigned targetColumn;
|
||||
|
Reference in New Issue
Block a user