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

List:       kde-commits
Subject:    [kdev-ruby/gsoc] duchain: Created the ModuleDeclaration class. This is the class that represents
From:       Miquel_Sabaté <mikisabate () gmail ! com>
Date:       2012-05-31 19:29:56
Message-ID: 20120531192956.753FDA60BB () git ! kde ! org
[Download RAW message or body]

Git commit dc4f9c2bf759257de041805ed0598d5b8b5a8fc8 by Miquel Sabaté.
Committed on 30/05/2012 at 16:53.
Pushed by mssola into branch 'gsoc'.

Created the ModuleDeclaration class. This is the class that represents
a module declaration and stores a variable length list of mixins by using
an appended list.

M  +1    -0    duchain/CMakeLists.txt
M  +24   -10   duchain/builders/declarationbuilder.cpp
M  +3    -1    duchain/builders/declarationbuilder.h
M  +0    -4    duchain/declarations/classdeclaration.h
A  +97   -0    duchain/declarations/moduledeclaration.cpp     [License: LGPL (v2+)]
A  +94   -0    duchain/declarations/moduledeclaration.h     [License: LGPL (v2+)]
M  +12   -0    duchain/navigation/declarationnavigationcontext.cpp

http://commits.kde.org/kdev-ruby/dc4f9c2bf759257de041805ed0598d5b8b5a8fc8

diff --git a/duchain/CMakeLists.txt b/duchain/CMakeLists.txt
index b0c2547..80c4920 100644
--- a/duchain/CMakeLists.txt
+++ b/duchain/CMakeLists.txt
@@ -19,6 +19,7 @@ set(rubyduchain_SRCS
     declarations/classdeclaration.cpp
     declarations/methoddeclaration.cpp
     declarations/variabledeclaration.cpp
+    declarations/moduledeclaration.cpp
 )
 
 kde4_add_library(kdev4rubyduchain SHARED ${rubyduchain_SRCS})
diff --git a/duchain/builders/declarationbuilder.cpp \
b/duchain/builders/declarationbuilder.cpp index 2134f1f..bfd403a 100644
--- a/duchain/builders/declarationbuilder.cpp
+++ b/duchain/builders/declarationbuilder.cpp
@@ -40,6 +40,7 @@
 #include <duchain/declarations/variabledeclaration.h>
 #include <duchain/declarations/methoddeclaration.h>
 #include <duchain/declarations/classdeclaration.h>
+#include <duchain/declarations/moduledeclaration.h>
 #include <duchain/types/classtype.h>
 
 
