[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdevelop/languages/cpp/cppduchain
From:       David Nolden <david.nolden.kde () art-master ! de>
Date:       2008-05-31 19:10:54
Message-ID: 1212261054.064914.12961.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 814956 by zwabel:

- Also give function bodies a scope identifier, and adjust the tests.
- When searching from within function definitions that have namespaces as part of their scope \
                identifiers, also search for the items within those namespaces, as specified in iso c++.
- Add a test to verify.



 M  +10 -7     contextbuilder.cpp  
 M  +3 -1      contextbuilder.h  
 M  +5 -0      cppduchain.cpp  
 M  +4 -1      cppduchain.h  
 M  +33 -0     cppducontext.h  
 M  +1 -1      dumpchain.cpp  
 M  +37 -5     tests/test_duchain.cpp  
 M  +1 -0      tests/test_duchain.h  


--- trunk/KDE/kdevelop/languages/cpp/cppduchain/contextbuilder.cpp #814955:814956
@@ -148,7 +148,7 @@
   DUContext* ctx = 0;
 
   if( first && last )
-    ctx = openContext(first, last, DUContext::Template, 0); //Open anonymous context for the \
template-parameters +    ctx = openContext(first, last, DUContext::Template); //Open anonymous context \
for the template-parameters  else
     ctx = openContextEmpty(ast, DUContext::Template); //Open an empty context, because there are no \
template-parameters  
@@ -462,8 +462,9 @@
 {
   PushValue<bool> push(m_inFunctionDefinition, (bool)node->function_body);
                  
+  QualifiedIdentifier functionName;
   if (m_compilingContexts && node->init_declarator && node->init_declarator->declarator && \
                node->init_declarator->declarator->id) {
-    QualifiedIdentifier functionName = identifierForName(node->init_declarator->declarator->id);
+    functionName = identifierForName(node->init_declarator->declarator->id);
     if (functionName.count() >= 2) {
       // This is a class function definition
       DUChainReadLocker lock(DUChain::lock());
@@ -483,17 +484,18 @@
       }
     }
   }
-  
   visitFunctionDeclaration(node);
 
   if (node->constructor_initializers && node->function_body) {
-    openContext(node->constructor_initializers, node->function_body, DUContext::Other);
+    openContext(node->constructor_initializers, node->function_body, DUContext::Other); //The \
constructor initializer context  addImportedContexts();
   }
   // Otherwise, the context is created in the function body visit
 
   visit(node->constructor_initializers);
+  m_openingFunctionBody = functionName;
   visit(node->function_body);
+  m_openingFunctionBody = QualifiedIdentifier();
 
   if (node->constructor_initializers)
     closeContext();
@@ -563,13 +565,13 @@
   }
 }
 
