~ubuntu-branches/ubuntu/karmic/kdevelop/karmic

« back to all changes in this revision

Viewing changes to languages/cpp/cppduchain/tests/test_duchain.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-06-28 20:48:13 UTC
  • mfrom: (1.1.12 upstream) (2.3.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20090628204813-m6qlb9e92ig9h04m
Tags: 4:3.9.94-1ubuntu1
* Merge from Debian experimental, remaining changes:
  - Conflict/replace -kde4 packages
  - Remove gdb from recommends, version >= 6.8.50 is not yet in Ubuntu

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <time.h>
40
40
#include "cpptypes.h"
41
41
#include "templateparameterdeclaration.h"
42
 
#include <language/editor/documentrange.h>
43
42
#include "cppeditorintegrator.h"
44
43
#include "dumptypes.h"
45
44
#include "environmentmanager.h"
46
45
#include <language/util/setrepository.h>
 
46
 
47
47
#include <language/editor/hashedstring.h>
 
48
#include <language/editor/documentrange.h>
 
49
 
48
50
#include "typeutils.h"
49
51
#include "templatedeclaration.h"
50
 
#include <language/duchain/indexedstring.h>
51
52
#include "rpp/chartools.h"
52
53
#include "rpp/pp-engine.h"
53
54
#include "rpp/preprocessor.h"
 
55
 
 
56
#include <language/duchain/indexedstring.h>
54
57
#include <language/duchain/classdeclaration.h>
55
58
#include <language/duchain/types/alltypes.h>
56
59
#include <language/duchain/persistentsymboltable.h>
57
60
#include <language/duchain/codemodel.h>
 
61
#include <language/codegen/coderepresentation.h>
58
62
 
59
63
#include "tokens.h"
60
64
#include "parsesession.h"
 
65
#include "astutilities.h"
61
66
 
62
67
//Extremely slow
63
68
// #define TEST_NORMAL_IMPORTS
67
72
#include <qtfunctiondeclaration.h>
68
73
#include <qwidget.h>
69
74
#include <language/duchain/navigation/abstractnavigationwidget.h>
 
75
#include <sourcemanipulation.h>
70
76
 
71
77
//Uncomment the following line to get additional output from the string-repository test
72
78
//#define DEBUG_STRINGREPOSITORY
167
173
  noDef = 0;
168
174
 
169
175
  DUChain::self()->disablePersistentStorage();
 
176
  KDevelop::CodeRepresentation::setDiskChangesForbidden(true);
170
177
 
171
178
  file1 = "file:///media/data/kdedev/4.0/kdevelop/languages/cpp/parser/duchain.cpp";
172
179
  file2 = "file:///media/data/kdedev/4.0/kdevelop/languages/cpp/parser/dubuilder.cpp";
342
349
}
343
350
 
344
351
void TestDUChain::testContextSearch() {
345
 
  QByteArray method("typedef union { char __size[2]; long int __align; } pthread_attr_t; struct Stru {};");
346
 
  
347
 
  TopDUContext* top = parse(method, DumpNone);
348
 
  DUChainWriteLocker lock(DUChain::lock());
349
 
  QCOMPARE(top->findContexts(DUContext::Class, QualifiedIdentifier("Stru") ).count(), 1);
350
 
  QCOMPARE(top->findContexts(DUContext::Namespace, QualifiedIdentifier("Stru") ).count(), 0);
 
352
  {
 
353
    QByteArray method("int t; struct C { }; void test() { C c; c.t = 3;}");
 
354
    
 
355
    TopDUContext* top = parse(method, DumpAll);
 
356
    DUChainWriteLocker lock(DUChain::lock());
 
357
    QCOMPARE(top->localDeclarations().count(), 3);
 
358
    QVERIFY(top->localDeclarations()[0]->uses().isEmpty());
 
359
    release(top);
 
360
  }
 
361
  {
 
362
    QByteArray method("typedef union { char __size[2]; long int __align; } pthread_attr_t; struct Stru {};");
 
363
    
 
364
    TopDUContext* top = parse(method, DumpNone);
 
365
    DUChainWriteLocker lock(DUChain::lock());
 
366
    QCOMPARE(top->findContexts(DUContext::Class, QualifiedIdentifier("Stru") ).count(), 1);
 
367
    QCOMPARE(top->findContexts(DUContext::Namespace, QualifiedIdentifier("Stru") ).count(), 0);
 
368
    release(top);
 
369
  }
351
370
}
352
371
 
353
372
void TestDUChain::testSeparateVariableDefinition() {
358
377
    * A prefix-context is created that surrounds S::testValue to represent the "S" part of the scope.
359
378
    */
360
379
    
361
 
    TopDUContext* top = parse(method, DumpAll);
 
380
    TopDUContext* top = parse(method, DumpNone);
362
381
    DUChainWriteLocker lock(DUChain::lock());
363
382
    QCOMPARE(top->localDeclarations().count(), 2);
364
383
    QCOMPARE(top->localDeclarations()[0]->qualifiedIdentifier(), QualifiedIdentifier("S"));
389
408
    //Declaration + definition
390
409
    QByteArray method("extern int x; int x;");
391
410
    
392
 
    TopDUContext* top = parse(method, DumpAll);
 
411
    TopDUContext* top = parse(method, DumpNone);
393
412
    DUChainWriteLocker lock(DUChain::lock());
394
413
    QCOMPARE(top->localDeclarations().count(), 2);
395
414
    ///@todo declaration/definition relationship
521
540
{
522
541
  TEST_FILE_PARSE_ONLY
523
542
 
524
 
  //                 0         1         2         3         4         5
525
 
  //                 012345678901234567890123456789012345678901234567890123456789
526
 
  QByteArray method("class A{ class B {}; }; class C : public A::B { C() : A::B() {} };");
527
 
 
528
 
  TopDUContext* top = parse(method, DumpNone);
529
 
 
530
 
  DUChainWriteLocker lock(DUChain::lock());
531
 
 
532
 
  QCOMPARE(top->localDeclarations().count(), 2);
533
 
  QCOMPARE(top->childContexts().count(), 2);
534
 
  QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
535
 
  QCOMPARE(top->childContexts()[1]->usesCount(), 2);
536
 
 
537
 
  QCOMPARE(top->childContexts()[1]->uses()[0].m_range, SimpleRange(0, 41, 0, 42));
538
 
  QCOMPARE(top->childContexts()[1]->uses()[1].m_range, SimpleRange(0, 44, 0, 45));
539
 
 
540
 
  QCOMPARE(top->localDeclarations()[0]->uses().count(), 1);
541
 
  QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().count(), 1);
542
 
 
543
 
  QCOMPARE(top->childContexts()[1]->childContexts().count(), 2);
544
 
  QCOMPARE(top->childContexts()[1]->childContexts()[1]->usesCount(), 2);
545
 
 
546
 
  release(top);
 
543
{
 
544
    //                 0         1         2         3         4         5
 
545
    //                 012345678901234567890123456789012345678901234567890123456789
 
546
    QByteArray method("namespace N { struct A { A(int); int m; }; }; struct B : public N::A { B() : N::A(5) { this->N::A::m = 5; } };");
 
547
 
 
548
    TopDUContext* top = parse(method, DumpAll);
 
549
 
 
550
    DUChainWriteLocker lock(DUChain::lock());
 
551
 
 
552
    QVERIFY(top->problems().isEmpty()); //N::A must be found in the constructor
 
553
    QCOMPARE(top->childContexts().count(), 2);
 
554
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
 
555
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().size(), 1);
 
556
    QCOMPARE(top->childContexts()[0]->childContexts().count(), 1);
 
557
    QCOMPARE(top->childContexts()[0]->childContexts()[0]->localDeclarations().count(), 2);
 
558
    QVERIFY(!top->childContexts()[0]->childContexts()[0]->localDeclarations()[1]->uses().isEmpty());
 
559
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().begin()->size(), 3);
 
