示例#1
0
void CppToolsPlugin::test_codegen_definition_empty_class()
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "};\n"
            "\n";

    const QByteArray dstText = "\n"
            "int x;\n"  // line 1
            "\n";

    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
    src->setUtf8Source(srcText);
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 1U);

    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
    dst->setUtf8Source(dstText);
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 1U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 1U);
    Declaration *decl = foo->memberAt(0)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 3U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl);
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
    QCOMPARE(loc.fileName(), dst->fileName());
    QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
    QCOMPARE(loc.suffix(), QString());
    QCOMPARE(loc.line(), 3U);
    QCOMPARE(loc.column(), 1U);
}
示例#2
0
/*!
    Should insert at line 3, column 1, with "public:\n" as prefix and without suffix.
 */
void CppToolsPlugin::test_codegen_public_in_empty_class()
{
    const QByteArray src = "\n"
            "class Foo\n" // line 1
            "{\n"
            "};\n"
            "\n";

    Document::Ptr doc = Document::create(QLatin1String("public_in_empty_class"));
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);

    Snapshot snapshot;
    snapshot.insert(doc);
    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    InsertionLocation loc = find.methodDeclarationInClass(
                doc->fileName(),
                foo,
                InsertionPointLocator::Public);
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
    QVERIFY(loc.suffix().isEmpty());
    QCOMPARE(loc.line(), 3U);
    QCOMPARE(loc.column(), 1U);
}
示例#3
0
void tst_FindUsages::shadowedNames_2()
{
    const QByteArray src = "\n"
                           "int a();\n"
                           "struct X{ int a(); };\n"
                           "int X::a() {}\n"
                           "void f(X x) { x.a(); }\n"
                           "void g() { a(); }\n";

    Document::Ptr doc = Document::create("shadowedNames_2");
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 5U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Class *c = doc->globalSymbolAt(1)->asClass();
    QVERIFY(c);
    QCOMPARE(c->name()->identifier()->chars(), "X");
    QCOMPARE(c->memberCount(), 1U);
    Declaration *d = c->memberAt(0)->asDeclaration();
    QVERIFY(d);
    QCOMPARE(d->name()->identifier()->chars(), "a");

    FindUsages findUsages(src, doc, snapshot);
    findUsages(d);
    QCOMPARE(findUsages.usages().size(), 3);
}
示例#4
0
void tst_FindUsages::lambdaCaptureByReference()
{
    const QByteArray src = "\n"
                           "void f() {\n"
                           "  int test;\n"
                           "  [&test] { ++test; };\n"
                           "}\n";
    Document::Ptr doc = Document::create("lambdaCaptureByReference");
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 1U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Function *f = doc->globalSymbolAt(0)->asFunction();
    QVERIFY(f);
    QCOMPARE(f->memberCount(), 1U);
    Block *b = f->memberAt(0)->asBlock();
    QCOMPARE(b->memberCount(), 2U);
    Declaration *d = b->memberAt(0)->asDeclaration();
    QVERIFY(d);
    QCOMPARE(d->name()->identifier()->chars(), "test");

    FindUsages findUsages(src, doc, snapshot);
    findUsages(d);
    QCOMPARE(findUsages.usages().size(), 3);
}
示例#5
0
void tst_FindUsages::inlineMethod()
{
    const QByteArray src = "\n"
                           "class Tst {\n"
                           "  int method(int arg) {\n"
                           "    return arg;\n"
                           "  }\n"
                           "};\n";
    Document::Ptr doc = Document::create("inlineMethod");
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 1U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Class *tst = doc->globalSymbolAt(0)->asClass();
    QVERIFY(tst);
    QCOMPARE(tst->memberCount(), 1U);
    Function *method = tst->memberAt(0)->asFunction();
    QVERIFY(method);
    QCOMPARE(method->argumentCount(), 1U);
    Argument *arg = method->argumentAt(0)->asArgument();
    QVERIFY(arg);
    QCOMPARE(arg->identifier()->chars(), "arg");

    FindUsages findUsages(src, doc, snapshot);
    findUsages(arg);
    QCOMPARE(findUsages.usages().size(), 2);
    QCOMPARE(findUsages.references().size(), 2);
}
示例#6
0
void tst_Lookup::class_with_baseclass()
{
    const QByteArray source = "\n"
                              "@implementation BaseZoo {} -(void)baseDecl; -(void)baseMethod{} @end\n"
                              "@interface Zoo: BaseZoo {} +(id)alloc; -(id)init; @end\n"
                              "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n";

    Document::Ptr doc = Document::create("class_with_baseclass");
    doc->setUtf8Source(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 3U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Document::Ptr emptyDoc = Document::create("<empty>");

    ObjCClass *baseZoo = doc->globalSymbolAt(0)->asObjCClass();
    QVERIFY(baseZoo);
    QVERIFY(!baseZoo->isInterface());
    QCOMPARE(baseZoo->memberCount(), 2U);

    ObjCClass *zooIface = doc->globalSymbolAt(1)->asObjCClass();
    QVERIFY(zooIface);
    QVERIFY(zooIface->isInterface());
    QVERIFY(zooIface->baseClass()->name() == baseZoo->name());

    ObjCClass *zooImpl = doc->globalSymbolAt(2)->asObjCClass();
    QVERIFY(zooImpl);
    QVERIFY(!zooImpl->isInterface());
    QCOMPARE(zooImpl->memberCount(), 3U);

    Declaration *baseDecl = baseZoo->memberAt(0)->asDeclaration();
    QVERIFY(baseDecl);
    QVERIFY(baseDecl->name() && baseDecl->name()->identifier());
    QCOMPARE(QLatin1String(baseDecl->name()->identifier()->chars()), QLatin1String("baseDecl"));

    ObjCMethod *baseMethod = baseZoo->memberAt(1)->asObjCMethod();
    QVERIFY(baseMethod);
    QVERIFY(baseMethod->name() && baseMethod->name()->identifier());
    QCOMPARE(QLatin1String(baseMethod->name()->identifier()->chars()), QLatin1String("baseMethod"));

    const LookupContext context(doc, snapshot);

    LookupScope *objClass = context.lookupType(baseZoo->name(), zooImpl->enclosingScope());
    QVERIFY(objClass != 0);
    QVERIFY(objClass->symbols().contains(baseZoo));

    QList<LookupItem> results = context.lookup(baseDecl->name(), zooImpl);
    QCOMPARE(results.size(), 1);
    QCOMPARE(results.at(0).declaration(), baseDecl);

    results = context.lookup(baseMethod->name(), zooImpl);
    QCOMPARE(results.size(), 1);
    QCOMPARE(results.at(0).declaration(), baseMethod);
}
示例#7
0
void tst_Lookup::class_with_protocol_with_protocol()
{
    const QByteArray source = "\n"
                              "@protocol P1 -(void)p1method; @end\n"
                              "@protocol P2 <P1> -(void)p2method; @end\n"
                              "@interface Zoo <P2> {} +(id)alloc; -(id)init; @end\n"
                              "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n";

    Document::Ptr doc = Document::create("class_with_protocol_with_protocol");
    doc->setUtf8Source(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 4U);

    Snapshot snapshot;
    snapshot.insert(doc);

    ObjCProtocol *P1 = doc->globalSymbolAt(0)->asObjCProtocol();
    QVERIFY(P1);
    QCOMPARE(P1->memberCount(), 1U);
    QCOMPARE(P1->protocolCount(), 0U);

    Declaration *p1method = P1->memberAt(0)->asDeclaration();
    QVERIFY(p1method);
    QCOMPARE(QLatin1String(p1method->name()->identifier()->chars()), QLatin1String("p1method"));

    ObjCProtocol *P2 = doc->globalSymbolAt(1)->asObjCProtocol();
    QVERIFY(P2);
    QCOMPARE(P2->memberCount(), 1U);
    QCOMPARE(P2->protocolCount(), 1U);
    QCOMPARE(QLatin1String(P2->protocolAt(0)->name()->identifier()->chars()), QLatin1String("P1"));

    ObjCClass *zooImpl = doc->globalSymbolAt(3)->asObjCClass();
    QVERIFY(zooImpl);

    const LookupContext context(doc, snapshot);

    {
        const QList<LookupItem> candidates = context.lookup(P1->name(), zooImpl->enclosingScope());
        QCOMPARE(candidates.size(), 1);
        QVERIFY(candidates.at(0).declaration() == P1);
    }

    {
        const QList<LookupItem> candidates = context.lookup(P2->protocolAt(0)->name(), zooImpl->enclosingScope());
        QCOMPARE(candidates.size(), 1);
        QVERIFY(candidates.first().declaration() == P1);
    }

    QList<LookupItem> results = context.lookup(p1method->name(), zooImpl);
    QCOMPARE(results.size(), 1);
    QCOMPARE(results.at(0).declaration(), p1method);
}
示例#8
0
/*!
    Should insert at line 18, column 1, with "private slots:\n" as prefix and "\n"
    as suffix.

    This is the typical Qt Designer case, with test-input like what the integration
    generates.
 */
void CppToolsPlugin::test_codegen_qtdesigner_integration()
{
    const QByteArray src = "/**** Some long (C)opyright notice ****/\n"
            "#ifndef MAINWINDOW_H\n"
            "#define MAINWINDOW_H\n"
            "\n"
            "#include <QMainWindow>\n"
            "\n"
            "namespace Ui {\n"
            "    class MainWindow;\n"
            "}\n"
            "\n"
            "class MainWindow : public QMainWindow\n" // line 10
            "{\n"
            "    Q_OBJECT\n"
            "\n"
            "public:\n" // line 14
            "    explicit MainWindow(QWidget *parent = 0);\n"
            "    ~MainWindow();\n"
            "\n"
            "private:\n" // line 18
            "    Ui::MainWindow *ui;\n"
            "};\n"
            "\n"
            "#endif // MAINWINDOW_H\n";

    Document::Ptr doc = Document::create(QLatin1String("qtdesigner_integration"));
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 2U);

    Class *foo = doc->globalSymbolAt(1)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 10U);
    QCOMPARE(foo->column(), 7U);

    Snapshot snapshot;
    snapshot.insert(doc);
    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    InsertionLocation loc = find.methodDeclarationInClass(
                doc->fileName(),
                foo,
                InsertionPointLocator::PrivateSlot);
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("private slots:\n"));
    QCOMPARE(loc.suffix(), QLatin1String("\n"));
    QCOMPARE(loc.line(), 18U);
    QCOMPARE(loc.column(), 1U);
}
示例#9
0
void tst_Lookup::base_class_defined_1()
{
    Overview overview;

    const QByteArray source = "\n"
        "class base {};\n"
        "class derived: public base {};\n";

    Document::Ptr doc = Document::create("base_class_defined_1");
    doc->setSource(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 2U);

    Snapshot snapshot;
    snapshot.insert(doc->fileName(), doc);

    Document::Ptr emptyDoc = Document::create("<empty>");

    Class *baseClass = doc->globalSymbolAt(0)->asClass();
    QVERIFY(baseClass);

    Class *derivedClass = doc->globalSymbolAt(1)->asClass();
    QVERIFY(derivedClass);

    LookupContext ctx(derivedClass, emptyDoc, doc, snapshot);

    const QList<Symbol *> candidates =
        ctx.resolveClass(derivedClass->baseClassAt(0)->name());

    QCOMPARE(candidates.size(), 1);
    QCOMPARE(candidates.at(0), baseClass);

    TranslationUnit *unit = doc->translationUnit();
    QVERIFY(unit != 0);

    TranslationUnitAST *ast = unit->ast()->asTranslationUnit();
    QVERIFY(ast != 0);

    ClassSymbols classSymbols(doc->control());
    classSymbols(ast);

    QCOMPARE(classSymbols.size(), 2);

    const QMap<Class *, ClassSpecifierAST *> classToAST =
            invert(classSymbols.asMap());

    QVERIFY(classToAST.value(baseClass) != 0);
    QVERIFY(classToAST.value(derivedClass) != 0);
}
示例#10
0
void tst_Lookup::base_class_defined_1()
{
    Overview overview;

    const QByteArray source = "\n"
        "class base {};\n"
        "class derived: public base {};\n";

    Document::Ptr doc = Document::create("base_class_defined_1");
    doc->setUtf8Source(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 2U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Class *baseClass = doc->globalSymbolAt(0)->asClass();
    QVERIFY(baseClass);

    Class *derivedClass = doc->globalSymbolAt(1)->asClass();
    QVERIFY(derivedClass);

    const LookupContext ctx(doc, snapshot);

    LookupScope *klass = ctx.lookupType(derivedClass->baseClassAt(0)->name(), derivedClass->enclosingScope());
    QVERIFY(klass != 0);

    QCOMPARE(klass->symbols().size(), 1);
    QCOMPARE(klass->symbols().first(), baseClass);

    TranslationUnit *unit = doc->translationUnit();
    QVERIFY(unit != 0);

    TranslationUnitAST *ast = unit->ast()->asTranslationUnit();
    QVERIFY(ast != 0);

    ClassSymbols classSymbols(unit);
    classSymbols(ast);

    QCOMPARE(classSymbols.size(), 2);

    const QMap<Class *, ClassSpecifierAST *> classToAST =
            invert(classSymbols.asMap());

    QVERIFY(classToAST.value(baseClass) != 0);
    QVERIFY(classToAST.value(derivedClass) != 0);
}
示例#11
0
QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, int sizeHint, const QString &scope)
{
    QString previousScope = switchScope(scope);
    items.clear();
    items.reserve(sizeHint);
    for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
        accept(doc->globalSymbolAt(i));
    }
    (void) switchScope(previousScope);
    QList<ModelItemInfo> result = items;
    strings.clear();
    items.clear();
    m_paths.clear();
    return result;
}
示例#12
0
void tst_FindUsages::staticVariables()
{
    const QByteArray src = "\n"
            "struct Outer\n"
            "{\n"
            "    static int Foo;\n"
            "    struct Inner\n"
            "    {\n"
            "        Outer *outer;\n"
            "        void foo();\n"
            "    };\n"
            "};\n"
            "\n"
            "int Outer::Foo = 42;\n"
            "\n"
            "void Outer::Inner::foo()\n"
            "{\n"
            "    Foo  = 7;\n"
            "    Outer::Foo = 7;\n"
            "    outer->Foo = 7;\n"
            "}\n"
            ;
    Document::Ptr doc = Document::create("staticVariables");
    doc->setUtf8Source(src);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 3U);

    Snapshot snapshot;
    snapshot.insert(doc);

    Class *c = doc->globalSymbolAt(0)->asClass();
    QVERIFY(c);
    QCOMPARE(c->name()->identifier()->chars(), "Outer");
    QCOMPARE(c->memberCount(), 2U);
    Declaration *d = c->memberAt(0)->asDeclaration();
    QVERIFY(d);
    QCOMPARE(d->name()->identifier()->chars(), "Foo");

    FindUsages findUsages(src, doc, snapshot);
    findUsages(d);
    QCOMPARE(findUsages.usages().size(), 5);
}
示例#13
0
IndexItem::Ptr SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
{
    IndexItem::Ptr root = IndexItem::create(findOrInsert(doc->fileName()), 100);

    { // RAII scope
        ScopedIndexItemPtr parentRaii(_parent, root);
        QString newScope = scope;
        ScopedScope scopeRaii(_scope, newScope);

        QTC_ASSERT(_parent, return IndexItem::Ptr());
        QTC_ASSERT(root, return IndexItem::Ptr());
        QTC_ASSERT(_parent->fileName() == findOrInsert(doc->fileName()),
                   return IndexItem::Ptr());

        for (unsigned i = 0, ei = doc->globalSymbolCount(); i != ei; ++i)
            accept(doc->globalSymbolAt(i));

        strings.scheduleGC();
        m_paths.clear();
    }

    root->squeeze();
    return root;
}
示例#14
0
void tst_Lookup::iface_impl_scoping()
{
    const QByteArray source = "\n"
                              "@interface Scooping{}-(int)method1:(int)arg;-(void)method2;@end\n"
                              "@implementation Scooping-(int)method1:(int)arg{return arg;}@end\n";

    Document::Ptr doc = Document::create("class_with_protocol_with_protocol");
    doc->setUtf8Source(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 2U);

    Snapshot snapshot;
    snapshot.insert(doc);

    ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass();
    QVERIFY(iface);
    QVERIFY(iface->isInterface());
    ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass();
    QVERIFY(impl);
    QVERIFY(!impl->isInterface());

    QCOMPARE(iface->memberCount(), 2U);
    QCOMPARE(impl->memberCount(), 1U);

    ObjCMethod *method1Impl = impl->memberAt(0)->asObjCMethod();
    QVERIFY(method1Impl);
    QCOMPARE(method1Impl->identifier()->chars(), "method1");

    // get the body of method1
    QCOMPARE(method1Impl->memberCount(), 2U);
    Argument *method1Arg = method1Impl->memberAt(0)->asArgument();
    QVERIFY(method1Arg);
    QCOMPARE(method1Arg->identifier()->chars(), "arg");
    QVERIFY(method1Arg->type()->isIntegerType());

    Block *method1Body = method1Impl->memberAt(1)->asBlock();
    QVERIFY(method1Body);

    const LookupContext context(doc, snapshot);

    { // verify if we can resolve "arg" in the body
        QCOMPARE(method1Impl->argumentCount(), 1U);
        Argument *arg = method1Impl->argumentAt(0)->asArgument();
        QVERIFY(arg);
        QVERIFY(arg->name());
        QVERIFY(arg->name()->identifier());
        QCOMPARE(arg->name()->identifier()->chars(), "arg");
        QVERIFY(arg->type()->isIntegerType());

        const QList<LookupItem> candidates = context.lookup(arg->name(), method1Body->enclosingScope());
        QCOMPARE(candidates.size(), 1);
        QVERIFY(candidates.at(0).declaration()->type()->asIntegerType());
    }

    Declaration *method2 = iface->memberAt(1)->asDeclaration();
    QVERIFY(method2);
    QCOMPARE(method2->identifier()->chars(), "method2");

    { // verify if we can resolve "method2" in the body
        const QList<LookupItem> candidates = context.lookup(method2->name(), method1Body->enclosingScope());
        QCOMPARE(candidates.size(), 1);
        QCOMPARE(candidates.at(0).declaration(), method2);
    }
}
示例#15
0
void tst_Lookup::simple_class_1()
{
    const QByteArray source = "\n"
        "@interface Zoo {} +(id)alloc; -(id)init; @end\n"
        "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n";

    Document::Ptr doc = Document::create("simple_class_1");
    doc->setUtf8Source(source);
    doc->parse();
    doc->check();

    QVERIFY(doc->diagnosticMessages().isEmpty());
    QCOMPARE(doc->globalSymbolCount(), 2U);

    Snapshot snapshot;
    snapshot.insert(doc);

    ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass();
    QVERIFY(iface);
    QVERIFY(iface->isInterface());
    QCOMPARE(iface->memberCount(), 2U);

    ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass();
    QVERIFY(impl);
    QVERIFY(!impl->isInterface());
    QCOMPARE(impl->memberCount(), 3U);

    Declaration *allocMethodIface = iface->memberAt(0)->asDeclaration();
    QVERIFY(allocMethodIface);
    QVERIFY(allocMethodIface->name() && allocMethodIface->name()->identifier());
    QCOMPARE(QLatin1String(allocMethodIface->name()->identifier()->chars()), QLatin1String("alloc"));

    ObjCMethod *allocMethodImpl = impl->memberAt(0)->asObjCMethod();
    QVERIFY(allocMethodImpl);
    QVERIFY(allocMethodImpl->name() && allocMethodImpl->name()->identifier());
    QCOMPARE(QLatin1String(allocMethodImpl->name()->identifier()->chars()), QLatin1String("alloc"));

    ObjCMethod *deallocMethod = impl->memberAt(2)->asObjCMethod();
    QVERIFY(deallocMethod);
    QVERIFY(deallocMethod->name() && deallocMethod->name()->identifier());
    QCOMPARE(QLatin1String(deallocMethod->name()->identifier()->chars()), QLatin1String("dealloc"));

    const LookupContext context(doc, snapshot);

    // check class resolving:
    LookupScope *klass = context.lookupType(impl->name(), impl->enclosingScope());
    QVERIFY(klass != 0);
    QCOMPARE(klass->symbols().size(), 2);
    QVERIFY(klass->symbols().contains(iface));
    QVERIFY(klass->symbols().contains(impl));

    // check method resolving:
    QList<LookupItem> results = context.lookup(allocMethodImpl->name(), impl);
    QCOMPARE(results.size(), 2);
    QCOMPARE(results.at(0).declaration(), allocMethodIface);
    QCOMPARE(results.at(1).declaration(), allocMethodImpl);

    results = context.lookup(deallocMethod->name(), impl);
    QCOMPARE(results.size(), 1);
    QCOMPARE(results.at(0).declaration(), deallocMethod);
}
示例#16
0
void CppToolsPlugin::test_codegen_definition_member_specific_file()
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "void bar();\n" // line 4
            "void baz();\n" // line 5
            "};\n"
            "\n"
            "void Foo::bar()\n"
            "{\n"
            "\n"
            "}\n";

    const QByteArray dstText = QString::fromLatin1(
                "\n"
                "#include \"%1/file.h\"\n" // line 1
                "int x;\n"
                "\n"
                "void Foo::foo()\n" // line 4
                "{\n"
                "\n"
                "}\n" // line 7
                "\n"
                "int y;\n").arg(QDir::tempPath()).toLatin1();

    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
    src->setUtf8Source(srcText);
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 2U);

    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
    dst->addIncludeFile(Document::Include(QLatin1String("file.h"), src->fileName(), 1,
                                          Client::IncludeLocal));
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
    dst->setUtf8Source(dstText);
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 3U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 3U);
    Declaration *decl = foo->memberAt(2)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 5U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl, true, dst->fileName());
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
    QCOMPARE(loc.fileName(), dst->fileName());
    QCOMPARE(loc.line(), 7U);
    QCOMPARE(loc.column(), 2U);
    QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
    QCOMPARE(loc.suffix(), QString());
}