-DUContext* ContextBuilder::openContext(AST* fromRange, AST* toRange, DUContext::ContextType type, \
NameAST* identifier) +DUContext* ContextBuilder::openContext(AST* fromRange, AST* toRange, \
DUContext::ContextType type, const KDevelop::QualifiedIdentifier& identifier)  {
   if (m_compilingContexts) {
 #ifdef DEBUG_UPDATE_MATCHING
     kDebug() << "opening context with text" << m_editor->tokensToStrings( fromRange->start_token, \
toRange->end_token );  #endif
-    DUContext* ret = openContextInternal(m_editor->findRangeForContext(fromRange->start_token, \
toRange->end_token), type, identifier ? identifierForName(identifier) : QualifiedIdentifier()); +    \
DUContext* ret = openContextInternal(m_editor->findRangeForContext(fromRange->start_token, \
toRange->end_token), type, identifier);  fromRange->ducontext = ret;
     return ret;
   } else {
@@ -723,7 +725,8 @@
 
 void ContextBuilder::visitCompoundStatement(CompoundStatementAST * node)
 {
-  openContext(node, DUContext::Other);
+  openContext(node, DUContext::Other, m_openingFunctionBody);
+  m_openingFunctionBody.clear();
 
   addImportedContexts();
 
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/contextbuilder.h #814955:814956
@@ -190,7 +190,7 @@
 
   KDevelop::DUContext* openContext(AST* range, KDevelop::DUContext::ContextType type, const \
KDevelop::QualifiedIdentifier& identifier);  KDevelop::DUContext* openContext(AST* range, \
                KDevelop::DUContext::ContextType type, NameAST* identifier = 0);
-  KDevelop::DUContext* openContext(AST* fromRange, AST* toRange, KDevelop::DUContext::ContextType type, \
NameAST* identifier = 0); +  KDevelop::DUContext* openContext(AST* fromRange, AST* toRange, \
KDevelop::DUContext::ContextType type, const KDevelop::QualifiedIdentifier& identifier = \
KDevelop::QualifiedIdentifier());  //Opens a context of size 0, starting at the given node
   KDevelop::DUContext* openContextEmpty(AST* range, KDevelop::DUContext::ContextType type);
   
@@ -224,6 +224,8 @@
   QStack<KDevelop::DUContext*> m_contextStack;
   QStack<int> m_nextContextStack;
   
+  QualifiedIdentifier m_openingFunctionBody; //Identifier of the currently opened function body, or \
empty. +  
   KDevelop::DUContext* m_lastContext; //Last context that was opened
 
   inline int& nextContextIndex() { return m_nextContextStack.top(); }
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppduchain.cpp #814955:814956
@@ -111,6 +111,11 @@
   { //Move context to the top context of type "Other". This is needed because every compound-statement \
creates a new sub-context.  context = context->parentContext();
   }
+  
+  //Since declarations are assigned to the bodies, not to the argument contexts, go to the body context \
to make the step to the function +  if(context->type() == DUContext::Function)
+    if(!context->importedChildContexts().isEmpty())
+      context = context->importedChildContexts().first();
 
   ///Step 1: Find the function-declaration for the function we are in
   Declaration* functionDeclaration = 0;
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppduchain.h #814955:814956
@@ -61,7 +61,10 @@
  * */
 KDEVCPPDUCHAIN_EXPORT QList< QPair<KDevelop::Declaration*, int> > hideOverloadedDeclarations( const \
QList< QPair<KDevelop::Declaration*, int> >& declarations );  
-  /**Tries determining the local class that the given code-context belongs to.*/
+  /**Tries determining the local class that the given code-context belongs to.
+   *
+   * This works within contexts of type DUContext::Other, as well as in argument contexts of type \
DUContext::Function(also within function definitions). +   */
 KDEVCPPDUCHAIN_EXPORT KDevelop::Declaration* localClassFromCodeContext(KDevelop::DUContext* context);
 
 /**
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppducontext.h #814955:814956
@@ -68,6 +68,7 @@
 #include <duchain/namespacealiasdeclaration.h>
 #include "typeutils.h"
 #include "cpptypes.h"
+#include "cppduchain.h"
 #include "templatedeclaration.h"
 #include "expressionparser.h"
 
@@ -569,6 +570,38 @@
       m_instantiatedFrom->m_instatiations.insert( this );
     }
 
+    virtual void applyUpwardsAliases(QList<QualifiedIdentifier>& identifiers) const
+    {
+      BaseContext::applyUpwardsAliases(identifiers);
+      ///@see Iso C++ 3.4.1 : Unqualified name lookup: 
+      ///We need to make sure that when leaving a function definition, the namespace components are \
searched +      QualifiedIdentifier prefix = BaseContext::localScopeIdentifier();
+      if(prefix.count() > 1) {
+        //This must be a function-definition, like void A::B::test() {}
+        KDevelop::Declaration* classDeclaration = \
Cpp::localClassFromCodeContext(const_cast<BaseContext*>((const BaseContext*)this)); +        \
if(classDeclaration && classDeclaration->internalContext()) { +          //If this is a definition of a \
class member, only add aliases for the namespace elements(The class scope will be +          //searched \
using then normal import logic) +          prefix = \
classDeclaration->internalContext()->scopeIdentifier(false); +        }else{
+          prefix.pop();
+        }
+        prefix.setExplicitlyGlobal(true);
+        
+        QList<QualifiedIdentifier> addIdentifiers;
+        
+        while(!prefix.isEmpty()) {
+          for(QList<QualifiedIdentifier>::const_iterator it = identifiers.begin(); it != \
identifiers.end(); ++it) { +            addIdentifiers.append(prefix + *it);
+          }
+          prefix.pop();
+        }
+        
+        if(!addIdentifiers.isEmpty())
+          identifiers = addIdentifiers + identifiers;
+      }
+    }
+
     /**
      * If this returns nonzero value, this context is a instatiation of some other context, and that \
                other context will be returned here.
      * */
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/dumpchain.cpp #814955:814956
@@ -186,7 +186,7 @@
       
       //IdentifiedType* idType = dynamic_cast<IdentifiedType*>(dec->abstractType().data());
       
-      kDebug(9007) << QString((indent+1) * 2, ' ') << "Declaration: " << dec->toString() << /*(idType ? \
(" (type-identity: " + idType->identifier().toString() + ")") : QString()) <<*/ " [" << \
dec->qualifiedIdentifier() << "]" << dec << "(internal ctx" << dec->internalContext() << ")" << \
dec->range().textRange() << "," << (dec->isDefinition() ? "defined, " : (dec->definition() ? "" : "no \
definition, ")) << dec->uses().count() << "use(s)."; +      kDebug(9007) << QString((indent+1) * 2, ' ') \
<< "Declaration: " << dec->toString() << /*(idType ? (" (type-identity: " + \
idType->identifier().toString() + ")") : QString()) <<*/ " [" << dec->qualifiedIdentifier() << "]" << dec \
<< "(internal ctx" << dec->internalContext() << ")" << dec->range().textRange() << "smart range:" << \
dec->smartRange() << "," << (dec->isDefinition() ? "defined, " : (dec->definition() ? "" : "no \
definition, ")) << dec->uses().count() << "use(s).";  if (dec->definition())
         kDebug(9007) << QString((indent+1) * 2 + 1, ' ') << "Definition:" << \
dec->definition()->range().textRange();  QMap<HashedString, QList<SimpleRange> > uses = dec->uses();
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/tests/test_duchain.cpp #814955:814956
@@ -29,6 +29,7 @@
 #include "usebuilder.h"
 #include <declaration.h>
 #include <dumpdotgraph.h>
+#include <typeinfo>
 #include <time.h>
 #include <set>
 #include <algorithm>
@@ -448,7 +449,7 @@
   QCOMPARE(main->importedParentContexts().count(), 1);
   QCOMPARE(main->childContexts().count(), 2);
   QCOMPARE(main->localDeclarations().count(), 0);
-  QVERIFY(main->localScopeIdentifier().isEmpty());
+  QCOMPARE(main->localScopeIdentifier(), QualifiedIdentifier("main"));
 
   QCOMPARE(findDeclaration(main, Identifier("i")), noDef);
 
@@ -827,8 +828,8 @@
   DUContext* testCtx = top->childContexts()[2];
   QCOMPARE(testCtx->childContexts().count(), 0);
   QCOMPARE(testCtx->localDeclarations().count(), 0);
-  QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier());
-  QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier());
+  QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier("test"));
+  QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier("test"));
 
   Declaration* bar2 = top->localDeclarations().first();
   QCOMPARE(bar2->identifier(), Identifier("bar"));
