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

List:       kde-commits
Subject:    =?utf-8?q?=5Bkdev-python=5D_duchain=3A_Re-declaring_a_function_a?=
From:       Sven Brauch <svenbrauch () googlemail ! com>
Date:       2011-06-20 23:06:52
Message-ID: 20110620230652.B5006A60A4 () git ! kde ! org
[Download RAW message or body]

Git commit 9e6cd846bf11813ef15ab40da1b7437055422990 by Sven Brauch.
Committed on 20/06/2011 at 23:13.
Pushed by brauch into branch 'master'.

Re-declaring a function as a non-function is now reported as an error.

We might want to support this later, but it's too difficult for now.
BUG:276100

M  +25   -2    duchain/declarationbuilder.cpp     
M  +3    -13   duchain/expressionvisitor.cpp     
M  +15   -2    duchain/helpers.cpp     
M  +11   -1    duchain/helpers.h     

http://commits.kde.org/kdev-python/9e6cd846bf11813ef15ab40da1b7437055422990

diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp
index 20861e5..8a6f632 100644
--- a/duchain/declarationbuilder.cpp
+++ b/duchain/declarationbuilder.cpp
@@ -149,7 +149,7 @@ template<typename T> T* \
DeclarationBuilder::visitVariableDeclaration(Identifier*  }
     }
     if ( existingDeclarations.length() ) {
-        Declaration* d = existingDeclarations.last();
+        Declaration* d = existingDeclarations.first();
         kDebug() << "last one: " << d << d->toString() << dynamic_cast<T*>(d) << \
wasEncountered(d);  if ( dynamic_cast<T*>(d) && ! wasEncountered(d) ) {
             kDebug() << "Opening previously existing declaration for " << \
d->toString(); @@ -161,6 +161,27 @@ template<typename T> T* \
DeclarationBuilder::visitVariableDeclaration(Identifier*  }
     }
     
+    if ( dec || ! existingDeclarations.isEmpty() ) {
+        Declaration* d = dec ? dec : existingDeclarations.first();
+        Q_ASSERT(d);
+        d = Helper::resolveAliasDeclaration(d);
+        if ( d && d->abstractType() && lastType() && lastType()->whichType() != \
AbstractType::TypeFunction && d->isFunctionDeclaration() ) { +            kWarning() \
<< "Found re-declaration, reporting error"; +            kDebug() << \
d->abstractType()->toString() << lastType()->toString() << \
d->abstractType()->whichType() << lastType()->whichType(); +            // assigning \
e.g. an integral value to something that was a function definition previously +       \
// is difficult to handle and most likely not what you want, so we just report an \
error. +            KDevelop::Problem *p = new KDevelop::Problem();
+            p->setFinalLocation(DocumentRange(currentlyParsedDocument(), \
SimpleRange( +                                node->startLine, node->startCol, \
node->startLine, (node->startLine == node->endLine ? node->endCol + 1 : 100)))); +    \
p->setSource(KDevelop::ProblemData::SemanticAnalysis); +            \
p->setSeverity(KDevelop::ProblemData::Error); +            \
p->setDescription(i18n("Re-declaration of \"" + node->value.toAscii() + "\" shadows a \
previous declaration with different type")); +            ProblemPointer ptr(p);
+            topContext()->addProblem(ptr);
+            return 0;
+        }
+    }
+    
     kDebug() << "VARIABLE CONTEXT: " << currentContext()->scopeIdentifier() << \
currentContext()->range().castToSimpleRange() << currentContext()->type() << \
DUContext::Class;  
     bool noFittingDeclaration = existingDeclarations.isEmpty() || ( ! \
existingDeclarations.isEmpty() && ! dynamic_cast<T*>(existingDeclarations.last()) ); \
@@ -323,6 +344,7 @@ Declaration* \
DeclarationBuilder::createModuleImportDeclaration(QString dottedNam  \
StructureType::Ptr moduleType(new StructureType());  openType(moduleType);
         DUChainWriteLocker lock(DUChain::lock());
+        setLastType(AbstractType::Ptr(0));
         resultingDeclaration = \
visitVariableDeclaration<Declaration>(declarationIdentifier, range);  \
Q_ASSERT(resultingDeclaration);  closeType();
@@ -439,7 +461,7 @@ void DeclarationBuilder::visitAssignment(AssignmentAst* node)
                 DUChainWriteLocker lock(DUChain::lock());
                 Declaration* dec = visitVariableDeclaration<Declaration>(target);
                 /** DEBUG **/
-                if ( tupleElementType ) {
+                if ( tupleElementType && dec ) {
                     VariableLengthContainer* type = \
                dynamic_cast<VariableLengthContainer*>(dec->abstractType().unsafeData());
                
                     kDebug() << "type is: " << dec->abstractType().unsafeData() << \
                type << \
                dynamic_cast<VariableLengthContainer*>(tupleElementType.unsafeData());
                
                     kDebug() << "indexed: " << tupleElementType->indexed().hash() << \
"<>" << dec->indexedType().hash(); @@ -625,6 +647,7 @@ void \
DeclarationBuilder::visitFunctionDefinition( FunctionDefinitionAst* node )  \
QList<Declaration*> existing;  
     FunctionDeclaration* dec = openDeclaration<FunctionDeclaration>( node->name, \
node ); +    Q_ASSERT(dec->isFunctionDeclaration());
     
     type = FunctionType::Ptr(new FunctionType());
     type->setReturnType(AbstractType::Ptr(new \
                IntegralType(IntegralType::TypeVoid)));
diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp
index e03eff2..c1710d5 100644
--- a/duchain/expressionvisitor.cpp
+++ b/duchain/expressionvisitor.cpp
@@ -81,16 +81,6 @@ void ExpressionVisitor::unknownTypeEncountered() {
     encounter(AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed)));
 }
 
-Declaration* ExpressionVisitor::resolveAliasDeclaration(Declaration* decl)
-{
-    AliasDeclaration* alias = dynamic_cast<AliasDeclaration*>(decl);
-    if ( alias ) {
-        return alias->aliasedDeclaration().data();
-    }
-    else
-        return decl;
-}
-
 void ExpressionVisitor::setTypesForEventualCall(DeclarationPointer \
actualDeclaration, AttributeAst* node, bool extendUnsureTypes)  {
     // if it's a function call, the result of that call will be the return type
@@ -196,7 +186,7 @@ void ExpressionVisitor::visitAttribute(AttributeAst* node)
         lock.unlock();
         kDebug() << "Found declarations for dotted name import: " << found;
         if ( ! found.isEmpty() ) {
-            Declaration* real = resolveAliasDeclaration(found.last());
+            Declaration* real = Helper::resolveAliasDeclaration(found.last());
             DeclarationPointer ptr = DeclarationPointer(real);
             setLastAccessedDeclaration(ptr);
             setLastAccessedAttributeDeclaration(ptr);
@@ -294,7 +284,7 @@ void ExpressionVisitor::visitAttribute(AttributeAst* node)
     // Step 5: Construct the type of the declaration which was found.
     DeclarationPointer actualDeclaration(0);
     if ( foundDecls.length() > 0 ) {
-        actualDeclaration = \
DeclarationPointer(resolveAliasDeclaration(foundDecls.last())); +        \
actualDeclaration = DeclarationPointer(Helper::resolveAliasDeclaration(foundDecls.last()));
  m_lastAccessedAttributeDeclaration = toSharedPtrList(foundDecls);
         m_lastAccessedDeclaration = toSharedPtrList(foundDecls);
         bool extendUnsure = false;
@@ -336,7 +326,7 @@ void ExpressionVisitor::visitCall(CallAst* node)
         return unknownTypeEncountered();
     }
     else {
-        Declaration* actualDeclaration = resolveAliasDeclaration(decls.last());
+        Declaration* actualDeclaration = \
                Helper::resolveAliasDeclaration(decls.last());
         kDebug() << "Resolved alias declaration: " << decls.last()->toString();
         ClassDeclaration* classDecl = \
                dynamic_cast<ClassDeclaration*>(actualDeclaration);
         FunctionDeclaration* funcDecl = \
                dynamic_cast<FunctionDeclaration*>(actualDeclaration);
diff --git a/duchain/helpers.cpp b/duchain/helpers.cpp
index 226737d..59cfcde 100644
--- a/duchain/helpers.cpp
+++ b/duchain/helpers.cpp
@@ -13,6 +13,7 @@
 #include <language/duchain/duchainlock.h>
 #include <language/duchain/duchain.h>
 #include <language/duchain/classdeclaration.h>
+#include <language/duchain/aliasdeclaration.h>
 
 using namespace KDevelop;
 
@@ -20,7 +21,7 @@ namespace Python {
 
 QList<KUrl> Helper::cachedSearchPaths;
 
-QList< DUContext* > Helper::inernalContextsForClass(StructureType::Ptr klassType, \
TopDUContext* context) +QList< DUContext* > \
Helper::inernalContextsForClass(StructureType::Ptr klassType, TopDUContext* context, \
int depth)  {
     QList<DUContext*> searchContexts;
     if ( ! klassType ) {
@@ -36,11 +37,23 @@ QList< DUContext* > \
                Helper::inernalContextsForClass(StructureType::Ptr klassType
             StructureType::Ptr baseClassType = base.baseClass.type<StructureType>();
             kDebug() << "Base class type: " << baseClassType;
             // recursive call, because the base class will have more base classes \
                eventually
-            searchContexts.append(Helper::inernalContextsForClass(baseClassType, \
context)); +            if ( depth < 10 ) {
+                searchContexts.append(Helper::inernalContextsForClass(baseClassType, \
context, depth + 1)); +            }
         }
     }
     return searchContexts;
 }
+
+Declaration* Helper::resolveAliasDeclaration(Declaration* decl)
+{
+    AliasDeclaration* alias = dynamic_cast<AliasDeclaration*>(decl);
+    if ( alias ) {
+        return alias->aliasedDeclaration().data();
+    }
+    else
+        return decl;
+}
     
 QList<KUrl> Helper::getSearchPaths(KUrl workingOnDocument)
 {
diff --git a/duchain/helpers.h b/duchain/helpers.h
index 2cb5b42..6611046 100644
--- a/duchain/helpers.h
+++ b/duchain/helpers.h
@@ -12,6 +12,7 @@
 #include <KDebug>
 
 #include "pythonduchainexport.h"
+#include <language/duchain/declaration.h>
 
 using namespace KDevelop;
 
@@ -46,7 +47,16 @@ public:
     * @param context TopContext for finding the declarations for types
     * @return list of contexts which were found
     **/
-    static QList<DUContext*> inernalContextsForClass(KDevelop::StructureType::Ptr \
klassType, TopDUContext* context); +    static QList<DUContext*> \
inernalContextsForClass(KDevelop::StructureType::Ptr klassType, TopDUContext* \
context, int depth = 0); +    
+    /**
+        * @brief Resolve the given declaration if it is an alias declaration.
+        *
+        * @param decl the declaration to resolve
+        * @return :Declaration* decl if not an alias declaration, \
decl->aliasedDeclaration().data otherwise +        * DUChain must be read locked
+        **/
+    static Declaration* resolveAliasDeclaration(Declaration* decl);
 };
 
 }


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

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