@@ -103,7 +104,7 @@ void DeclarationBuilder::visitClassStatement(RubyAst *node)
             appendProblem(node->tree, i18n("NameError: undefined local variable or \
method `%1'", baseId.toString()));  else {
             ClassDeclaration *realClass = dynamic_cast<ClassDeclaration \
                *>(baseDecl);
-            if (!realClass || realClass->classType() == \
ClassDeclarationData::Interface) +            if (!realClass)
                 appendProblem(node->tree, i18n("TypeError: wrong argument type \
(expected Class)"));  else {
                 currentContext()->addImportedParentContext(realClass->internalContext());
 @@ -140,10 +141,9 @@ void DeclarationBuilder::visitModuleStatement(RubyAst* node)
     QualifiedIdentifier id = getIdentifier(node);
 
     setComment(getComment(node));
-    ClassDeclaration *decl = openDeclaration<ClassDeclaration>(id, range);
+    ModuleDeclaration *decl = openDeclaration<ModuleDeclaration>(id, range);
+    decl->clearModuleMixins();
     decl->setKind(KDevelop::Declaration::Type);
-    decl->clearBaseClasses();
-    decl->setClassType(ClassDeclarationData::Interface);
     m_accessPolicyStack.push(Declaration::Public);
     lastClassModule = decl;
     insideClassModule = true;
@@ -427,7 +427,21 @@ void DeclarationBuilder::visitMethodCall(RubyAst *node)
 void DeclarationBuilder::visitInclude(RubyAst *node)
 {
     RubyAst *module = new RubyAst(node->tree->r, node->context);
-    Declaration *decl = getModuleDeclaration(module);
+    ModuleDeclaration *decl = getModuleDeclaration(module);
+
+    // Register module mix-in
+    if (lastClassModule) {
+        ModuleDeclaration *current = dynamic_cast<ModuleDeclaration \
*>(lastClassModule); +        // TODO: accept classes
+        if (current) {
+            ModuleMixin mixin;
+            mixin.included = true;
+            mixin.module = decl->indexedType();
+            current->addModuleMixin(mixin);
+        }
+    } else {
+        // TODO: register to the Kernel module
+    }
 
     if (decl) {
         QList<MethodDeclaration *> iMethods = getDeclaredMethods(decl);
@@ -448,7 +462,7 @@ void DeclarationBuilder::visitInclude(RubyAst *node)
 void DeclarationBuilder::visitExtend(RubyAst *node)
 {
     RubyAst *module = new RubyAst(node->tree->r, node->context);
-    Declaration *decl = getModuleDeclaration(module);
+    ModuleDeclaration *decl = getModuleDeclaration(module);
 
     if (decl) {
         QList<MethodDeclaration *> eMethods = getDeclaredMethods(decl);
@@ -585,7 +599,7 @@ KDevelop::RangeInRevision DeclarationBuilder::getNameRange(const \
RubyAst *node)  return m_editor->findRange(rb_name_node(node->tree));
 }
 
-Declaration * DeclarationBuilder::getModuleDeclaration(const RubyAst *module)
+ModuleDeclaration * DeclarationBuilder::getModuleDeclaration(const RubyAst *module)
 {
     /*
      * NOTE: this is a convenient method that allows us to retrieve the declaration \
of @@ -596,7 +610,7 @@ Declaration * DeclarationBuilder::getModuleDeclaration(const \
RubyAst *module)  DUChainReadLocker rlock(DUChain::lock());
     RubyAst *aux = new RubyAst(module->tree, module->context);
     DUContext *lastCtx = module->context;
-    Declaration *lastDecl = NULL;
+    ModuleDeclaration *lastDecl = NULL;
 
     if (aux->tree->kind == token_method_call)
         aux->tree = aux->tree->l;
@@ -604,8 +618,8 @@ Declaration * DeclarationBuilder::getModuleDeclaration(const \
RubyAst *module)  QualifiedIdentifier id = getIdentifier(aux);
         QList<Declaration *> list = lastCtx->findDeclarations(id.last());
         if (!list.empty()) {
-            ClassDeclaration *d = dynamic_cast<ClassDeclaration *>(list.last());
-            if (!d || d->classType() != ClassDeclarationData::Interface) {
+            ModuleDeclaration *d = dynamic_cast<ModuleDeclaration *>(list.last());
+            if (!d) {
                 rlock.unlock();
                 appendProblem(n, i18n("TypeError: wrong argument type (expected \
Module)"));  return NULL;
diff --git a/duchain/builders/declarationbuilder.h \
b/duchain/builders/declarationbuilder.h index 01ba3d0..ab67596 100644
--- a/duchain/builders/declarationbuilder.h
+++ b/duchain/builders/declarationbuilder.h
@@ -32,6 +32,8 @@
 namespace Ruby
 {
 
+class ModuleDeclaration;
+
 typedef KDevelop::AbstractDeclarationBuilder<RubyAst, NameAst, TypeBuilder> \
DeclarationBuilderBase;  
 /**
@@ -77,7 +79,7 @@ private:
                                 KDevelop::Declaration *decl); // TODO: change to \
MethodDeclaration  void appendProblem(Node* node, const QString &msg);
     KDevelop::RangeInRevision getNameRange(const RubyAst *node);
-    Declaration *getModuleDeclaration(const RubyAst *module); // NOTE: read comment \
at the implementation of this method +    ModuleDeclaration * \
getModuleDeclaration(const RubyAst *module); // NOTE: read comment at the \
                implementation of this method
     Declaration *lastClassModule; // TODO: pair it with insideClassModule and give \
it a proper name. TODO: by default point to the Kernel module  bool \
insideClassModule;  
diff --git a/duchain/declarations/classdeclaration.h \
b/duchain/declarations/classdeclaration.h index 243b26a..3ede52d 100644
--- a/duchain/declarations/classdeclaration.h
+++ b/duchain/declarations/classdeclaration.h
@@ -25,10 +25,6 @@
 #include <language/duchain/classdeclaration.h>
 #include <duchain/duchainexport.h>
 
-/*
- * WARNING: This file is under development.
- */
-
 
 namespace Ruby
 {
diff --git a/duchain/declarations/moduledeclaration.cpp \
b/duchain/declarations/moduledeclaration.cpp new file mode 100644
index 0000000..029b8b5
--- /dev/null
+++ b/duchain/declarations/moduledeclaration.cpp
@@ -0,0 +1,97 @@
+/*
+ * This file is part of KDevelop
+ * Copyright 2012  Miquel Sabaté <mikisabate@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <duchain/declarations/moduledeclaration.h>
+#include <language/duchain/identifier.h>
+#include <language/duchain/declaration.h>
+#include <language/duchain/appendedlist.h>
+#include <language/duchain/duchainregister.h>
+
+
+namespace Ruby
+{
+
+REGISTER_DUCHAIN_ITEM(ModuleDeclaration);
+DEFINE_LIST_MEMBER_HASH(ModuleDeclarationData, moduleMixins, ModuleMixin)
+
+
+ModuleDeclaration::ModuleDeclaration(const ModuleDeclaration &rhs)
+    : KDevelop::Declaration(*new ModuleDeclarationData(*rhs.d_func()))
+{
+    /* There's nothing to do here */
+}
+
+ModuleDeclaration::ModuleDeclaration(ModuleDeclarationData &data)
+    : KDevelop::Declaration(data)
+{
+
+}
+
+ModuleDeclaration::ModuleDeclaration(const KDevelop::RangeInRevision &range, \
KDevelop::DUContext *context) +    : KDevelop::Declaration(*new \
ModuleDeclarationData, range) +{
+    d_func_dynamic()->setClassId(this);
+    if (context)
+        setContext(context);
+}
+
+ModuleDeclaration::~ModuleDeclaration()
+{
+
+}
+
+void ModuleDeclaration::clearModuleMixins()
+{
+    bool wasInSymbolTable = inSymbolTable();
+    setInSymbolTable(false);
+    d_func_dynamic()->moduleMixinsList().clear();
+    setInSymbolTable(wasInSymbolTable);
+}
+
+uint ModuleDeclaration::moduleMixinsSize()
+{
+    return d_func()->moduleMixinsSize();
+}
+
+const ModuleMixin * ModuleDeclaration::moduleMixins() const
+{
+    return d_func()->moduleMixins();
+}
+
+void ModuleDeclaration::addModuleMixin(ModuleMixin module)
+{
+    bool wasInSymbolTable = inSymbolTable();
+    setInSymbolTable(false);
+    d_func_dynamic()->moduleMixinsList().append(module);
+    setInSymbolTable(wasInSymbolTable);
+}
+
+QString ModuleDeclaration::toString() const
+{
+    return "module " + identifier().toString();
+}
+
+KDevelop::Declaration * ModuleDeclaration::clonePrivate() const
+{
+    return new ModuleDeclaration(*this);
+}
+
+} // End of namespace Ruby
diff --git a/duchain/declarations/moduledeclaration.h \
b/duchain/declarations/moduledeclaration.h new file mode 100644
index 0000000..812350f
--- /dev/null
+++ b/duchain/declarations/moduledeclaration.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of KDevelop
+ * Copyright 2012  Miquel Sabaté <mikisabate@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef MODULE_DECLARATION_H
+#define MODULE_DECLARATION_H
+
+
+#include <duchain/duchainexport.h>
+#include <language/duchain/declaration.h>
+#include <language/duchain/declarationdata.h>
+
+
+namespace Ruby
+{
+
+struct KDEVRUBYDUCHAIN_EXPORT ModuleMixin {
+    KDevelop::IndexedType module;
+    bool included;
+};
+
+KDEVPLATFORMLANGUAGE_EXPORT DECLARE_LIST_MEMBER_HASH(ModuleDeclarationData, \
moduleMixins, ModuleMixin) +
+class KDEVRUBYDUCHAIN_EXPORT ModuleDeclarationData : public \
KDevelop::DeclarationData +{
+public:
+    ModuleDeclarationData()
+    {
+        initializeAppendedLists();
+    }
+
+    ModuleDeclarationData(const ModuleDeclarationData &rhs) : \
KDevelop::DeclarationData(rhs) +    {
+        initializeAppendedLists();
+        copyListsFrom(rhs);
+    }
+
+    ~ModuleDeclarationData()
+    {
+        freeAppendedLists();
+    }
+
+    START_APPENDED_LISTS_BASE(ModuleDeclarationData, KDevelop::DeclarationData);
+    APPENDED_LIST_FIRST(ModuleDeclarationData, ModuleMixin, moduleMixins);
+    END_APPENDED_LISTS(ModuleDeclarationData, moduleMixins);
+};
+
+
+class KDEVRUBYDUCHAIN_EXPORT ModuleDeclaration : public KDevelop::Declaration
+{
+public:
+    ModuleDeclaration(const ModuleDeclaration &rhs);
+    ModuleDeclaration(ModuleDeclarationData &data);
+    ModuleDeclaration(const KDevelop::RangeInRevision &range, KDevelop::DUContext \
*context); +    ~ModuleDeclaration();
+
+    void clearModuleMixins();
+    uint moduleMixinsSize();
+    const ModuleMixin * moduleMixins() const;
+    void addModuleMixin(ModuleMixin module);
+
+    QString toString() const;
+
+    enum { Identity = 44 };
+
+private:
+    virtual KDevelop::Declaration * clonePrivate() const;
+    DUCHAIN_DECLARE_DATA(ModuleDeclaration)
+};
+
+} // End of namespace Ruby
+
+
+Q_DECLARE_TYPEINFO(Ruby::ModuleMixin, Q_MOVABLE_TYPE); // TODO: check this
+
+
+#endif /* MODULE_DECLARATION_H */
diff --git a/duchain/navigation/declarationnavigationcontext.cpp \
b/duchain/navigation/declarationnavigationcontext.cpp index 020b230..37bbcaf 100644
--- a/duchain/navigation/declarationnavigationcontext.cpp
+++ b/duchain/navigation/declarationnavigationcontext.cpp
@@ -29,6 +29,7 @@
 #include <duchain/helpers.h>
 #include <duchain/declarations/classdeclaration.h>
 #include <duchain/declarations/methoddeclaration.h>
+#include <duchain/declarations/moduledeclaration.h>
 #include <duchain/navigation/declarationnavigationcontext.h>
 
 
@@ -49,6 +50,7 @@ void DeclarationNavigationContext::htmlClass()
     StructureType::Ptr klass = m_declaration->abstractType().cast<StructureType>();
     Q_ASSERT(klass);
     ClassDeclaration *classDecl = dynamic_cast<ClassDeclaration \
*>(klass->declaration(m_topContext.data())); +    ModuleDeclaration *mDecl = \
dynamic_cast<ModuleDeclaration *>(klass->declaration(m_topContext.data()));  
     if (classDecl) {
         /* Write class type */
@@ -66,6 +68,12 @@ void DeclarationNavigationContext::htmlClass()
             eventuallyMakeTypeLinks(base);
         }
         modifyHtml() += " ";
+    } else if (mDecl) {
+        modifyHtml() += "module ";
+        /* Write identifier */
+        eventuallyMakeTypeLinks(m_declaration->abstractType());
+        /* Write inheritance */
+        modifyHtml() += " ";
     }
 }
 
@@ -83,8 +91,12 @@ void DeclarationNavigationContext::makeLink(const QString &name, \
DeclarationPoin  QString \
DeclarationNavigationContext::declarationKind(DeclarationPointer decl)  {
     const MethodDeclaration *md = dynamic_cast<const MethodDeclaration \
*>(decl.data()); +    
     if (md)
         return (md->isClassMethod()) ? "Class method" : "Instance method";
+    ModuleDeclaration *mDecl = dynamic_cast<ModuleDeclaration *>(decl.data());
+    if (mDecl)
+        return NULL;
     return KDevelop::AbstractNavigationContext::declarationKind(decl);
 }
 


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

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