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

List:       kde-commits
Subject:    [kdev-qmljs] codecompletion: Handle namespace imports, classes and wrappers in code-completion
From:       Denis Steckelmacher <steckdenis () yahoo ! fr>
Date:       2014-05-31 14:10:14
Message-ID: E1WqjzC-0003mh-Fi () scm ! kde ! org
[Download RAW message or body]

Git commit 53eacaae8e75040313ea631634b9f62a8101a609 by Denis Steckelmacher.
Committed on 31/05/2014 at 14:08.
Pushed by dsteckelmacher into branch 'master'.

Handle namespace imports, classes and wrappers in code-completion

REVIEW: 118435

M  +1    -0    codecompletion/CMakeLists.txt
A  +72   -0    codecompletion/completionitem.cpp     [License: GPL (v2/3)]
C  +8    -12   codecompletion/completionitem.h [from: codecompletion/context.h - 059% \
similarity] M  +49   -39   codecompletion/context.cpp
M  +3    -2    codecompletion/context.h

http://commits.kde.org/kdev-qmljs/53eacaae8e75040313ea631634b9f62a8101a609

diff --git a/codecompletion/CMakeLists.txt b/codecompletion/CMakeLists.txt
index de6f53c..9b62fb4 100644
--- a/codecompletion/CMakeLists.txt
+++ b/codecompletion/CMakeLists.txt
@@ -4,6 +4,7 @@ include_directories(
 )
 
 set(completion_SRCS
+    completionitem.cpp
     context.cpp
     model.cpp
     worker.cpp
diff --git a/codecompletion/completionitem.cpp b/codecompletion/completionitem.cpp
new file mode 100644
index 0000000..d90569c
--- /dev/null
+++ b/codecompletion/completionitem.cpp
@@ -0,0 +1,72 @@
+/*
+ * This file is part of qmljs, the QML/JS language support plugin for KDevelop
+ * Copyright (c) 2014 Denis Steckelmacher <steckdenis@yahoo.fr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "completionitem.h"
+
+#include <language/codecompletion/codecompletionmodel.h>
+#include <language/duchain/declaration.h>
+#include <language/duchain/classdeclaration.h>
+#include <language/duchain/duchainlock.h>
+#include <language/duchain/types/abstracttype.h>
+#include <language/duchain/types/structuretype.h>
+
+using namespace QmlJS;
+using namespace KDevelop;
+
+CompletionItem::CompletionItem(DeclarationPointer decl, int inheritanceDepth)
+: NormalDeclarationCompletionItem(decl, KSharedPtr<CodeCompletionContext>(), \
inheritanceDepth) +{
+}
+
+QVariant CompletionItem::data(const QModelIndex& index, int role, const \
CodeCompletionModel* model) const +{
+    DUChainReadLocker lock;
+    Declaration* decl = declaration().data();
+    ClassDeclaration* classDecl = dynamic_cast<ClassDeclaration *>(decl);
+    StructureType::Ptr declType = \
StructureType::Ptr::dynamicCast(decl->abstractType()); +
+    if (role == Qt::DisplayRole && index.column() == CodeCompletionModel::Prefix) {
+        if (classDecl) {
+            if (classDecl->classType() == ClassDeclarationData::Class) {
+                // QML component
+                return QString("component");
+            } else if (classDecl->classType() == ClassDeclarationData::Interface) {
+                // C++-ish QML component
+                return QString("wrapper");
+            }
+        }
+
+        if (declType &&
+            decl->kind() == Declaration::Instance &&
+            declType->declarationId().qualifiedIdentifier().isEmpty()) {
+            // QML component instance. The type that should be displayed is the
+            // base class of its anonymous class
+            ClassDeclaration* anonymousClass = dynamic_cast<ClassDeclaration \
*>(declType->declaration(decl->topContext())); +
+            if (anonymousClass && anonymousClass->baseClassesSize() > 0) {
+                return \
anonymousClass->baseClasses()[0].baseClass.abstractType()->toString(); +            }
+        }
+    }
+
+    return NormalDeclarationCompletionItem::data(index, role, model);
+}
diff --git a/codecompletion/context.h b/codecompletion/completionitem.h
similarity index 59%
copy from codecompletion/context.h
copy to codecompletion/completionitem.h
index 09b3d8f..b8e47fa 100644
--- a/codecompletion/context.h
+++ b/codecompletion/completionitem.h
@@ -1,6 +1,6 @@
 /*
  * This file is part of qmljs, the QML/JS language support plugin for KDevelop
- * Copyright (c) 2013 Sven Brauch <svenbrauch@googlemail.com>
+ * Copyright (c) 2014 Denis Steckelmacher <steckdenis@yahoo.fr>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -20,25 +20,21 @@
  *
  */
 
-#ifndef QMLJS_CONTEXT_H
-#define QMLJS_CONTEXT_H
+#ifndef __COMPLETIONITEM_H__
+#define __COMPLETIONITEM_H__
 
-#include <language/codecompletion/codecompletioncontext.h>
-#include <language/duchain/ducontext.h>
+#include <language/codecompletion/normaldeclarationcompletionitem.h>
 
 namespace QmlJS {
 
-class CodeCompletionContext : public KDevelop::CodeCompletionContext
+class CompletionItem : public KDevelop::NormalDeclarationCompletionItem
 {
 public:
-    CodeCompletionContext(const KDevelop::DUContextPointer& context, const QString& \
                text,
-                          const KDevelop::CursorInRevision& position, int depth = \
                0);
-    virtual QList< KDevelop::CompletionTreeItemPointer > completionItems(bool& \
abort, bool fullCompletion = true); +    CompletionItem(KDevelop::DeclarationPointer \
decl, int inheritanceDepth);  
-private:
-    QList<KDevelop::CompletionTreeItemPointer> globalItems() const;
+    virtual QVariant data(const QModelIndex& index, int role, const \
KDevelop::CodeCompletionModel* model) const;  };
 
 }
 
-#endif // QMLJS_CONTEXT_H
+#endif
\ No newline at end of file
diff --git a/codecompletion/context.cpp b/codecompletion/context.cpp
index 751dc8e..1e57197 100644
--- a/codecompletion/context.cpp
+++ b/codecompletion/context.cpp
@@ -21,12 +21,14 @@
  */
 
 #include "context.h"
+#include "completionitem.h"
 
 #include <language/codecompletion/codecompletionitem.h>
 #include <language/codecompletion/normaldeclarationcompletionitem.h>
 #include <language/duchain/declaration.h>
 #include <language/duchain/duchainlock.h>
 #include <language/duchain/classdeclaration.h>
+#include <language/duchain/namespacealiasdeclaration.h>
 #include <language/duchain/codemodel.h>
 
 using namespace KDevelop;
@@ -35,19 +37,6 @@ typedef QPair<Declaration*, int> DeclarationDepthPair;
 
 namespace QmlJS {
 
-class UiObjectDefinitionItem : public NormalDeclarationCompletionItem
-{
-public:
-    UiObjectDefinitionItem(const DeclarationPointer& decl)
-    : NormalDeclarationCompletionItem(decl)
-    {
-    }
-    virtual KTextEditor::CodeCompletionModel::CompletionProperties \
                completionProperties() const
-    {
-        return KTextEditor::CodeCompletionModel::GlobalScope | \
                KTextEditor::CodeCompletionModel::Class;
-    }
-};
-
 CodeCompletionContext::CodeCompletionContext(const DUContextPointer& context, const \
                QString& text,
                                              const CursorInRevision& position, int \
depth)  : KDevelop::CodeCompletionContext(context, text, position, depth)
@@ -56,7 +45,7 @@ CodeCompletionContext::CodeCompletionContext(const \
DUContextPointer& context, co  // ...
 }
 
-QList< CompletionTreeItemPointer > CodeCompletionContext::completionItems(bool& \
abort, bool fullCompletion) +QList<CompletionTreeItemPointer> \
CodeCompletionContext::completionItems(bool& abort, bool fullCompletion)  {
     Q_UNUSED (fullCompletion);
 
@@ -65,47 +54,68 @@ QList< CompletionTreeItemPointer > \
CodeCompletionContext::completionItems(bool&  
     QList<CompletionTreeItemPointer> items;
 
-    if ( abort ) {
+    if (abort) {
         return items;
     }
 
+    items << completionsInContext(m_duContext);
+    items << globalCompletions();
+
+    return items;
+}
+
+QList<CompletionTreeItemPointer> CodeCompletionContext::completionsInContext(const \
DUContextPointer& context) +{
+    QList<CompletionTreeItemPointer> items;
     DUChainReadLocker lock;
-    if ( m_duContext ) {
-        items += globalItems();
 
-        const QList<DeclarationDepthPair>& locals = \
                m_duContext->allDeclarations(m_position, duContext()->topContext());
-        foreach ( const DeclarationDepthPair& decl, locals ) {
-            if (dynamic_cast<ClassDeclaration*>(decl.first)) {
+    if (context) {
+        const QList<DeclarationDepthPair>& declarations = context->allDeclarations(
+            context == m_duContext ? m_position : CursorInRevision::invalid(),
+            context->topContext()
+        );
+
+        foreach (const DeclarationDepthPair& decl, declarations) {
+            DeclarationPointer declaration(decl.first);
+
+            if (decl.first->kind() == Declaration::NamespaceAlias) {
+                continue;
+            } else if (decl.first->qualifiedIdentifier().isEmpty()) {
                 continue;
             }
-            DeclarationPointer declaration(decl.first);
-            items << CompletionTreeItemPointer(new \
NormalDeclarationCompletionItem(declaration)); +
+            items << CompletionTreeItemPointer(new CompletionItem(declaration, \
decl.second));  }
     }
+
     return items;
 }
 
-QList<CompletionTreeItemPointer> CodeCompletionContext::globalItems() const
+QList<CompletionTreeItemPointer> CodeCompletionContext::globalCompletions()
 {
-    QList<CompletionTreeItemPointer> ret;
-
-    uint itemCount = 0;
-    const CodeModelItem* items = 0;
-    CodeModel::self().items(m_duContext->url(), itemCount, items);
-    for (uint i = 0; i < itemCount; ++i) {
-        const CodeModelItem& item = items[i];
-        if (item.kind & CodeModelItem::Class && item.id.isValid()) {
-            foreach (Declaration* dec, \
                m_duContext->findDeclarations(item.id.identifier())) {
-                if (dynamic_cast<ClassDeclaration*>(dec)) {
-                    ret << CompletionTreeItemPointer(new \
                UiObjectDefinitionItem(DeclarationPointer(dec)));
-                    break;
-                }
-            }
+    QList<CompletionTreeItemPointer> items;
+
+    // Iterate over all the imported namespaces and add their definitions
+    DUChainReadLocker lock;
+    QList<Declaration*> imports = \
m_duContext->findDeclarations(globalImportIdentifier()); +    QList<Declaration*> \
realImports; +
+    foreach (Declaration* import, imports) {
+        if (import->kind() != Declaration::NamespaceAlias) {
+            continue;
         }
+
+        NamespaceAliasDeclaration* decl = static_cast<NamespaceAliasDeclaration \
*>(import); +        realImports << \
m_duContext->findDeclarations(decl->importIdentifier());  }
 
-    return ret;
-}
+    lock.unlock();
 
+    foreach (Declaration* import, realImports) {
+        items << completionsInContext(DUContextPointer(import->internalContext()));
+    }
+
+    return items;
+}
 
 }
diff --git a/codecompletion/context.h b/codecompletion/context.h
index 09b3d8f..0683974 100644
--- a/codecompletion/context.h
+++ b/codecompletion/context.h
@@ -33,10 +33,11 @@ class CodeCompletionContext : public \
KDevelop::CodeCompletionContext  public:
     CodeCompletionContext(const KDevelop::DUContextPointer& context, const QString& \
                text,
                           const KDevelop::CursorInRevision& position, int depth = \
                0);
-    virtual QList< KDevelop::CompletionTreeItemPointer > completionItems(bool& \
abort, bool fullCompletion = true); +    virtual \
QList<KDevelop::CompletionTreeItemPointer> completionItems(bool& abort, bool \
fullCompletion = true);  
 private:
-    QList<KDevelop::CompletionTreeItemPointer> globalItems() const;
+    QList<KDevelop::CompletionTreeItemPointer> completionsInContext(const \
KDevelop::DUContextPointer& context); +    QList<KDevelop::CompletionTreeItemPointer> \
globalCompletions();  };
 
 }


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

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