@@ -875,6 +876,37 @@
   release(top);
 }
 
+void TestDUChain::testSearchAcrossNamespace2()
+{
+  TEST_FILE_PARSE_ONLY
+
+  //                 0         1         2         3         4         5         6         7
+  //                 \
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + \
QByteArray method("namespace A {class B{}; } namespace A { class C{ void member(B);};  } void \
A::C::member(B b) {B c;}"); +
+  DUContext* top = parse(method, DumpNone);
+
+  DUChainWriteLocker lock(DUChain::lock());
+  
+  QVERIFY(!top->parentContext());
+  QCOMPARE(top->childContexts().count(), 4);
+  QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
+  QCOMPARE(top->childContexts()[1]->localDeclarations().count(), 1);
+  QCOMPARE(top->childContexts()[2]->localDeclarations().count(), 1);
+  QCOMPARE(top->childContexts()[2]->type(), DUContext::Function);
+  QCOMPARE(top->childContexts()[2]->localDeclarations().count(), 1);
+  QCOMPARE(top->childContexts()[2]->localScopeIdentifier(), QualifiedIdentifier("A::C::member"));
+  QVERIFY(top->childContexts()[2]->localDeclarations()[0]->abstractType()); //B should be found from \
that position +  QVERIFY(!dynamic_cast<DelayedType*>(top->childContexts()[2]->localDeclarations()[0]->abstractType().data()));
 +  QCOMPARE(top->childContexts()[3]->type(), DUContext::Other);
+  QCOMPARE(top->childContexts()[3]->localDeclarations().count(), 1);
+  QVERIFY(top->childContexts()[3]->localDeclarations()[0]->abstractType()); //B should be found from \
that position +  QCOMPARE(top->childContexts()[3]->localScopeIdentifier(), \
QualifiedIdentifier("A::C::member")); +  \
QVERIFY(!dynamic_cast<DelayedType*>(top->childContexts()[3]->localDeclarations()[0]->abstractType().data()));
 +
+  release(top);
+}
+
 void TestDUChain::testDeclareUsingNamespace2()
 {
   TEST_FILE_PARSE_ONLY
@@ -978,8 +1010,8 @@
   QCOMPARE(testCtx->importedParentContexts().count(), 1);
   QCOMPARE(testCtx->childContexts().count(), 0);
   QCOMPARE(testCtx->localDeclarations().count(), 0);
-  QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier());
-  QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier());
+  QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier("test"));
+  QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier("test"));
   
   release(top);
 }
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/tests/test_duchain.h #814955:814956
@@ -71,6 +71,7 @@
   void testDeclareUsingNamespace();
   void testDeclareUsingNamespace2();
   void testSearchAcrossNamespace();
+  void testSearchAcrossNamespace2();
   void testTemplateEnums();
   void testIntegralTemplates();
   void testTypedef();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic