Commit a6024bbc authored by Milian Wolff's avatar Milian Wolff
Browse files

properly update ranges of declarations we reuse (i.e. encounter)

BUG: 281668
parent e64094f5
......@@ -150,7 +150,7 @@ DUContext* ContextBuilder::contextFromNode(AstNode* node)
RangeInRevision ContextBuilder::editorFindRange(AstNode* fromRange, AstNode* toRange)
{
return m_editor->findRange(fromRange, toRange);
return m_editor->findRange(fromRange, toRange ? toRange : fromRange);
}
CursorInRevision ContextBuilder::startPos(AstNode* node)
......
......@@ -62,7 +62,7 @@ protected:
virtual void startVisiting(AstNode* node);
virtual void setContextOnNode(AstNode* node, KDevelop::DUContext* ctx);
virtual KDevelop::DUContext* contextFromNode(AstNode* node);
virtual KDevelop::RangeInRevision editorFindRange(AstNode* fromRange, AstNode* toRange);
virtual KDevelop::RangeInRevision editorFindRange(AstNode* fromRange, AstNode* toRange = 0);
/// Find Cursor for start of a node, useful to limit findLocalDeclarations() searches.
KDevelop::CursorInRevision startPos( AstNode* node);
......
......@@ -563,6 +563,7 @@ void DeclarationBuilder::visitFunctionDeclarationStatement(FunctionDeclarationSt
FunctionDeclaration* dec = m_functions.value(node->functionName->string, 0);
Q_ASSERT(dec);
// seems like we have to set that, else the usebuilder crashes
DeclarationBuilderBase::setEncountered(dec);
openDeclarationInternal(dec);
......@@ -971,9 +972,13 @@ void DeclarationBuilder::declareFoundVariable(AbstractType::Ptr type)
DUChainWriteLocker lock(DUChain::lock());
foreach ( Declaration* dec, ctx->findDeclarations(m_findVariable.identifier) ) {
if ( dec->kind() == Declaration::Instance ) {
if (!wasEncountered(dec)) {
// just like a "redeclaration", hence we must update the range
// TODO: do the same for all other uses of "encounter"?
dec->setRange(editorFindRange(m_findVariable.node));
encounter(dec);
}
isDeclared = true;
// update comment but nothing else
encounter(dec);
break;
}
}
......@@ -1167,6 +1172,7 @@ void DeclarationBuilder::closeContext()
DeclarationBuilderBase::closeContext();
setCompilingContexts(false);
}
void DeclarationBuilder::encounter(Declaration* dec)
{
// when we are recompiling, it's important to mark decs as encountered
......
......@@ -225,4 +225,47 @@ void TestDUChainMultipleFiles::testForeachImportedIdentifier()
}
}
void TestDUChainMultipleFiles::testUpdateForeach()
{
TopDUContext::Features features = TopDUContext::AllDeclarationsContextsAndUses;
TestProject* project = new TestProject;
m_projectController->clearProjects();
m_projectController->addProject(project);
TestFile f("<?\n$k = null;\nforeach(array() as $i => $k) {}\n", "php", project);
f.parse(features);
f.waitForParsed();
QVERIFY(f.topContext());
{
DUChainWriteLocker lock;
QVERIFY(f.topContext()->problems().isEmpty());
QCOMPARE(f.topContext()->findDeclarations(Identifier("k")).count(), 1);
Declaration* kDec = f.topContext()->findDeclarations(Identifier("k")).first();
QCOMPARE(kDec->rangeInCurrentRevision().start.line, 1);
QCOMPARE(kDec->rangeInCurrentRevision().start.column, 0);
QCOMPARE(kDec->uses().count(), 1);
QCOMPARE(kDec->uses().begin()->count(), 1);
QCOMPARE(kDec->uses().begin()->begin()->start.line, 2);
}
// delete $k = null; line
f.setFileContents("<?\nforeach(array() as $i => $k) {}\n");
f.parse(static_cast<TopDUContext::Features>(features | TopDUContext::ForceUpdate));
f.waitForParsed();
QVERIFY(f.topContext());
{
DUChainWriteLocker lock;
QVERIFY(f.topContext()->problems().isEmpty());
QCOMPARE(f.topContext()->findDeclarations(Identifier("k")).count(), 1);
Declaration* kDec = f.topContext()->findDeclarations(Identifier("k")).first();
QCOMPARE(kDec->rangeInCurrentRevision().start.line, 1);
QCOMPARE(kDec->rangeInCurrentRevision().start.column, 25);
QCOMPARE(kDec->uses().count(), 0);
}
}
#include "duchain_multiplefiles.moc"
......@@ -42,8 +42,8 @@ private slots:
void testNonExistingGlobalFunction();
void testImportsStaticFunctionNotYetParsed();
void testNonExistingStaticFunction();
void testForeachImportedIdentifier();
void testUpdateForeach();
private:
KDevelop::TestProjectController* m_projectController;
};
......
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