Commit ca291fbc authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar

C++: fix functionAt(), moved it, and added test.

Thanks to Jesper K. Pedersen for the fix!

Change-Id: Ie49c3352e26a9632b1500596b00d559bfe932dff
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 6a4a9266
......@@ -464,6 +464,57 @@ void Document::setGlobalNamespace(Namespace *globalNamespace)
_globalNamespace = globalNamespace;
}
/*!
* Extract the function name including scope at the given position.
*
* Note that a function (scope) starts at the name of that function, not at the return type. The
* implication is that this method will return an empty string when the line/column is on the
* return type.
*
* \param line the line number, starting with line 1
* \param column the column number, starting with column 1
*/
QString Document::functionAt(int line, int column) const
{
if (line < 1 || column < 1)
return QString();
CPlusPlus::Symbol *symbol = lastVisibleSymbolAt(line, column);
if (!symbol)
return QString();
// Find the enclosing function scope (which might be several levels up, or we might be standing
// on it)
Scope *scope;
if (symbol->isScope())
scope = symbol->asScope();
else
scope = symbol->enclosingScope();
while (scope && !scope->isFunction() )
scope = scope->enclosingScope();
if (!scope)
return QString();
// We found the function scope, extract its name.
const Overview o;
QString rc = o.prettyName(scope->name());
// Prepend namespace "Foo::Foo::foo()" up to empty root namespace
for (const Symbol *owner = scope->enclosingNamespace();
owner; owner = owner->enclosingNamespace()) {
const QString name = o.prettyName(owner->name());
if (name.isEmpty()) {
break;
} else {
rc.prepend(QLatin1String("::"));
rc.prepend(name);
}
}
return rc;
}
Scope *Document::scopeAt(unsigned line, unsigned column)
{
FindScopeAt findScopeAt(_translationUnit, line, column);
......
......@@ -99,6 +99,7 @@ public:
QList<Macro> definedMacros() const
{ return _definedMacros; }
QString functionAt(int line, int column) const;
Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
Scope *scopeAt(unsigned line, unsigned column = 0);
......
......@@ -55,29 +55,13 @@ QString AbstractEditorSupport::functionAt(const CppModelManagerInterface *modelM
const QString &fileName,
int line, int column)
{
const CPlusPlus::Snapshot snapshot = modelManager->snapshot();
const CPlusPlus::Document::Ptr document = snapshot.document(fileName);
if (!document)
if (!modelManager)
return QString();
if (const CPlusPlus::Symbol *symbol = document->lastVisibleSymbolAt(line, column))
if (const CPlusPlus::Scope *scope = symbol->enclosingScope())
if (const CPlusPlus::Scope *functionScope = scope->enclosingFunction())
if (const CPlusPlus::Symbol *function = functionScope) {
const CPlusPlus::Overview o;
QString rc = o.prettyName(function->name());
// Prepend namespace "Foo::Foo::foo()" up to empty root namespace
for (const CPlusPlus::Symbol *owner = function->enclosingNamespace();
owner; owner = owner->enclosingNamespace()) {
const QString name = o.prettyName(owner->name());
if (name.isEmpty()) {
break;
} else {
rc.prepend(QLatin1String("::"));
rc.prepend(name);
}
}
return rc;
}
const CPlusPlus::Snapshot snapshot = modelManager->snapshot();
if (const CPlusPlus::Document::Ptr document = snapshot.document(fileName))
return document->functionAt(line, column);
return QString();
}
......
......@@ -87,6 +87,7 @@ class tst_Lookup: public QObject
private Q_SLOTS:
void base_class_defined_1();
void document_functionAt_1();
// Objective-C
void simple_class_1();
......@@ -153,6 +154,30 @@ void tst_Lookup::base_class_defined_1()
QVERIFY(classToAST.value(derivedClass) != 0);
}
void tst_Lookup::document_functionAt_1()
{
const QByteArray source = "\n"
"void Foo::Bar() {\n" // line 1
" \n" // line 2
" for (int i=0; i < 10; ++i) {\n"
" \n" // line 4
" }\n"
"}\n"; // line 7
Document::Ptr doc = Document::create("document_functionAt_1");
doc->setUtf8Source(source);
doc->parse();
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
QCOMPARE(doc->functionAt(1, 2), QString());
QCOMPARE(doc->functionAt(1, 11), QString(QLatin1String("Foo::Bar")));
QCOMPARE(doc->functionAt(2, 2), QString(QLatin1String("Foo::Bar")));
QCOMPARE(doc->functionAt(3, 10), QString(QLatin1String("Foo::Bar")));
QCOMPARE(doc->functionAt(4, 3), QString(QLatin1String("Foo::Bar")));
QCOMPARE(doc->functionAt(6, 1), QString(QLatin1String("Foo::Bar")));
}
void tst_Lookup::simple_class_1()
{
const QByteArray source = "\n"
......
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