| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtTest>
 | 
					
						
							|  |  |  | #include <QObject>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <ASTVisitor.h>
 | 
					
						
							|  |  |  | #include <TranslationUnit.h>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | #include <CppDocument.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | #include <Literals.h>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | #include <LookupContext.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | #include <Name.h>
 | 
					
						
							|  |  |  | #include <ResolveExpression.h>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <Overview.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 11:21:25 +02:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:56:09 +01:00
										 |  |  | template <template <typename, typename> class _Map, typename _T1, typename _T2> | 
					
						
							|  |  |  | _Map<_T2, _T1> invert(const _Map<_T1, _T2> &m) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _Map<_T2, _T1> i; | 
					
						
							|  |  |  |     typename _Map<_T1, _T2>::const_iterator it = m.constBegin(); | 
					
						
							|  |  |  |     for (; it != m.constEnd(); ++it) { | 
					
						
							|  |  |  |         i.insertMulti(it.value(), it.key()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return i; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  | class ClassSymbols: protected ASTVisitor, | 
					
						
							|  |  |  |     public QMap<ClassSpecifierAST *, Class *> | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2009-11-17 14:30:01 +01:00
										 |  |  |     ClassSymbols(TranslationUnit *translationUnit) | 
					
						
							|  |  |  |         : ASTVisitor(translationUnit) | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  |     { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:56:09 +01:00
										 |  |  |     QMap<ClassSpecifierAST *, Class *> asMap() const | 
					
						
							|  |  |  |     { return *this; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  |     void operator()(AST *ast) | 
					
						
							|  |  |  |     { accept(ast); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     virtual bool visit(ClassSpecifierAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |         Class *classSymbol = ast->symbol; | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  |         Q_ASSERT(classSymbol != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         insert(ast, classSymbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | class tst_Lookup: public QObject | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_OBJECT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private Q_SLOTS: | 
					
						
							|  |  |  |     void base_class_defined_1(); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Objective-C
 | 
					
						
							|  |  |  |     void simple_class_1(); | 
					
						
							|  |  |  |     void class_with_baseclass(); | 
					
						
							|  |  |  |     void class_with_protocol_with_protocol(); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |     void iface_impl_scoping(); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							| 
									
										
										
										
											2009-12-07 12:00:35 +01:00
										 |  |  |     snapshot.insert(doc); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Class *baseClass = doc->globalSymbolAt(0)->asClass(); | 
					
						
							|  |  |  |     QVERIFY(baseClass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Class *derivedClass = doc->globalSymbolAt(1)->asClass(); | 
					
						
							|  |  |  |     QVERIFY(derivedClass); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     const LookupContext ctx(doc, snapshot); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     ClassOrNamespace *klass = ctx.lookupType(derivedClass->baseClassAt(0)->name(), derivedClass->scope()); | 
					
						
							|  |  |  |     QVERIFY(klass != 0); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(klass->symbols().size(), 1); | 
					
						
							|  |  |  |     QCOMPARE(klass->symbols().first(), baseClass); | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     TranslationUnit *unit = doc->translationUnit(); | 
					
						
							|  |  |  |     QVERIFY(unit != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TranslationUnitAST *ast = unit->ast()->asTranslationUnit(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:30:01 +01:00
										 |  |  |     ClassSymbols classSymbols(unit); | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  |     classSymbols(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QCOMPARE(classSymbols.size(), 2); | 
					
						
							| 
									
										
										
										
											2009-02-09 11:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const QMap<Class *, ClassSpecifierAST *> classToAST = | 
					
						
							|  |  |  |             invert(classSymbols.asMap()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(classToAST.value(baseClass) != 0); | 
					
						
							|  |  |  |     QVERIFY(classToAST.value(derivedClass) != 0); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 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->setSource(source); | 
					
						
							|  |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  |     QCOMPARE(doc->globalSymbolCount(), 2U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Snapshot snapshot; | 
					
						
							| 
									
										
										
										
											2009-12-07 12:00:35 +01:00
										 |  |  |     snapshot.insert(doc); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ObjCMethod *allocMethod = impl->memberAt(0)->asObjCMethod(); | 
					
						
							|  |  |  |     QVERIFY(allocMethod); | 
					
						
							|  |  |  |     QVERIFY(allocMethod->name() && allocMethod->name()->identifier()); | 
					
						
							|  |  |  |     QCOMPARE(QLatin1String(allocMethod->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")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     const LookupContext context(doc, snapshot); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // check class resolving:
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     ClassOrNamespace *klass = context.lookupType(impl->name(), impl->scope()); | 
					
						
							|  |  |  |     QVERIFY(klass != 0); | 
					
						
							|  |  |  |     QCOMPARE(klass->symbols().size(), 2); | 
					
						
							|  |  |  |     QVERIFY(klass->symbols().contains(iface)); | 
					
						
							|  |  |  |     QVERIFY(klass->symbols().contains(impl)); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // check method resolving:
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QList<Symbol *> results = context.lookup(allocMethod->name(), impl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 2); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(results.at(0), allocMethod); | 
					
						
							|  |  |  |     QCOMPARE(results.at(1), allocMethod); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     results = context.lookup(deallocMethod->name(), impl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(results.at(0), deallocMethod); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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->setSource(source); | 
					
						
							|  |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  |     QCOMPARE(doc->globalSymbolCount(), 3U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Snapshot snapshot; | 
					
						
							| 
									
										
										
										
											2009-12-07 12:00:35 +01:00
										 |  |  |     snapshot.insert(doc); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     const LookupContext context(doc, snapshot); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     ClassOrNamespace *objClass = context.lookupType(baseZoo->name(), zooImpl->scope()); | 
					
						
							|  |  |  |     QVERIFY(objClass != 0); | 
					
						
							|  |  |  |     QVERIFY(objClass->symbols().contains(baseZoo)); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QList<Symbol *> results = context.lookup(baseDecl->name(), zooImpl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(results.at(0), baseDecl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     results = context.lookup(baseMethod->name(), zooImpl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(results.at(0), baseMethod); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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->setSource(source); | 
					
						
							|  |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  |     QCOMPARE(doc->globalSymbolCount(), 4U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Snapshot snapshot; | 
					
						
							| 
									
										
										
										
											2009-12-07 12:00:35 +01:00
										 |  |  |     snapshot.insert(doc); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     const LookupContext context(doc, snapshot); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |         const QList<Symbol *> candidates = context.lookup(P1->name(), zooImpl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							|  |  |  |         QVERIFY(candidates.contains(P1)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |         const QList<Symbol *> candidates = context.lookup(P2->protocolAt(0)->name(), zooImpl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							|  |  |  |         QVERIFY(candidates.contains(P1)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QList<Symbol *> results = context.lookup(p1method->name(), zooImpl->scope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QCOMPARE(results.at(0), p1method); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  | 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->setSource(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(), 1U); | 
					
						
							|  |  |  |     Block *method1Body = method1Impl->memberAt(0)->asBlock(); | 
					
						
							|  |  |  |     QVERIFY(method1Body); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     const LookupContext context(doc, snapshot); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     { // 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"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |         const QList<Symbol *> candidates = context.lookup(arg->name(), method1Body->scope()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							|  |  |  |         QVERIFY(candidates.at(0)->type()->asIntegerType()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Declaration *method2 = iface->memberAt(1)->asDeclaration(); | 
					
						
							|  |  |  |     QVERIFY(method2); | 
					
						
							|  |  |  |     QCOMPARE(method2->identifier()->chars(), "method2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { // verify if we can resolve "method2" in the body
 | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |         const QList<Symbol *> candidates = context.lookup(method2->name(), method1Body->scope()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							|  |  |  |         QCOMPARE(candidates.at(0), method2); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | QTEST_APPLESS_MAIN(tst_Lookup) | 
					
						
							|  |  |  | #include "tst_lookup.moc"
 |