560
 
 
561
    release(top);
 
562
  }
 
563
 
 
564
  {
 
565
    //                 0         1         2         3         4         5
 
566
    //                 012345678901234567890123456789012345678901234567890123456789
 
567
    QByteArray method("class A{ class B {}; }; class C : public A::B { C() : A::B() {} };");
 
568
 
 
569
    TopDUContext* top = parse(method, DumpNone);
 
570
 
 
571
    DUChainWriteLocker lock(DUChain::lock());
 
572
 
 
573
    QCOMPARE(top->localDeclarations().count(), 2);
 
574
    QCOMPARE(top->childContexts().count(), 2);
 
575
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
 
576
    QCOMPARE(top->childContexts()[1]->usesCount(), 2);
 
577
 
 
578
    QCOMPARE(top->childContexts()[1]->uses()[0].m_range, SimpleRange(0, 41, 0, 42));
 
579
    QCOMPARE(top->childContexts()[1]->uses()[1].m_range, SimpleRange(0, 44, 0, 45));
 
580
 
 
581
    QCOMPARE(top->localDeclarations()[0]->uses().count(), 1);
 
582
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().count(), 1);
 
583
 
 
584
    QCOMPARE(top->childContexts()[1]->childContexts().count(), 2);
 
585
    QCOMPARE(top->childContexts()[1]->childContexts()[1]->usesCount(), 2);
 
586
 
 
587
    release(top);
 
588
  }
547
589
}
548
590
 
549
591
 
553
595
 
554
596
    //                 0         1         2         3         4         5
555
597
    //                 012345678901234567890123456789012345678901234567890123456789
556
 
    QByteArray method("namespace Search { typedef int StateHypothesisIndex; StateHypothesisIndex i; }");
 
598
    QByteArray method("namespace Search { typedef int StateHypothesisIndexwqeqrqwe; StateHypothesisIndexwqeqrqwe i; }");
557
599
 
558
600
    TopDUContext* top = parse(method, DumpAll);
559
601
 
984
1026
    QVERIFY(!memberFun->isStatic());
985
1027
}
986
1028
 
 
1029
 
 
1030
void TestDUChain::testAssignedContexts()
 
1031
{
 
1032
  {
 
1033
    QByteArray method("void test() { int i; if(i) { int q; }  int c; while(c) { char q; } int w; { float q;  } }");
 
1034
 
 
1035
    TopDUContext* top = parse(method, DumpNone);
 
1036
 
 
1037
    DUChainWriteLocker lock(DUChain::lock());
 
1038
    QCOMPARE(top->childContexts().count(), 2);
 
1039
    QCOMPARE(top->childContexts()[1]->type(), DUContext::Other);
 
1040
    QCOMPARE(top->childContexts()[1]->childContexts().count(), 4);
 
1041
    QCOMPARE(top->childContexts()[1]->localDeclarations().count(), 3);
 
1042
    QVERIFY(!top->childContexts()[1]->childContexts()[0]->owner());
 
1043
    QVERIFY(!top->childContexts()[1]->childContexts()[1]->owner());
 
1044
    QVERIFY(!top->childContexts()[1]->childContexts()[2]->owner());
 
1045
    QVERIFY(!top->childContexts()[1]->childContexts()[3]->owner());
 
1046
    release(top);
 
1047
  }
 
1048
}
 
1049
 
987
1050
void TestDUChain::testTryCatch() {
988
1051
  TEST_FILE_PARSE_ONLY
989
1052
  {
1062
1125
    QVERIFY(top->childContexts()[0]->childContexts()[0]->childContexts()[0]->isPropagateDeclarations());
1063
1126
    QVERIFY(!top->childContexts()[0]->childContexts()[0]->childContexts()[0]->localDeclarations()[0]->uses().isEmpty());
1064
1127
    QCOMPARE(top->childContexts()[2]->usesCount(), 9);
 
1128
    
 
1129
    //Now test Ast mappings
 
1130
    parse(method, DumpNone, top, true);
 
1131
    //!@todo conversions through KSharedPtr
 
1132
    QVERIFY(top->ast().data());
 
1133
    QVERIFY(dynamic_cast<ParseSession *>(top->ast().data()));
 
1134
    ParseSession::Ptr session = ParseSession::Ptr( dynamic_cast<ParseSession *>(top->ast().data()) );
 
1135
    QVERIFY(session);
 
1136
    TranslationUnitAST * ast = session->topAstNode();
 
1137
    QVERIFY(ast);
 
1138
    QCOMPARE(ast->declarations->count(), 3);
 
1139
    
 
1140
    //First verify that the node indices correspond to the expected type,
 
1141
    //then test that they correspond to their DUChain mappings
 
1142
    QVERIFY(AstUtils::childNode<SimpleDeclarationAST>(ast, 0));
 
1143
    QCOMPARE(AstUtils::childNode<SimpleDeclarationAST>(ast, 0)->type_specifier,
 
1144
             session->astNodeFromDeclaration(KDevelop::DeclarationPointer(top->localDeclarations()[0])));
 
1145
    QVERIFY(AstUtils::childNode<SimpleDeclarationAST>(ast, 1));
 
1146
    QCOMPARE(AstUtils::childNode<SimpleDeclarationAST>(ast, 1),
 
1147
             session->astNodeFromDeclaration(KDevelop::DeclarationPointer(top->localDeclarations()[1])));
 
1148
    QVERIFY(AstUtils::childNode<FunctionDefinitionAST>(ast, 2));
 
1149
    QCOMPARE(AstUtils::childNode<FunctionDefinitionAST>(ast, 2),
 
1150
             session->astNodeFromDeclaration(KDevelop::DeclarationPointer(top->localDeclarations()[2])) );
 
1151
             
 
1152
    release(top);
1065
1153
  }
1066
1154
 
1067
1155
  {
1256
1344
  {
1257
1345
    QByteArray method("namespace B {class C {struct A;void test();};};using namespace B;struct C::A {};");
1258
1346
 
1259
 
    TopDUContext* top = parse(method, DumpNone);
 
1347
    TopDUContext* top = parse(method, DumpAll);
1260
1348
 
1261
1349
    DUChainWriteLocker lock(DUChain::lock());
1262
1350
 
1305
1393
  {
1306
1394
  QByteArray method("struct A {struct C c; }; struct C { int v; };");
1307
1395
 
1308
 
  /* Expected result: the elaborated type-specifier "struct C" within the declaration "struct A" should create a new global declaration.
1309
 
  */
 
1396
  //Expected result: the elaborated type-specifier "struct C" within the declaration "struct A" should create a new global declaration.
 
1397
  
1310
1398
 
1311
1399
  TopDUContext* top = parse(method, DumpNone);
1312
1400
 
1319
1407
  kDebug() << "TYPE:" << top->childContexts()[0]->localDeclarations()[0]->abstractType()->toString() << typeid(*top->childContexts()[0]->localDeclarations()[0]->abstractType()).name();
1320
1408
  QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->indexedType(), top->localDeclarations()[1]->indexedType());
1321
1409
 
1322
 
  QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->kind(), Declaration::Instance); /*QVERIFY(top->localDeclarations()[0]->kind() == Declaration::Type);
1323
 
  QVERIFY(top->localDeclarations()[1]->kind() == Declaration::Instance);*/
 
1410
  QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->kind(), Declaration::Instance);
 
1411
  //QVERIFY(top->localDeclarations()[0]->kind() == Declaration::Type);
 
1412
  //QVERIFY(top->localDeclarations()[1]->kind() == Declaration::Instance);
1324
1413
  release(top);
1325
1414
  }
