| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2011-02-18 14:48:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2015-01-14 18:07:15 +01:00
										 |  |  | ** Copyright (C) 2015 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: http://www.qt.io/licensing
 | 
					
						
							| 
									
										
										
										
											2011-02-18 14:48:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2011-02-18 14:48:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2015-01-14 18:07:15 +01:00
										 |  |  | ** a written agreement between you and The Qt Company.  For licensing terms and | 
					
						
							|  |  |  | ** conditions see http://www.qt.io/terms-conditions.  For further information
 | 
					
						
							| 
									
										
										
										
											2014-10-01 13:21:18 +02:00
										 |  |  | ** use the contact form at http://www.qt.io/contact-us.
 | 
					
						
							| 
									
										
										
										
											2011-02-18 14:48:16 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							| 
									
										
										
										
											2014-10-01 13:21:18 +02:00
										 |  |  | ** General Public License version 2.1 or version 3 as published by the Free | 
					
						
							|  |  |  | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | 
					
						
							|  |  |  | ** LICENSE.LGPLv3 included in the packaging of this file.  Please review the | 
					
						
							|  |  |  | ** following information to ensure the GNU Lesser General Public License | 
					
						
							|  |  |  | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
 | 
					
						
							|  |  |  | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2015-01-14 18:07:15 +01:00
										 |  |  | ** In addition, as a special exception, The Qt Company gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in The Qt Company LGPL Exception | 
					
						
							| 
									
										
										
										
											2011-02-18 14:48:16 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtTest>
 | 
					
						
							|  |  |  | #include <QObject>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 11:35:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-27 18:54:03 +01:00
										 |  |  | #include <cplusplus/AST.h>
 | 
					
						
							|  |  |  | #include <cplusplus/ASTVisitor.h>
 | 
					
						
							|  |  |  | #include <cplusplus/CppDocument.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Literals.h>
 | 
					
						
							|  |  |  | #include <cplusplus/LookupContext.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Name.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Overview.h>
 | 
					
						
							|  |  |  | #include <cplusplus/ResolveExpression.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Symbols.h>
 | 
					
						
							|  |  |  | #include <cplusplus/TranslationUnit.h>
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 15:32:04 +10:00
										 |  |  | //TESTED_COMPONENT=src/libs/cplusplus
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  | private slots: | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  |     void base_class_defined_1(); | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void document_functionAt_data(); | 
					
						
							|  |  |  |     void document_functionAt(); | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // template instantiation:
 | 
					
						
							|  |  |  |     void templates_1(); | 
					
						
							|  |  |  |     void templates_2(); | 
					
						
							|  |  |  |     void templates_3(); | 
					
						
							|  |  |  |     void templates_4(); | 
					
						
							|  |  |  |     void templates_5(); | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 17:42:34 +03:00
										 |  |  |     LookupScope *klass = ctx.lookupType(derivedClass->baseClassAt(0)->name(), derivedClass->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  | void tst_Lookup::document_functionAt_data() | 
					
						
							| 
									
										
										
										
											2013-05-02 14:55:56 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  |     QTest::addColumn<QByteArray>("source"); | 
					
						
							|  |  |  |     QTest::addColumn<int>("line"); | 
					
						
							|  |  |  |     QTest::addColumn<int>("column"); | 
					
						
							|  |  |  |     QTest::addColumn<QString>("expectedFunction"); | 
					
						
							| 
									
										
										
										
											2014-11-11 12:52:46 +01:00
										 |  |  |     QTest::addColumn<int>("expectedOpeningDeclaratorParenthesisLine"); | 
					
						
							|  |  |  |     QTest::addColumn<int>("expectedClosingBraceLine"); | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-11 10:44:06 +01:00
										 |  |  |     QByteArray source = "\n" | 
					
						
							| 
									
										
										
										
											2013-05-02 14:55:56 +02:00
										 |  |  |             "void Foo::Bar() {\n" // line 1
 | 
					
						
							| 
									
										
										
										
											2014-11-11 10:44:06 +01:00
										 |  |  |             "    \n" | 
					
						
							|  |  |  |             "    for (int i=0; i < 10; ++i) {\n" // line 3
 | 
					
						
							|  |  |  |             "        \n" | 
					
						
							|  |  |  |             "    }\n" // line 5
 | 
					
						
							|  |  |  |             "}\n"; | 
					
						
							|  |  |  |     QString expectedFunction = QString::fromLatin1("Foo::Bar"); | 
					
						
							| 
									
										
										
										
											2014-11-11 12:52:46 +01:00
										 |  |  |     QTest::newRow("nonInline1") << source << 1 << 2 << QString() << -1 << -1; | 
					
						
							|  |  |  |     QTest::newRow("nonInline2") << source << 1 << 11 << expectedFunction << 1 << 6; | 
					
						
							|  |  |  |     QTest::newRow("nonInline3") << source << 2 << 2 << expectedFunction << 1 << 6; | 
					
						
							|  |  |  |     QTest::newRow("nonInline4") << source << 3 << 10 << expectedFunction << 1 << 6; | 
					
						
							|  |  |  |     QTest::newRow("nonInline5") << source << 4 << 3 << expectedFunction << 1 << 6; | 
					
						
							|  |  |  |     QTest::newRow("nonInline6") << source << 6 << 1 << expectedFunction << 1 << 6; | 
					
						
							| 
									
										
										
										
											2014-11-11 10:44:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     source = "\n" | 
					
						
							|  |  |  |             "namespace N {\n" // line 1
 | 
					
						
							|  |  |  |             "class C {\n" | 
					
						
							|  |  |  |             "    void f()\n" // line 3
 | 
					
						
							|  |  |  |             "    {\n" | 
					
						
							|  |  |  |             "    }\n" // line 5
 | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "}\n"; // line 7
 | 
					
						
							|  |  |  |     expectedFunction = QString::fromLatin1("N::C::f"); | 
					
						
							| 
									
										
										
										
											2014-11-11 12:52:46 +01:00
										 |  |  |     QTest::newRow("inline1") << source << 1 << 2 << QString() << -1 << -1; | 
					
						
							|  |  |  |     QTest::newRow("inline2") << source << 2 << 10 << QString() << -1 << -1; | 
					
						
							|  |  |  |     QTest::newRow("inline2") << source << 3 << 10 << expectedFunction << 3 << 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     source = "\n" | 
					
						
							|  |  |  |             "void f(Helper helper = [](){})\n" // line 1
 | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "}\n"; // line 3
 | 
					
						
							|  |  |  |     expectedFunction = QString::fromLatin1("f"); | 
					
						
							|  |  |  |     QTest::newRow("inlineWithLambdaArg1") << source << 2 << 1 << expectedFunction << 1 << 3; | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_Lookup::document_functionAt() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QFETCH(QByteArray, source); | 
					
						
							|  |  |  |     QFETCH(int, line); | 
					
						
							|  |  |  |     QFETCH(int, column); | 
					
						
							|  |  |  |     QFETCH(QString, expectedFunction); | 
					
						
							| 
									
										
										
										
											2014-11-11 12:52:46 +01:00
										 |  |  |     QFETCH(int, expectedOpeningDeclaratorParenthesisLine); | 
					
						
							|  |  |  |     QFETCH(int, expectedClosingBraceLine); | 
					
						
							| 
									
										
										
										
											2013-05-02 14:55:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-11 10:38:01 +01:00
										 |  |  |     Document::Ptr doc = Document::create("document_functionAt"); | 
					
						
							| 
									
										
										
										
											2013-05-02 14:55:56 +02:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							|  |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							| 
									
										
										
										
											2014-11-11 12:52:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int actualOpeningDeclaratorParenthesisLine = -1; | 
					
						
							|  |  |  |     int actualClosingBraceLine = -1; | 
					
						
							|  |  |  |     const QString actualFunction = doc->functionAt(line, column, | 
					
						
							|  |  |  |                                                    &actualOpeningDeclaratorParenthesisLine, | 
					
						
							|  |  |  |                                                    &actualClosingBraceLine); | 
					
						
							|  |  |  |     QCOMPARE(actualFunction, expectedFunction); | 
					
						
							|  |  |  |     QCOMPARE(actualOpeningDeclaratorParenthesisLine, expectedOpeningDeclaratorParenthesisLine); | 
					
						
							|  |  |  |     QCOMPARE(actualClosingBraceLine, expectedClosingBraceLine); | 
					
						
							| 
									
										
										
										
											2013-05-02 14:55:56 +02: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"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-20 12:13:44 +02:00
										 |  |  |     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")); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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:
 | 
					
						
							| 
									
										
										
										
											2015-04-20 17:42:34 +03:00
										 |  |  |     LookupScope *klass = context.lookupType(impl->name(), impl->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     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-08-11 16:06:40 +02:00
										 |  |  |     QList<LookupItem> results = context.lookup(allocMethodImpl->name(), impl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 2); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     QCOMPARE(results.at(0).declaration(), allocMethodIface); | 
					
						
							|  |  |  |     QCOMPARE(results.at(1).declaration(), allocMethodImpl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-11 16:06:40 +02:00
										 |  |  |     results = context.lookup(deallocMethod->name(), impl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     QCOMPARE(results.at(0).declaration(), 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"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 17:42:34 +03:00
										 |  |  |     LookupScope *objClass = context.lookupType(baseZoo->name(), zooImpl->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-05-18 10:33:35 +02:00
										 |  |  |     QVERIFY(objClass != 0); | 
					
						
							|  |  |  |     QVERIFY(objClass->symbols().contains(baseZoo)); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-11 16:06:40 +02:00
										 |  |  |     QList<LookupItem> results = context.lookup(baseDecl->name(), zooImpl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     QCOMPARE(results.at(0).declaration(), baseDecl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-11 16:06:40 +02:00
										 |  |  |     results = context.lookup(baseMethod->name(), zooImpl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     QCOMPARE(results.at(0).declaration(), 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"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     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-08-26 16:16:22 +02:00
										 |  |  |         const QList<LookupItem> candidates = context.lookup(P1->name(), zooImpl->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |         QVERIFY(candidates.at(0).declaration() == P1); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |         const QList<LookupItem> candidates = context.lookup(P2->protocolAt(0)->name(), zooImpl->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |         QVERIFY(candidates.first().declaration() == P1); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-11 16:06:40 +02:00
										 |  |  |     QList<LookupItem> results = context.lookup(p1method->name(), zooImpl); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     QCOMPARE(results.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     QCOMPARE(results.at(0).declaration(), 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"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2010-08-13 16:52:59 +02:00
										 |  |  |     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(); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2010-09-15 10:17:56 +02:00
										 |  |  |         QCOMPARE(method1Impl->argumentCount(), 1U); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |         Argument *arg = method1Impl->argumentAt(0)->asArgument(); | 
					
						
							|  |  |  |         QVERIFY(arg); | 
					
						
							|  |  |  |         QVERIFY(arg->name()); | 
					
						
							|  |  |  |         QVERIFY(arg->name()->identifier()); | 
					
						
							|  |  |  |         QCOMPARE(arg->name()->identifier()->chars(), "arg"); | 
					
						
							| 
									
										
										
										
											2010-08-13 16:52:59 +02:00
										 |  |  |         QVERIFY(arg->type()->isIntegerType()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |         const QList<LookupItem> candidates = context.lookup(arg->name(), method1Body->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |         QVERIFY(candidates.at(0).declaration()->type()->asIntegerType()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Declaration *method2 = iface->memberAt(1)->asDeclaration(); | 
					
						
							|  |  |  |     QVERIFY(method2); | 
					
						
							|  |  |  |     QCOMPARE(method2->identifier()->chars(), "method2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { // verify if we can resolve "method2" in the body
 | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |         const QList<LookupItem> candidates = context.lookup(method2->name(), method1Body->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |         QCOMPARE(candidates.size(), 1); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |         QCOMPARE(candidates.at(0).declaration(), method2); | 
					
						
							| 
									
										
										
										
											2010-02-10 16:53:01 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  | void tst_Lookup::templates_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QByteArray source = "\n" | 
					
						
							|  |  |  |             "namespace std {\n" | 
					
						
							|  |  |  |             "    template <typename T>\n" | 
					
						
							|  |  |  |             "    struct _List_iterator {\n" | 
					
						
							|  |  |  |             "        T data;\n" | 
					
						
							|  |  |  |             "    };\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    template <typename T>\n" | 
					
						
							|  |  |  |             "    struct list {\n" | 
					
						
							|  |  |  |             "        typedef _List_iterator<T> iterator;\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "        iterator begin();\n" | 
					
						
							|  |  |  |             "        _List_iterator<T> end();\n" | 
					
						
							|  |  |  |             "    };\n" | 
					
						
							|  |  |  |             "}\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "struct Point {\n" | 
					
						
							|  |  |  |             "    int x, y;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "int main()\n" | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "    std::list<Point> l;\n" | 
					
						
							|  |  |  |             "    l.begin();  // std::_List_iterator<Point> .. and not only _List_iterator<Point>\n" | 
					
						
							|  |  |  |             "    l.end(); // std::_List_iterator<Point>\n" | 
					
						
							|  |  |  |             "}\n"; | 
					
						
							|  |  |  |     Document::Ptr doc = Document::create("templates_1"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_Lookup::templates_2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QByteArray source = "\n" | 
					
						
							|  |  |  |             "template <typename T1>\n" | 
					
						
							|  |  |  |             "struct Node {\n" | 
					
						
							|  |  |  |             "    T1 value;\n" | 
					
						
							|  |  |  |             "    Node *next;\n" | 
					
						
							|  |  |  |             "    Node<T1> *other_next;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "template <typename T2>\n" | 
					
						
							|  |  |  |             "struct List {\n" | 
					
						
							|  |  |  |             "    Node<T2> *elements;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "int main()\n" | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "    List<int> *e;\n" | 
					
						
							|  |  |  |             "    e->elements; // Node<int> *\n" | 
					
						
							|  |  |  |             "    e->elements->next; // Node<int> *\n" | 
					
						
							|  |  |  |             "    e->elements->other_next; // Node<int> *\n" | 
					
						
							|  |  |  |             "}\n" | 
					
						
							|  |  |  | ; | 
					
						
							|  |  |  |     Document::Ptr doc = Document::create("templates_2"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_Lookup::templates_3() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QByteArray source = "\n" | 
					
						
							|  |  |  |             "struct Point {\n" | 
					
						
							|  |  |  |             "    int x, y;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "template <typename T = Point>\n" | 
					
						
							|  |  |  |             "struct List {\n" | 
					
						
							|  |  |  |             "    const T &at(int);\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "int main()\n" | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "    List<> l;\n" | 
					
						
							|  |  |  |             "    l.at(0); // const Point &\n" | 
					
						
							|  |  |  |             "}\n"; | 
					
						
							|  |  |  |     Document::Ptr doc = Document::create("templates_3"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_Lookup::templates_4() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QByteArray source = "\n" | 
					
						
							|  |  |  |             "template <typename T>\n" | 
					
						
							|  |  |  |             "struct Allocator {\n" | 
					
						
							|  |  |  |             "    typedef T *pointer_type;\n" | 
					
						
							|  |  |  |             "    typedef T &reference_type;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "template <typename T>\n" | 
					
						
							|  |  |  |             "struct SharedPtr {\n" | 
					
						
							|  |  |  |             "    typedef typename Allocator<T>::pointer_type pointer_type;\n" | 
					
						
							|  |  |  |             "    typedef typename Allocator<T>::reference_type reference_type;\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    pointer_type operator->();\n" | 
					
						
							|  |  |  |             "    reference_type operator*();\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    pointer_type data();\n" | 
					
						
							|  |  |  |             "    reference_type get();\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "struct Point {\n" | 
					
						
							|  |  |  |             "    int x,y;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "int main()\n" | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "    SharedPtr<Point> l;\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    l->x; // int\n" | 
					
						
							|  |  |  |             "    (*l); // Point &\n" | 
					
						
							|  |  |  |             "}\n"; | 
					
						
							|  |  |  |     Document::Ptr doc = Document::create("templates_4"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_Lookup::templates_5() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QByteArray source = "\n" | 
					
						
							|  |  |  |             "struct Point {\n" | 
					
						
							|  |  |  |             "    int x,y;\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "template <typename _Tp>\n" | 
					
						
							|  |  |  |             "struct Allocator {\n" | 
					
						
							|  |  |  |             "    typedef const _Tp &const_reference;\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    const_reference get();\n" | 
					
						
							|  |  |  |             "};\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "int main()\n" | 
					
						
							|  |  |  |             "{\n" | 
					
						
							|  |  |  |             "    Allocator<Point>::const_reference r = pt;\n" | 
					
						
							|  |  |  |             "    //r.; // const Point &\n" | 
					
						
							|  |  |  |             "\n" | 
					
						
							|  |  |  |             "    Allocator<Point> a;\n" | 
					
						
							|  |  |  |             "    a.get(); // const Point &\n" | 
					
						
							|  |  |  |             "}\n"; | 
					
						
							|  |  |  |     Document::Ptr doc = Document::create("templates_5"); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:53:56 +01:00
										 |  |  |     doc->setUtf8Source(source); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(doc->diagnosticMessages().isEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 10:21:29 +01:00
										 |  |  | QTEST_APPLESS_MAIN(tst_Lookup) | 
					
						
							|  |  |  | #include "tst_lookup.moc"
 |