Beispiel #1
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);
}
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);
}
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);
}
bool DeclarationContainer::registerDeclaration(
	Declaration const& _declaration,
	ASTString const* _name,
	bool _invisible,
	bool _update
)
{
	if (!_name)
		_name = &_declaration.name();
	if (_name->empty())
		return true;

	if (_update)
	{
		solAssert(!dynamic_cast<FunctionDefinition const*>(&_declaration), "Attempt to update function definition.");
		m_declarations.erase(*_name);
		m_invisibleDeclarations.erase(*_name);
	}
	else if (conflictingDeclaration(_declaration, _name))
		return false;

	vector<Declaration const*>& decls = _invisible ? m_invisibleDeclarations[*_name] : m_declarations[*_name];
	if (!contains(decls, &_declaration))
		decls.push_back(&_declaration);
	return true;
}
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);
}
Beispiel #6
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);
}