1326
1415
  {
1327
1416
  QByteArray method("struct A {inline struct C c() {}; }; struct C { int v; };");
1328
1417
 
1329
 
  /* Expected result: the elaborated type-specifier "struct C" within the declaration "struct A" should create a new global declaration.
1330
 
  */
 
1418
  //Expected result: the elaborated type-specifier "struct C" within the declaration "struct A" should create a new global declaration.
 
1419
  
1331
1420
 
1332
1421
  TopDUContext* top = parse(method, DumpNone);
1333
1422
 
1344
1433
  QCOMPARE(function->returnType()->indexed(), top->localDeclarations()[1]->indexedType());
1345
1434
  //QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->indexedType(), top->localDeclarations()[1]->indexedType());
1346
1435
 
1347
 
  //QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->kind(), Declaration::Instance); /*QVERIFY(top->localDeclarations()[0]->kind() == Declaration::Type);
1348
 
//   QVERIFY(top->localDeclarations()[1]->kind() == Declaration::Instance);
 
1436
  //QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->kind(), Declaration::Instance);
 
1437
  //QVERIFY(top->localDeclarations()[0]->kind() == Declaration::Type);
 
1438
  //QVERIFY(top->localDeclarations()[1]->kind() == Declaration::Instance);
1349
1439
  release(top);
1350
1440
  }
1351
1441
 
1393
1483
  DUChainWriteLocker lock(DUChain::lock());
1394
1484
 
1395
1485
  DumpDotGraph dump;
1396
 
/*  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
 
1486
//  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
1397
1487
 
1398
 
  kDebug() << "ENDE ENDE ENDE";
1399
 
  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);*/
 
1488
//  kDebug() << "ENDE ENDE ENDE";
 
1489
//  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
1400
1490
 
1401
1491
  QVERIFY(!top->parentContext());
1402
1492
  QCOMPARE(top->childContexts().count(), 3);
1430
1520
  Declaration* defRec = classA->localDeclarations()[1];
1431
1521
  QVERIFY(defRec->abstractType());
1432
1522
  QCOMPARE(defRec->abstractType()->indexed(), defClassA->abstractType()->indexed());
1433
 
 
 
1523
  
 
1524
  //Test Ast-DuChain mappings
 
1525
  parse(method, DumpAST, top, true);
 
1526
  
 
1527
  ParseSession::Ptr session = ParseSession::Ptr(dynamic_cast<ParseSession *>(top->ast().data()));
 
1528
  TranslationUnitAST * ast = session->topAstNode();
 
1529
  QVERIFY(ast);
 
1530
  ClassSpecifierAST * classAst = AstUtils::node_cast<ClassSpecifierAST>
 
1531
                               (AstUtils::childNode<SimpleDeclarationAST>(ast, 0)->type_specifier);
 
1532
  QVERIFY(classAst);
 
1533
  kDebug() << "count:" << classAst->member_specs->count();
 
1534
  QCOMPARE(session->declarationFromAstNode( AstUtils::childNode<SimpleDeclarationAST>(ast, 0)->type_specifier ),
 
1535
           KDevelop::DeclarationPointer(top->localDeclarations()[0]));
 
1536
  QCOMPARE(session->declarationFromAstNode( AstUtils::childNode<FunctionDefinitionAST>(classAst, 0) ),
 
1537
           KDevelop::DeclarationPointer(top->childContexts()[0]->localDeclarations()[0]));
 
1538
           
 
1539
  //I haven't figured out why the AST inserts a NULL node after A's constructor
 
1540
  QCOMPARE(session->declarationFromAstNode( AstUtils::childNode<SimpleDeclarationAST>(classAst, 2) ),
 
1541
           KDevelop::DeclarationPointer(top->childContexts()[0]->localDeclarations()[1]));
 
1542
  QCOMPARE(session->declarationFromAstNode( AstUtils::childNode<SimpleDeclarationAST>(classAst, 3) ),
 
1543
           KDevelop::DeclarationPointer(top->childContexts()[0]->localDeclarations()[2]));
 
1544
           
1434
1545
  release(top);
1435
1546
}
1436
1547
 
1442
1553
  //                 01234567890123456789012345678901234567890123456789012345678901234567890123456789
1443
1554
  QByteArray method("class A { friend class F; }; ");
1444
1555
 
1445
 
  TopDUContext* top = parse(method, DumpAll);
 
1556
  TopDUContext* top = parse(method, DumpNone);
1446
1557
 
1447
1558
  DUChainWriteLocker lock(DUChain::lock());
1448
1559
 
1449
1560
  DumpDotGraph dump;
1450
 
/*  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
 
1561
//  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
1451
1562
 
1452
 
  kDebug() << "ENDE ENDE ENDE";
1453
 
  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);*/
 
1563
//  kDebug() << "ENDE ENDE ENDE";
 
1564
//  kDebug() << "dot-graph: \n" << dump.dotGraph(top, false);
1454
1565
 
1455
1566
  QVERIFY(!top->parentContext());
1456
1567
  QCOMPARE(top->childContexts().count(), 1);
1721
1832
  //QCOMPARE(top->namespaceAliases().count(), 1);
