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); }
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); }