From 6fe6f5cdb14422a7125c476a5e631385daf0a655 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Mon, 20 Feb 2012 12:39:08 +0100
Subject: [PATCH] C++: make highlighting/completion plugable.

Change-Id: I990fdf5411153041c6b4c62f31b453342d59de53
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
---
 src/plugins/cppeditor/cppeditor.cpp           | 19 +++--
 src/plugins/cppeditor/cppeditor.h             |  3 +
 src/plugins/cpptools/cppcompletionsupport.cpp | 39 ++-------
 src/plugins/cpptools/cppcompletionsupport.h   | 33 +++++---
 .../cpptools/cppcompletionsupportinternal.cpp | 83 +++++++++++++++++++
 .../cpptools/cppcompletionsupportinternal.h   | 64 ++++++++++++++
 .../cpptools/cpphighlightingsupport.cpp       | 19 ++---
 src/plugins/cpptools/cpphighlightingsupport.h | 29 +++++--
 .../cpphighlightingsupportinternal.cpp        | 66 +++++++++++++++
 .../cpptools/cpphighlightingsupportinternal.h | 70 ++++++++++++++++
 src/plugins/cpptools/cppmodelmanager.cpp      | 38 +++++++--
 src/plugins/cpptools/cppmodelmanager.h        | 11 +++
 src/plugins/cpptools/cpptools.pro             |  4 +
 .../cpptools/cpptoolseditorsupport.cpp        | 14 +---
 src/plugins/cpptools/cpptoolseditorsupport.h  |  9 --
 15 files changed, 407 insertions(+), 94 deletions(-)
 create mode 100644 src/plugins/cpptools/cppcompletionsupportinternal.cpp
 create mode 100644 src/plugins/cpptools/cppcompletionsupportinternal.h
 create mode 100644 src/plugins/cpptools/cpphighlightingsupportinternal.cpp
 create mode 100644 src/plugins/cpptools/cpphighlightingsupportinternal.h

diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index a7f60d35be2..4bf4a4fc40b 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -424,6 +424,8 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
     , m_firstRenameChange(false)
     , m_objcEnabled(false)
     , m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings())
+    , m_completionSupport(0)
+    , m_highlightingSupport(0)
 {
     m_initialized = false;
     qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
@@ -440,10 +442,11 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
     baseTextDocument()->setSyntaxHighlighter(new CppHighlighter);
 
     m_modelManager = CppModelManagerInterface::instance();
-
     if (m_modelManager) {
         connect(m_modelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
                 this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
+        m_completionSupport = m_modelManager->completionSupport(editor());
+        m_highlightingSupport = m_modelManager->highlightingSupport(editor());
     }
 
     m_highlightRevision = 0;
@@ -477,6 +480,9 @@ CPPEditorWidget::~CPPEditorWidget()
         m_modelManager->GC();
         numberOfClosedEditors = 0;
     }
+
+    delete m_highlightingSupport;
+    delete m_completionSupport;
 }
 
 TextEditor::BaseTextEditor *CPPEditorWidget::createEditor()