1722
1833
  //QCOMPARE(top->namespaceAliases().first()->nsIdentifier, QualifiedIdentifier("foo"));
1723
1834
 
1724
 
/*  QCOMPARE(findDeclaration(top, QualifiedIdentifier("bar2")), bar2);*/
 
1835
  //QCOMPARE(findDeclaration(top, QualifiedIdentifier("bar2")), bar2);
1725
1836
  QCOMPARE(findDeclaration(top, QualifiedIdentifier("::bar")), noDef);
1726
1837
  QCOMPARE(findDeclaration(top, QualifiedIdentifier("foo::bar2")), bar2);
1727
1838
  QCOMPARE(findDeclaration(top, QualifiedIdentifier("foo2::bar2")), bar2);
1747
1858
  //                 01234567890123456789012345678901234567890123456789012345678901234567890123456789
1748
1859
  QByteArray method("namespace foo { int bar; } using namespace foo; namespace alternativeFoo = foo; int test() { return bar; }");
1749
1860
 
1750
 
  TopDUContext* top = parse(method, DumpAll);
 
1861
  TopDUContext* top = parse(method, DumpNone);
1751
1862
 
1752
1863
  DUChainWriteLocker lock(DUChain::lock());
1753
1864
 
1806
1917
  {
1807
1918
    QByteArray text("#define Q___qt_sig_slot__S signals\n#define signals bla\n#undef signals\nclass C {Q___qt_sig_slot__S: void signal2(); public slots: void slot2();}; ");
1808
1919
 
1809
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(text, DumpAll));
 
1920
    TopDUContext* top = parse(text, DumpNone);
1810
1921
 
1811
1922
    DUChainWriteLocker lock(DUChain::lock());
1812
1923
    QCOMPARE(top->localDeclarations().count(), 1);
1828
1939
  {
1829
1940
    QByteArray text("namespace A { class B;} class Q { public slots: void slot(A::B b, const Q* q); }; ");
1830
1941
 
1831
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(text, DumpNone));
 
1942
    TopDUContext* top = parse(text, DumpNone);
1832
1943
 
1833
1944
    DUChainWriteLocker lock(DUChain::lock());
1834
1945
    QCOMPARE(top->localDeclarations().count(), 2);
1846
1957
  {
1847
1958
    QByteArray text("class TE; class QObject { void connect(QObject* from, const char* signal, QObject* to, const char* slot); void connect(QObject* from, const char* signal, const char* slot); }; class A : public QObject { public slots: void slot1(); void slot2(TE*); signals: void signal1(TE*, char);void signal2(); public: void test() { \nconnect(this, __qt_sig_slot__( signal1(TE*, const char&)), this, __qt_sig_slot__(slot2(TE*))); \nconnect(this, __qt_sig_slot__(signal2()), \n__qt_sig_slot__(slot1())); } };");
1848
1959
 
1849
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(text, DumpNone));
 
1960
    TopDUContext* top = parse(text, DumpNone);
1850
1961
 
1851
1962
    DUChainWriteLocker lock(DUChain::lock());
1852
1963
    QCOMPARE(top->localDeclarations().count(), 3);
1855
1966
    QtFunctionDeclaration* qtDecl = dynamic_cast<QtFunctionDeclaration*>(top->childContexts()[1]->localDeclarations()[0]);
1856
1967
    QVERIFY(qtDecl);
1857
1968
    QVERIFY(top->childContexts()[1]->localDeclarations()[0]->uses().count());
1858
 
/*    kDebug() << top->childContexts()[1]->localDeclarations()[0]->uses().begin()->first().textRange();
1859
 
    kDebug() << top->childContexts()[1]->localDeclarations()[1]->uses().begin()->first().textRange();
1860
 
    kDebug() << top->childContexts()[1]->localDeclarations()[2]->uses().begin()->first().textRange();
1861
 
    kDebug() << top->childContexts()[1]->localDeclarations()[3]->uses().begin()->first().textRange();*/
 
1969
    //kDebug() << top->childContexts()[1]->localDeclarations()[0]->uses().begin()->first().textRange();
 
1970
    //kDebug() << top->childContexts()[1]->localDeclarations()[1]->uses().begin()->first().textRange();
 
1971
    //kDebug() << top->childContexts()[1]->localDeclarations()[2]->uses().begin()->first().textRange();
 
1972
    //kDebug() << top->childContexts()[1]->localDeclarations()[3]->uses().begin()->first().textRange();
1862
1973
    QCOMPARE(top->childContexts()[1]->localDeclarations()[0]->uses().begin()->first().textRange(), SimpleRange(3, 16, 3, 21).textRange());
1863
1974
    QVERIFY(top->childContexts()[1]->localDeclarations()[1]->uses().count());
1864
1975
    QCOMPARE(top->childContexts()[1]->localDeclarations()[1]->uses().begin()->first().textRange(), SimpleRange(1, 81, 1, 86).textRange());
1875
1986
  {
1876
1987
    QByteArray text("class QObject { void connect(QObject* from, const char* signal, QObject* to, const char* slot); void connect(QObject* from, const char* signal, const char* slot); }; struct AA : QObject { signals: void signal1(int); void signal2(); };struct T{operator AA*() const; };class A : AA { public slots: void slot1(); void slot2(); signals: void signal1();public: void test() {T t;connect(t, __qt_sig_slot__(signal2()), this, __qt_sig_slot__(slot2()));connect(this, __qt_sig_slot__(signal1(int)), __qt_sig_slot__(slot1())); } }; ");
1877
1988
 
1878
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(text, DumpNone));
 
1989
    TopDUContext* top = parse(text, DumpNone);
1879
1990
 
1880
1991
    DUChainWriteLocker lock(DUChain::lock());
1881
1992
    QCOMPARE(top->localDeclarations().count(), 4);
1907
2018
  //               01234567890123456789012345678901234567890123456789012345678901234567890123456789
1908
2019
  QByteArray text("class B{}; class A { char at(B* b); A(); ~A(); }; \n char A::at(B* b) {B* b; at(b); }; A::A() : i(3) {}; A::~A() {}; ");
1909
2020
 
1910
 
  TopDUContext* top = dynamic_cast<TopDUContext*>(parse(text, DumpAll));
 
2021
  TopDUContext* top = parse(text, DumpAll);
1911
2022
 
1912
2023
  DUChainWriteLocker lock(DUChain::lock());
1913
2024
 
2037
2148
  {
2038
2149
    QByteArray text("void test(int, int&);");
2039
2150
 
2040
 
    TopDUContext* top = parse(text, DumpAll);
 
2151
    TopDUContext* top = parse(text, DumpNone);
2041
2152
 
2042
2153
    DUChainWriteLocker lock(DUChain::lock());
2043
2154
 
2334
2445
void TestDUChain::testTypedef() {
2335
2446
  QByteArray method("/*This is A translation-unit*/ \n/*This is class A*/class A { }; \ntypedef A B;//This is a typedef\nvoid test() { };\nconst B c;");
2336
2447
 
2337
 
  TopDUContext* top = parse(method, DumpAll);
 
2448
  TopDUContext* top = parse(method, DumpNone);
2338
2449
 
2339
2450
  DUChainWriteLocker lock(DUChain::lock());
2340
2451
  QCOMPARE(top->localDeclarations().count(), 4);
2440
2551
    DUChainWriteLocker lock(DUChain::lock());
2441
2552
  
2442
2553
    QCOMPARE(top->localDeclarations().count(), 6);
2443
 
    Declaration* ADecl = top->localDeclarations()[0];
2444
 
    Declaration* BDecl = top->localDeclarations()[1];
2445
 
    Declaration* CDecl = top->localDeclarations()[2];
2446
2554
    
2447
2555
    Declaration* EDecl = top->localDeclarations()[3];
2448
2556
    Declaration* E1Decl = top->localDeclarations()[4];
2586
2694
    DUChainWriteLocker lock(DUChain::lock());
2587
2695
 
2588
2696
    QCOMPARE(top->localDeclarations().count(), 3);
2589
 
    Declaration* ADecl = top->localDeclarations()[0];
2590
 
    Declaration* BDecl = top->localDeclarations()[1];
2591
2697
    Declaration* testDecl = top->localDeclarations()[2];
2592
2698
 
2593
2699
    TemplateDeclaration* templateTestDecl = dynamic_cast<TemplateDeclaration*>(testDecl);
2635
2741
 
2636
2742
  QCOMPARE(top->localDeclarations().count(), 1);
2637
2743
  QCOMPARE(top->childContexts().count(), 2);
2638
 
  Declaration* ADecl = top->localDeclarations()[0];
2639
2744
 
2640
2745
  QCOMPARE(top->childContexts()[1]->localDeclarations().count(), 1);
2641
2746
  Declaration* dec = findDeclaration( top, QualifiedIdentifier( "A<int>::i") );
2906
3011
  release(top);
2907
3012
}
2908
3013
 
 
3014
void TestDUChain::testSourceCodeInsertion()
 
3015
{
 
3016
  {
 
3017
    QByteArray method("namespace A {\nclass B {};\n}\n");
 
3018
    
 
3019
    TopDUContext* top = parse(method, DumpNone);
 
3020
    
 
3021
    DUChainWriteLocker lock(DUChain::lock());
 
3022
    InsertArtificialCodeRepresentation repr(top->url(), QString::fromUtf8(method));
 
3023
    
 
3024
    QCOMPARE(top->childContexts().count(), 1);
 
3025
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
 
3026
 
 
3027
    QCOMPARE(repr.text().trimmed().split('\n').count(), 3);
 
3028
    {
 
3029
      Cpp::SourceCodeInsertion ins(top);
 
3030
      ins.insertForwardDeclaration(top->childContexts()[0]->localDeclarations()[0]);
 
3031
      DocumentChangeSet::ChangeResult result = ins.changes().applyAllChanges(KDevelop::DocumentChangeSet::StopOnFailedChange);
 
3032
      QVERIFY(result);
 
3033
      kDebug() << repr.text();
 
3034
//       QVERIFY(repr.text().trimmed().remove(' ').remove('\n').contains(QString("int testVar;").remove(' ')));
 
3035
      
 
3036
      //Only one newline should be added
 
3037
      QCOMPARE(repr.text().trimmed().split('\n').count(), 4);
 
3038
    }
 
3039
    
 
3040
    top = parse(repr.text().toUtf8(), DumpNone, top);
 
3041
    
 
3042
    QCOMPARE(top->childContexts().count(), 1);
 
3043
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 2);
 
3044
    
 
3045
    release(top);
 
3046
  }
 
3047
  
 
3048
  {
 
3049
    QByteArray method("");
 
3050
    
 
3051
    TopDUContext* top = parse(method, DumpNone);
 
3052
    
 
3053
    DUChainWriteLocker lock(DUChain::lock());
 
3054
    InsertArtificialCodeRepresentation repr(top->url(), QString::fromUtf8(method));
 
3055
    
 
3056
    {
 
3057
      Cpp::SourceCodeInsertion ins(top);
 
3058
      ins.insertFunctionDeclaration(Identifier("test"), AbstractType::Ptr(new IntegralType(IntegralType::TypeVoid)), QList<Cpp::SourceCodeInsertion::SignatureItem>(), false, "{ this is the body; }");
 
3059
      DocumentChangeSet::ChangeResult result = ins.changes().applyAllChanges(KDevelop::DocumentChangeSet::StopOnFailedChange);
 
3060
      kDebug() << result.m_failureReason;
 
3061
      QVERIFY(result);
 
3062
      kDebug() << repr.text();
 
3063
      QVERIFY(repr.text().trimmed().remove(' ').remove('\n').contains(QString("void test() { this is the body; }").remove(' ')));
 
3064
      
 
3065
      //Only one newline should be added
 
3066
      QCOMPARE(repr.text().split('\n').count(), 2);
 
3067
    }
 
3068
    
 
3069
    top = parse(repr.text().toUtf8(), DumpNone, top);
 
3070
    
 
3071
    QCOMPARE(top->localDeclarations().count(), 1);
 
3072
 
 
3073
    {
 
3074
      Cpp::SourceCodeInsertion ins(top);
 
3075
      ins.insertVariableDeclaration(Identifier("testVar"), AbstractType::Ptr(new IntegralType(IntegralType::TypeInt)));
 
3076
      DocumentChangeSet::ChangeResult result = ins.changes().applyAllChanges(KDevelop::DocumentChangeSet::StopOnFailedChange);
 
3077
      QVERIFY(result);
 
3078
      kDebug() << repr.text();
 
3079
      QVERIFY(repr.text().trimmed().remove(' ').remove('\n').contains(QString("int testVar;").remove(' ')));
 
3080
      
 
3081
      //Only one newline should be added
 
3082
      QCOMPARE(repr.text().split('\n').count(), 3);
 
3083
    }
 
3084
    
 
3085
    top = parse(repr.text().toUtf8(), DumpNone, top);
 
3086
    
 
3087
    QCOMPARE(top->localDeclarations().count(), 2);
 
3088
    QCOMPARE(top->localDeclarations()[0]->identifier(), Identifier("test"));
 
3089
    QCOMPARE(top->localDeclarations()[1]->identifier(), Identifier("testVar"));
 
3090
 
 
3091
    {
 
3092
      Cpp::SourceCodeInsertion ins(top);
 
3093
      ins.setInsertBefore(top->localDeclarations()[1]->range().start);
 
3094
      ins.insertForwardDeclaration(top->localDeclarations()[1]);
 
3095
      DocumentChangeSet::ChangeResult result = ins.changes().applyAllChanges(KDevelop::DocumentChangeSet::StopOnFailedChange);
 
3096
      QVERIFY(result);
 
3097
      kDebug() << repr.text();
 
3098
//       QVERIFY(repr.text().trimmed().remove(' ').remove('\n').contains(QString("int testVar;").remove(' ')));
 
3099
      
 
3100
      //Only one newline should be added
 
3101
      QCOMPARE(repr.text().trimmed().split('\n').count(), 3);
 
3102
    }
 
3103
    
 
3104
    top = parse(repr.text().toUtf8(), DumpNone, top);
 
3105
    
 
3106
    QCOMPARE(top->localDeclarations().count(), 3);
 
3107
    ///@todo Wrong order (Minor issue when updating without smart-ranges)
 
3108
    QCOMPARE(top->localDeclarations()[0]->identifier(), Identifier("test"));
 
3109
    QCOMPARE(top->localDeclarations()[1]->identifier(), Identifier("testVar"));
 
3110
    QCOMPARE(top->localDeclarations()[2]->identifier(), Identifier("testVar"));
 
3111
    
 
3112
    release(top);
 
3113
  }
 
3114
}
 