@@ -1853,8 +1859,8 @@ void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
 
         if (! semanticHighlighterDisabled && semanticInfo.doc) {
             if (Core::EditorManager::instance()->currentEditor() == editor()) {
-                if (CppTools::CppHighlightingSupport *hs = modelManager()->highlightingSupport(editor())) {
-                    m_highlighter = hs->highlightingFuture(semanticInfo.doc, semanticInfo.snapshot);
+                if (m_highlightingSupport) {
+                    m_highlighter = m_highlightingSupport->highlightingFuture(semanticInfo.doc, semanticInfo.snapshot);
                     m_highlightRevision = semanticInfo.revision;
                     m_highlightWatcher.setFuture(m_highlighter);
                 }
@@ -2158,9 +2164,10 @@ TextEditor::IAssistInterface *CPPEditorWidget::createAssistInterface(
     TextEditor::AssistReason reason) const
 {
     if (kind == TextEditor::Completion) {
-        if (CppTools::CppCompletionSupport *cs = m_modelManager->completionSupport(editor()))
-            return cs->createAssistInterface(ProjectExplorer::ProjectExplorerPlugin::currentProject(),
-                                             document(), position(), reason);
+        if (m_completionSupport)
+            return m_completionSupport->createAssistInterface(
+                        ProjectExplorer::ProjectExplorerPlugin::currentProject(),
+                        document(), position(), reason);
     } else if (kind == TextEditor::QuickFix) {
         if (!semanticInfo().doc || isOutdated())
             return 0;
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 82cba02a943..999e4dacc76 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -333,6 +333,9 @@ private:
     QSharedPointer<FunctionDeclDefLink> m_declDefLink;
 
     CppTools::CommentsSettings m_commentsSettings;
+
+    CppTools::CppCompletionSupport *m_completionSupport;
+    CppTools::CppHighlightingSupport *m_highlightingSupport;
 };
 
 
diff --git a/src/plugins/cpptools/cppcompletionsupport.cpp b/src/plugins/cpptools/cppcompletionsupport.cpp
index 30c2d8c3639..cd9e6515d02 100644
--- a/src/plugins/cpptools/cppcompletionsupport.cpp
+++ b/src/plugins/cpptools/cppcompletionsupport.cpp
@@ -30,43 +30,20 @@
 **
 **************************************************************************/
 
-#include "cppcompletionassist.h"
 #include "cppcompletionsupport.h"
-#include "cppmodelmanager.h"
-#include "cpptoolseditorsupport.h"
 
-#include <coreplugin/idocument.h>
-#include <projectexplorer/project.h>
-#include <texteditor/codeassist/iassistinterface.h>
-
-using namespace CPlusPlus;
 using namespace CppTools;
-using namespace CppTools::Internal;
 
-CppCompletionSupport::CppCompletionSupport(CppEditorSupport *editorSupport)
-    : m_editorSupport(editorSupport)
+CppCompletionSupport::CppCompletionSupport(TextEditor::ITextEditor *editor)
+    : m_editor(editor)
+{
+    Q_ASSERT(editor);
+}
+
+CppCompletionSupport::~CppCompletionSupport()
 {
-    Q_ASSERT(editorSupport);
 }
 
-TextEditor::IAssistInterface *CppCompletionSupport::createAssistInterface(ProjectExplorer::Project *project,
-                                                                          QTextDocument *document,
-                                                                          int position,
-                                                                          TextEditor::AssistReason reason) const
+CppCompletionSupportFactory::~CppCompletionSupportFactory()
 {
-    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
-    QStringList includePaths;
-    QStringList frameworkPaths;
-    if (project) {
-        includePaths = modelManager->projectInfo(project).includePaths();
-        frameworkPaths = modelManager->projectInfo(project).frameworkPaths();
-    }
-    return new CppTools::Internal::CppCompletionAssistInterface(
-                document,
-                position,
-                m_editorSupport->textEditor()->document(),
-                reason,
-                modelManager->snapshot(),
-                includePaths,
-                frameworkPaths);
 }
diff --git a/src/plugins/cpptools/cppcompletionsupport.h b/src/plugins/cpptools/cppcompletionsupport.h
index 5764e18fca9..a530b8d1c23 100644
--- a/src/plugins/cpptools/cppcompletionsupport.h
+++ b/src/plugins/cpptools/cppcompletionsupport.h
@@ -41,35 +41,42 @@ QT_BEGIN_NAMESPACE
 class QTextDocument;
 QT_END_NAMESPACE
 
-namespace Core {
-class IDocument;
-}
-
 namespace ProjectExplorer {
 class Project;
 }
 
 namespace TextEditor {
 class IAssistInterface;
+class ITextEditor;
 }
 
 namespace CppTools {
-namespace Internal {
-class CppEditorSupport;
-}
 
 class CPPTOOLS_EXPORT CppCompletionSupport
 {
 public:
-    CppCompletionSupport(Internal::CppEditorSupport *editorSupport);
+    CppCompletionSupport(TextEditor::ITextEditor *editor);
+    virtual ~CppCompletionSupport() = 0;
 
-    TextEditor::IAssistInterface *createAssistInterface(ProjectExplorer::Project *project,
-                                                        QTextDocument *document,
-                                                        int position,
-                                                        TextEditor::AssistReason reason) const;
+    virtual TextEditor::IAssistInterface *createAssistInterface(ProjectExplorer::Project *project,
+                                                                QTextDocument *document,
+                                                                int position,
+                                                                TextEditor::AssistReason reason) const = 0;
+
+protected:
+    TextEditor::ITextEditor *editor() const
+    { return m_editor; }
 
 private:
-    Internal::CppEditorSupport *m_editorSupport;
+    TextEditor::ITextEditor *m_editor;
+};
+
+class CPPTOOLS_EXPORT CppCompletionSupportFactory
+{
+public:
+    virtual ~CppCompletionSupportFactory() = 0;
+
+    virtual CppCompletionSupport *completionSupport(TextEditor::ITextEditor *editor) = 0;
 };
 
 } // namespace CppTools
diff --git a/src/plugins/cpptools/cppcompletionsupportinternal.cpp b/src/plugins/cpptools/cppcompletionsupportinternal.cpp
new file mode 100644
index 00000000000..7f7fa185259
--- /dev/null
+++ b/src/plugins/cpptools/cppcompletionsupportinternal.cpp
@@ -0,0 +1,83 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "cppcompletionassist.h"
+#include "cppcompletionsupportinternal.h"
+#include "cppmodelmanager.h"
+
+#include <coreplugin/idocument.h>
+#include <projectexplorer/project.h>
+#include <texteditor/codeassist/iassistinterface.h>
+
+using namespace CPlusPlus;
+using namespace CppTools;
+using namespace CppTools::Internal;
+
+CppCompletionSupportInternal::CppCompletionSupportInternal(TextEditor::ITextEditor *editor)
+    : CppCompletionSupport(editor)
+{
+}
+
+CppCompletionSupportInternal::~CppCompletionSupportInternal()
+{
+}
+
+TextEditor::IAssistInterface *CppCompletionSupportInternal::createAssistInterface(
+        ProjectExplorer::Project *project,
+        QTextDocument *document,
+        int position,
+        TextEditor::AssistReason reason) const
+{
+    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
+    QStringList includePaths;
+    QStringList frameworkPaths;
+    if (project) {
+        includePaths = modelManager->projectInfo(project).includePaths();
+        frameworkPaths = modelManager->projectInfo(project).frameworkPaths();
+    }
+    return new CppTools::Internal::CppCompletionAssistInterface(
+                document,
+                position,
+                editor()->document(),
+                reason,
+                modelManager->snapshot(),
+                includePaths,
+                frameworkPaths);
+}
+
+CppCompletionSupportInternalFactory::~CppCompletionSupportInternalFactory()
+{}
+
+CppCompletionSupport *CppCompletionSupportInternalFactory::completionSupport(TextEditor::ITextEditor *editor)
+{
+    return new CppCompletionSupportInternal(editor);
+}
diff --git a/src/plugins/cpptools/cppcompletionsupportinternal.h b/src/plugins/cpptools/cppcompletionsupportinternal.h
new file mode 100644
index 00000000000..4e5c7d94d90
--- /dev/null
+++ b/src/plugins/cpptools/cppcompletionsupportinternal.h
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CPPTOOLS_CPPCOMPLETIONSUPPORTINTERNAL_H
+#define CPPTOOLS_CPPCOMPLETIONSUPPORTINTERNAL_H
+
+#include "cppcompletionsupport.h"
+
+namespace CppTools {
+namespace Internal {
+
+class CppCompletionSupportInternal: public CppCompletionSupport
+{
+public:
+    CppCompletionSupportInternal(TextEditor::ITextEditor *editor);
+    virtual ~CppCompletionSupportInternal();
+
+    virtual TextEditor::IAssistInterface *createAssistInterface(ProjectExplorer::Project *project,
+                                                                QTextDocument *document,
+                                                                int position,
+                                                                TextEditor::AssistReason reason) const;
+};
+
+class CppCompletionSupportInternalFactory: public CppCompletionSupportFactory
+{
+public:
+    virtual ~CppCompletionSupportInternalFactory();
+
+    virtual CppCompletionSupport *completionSupport(TextEditor::ITextEditor *editor);
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+#endif // CPPTOOLS_CPPCOMPLETIONSUPPORTINTERNAL_H
diff --git a/src/plugins/cpptools/cpphighlightingsupport.cpp b/src/plugins/cpptools/cpphighlightingsupport.cpp
index 6326b623044..2ae4311613b 100644
--- a/src/plugins/cpptools/cpphighlightingsupport.cpp
+++ b/src/plugins/cpptools/cpphighlightingsupport.cpp
@@ -30,23 +30,20 @@
 **
 **************************************************************************/
 
-#include "cppchecksymbols.h"
 #include "cpphighlightingsupport.h"
-#include "cpptoolseditorsupport.h"
 
-#include <cplusplus/LookupContext.h>
-
-using namespace CPlusPlus;
 using namespace CppTools;
-using namespace CppTools::Internal;
 
-CppHighlightingSupport::CppHighlightingSupport()
+CppHighlightingSupport::CppHighlightingSupport(TextEditor::ITextEditor *editor)
+    : m_editor(editor)
+{
+    Q_ASSERT(editor);
+}
+
+CppHighlightingSupport::~CppHighlightingSupport()
 {
 }
 
-QFuture<CppHighlightingSupport::Use> CppHighlightingSupport::highlightingFuture(
-        const Document::Ptr &doc, const Snapshot &snapshot) const
+CppHighlightingSupportFactory::~CppHighlightingSupportFactory()
 {
-    LookupContext context(doc, snapshot);
-    return CheckSymbols::go(doc, context);
 }
diff --git a/src/plugins/cpptools/cpphighlightingsupport.h b/src/plugins/cpptools/cpphighlightingsupport.h
index 9776802c110..6b805420373 100644
--- a/src/plugins/cpptools/cpphighlightingsupport.h
+++ b/src/plugins/cpptools/cpphighlightingsupport.h
@@ -40,21 +40,38 @@
 
 #include <QFuture>
 
-namespace CppTools {
-namespace Internal {
-class CppEditorSupport;
+namespace TextEditor {
+class ITextEditor;
 }
 
+namespace CppTools {
+
 class CPPTOOLS_EXPORT CppHighlightingSupport
 {
 public:
     typedef TextEditor::SemanticHighlighter::Result Use;
 
 public:
-    CppHighlightingSupport();
+    CppHighlightingSupport(TextEditor::ITextEditor *editor);
+    virtual ~CppHighlightingSupport() = 0;
+
+    virtual QFuture<Use> highlightingFuture(const CPlusPlus::Document::Ptr &doc,
+                                            const CPlusPlus::Snapshot &snapshot) const = 0;
+
+protected:
+    TextEditor::ITextEditor *editor() const
+    { return m_editor; }
+
+private:
+    TextEditor::ITextEditor *m_editor;
+};
+
+class CPPTOOLS_EXPORT CppHighlightingSupportFactory
+{
+public:
+    virtual ~CppHighlightingSupportFactory() = 0;
 
-    QFuture<Use> highlightingFuture(const CPlusPlus::Document::Ptr &doc,
-                                    const CPlusPlus::Snapshot &snapshot) const;
+    virtual CppHighlightingSupport *highlightingSupport(TextEditor::ITextEditor *editor) = 0;
 };
 
 } // namespace CppTools
diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp
new file mode 100644
index 00000000000..f9cfcecaa7e
--- /dev/null
+++ b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "cppchecksymbols.h"
+#include "cpphighlightingsupportinternal.h"
+
+#include <cplusplus/LookupContext.h>
+
+using namespace CPlusPlus;
+using namespace CppTools;
+using namespace CppTools::Internal;
+
+CppHighlightingSupportInternal::CppHighlightingSupportInternal(TextEditor::ITextEditor *editor)
+    : CppHighlightingSupport(editor)
+{
+}
+
+CppHighlightingSupportInternal::~CppHighlightingSupportInternal()
+{
+}
+
+QFuture<CppHighlightingSupport::Use> CppHighlightingSupportInternal::highlightingFuture(
+        const Document::Ptr &doc,
+        const Snapshot &snapshot) const
+{
+    LookupContext context(doc, snapshot);
+    return CheckSymbols::go(doc, context);
+}
+
+CppHighlightingSupportInternalFactory::~CppHighlightingSupportInternalFactory()
+{
+}
+
+CppHighlightingSupport *CppHighlightingSupportInternalFactory::highlightingSupport(TextEditor::ITextEditor *editor)
+{
+    return new CppHighlightingSupportInternal(editor);
+}
diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.h b/src/plugins/cpptools/cpphighlightingsupportinternal.h
new file mode 100644
index 00000000000..52ab1f81184
--- /dev/null
+++ b/src/plugins/cpptools/cpphighlightingsupportinternal.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
+#define CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
+
+#include "cpphighlightingsupport.h"
+
+#include <cplusplus/CppDocument.h>
+#include <texteditor/semantichighlighter.h>
+
+#include <QFuture>
+
+namespace CppTools {
+namespace Internal {
+
+class CppHighlightingSupportInternal: public CppHighlightingSupport
+{
+public:
+    typedef TextEditor::SemanticHighlighter::Result Use;
+
+public:
+    CppHighlightingSupportInternal(TextEditor::ITextEditor *editor);
+    virtual ~CppHighlightingSupportInternal();
+
+    virtual QFuture<Use> highlightingFuture(const CPlusPlus::Document::Ptr &doc,
+                                            const CPlusPlus::Snapshot &snapshot) const;
+};
+
+class CppHighlightingSupportInternalFactory: public CppHighlightingSupportFactory
+{
+public:
+    virtual ~CppHighlightingSupportInternalFactory();
+
+    virtual CppHighlightingSupport *highlightingSupport(TextEditor::ITextEditor *editor);
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+#endif // CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 81e4ca6e0c8..ed8c716ae59 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -34,6 +34,10 @@
 #include <cplusplus/Overview.h>
 
 #include "cppmodelmanager.h"
+#include "cppcompletionsupport.h"
+#include "cppcompletionsupportinternal.h"
+#include "cpphighlightingsupport.h"
+#include "cpphighlightingsupportinternal.h"
 #include "abstracteditorsupport.h"
 #ifndef ICHECK_BUILD
 #  include "cpptoolsconstants.h"
@@ -730,10 +734,18 @@ CppModelManager::CppModelManager(QObject *parent)
 
     connect(Core::ICore::editorManager(), SIGNAL(editorAboutToClose(Core::IEditor *)),
         this, SLOT(editorAboutToClose(Core::IEditor *)));
+
+    m_completionFallback = new CppCompletionSupportInternalFactory;
+    m_completionFactory = m_completionFallback;
+    m_highlightingFallback = new CppHighlightingSupportInternalFactory;
+    m_highlightingFactory = m_highlightingFallback;
 }
 
 CppModelManager::~CppModelManager()
-{ }
+{
+    delete m_completionFallback;
+    delete m_highlightingFallback;
+}
 
 Snapshot CppModelManager::snapshot() const
 {
@@ -1395,20 +1407,36 @@ void CppModelManager::finishedRefreshingSourceFiles(const QStringList &files)
 
 CppCompletionSupport *CppModelManager::completionSupport(Core::IEditor *editor) const
 {
-    if (CppEditorSupport *es = editorSupport(qobject_cast<TextEditor::ITextEditor *>(editor)))
-        return es->completionSupport();
+    if (TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor))
+        return m_completionFactory->completionSupport(textEditor);
     else
         return 0;
 }
 
+void CppModelManager::setCompletionSupportFactory(CppCompletionSupportFactory *completionFactory)
+{
+    if (completionFactory)
+        m_completionFactory = completionFactory;
+    else
+        m_completionFactory = m_completionFallback;
+}
+
 CppHighlightingSupport *CppModelManager::highlightingSupport(Core::IEditor *editor) const
 {
-    if (CppEditorSupport *es = editorSupport(qobject_cast<TextEditor::ITextEditor *>(editor)))
-        return es->highlightingSupport();
+    if (TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor))
+        return m_highlightingFactory->highlightingSupport(textEditor);
     else
         return 0;
 }
 
+void CppModelManager::setHighlightingSupportFactory(CppHighlightingSupportFactory *highlightingFactory)
+{
+    if (highlightingFactory)
+        m_highlightingFactory = highlightingFactory;
+    else
+        m_highlightingFactory = m_highlightingFallback;
+}
+
 void CppModelManager::setExtraDiagnostics(const QString &fileName, int kind,
                                           const QList<Document::DiagnosticMessage> &diagnostics)
 {
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index d56045c2e9e..dab51c3c774 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -76,6 +76,9 @@ namespace CPlusPlus {
 
 namespace CppTools {
 
+class CppCompletionSupportFactory;
+class CppHighlightingSupportFactory;
+
 namespace Internal {
 
 class CppEditorSupport;
@@ -135,7 +138,10 @@ public:
     void finishedRefreshingSourceFiles(const QStringList &files);
 
     virtual CppCompletionSupport *completionSupport(Core::IEditor *editor) const;
+    void setCompletionSupportFactory(CppCompletionSupportFactory *completionFactory);
+
     virtual CppHighlightingSupport *highlightingSupport(Core::IEditor *editor) const;
+    void setHighlightingSupportFactory(CppHighlightingSupportFactory *highlightingFactory);
 
 Q_SIGNALS:
     void projectPathChanged(const QString &projectPath);
@@ -240,6 +246,11 @@ private:
     QHash<QString, QHash<int, QList<CPlusPlus::Document::DiagnosticMessage> > > m_extraDiagnostics;
 
     QMap<QString, QList<ProjectPart::Ptr> > m_srcToProjectPart;
+
+    CppCompletionSupportFactory *m_completionFactory;
+    CppCompletionSupportFactory *m_completionFallback;
+    CppHighlightingSupportFactory *m_highlightingFactory;
+    CppHighlightingSupportFactory *m_highlightingFallback;
 };
 #endif
 
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index e685f307b7b..ac622e00f29 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -40,7 +40,9 @@ HEADERS += completionsettingspage.h \
     commentssettings.h \
     symbolfinder.h \
     cppcompletionsupport.h \
+    cppcompletionsupportinternal.h \
     cpphighlightingsupport.h \
+    cpphighlightingsupportinternal.h \
     cppchecksymbols.h \
     cpplocalsymbols.h \
     cppsemanticinfo.h
@@ -75,7 +77,9 @@ SOURCES += completionsettingspage.cpp \
     commentssettings.cpp \
     symbolfinder.cpp \
     cppcompletionsupport.cpp \
+    cppcompletionsupportinternal.cpp \
     cpphighlightingsupport.cpp \
+    cpphighlightingsupportinternal.cpp \
     cppchecksymbols.cpp \
     cpplocalsymbols.cpp \
     cppsemanticinfo.cpp
diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp
index d1c75e60635..544a26f88e5 100644
--- a/src/plugins/cpptools/cpptoolseditorsupport.cpp
+++ b/src/plugins/cpptools/cpptoolseditorsupport.cpp
@@ -53,9 +53,7 @@ using namespace CPlusPlus;
 CppEditorSupport::CppEditorSupport(CppModelManager *modelManager)
     : QObject(modelManager),
       _modelManager(modelManager),
-      _updateDocumentInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL),
-      m_completionSupport(new CppCompletionSupport(this)),
-      m_highlightingSupport(new CppHighlightingSupport)
+      _updateDocumentInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL)
 {
     _revision = 0;
 
@@ -103,16 +101,6 @@ unsigned CppEditorSupport::editorRevision() const
     return 0;
 }
 
-CppTools::CppCompletionSupport *CppEditorSupport::completionSupport() const
-{
-    return m_completionSupport.data();
-}
-
-CppHighlightingSupport *CppEditorSupport::highlightingSupport() const
-{
-    return m_highlightingSupport.data();
-}
-
 int CppEditorSupport::updateDocumentInterval() const
 { return _updateDocumentInterval; }
 
diff --git a/src/plugins/cpptools/cpptoolseditorsupport.h b/src/plugins/cpptools/cpptoolseditorsupport.h
index 065d3c5e1b2..d8570f8fa23 100644
--- a/src/plugins/cpptools/cpptoolseditorsupport.h
+++ b/src/plugins/cpptools/cpptoolseditorsupport.h
@@ -57,10 +57,6 @@ namespace TextEditor {
 } // namespace TextEditor
 
 namespace CppTools {
-
-class CppCompletionSupport;
-class CppHighlightingSupport;
-
 namespace Internal {
 
 class CppModelManager;
@@ -82,9 +78,6 @@ public:
     QString contents();
     unsigned editorRevision() const;
 
-    CppCompletionSupport *completionSupport() const;
-    CppHighlightingSupport *highlightingSupport() const;
-
 Q_SIGNALS:
     void contentsChanged();
 
@@ -102,8 +95,6 @@ private:
     QFuture<void> _documentParser;
     QString _cachedContents;
     unsigned _revision;
-    QScopedPointer<CppCompletionSupport> m_completionSupport;
-    QScopedPointer<CppHighlightingSupport> m_highlightingSupport;
 };
 
 } // namespace Internal
-- 
GitLab