3115
 
 
3116
void TestDUChain::testSimplifiedTypeString()
 
3117
{
 
3118
  {
 
3119
    QByteArray method("template<class T> class Template { class Member; Member mem; }; Template< Template< int >* >::Member q;\n");
 
3120
    
 
3121
    TopDUContext* top = parse(method, DumpNone);
 
3122
    
 
3123
    InsertArtificialCodeRepresentation repr(top->url(), QString::fromUtf8(method));
 
3124
 
 
3125
    DUChainWriteLocker lock(DUChain::lock());
 
3126
    QCOMPARE(top->localDeclarations().count(), 2);
 
3127
    
 
3128
    QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[1]->abstractType(), top).remove(' '), QString("Template<Template<int>*>::Member").remove(' '));
 
3129
    release(top);
 
3130
  }
 
3131
  {
 
3132
  ///@todo Add more tests for this
 
3133
    QByteArray method("template<typename T> struct F; template<class T> class Tc; Tc<const F<int*>*> t; const Tc<const F<int*>*>**const*& Test1; Tc<F<int*>*>* test();\n");
 
3134
    
 
3135
    TopDUContext* top = parse(method, DumpNone);
 
3136
    
 
3137
    InsertArtificialCodeRepresentation repr(top->url(), QString::fromUtf8(method));
 
3138
 
 
3139
    DUChainWriteLocker lock(DUChain::lock());
 
3140
    QCOMPARE(top->localDeclarations().count(), 5);
 
3141
    QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[2]->abstractType(), top).remove(' '), QString("Tc<const F<int*>*>").remove(' '));
 
3142
    QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[3]->abstractType(), top).remove(' '), QString("constTc<const F<int*>*>**const*&").remove(' '));
 
3143
    FunctionType::Ptr funType = top->localDeclarations()[4]->abstractType().cast<FunctionType>();
 
3144
    QVERIFY(funType);
 
3145
    QVERIFY(funType->returnType());
 
3146
    
 
3147
    //For loop is needed to test the updating, as there was a problem with that
 
3148
    for(int a = 0; a < 3; ++a) {
 
3149
      kDebug() << "run" << a;
 
3150
      lock.unlock();
 
3151
      parse(method, DumpNone, top);
 
3152
      lock.lock();
 
3153
      repr.setText(QString::fromUtf8(method));
 
3154
      Cpp::SourceCodeInsertion ins(top);
 
3155
      ins.insertFunctionDeclaration(Identifier("test"), funType->returnType(), QList<Cpp::SourceCodeInsertion::SignatureItem>(), false, "{ this is the body; }");
 
3156
      DocumentChangeSet::ChangeResult result = ins.changes().applyAllChanges(KDevelop::DocumentChangeSet::StopOnFailedChange);
 
3157
      kDebug() << result.m_failureReason;
 
3158
      QVERIFY(result);
 
3159
      kDebug() << repr.text();
 
3160
      QVERIFY(repr.text().trimmed().remove(' ').remove('\n').contains(QString("Tc< F< int* >* >* test() { this is the body; }").remove(' ')));
 
3161
      lock.unlock();
 
3162
      parse(repr.text().toUtf8(), DumpNone, top);
 
3163
      lock.lock();
 
3164
      QVERIFY(top->localDeclarations().count() == 6);
 
3165
      
 
3166
      FunctionType::Ptr funType2 = top->localDeclarations()[5]->abstractType().cast<FunctionType>();
 
3167
      QVERIFY(funType2);
 
3168
      QVERIFY(funType2->returnType());
 
3169
      QVERIFY(funType2->returnType()->equals(funType->returnType().unsafeData()));
 
3170
      QCOMPARE(Cpp::simplifiedTypeString(funType2->returnType(), top).remove(' '), QString("Tc< F< int* >* >*").remove(' '));
 
3171
    }
 
3172
    
 
3173
    release(top);
 
3174
  }
 
3175
}
 
3176
 
2909
3177
void TestDUChain::testTemplateReference() {
2910
3178
  QByteArray method("class A; template<class T> class CC; void test(CC<const A*>& item); const A& a;const A*** b;CC<const A>  cca;");
2911
3179
 
2920
3188
  QVERIFY(argType.cast<ReferenceType>());
2921
3189
  QCOMPARE(argType->toString().remove(' '), QString("CC<constA*>&"));
2922
3190
  {
2923
 
/*    QWidget* navigationWidget = top->childContexts()[1]->createNavigationWidget(top->childContexts()[1]->localDeclarations()[0]);
2924
 
    QVERIFY(navigationWidget);
2925
 
    KDevelop::AbstractNavigationWidget* nWidget = dynamic_cast<KDevelop::AbstractNavigationWidget*>(navigationWidget);
2926
 
    QVERIFY(nWidget);
2927
 
    QVERIFY(nWidget->context());
2928
 
    QString html = nWidget->context()->html();
2929
 
    kDebug() << "html:" << html;*/
 
3191
//     QWidget* navigationWidget = top->childContexts()[1]->createNavigationWidget(top->childContexts()[1]->localDeclarations()[0]);
 
3192
//     QVERIFY(navigationWidget);
 
3193
//     KDevelop::AbstractNavigationWidget* nWidget = dynamic_cast<KDevelop::AbstractNavigationWidget*>(navigationWidget);
 
3194
//     QVERIFY(nWidget);
 
3195
//     QVERIFY(nWidget->context());
 
3196
//     QString html = nWidget->context()->html();
 
3197
//     kDebug() << "html:" << html;
2930
3198
  }
2931
 
  QCOMPARE(Cpp::shortenedTypeString(top->childContexts()[1]->localDeclarations()[0], top, 10000).remove(' '), QString("CC<constA*>&"));
 
3199
  QCOMPARE(Cpp::simplifiedTypeString(top->childContexts()[1]->localDeclarations()[0]->abstractType(), top).remove(' '), QString("CC<constA*>&"));
2932
3200
  QVERIFY(top->localDeclarations()[3]->abstractType());
2933
 
  QCOMPARE(Cpp::shortenedTypeString(top->localDeclarations()[3], top, 10000).remove(' '), QString("constA&"));
2934
 
  QCOMPARE(Cpp::shortenedTypeString(top->localDeclarations()[4], top, 10000).remove(' '), QString("constA***"));
 
3201
  QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[3]->abstractType(), top).remove(' '), QString("constA&"));
 
3202
  QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[4]->abstractType(), top).remove(' '), QString("constA***"));
2935
3203
  AbstractType::Ptr type = top->localDeclarations()[5]->abstractType();
2936
3204
  QVERIFY(type);
2937
3205
  QCOMPARE(type->toString().remove(' '), QString("CC<constA>"));
2938
 
  QCOMPARE(Cpp::shortenedTypeString(top->localDeclarations()[5], top, 10000).remove(' '), QString("CC<constA>"));
 
3206
  QCOMPARE(Cpp::simplifiedTypeString(top->localDeclarations()[5]->abstractType(), top).remove(' '), QString("CC<constA>"));
 
3207
  release(top);
2939
3208
}
2940
3209
 
2941
3210
void TestDUChain::testTemplates() {
3159
3428
  release(top);
3160
3429
}
3161
3430
 
 
3431
void TestDUChain::testTemplates4()
 
3432
{
 
3433
  {
 
3434
    QByteArray method("template<class A> class Temp { typedef A Mem; }; class B {class A { typedef int AMember; }; }; ");
 
3435
 
 
3436
    TopDUContext* top = parse(method, DumpNone);
 
3437
 
 
3438
    DUChainWriteLocker lock(DUChain::lock());
 
3439
    QCOMPARE(top->childContexts().count(), 3);
 
3440
    Declaration* memDecl = findDeclaration(top->childContexts()[2], QualifiedIdentifier("Temp<A>::Mem"));;
 
3441
    QVERIFY(memDecl);
 
3442
    QCOMPARE(unAliasedType(memDecl->abstractType())->toString(), QString("B::A"));
 
3443
    QVERIFY(findDeclaration(top->childContexts()[2], QualifiedIdentifier("Temp<A>::Mem::AMember")));
 
3444
 
 
3445
    release(top);
 
3446
  }
 
3447
  {
 
3448
    QByteArray method("template<class T> struct Cnt { typedef T Val; }; struct Item; template<class Value> struct Freqto { struct Item { typedef Value Value2; }; struct Pattern : public Cnt<Item> { }; };");
 
3449
 
 
3450
    TopDUContext* top = parse(method, DumpNone);
 
3451
    DUChainWriteLocker lock(DUChain::lock());
 
3452
    QCOMPARE(top->childContexts().count(), 4);
 
3453
    QCOMPARE(top->childContexts()[3]->childContexts().count(), 2);
 
3454
    
 
3455
    //The import should have been delayed, since it needs 'Item'
 
3456
    QVERIFY(top->childContexts()[3]->childContexts()[1]->owner());
 
3457
    ClassDeclaration* classDecl = dynamic_cast<ClassDeclaration*>(top->childContexts()[3]->childContexts()[1]->owner());
 
3458
    QVERIFY(classDecl);
 
3459
    QCOMPARE(classDecl->baseClassesSize(), 1u);
 
3460
    QVERIFY(top->childContexts()[3]->childContexts()[1]->importedParentContexts().isEmpty());
 
3461
    QVERIFY(classDecl->baseClasses()[0].baseClass.type<DelayedType>());
 
3462
    kDebug() << classDecl->baseClasses()[0].baseClass.abstractType()->toString();
 
3463
    Declaration* val2Decl = findDeclaration(top, QualifiedIdentifier("Freqto<int>::Pattern::Val::Value2"));
 
3464
    QVERIFY(val2Decl);
 
3465
    QCOMPARE(unAliasedType(val2Decl->abstractType())->toString(), QString("int"));
 
3466
 
 
3467
    release(top);
 
3468
  }
 
3469
}
 
3470
 
3162
3471
void TestDUChain::testTemplates2() {
3163
3472
  QByteArray method("struct S {} ; template<class TT> class Base { struct Alloc { typedef TT& referenceType; }; }; template<class T> struct Class : public Base<T> { typedef typename Base<T>::Alloc Alloc; typedef typename Alloc::referenceType reference; reference member; }; Class<S*&> instance;");
3164
3473
 
3165
 
  TopDUContext* top = parse(method, DumpAll);
 
3474
  TopDUContext* top = parse(method, DumpNone);
3166
3475
 
3167
3476
  DUChainWriteLocker lock(DUChain::lock());
3168
3477
 
3192
3501
  QVERIFY(memberDecl->abstractType());
3193
3502
  QCOMPARE(memberDecl->abstractType()->toString(), QString("Class< S*& >"));
3194
3503
 
3195
 
/*  memberDecl = findDeclaration(top, QualifiedIdentifier("Class<S>::Alloc<S>::referenceType"));
3196
 
  QVERIFY(memberDecl);
3197
 
  QVERIFY(memberDecl->abstractType());
3198
 
  QCOMPARE(memberDecl->abstractType()->toString(), QString("S&"));*/
 
3504
//   memberDecl = findDeclaration(top, QualifiedIdentifier("Class<S>::Alloc<S>::referenceType"));
 
3505
//   QVERIFY(memberDecl);
 
3506
//   QVERIFY(memberDecl->abstractType());
 
3507
//   QCOMPARE(memberDecl->abstractType()->toString(), QString("S&"/*));
3199
3508
 
3200
3509
  memberDecl = findDeclaration(top, QualifiedIdentifier("Class<S*>::member"));
3201
3510
  QVERIFY(memberDecl);
3412
3721
  release(top);
3413
3722
}
3414
3723
 
 
3724
 
 
3725
void TestDUChain::testOperatorUses()
 
3726
{
 
3727
  {
 
3728
    QByteArray method("struct S { bool operator() () const {}  };void test() { S s; s(); S()(); } ");
 
3729
 
 
3730
    TopDUContext* top = parse(method, DumpAll);
 
3731
 
 
3732
    DUChainWriteLocker lock(DUChain::lock());
 
3733
    QCOMPARE(top->localDeclarations().count(), 2);
 
3734
    QCOMPARE(top->localDeclarations()[0]->uses().size(), 1);
 
3735
    QCOMPARE(top->localDeclarations()[0]->uses().begin()->size(), 2);
 
3736
    QCOMPARE(top->childContexts().count(), 3);
 
3737
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
 
3738
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().size(), 1);
 
3739
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().begin()->size(), 2);
 
3740
 
 
3741
    release(top);
 
3742
  }
 
3743
  {
 
3744
    QByteArray method("struct S { S operator() () const {}; S(int) {};  };void test() { S s(1); s(); S(1)()(); } ");
 
3745
 
 
3746
    TopDUContext* top = parse(method, DumpAll);
 
3747
 
 
3748
    DUChainWriteLocker lock(DUChain::lock());
 
3749
    QCOMPARE(top->localDeclarations().count(), 2);
 
3750
    QCOMPARE(top->localDeclarations()[0]->uses().size(), 1);
 
3751
    QCOMPARE(top->localDeclarations()[0]->uses().begin()->size(), 3);
 
3752
    QCOMPARE(top->childContexts().count(), 3);
 
3753
    QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 2);
 
3754
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().size(), 1);
 
3755
    QCOMPARE(top->childContexts()[0]->localDeclarations()[0]->uses().begin()->size(), 3);
 
3756
    QCOMPARE(top->childContexts()[0]->localDeclarations()[1]->uses().size(), 1);
 
3757
    ///@todo Also build constructor-uses for initializers
 
3758
    QCOMPARE(top->childContexts()[0]->localDeclarations()[1]->uses().begin()->size(), 1);
 
3759
//     QCOMPARE(top->childContexts()[0]->localDeclarations()[1]->uses().begin()->at(0).textRange(), KTextEditor::Range(0, 68, 0, 69));
 
3760
    QCOMPARE(top->childContexts()[0]->localDeclarations()[1]->uses().begin()->at(0).textRange(), KTextEditor::Range(0, 79, 0, 80));
 
3761
 
 
3762
    release(top);
 
3763
  }
 
3764
}
 
3765
 
3415
3766
struct TestContext {
3416
3767
  TestContext() {
3417
3768
    static int number = 0;
3878
4229
  {
3879
4230
    QByteArray method("class A{}; const char* a; const char& b; char* const & c; char* const d; const A e; const A* f; A* const g;");
3880
4231
 
3881
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(method, DumpNone));
 
4232
    TopDUContext* top = parse(method, DumpNone);
3882
4233
 
3883
4234
    DUChainWriteLocker lock(DUChain::lock());
3884
4235
    QCOMPARE(top->localDeclarations().size(), 8);
3935
4286
  {
3936
4287
    QByteArray method("class A; template<class T> class B; B<const A*> ca;B<A* const> cb;");
3937
4288
 
3938
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(method, DumpNone));
 
4289
    TopDUContext* top = parse(method, DumpNone);
3939
4290
 
3940
4291
    DUChainWriteLocker lock(DUChain::lock());
3941
4292
    QCOMPARE(top->localDeclarations().size(), 4);
3946
4297
  {
3947
4298
    QByteArray method("class A; A* a = const_cast<A*>(bla);");
3948
4299
 
3949
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(method, DumpNone));
 
4300
    TopDUContext* top = parse(method, DumpNone);
3950
4301
 
3951
4302
    DUChainWriteLocker lock(DUChain::lock());
3952
4303
    QCOMPARE(top->localDeclarations().size(), 2);
3955
4306
  {
3956
4307
    QByteArray method("class C;const C& c;");
3957
4308
 
3958
 
    TopDUContext* top = dynamic_cast<TopDUContext*>(parse(method, DumpNone));
 
4309
    TopDUContext* top = parse(method, DumpNone);
3959
4310
 
3960
4311
    DUChainWriteLocker lock(DUChain::lock());
3961
4312
    QCOMPARE(top->localDeclarations().size(), 2);
3970
4321
{
3971
4322
  QByteArray method("template<class T> class C { template<class T2> class C2{}; }; ");
3972
4323
 
3973
 
  TopDUContext* top = dynamic_cast<TopDUContext*>(parse(method, DumpNone));
 
4324
  TopDUContext* top = parse(method, DumpNone);
3974
4325
 
3975
4326
  DUChainWriteLocker lock(DUChain::lock());
3976
4327
 
4316
4667
  kDebug() << a << "successful tests";
4317
4668
}
4318
4669
 
4319
 
TopDUContext* TestDUChain::parse(const QByteArray& unit, DumpAreas dump, TopDUContext* update)
 
4670
TopDUContext* TestDUChain::parse(const QByteArray& unit, DumpAreas dump, TopDUContext* update, bool keepAst)
4320
4671
{
4321
4672
  if (dump)
4322
4673
    kDebug(9007) << "==== Beginning new test case...:" << endl << unit;
4323
4674
 
4324
 
  ParseSession* session = new ParseSession();
 
4675
  //If the AST flag is set, then the parse session needs to be owned by a shared pointer
 
4676
  ParseSession::Ptr session(new ParseSession());
4325
4677
 
4326
4678
  rpp::Preprocessor preprocessor;
4327
4679
  rpp::pp pp(&preprocessor);
4329
4681
  session->setContentsAndGenerateLocationTable(pp.processFile("anonymous", unit));
4330
4682
 
4331
4683
  Parser parser(&control);
4332
 
  TranslationUnitAST* ast = parser.parse(session);
4333
 
  ast->session = session;
 
4684
  TranslationUnitAST* ast = parser.parse(session.data());
 
4685
  ast->session = session.data();
4334
4686
 
4335
4687
  if (dump & DumpAST) {
4336
4688
    kDebug(9007) << "===== AST:";
4337
 
    cppDumper.dump(ast, session);
 
4689
    cppDumper.dump(ast, session.data());
4338
4690
  }
4339
4691
 
4340
4692
  static int testNumber = 0;
4341
4693
  IndexedString url(QString("/internal/%1").arg(testNumber++));
4342
4694
 
4343
 
  DeclarationBuilder definitionBuilder(session);
 
4695
  DeclarationBuilder definitionBuilder(session.data());
4344
4696
  Cpp::EnvironmentFilePointer file( new Cpp::EnvironmentFile( url, 0 ) );
 
4697
  
 
4698
  //HACK Should actually use DUChain::updateContextForUrl
 
4699
  kDebug() << "update->features & TopDUContext::AST: " << (update ? update->features() & TopDUContext::AST : 0);
 
4700
  if(keepAst)
 
4701
  {
 
4702
    definitionBuilder.setMapAst(true);
 
4703
    update->setAst( IAstContainer::Ptr( session.data() ) );
 
4704
  }
4345
4705
  TopDUContext* top = definitionBuilder.buildDeclarations(file, ast, 0, ReferencedTopDUContext(update));
4346
4706
  if(update) {
4347
4707
    Q_ASSERT(top == update);
4348
4708
  }
4349
4709
 
4350
 
  UseBuilder useBuilder(session);
 
4710
  UseBuilder useBuilder(session.data());
4351
4711
  useBuilder.buildUses(ast);
4352
4712
 
4353
4713
  if (dump & DumpDUChain) {
4368
4728
  if (dump)
4369
4729
    kDebug(9007) << "===== Finished test case.";
4370
4730
 
4371
 
  delete session;
4372
 
 
4373
4731
  return top;
4374
4732
}
4375
4733