summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel.pro20
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel.qbs6
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp5
-rw-r--r--src/plugins/clangcodemodel/clangcompletion.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangcompletion.h2
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentparser.cpp128
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentparser.h (renamed from src/plugins/clangcodemodel/clanghighlightingsupport.h)45
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp184
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.h74
-rw-r--r--src/plugins/clangcodemodel/clanghighlightingsupport.cpp96
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.h9
-rw-r--r--src/plugins/clangcodemodel/cppcreatemarkers.cpp87
-rw-r--r--src/plugins/clangcodemodel/cppcreatemarkers.h17
-rw-r--r--src/plugins/clangcodemodel/semanticmarker.cpp15
-rw-r--r--src/plugins/clangcodemodel/semanticmarker.h14
-rw-r--r--src/plugins/cppeditor/cppcodemodelinspectordialog.cpp17
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp526
-rw-r--r--src/plugins/cppeditor/cppeditor.h48
-rw-r--r--src/plugins/cppeditor/cppeditor.pro2
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs1
-rw-r--r--src/plugins/cppeditor/cppeditordocument.cpp193
-rw-r--r--src/plugins/cppeditor/cppeditordocument.h57
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.cpp1
-rw-r--r--src/plugins/cppeditor/cppeditortestcase.cpp8
-rw-r--r--src/plugins/cppeditor/cppincludehierarchymodel.cpp55
-rw-r--r--src/plugins/cppeditor/cppincludehierarchymodel.h5
-rw-r--r--src/plugins/cppeditor/cpplocalrenaming.cpp3
-rw-r--r--src/plugins/cppeditor/cpplocalrenaming.h5
-rw-r--r--src/plugins/cppeditor/cppquickfixassistant.cpp4
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp1
-rw-r--r--src/plugins/cppeditor/cppuseselections_test.cpp2
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.cpp451
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.h119
-rw-r--r--src/plugins/cpptools/baseeditordocumentparser.cpp12
-rw-r--r--src/plugins/cpptools/baseeditordocumentparser.h8
-rw-r--r--src/plugins/cpptools/baseeditordocumentprocessor.cpp135
-rw-r--r--src/plugins/cpptools/baseeditordocumentprocessor.h99
-rw-r--r--src/plugins/cpptools/builtineditordocumentparser.cpp11
-rw-r--r--src/plugins/cpptools/builtineditordocumentparser.h6
-rw-r--r--src/plugins/cpptools/builtineditordocumentprocessor.cpp253
-rw-r--r--src/plugins/cpptools/builtineditordocumentprocessor.h80
-rw-r--r--src/plugins/cpptools/cppchecksymbols.cpp60
-rw-r--r--src/plugins/cpptools/cppchecksymbols.h4
-rw-r--r--src/plugins/cpptools/cppcompletion_test.cpp4
-rw-r--r--src/plugins/cpptools/cppcompletionassist.cpp18
-rw-r--r--src/plugins/cpptools/cppcompletionassist.h16
-rw-r--r--src/plugins/cpptools/cppcompletionassistprovider.h2
-rw-r--r--src/plugins/cpptools/cpphighlightingsupportinternal.cpp104
-rw-r--r--src/plugins/cpptools/cpplocalsymbols.cpp6
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp102
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h25
-rw-r--r--src/plugins/cpptools/cppmodelmanager_test.cpp34
-rw-r--r--src/plugins/cpptools/cppmodelmanagerinterface.h17
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupport.h6
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupportinternal.cpp12
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupportinternal.h4
-rw-r--r--src/plugins/cpptools/cppsemanticinfo.cpp2
-rw-r--r--src/plugins/cpptools/cppsemanticinfo.h24
-rw-r--r--src/plugins/cpptools/cppsemanticinfoupdater.cpp226
-rw-r--r--src/plugins/cpptools/cppsemanticinfoupdater.h (renamed from src/plugins/cpptools/cpphighlightingsupportinternal.h)41
-rw-r--r--src/plugins/cpptools/cppsourceprocessor_test.cpp14
-rw-r--r--src/plugins/cpptools/cpptools.pro16
-rw-r--r--src/plugins/cpptools/cpptools.qbs8
-rw-r--r--src/plugins/cpptools/cppworkingcopy.h3
-rw-r--r--src/plugins/cpptools/editordocumenthandle.cpp (renamed from src/plugins/cpptools/cpphighlightingsupport.cpp)19
-rw-r--r--src/plugins/cpptools/editordocumenthandle.h55
-rw-r--r--src/plugins/cpptools/semantichighlighter.cpp165
-rw-r--r--src/plugins/cpptools/semantichighlighter.h (renamed from src/plugins/cpptools/cpphighlightingsupport.h)55
-rw-r--r--src/plugins/designer/gotoslot_test.cpp21
70 files changed, 2787 insertions, 1098 deletions
diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro
index 28b111b42e..ebbb29c8e4 100644
--- a/src/plugins/clangcodemodel/clangcodemodel.pro
+++ b/src/plugins/clangcodemodel/clangcodemodel.pro
@@ -17,18 +17,14 @@ contains(DEFINES, CLANG_COMPLETION) {
}
contains(DEFINES, CLANG_HIGHLIGHTING) {
- HEADERS += cppcreatemarkers.h clanghighlightingsupport.h
- SOURCES += cppcreatemarkers.cpp clanghighlightingsupport.cpp
+ HEADERS += cppcreatemarkers.h
+ SOURCES += cppcreatemarkers.cpp
}
-HEADERS += clangutils.h \
- cxprettyprinter.h
-
-SOURCES += clangutils.cpp \
- cxprettyprinter.cpp
-
SOURCES += \
$$PWD/clangcodemodelplugin.cpp \
+ $$PWD/clangeditordocumentparser.cpp \
+ $$PWD/clangeditordocumentprocessor.cpp \
$$PWD/sourcemarker.cpp \
$$PWD/symbol.cpp \
$$PWD/sourcelocation.cpp \
@@ -48,6 +44,8 @@ SOURCES += \
HEADERS += \
$$PWD/clangcodemodelplugin.h \
+ $$PWD/clangeditordocumentparser.h \
+ $$PWD/clangeditordocumentprocessor.h \
$$PWD/clang_global.h \
$$PWD/sourcemarker.h \
$$PWD/constants.h \
@@ -68,6 +66,12 @@ HEADERS += \
$$PWD/raii/scopedclangoptions.h \
$$PWD/clangmodelmanagersupport.h
+HEADERS += clangutils.h \
+ cxprettyprinter.h
+
+SOURCES += clangutils.cpp \
+ cxprettyprinter.cpp
+
contains(DEFINES, CLANG_INDEXING) {
HEADERS += \
$$PWD/clangindexer.h \
diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs
index 499f2e0492..1da1f421d6 100644
--- a/src/plugins/clangcodemodel/clangcodemodel.qbs
+++ b/src/plugins/clangcodemodel/clangcodemodel.qbs
@@ -94,8 +94,6 @@ QtcPlugin {
name: "Highlighting support"
condition: product.clangHighlighting
files: [
- "clanghighlightingsupport.cpp",
- "clanghighlightingsupport.h",
"cppcreatemarkers.cpp",
"cppcreatemarkers.h",
]
@@ -156,6 +154,10 @@ QtcPlugin {
files: [
"clang_global.h",
+ "clangeditordocumentparser.cpp",
+ "clangeditordocumentparser.h",
+ "clangeditordocumentprocessor.cpp",
+ "clangeditordocumentprocessor.h",
"clangmodelmanagersupport.cpp",
"clangmodelmanagersupport.h",
"clangcodemodelplugin.cpp",
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
index f6297b84a5..57e94003c2 100644
--- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
+++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
@@ -29,7 +29,6 @@
#include "clangcodemodelplugin.h"
#include "clangprojectsettingspropertiespage.h"
-#include "fastindexer.h"
#include "pchmanager.h"
#include "utils.h"
@@ -65,11 +64,9 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
ClangCodeModel::Internal::initializeClang();
PchManager *pchManager = new PchManager(this);
- FastIndexer *fastIndexer = 0;
#ifdef CLANG_INDEXING
m_indexer.reset(new ClangIndexer);
- fastIndexer = m_indexer.data();
CppTools::CppModelManagerInterface::instance()->setIndexingSupport(m_indexer->indexingSupport());
#endif // CLANG_INDEXING
@@ -80,7 +77,7 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
connect(CppTools::CppModelManagerInterface::instance(), SIGNAL(projectPartsUpdated(ProjectExplorer::Project*)),
pchManager, SLOT(onProjectPartsUpdated(ProjectExplorer::Project*)));
- m_modelManagerSupport.reset(new ModelManagerSupport(fastIndexer));
+ m_modelManagerSupport.reset(new ModelManagerSupport);
CppTools::CppModelManagerInterface::instance()->addModelManagerSupport(
m_modelManagerSupport.data());
diff --git a/src/plugins/clangcodemodel/clangcompletion.cpp b/src/plugins/clangcodemodel/clangcompletion.cpp
index b4456c61b3..9fbd1d0f29 100644
--- a/src/plugins/clangcodemodel/clangcompletion.cpp
+++ b/src/plugins/clangcodemodel/clangcompletion.cpp
@@ -203,15 +203,14 @@ IAssistProcessor *ClangCompletionAssistProvider::createProcessor() const
}
IAssistInterface *ClangCompletionAssistProvider::createAssistInterface(
- ProjectExplorer::Project *project, TextEditor::BaseTextEditor *editor,
+ ProjectExplorer::Project *project, const QString &filePath,
QTextDocument *document, bool isObjCEnabled, int position, AssistReason reason) const
{
Q_UNUSED(project);
Q_UNUSED(isObjCEnabled);
- QString fileName = editor->document()->filePath();
CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
- QList<ProjectPart::Ptr> parts = modelManager->projectPart(fileName);
+ QList<ProjectPart::Ptr> parts = modelManager->projectPart(filePath);
if (parts.isEmpty())
parts += modelManager->fallbackProjectPart();
ProjectPart::HeaderPaths headerPaths;
@@ -220,7 +219,7 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface(
foreach (ProjectPart::Ptr part, parts) {
if (part.isNull())
continue;
- options = ClangCodeModel::Utils::createClangOptions(part, fileName);
+ options = ClangCodeModel::Utils::createClangOptions(part, filePath);
pchInfo = PchManager::instance()->pchInfo(part);
if (!pchInfo.isNull())
options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
@@ -230,7 +229,7 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface(
return new ClangCodeModel::ClangCompletionAssistInterface(
m_clangCompletionWrapper,
- document, position, fileName, reason,
+ document, position, filePath, reason,
options, headerPaths, pchInfo);
}
diff --git a/src/plugins/clangcodemodel/clangcompletion.h b/src/plugins/clangcodemodel/clangcompletion.h
index 180d7ec763..152439c54a 100644
--- a/src/plugins/clangcodemodel/clangcompletion.h
+++ b/src/plugins/clangcodemodel/clangcompletion.h
@@ -58,7 +58,7 @@ public:
virtual TextEditor::IAssistProcessor *createProcessor() const;
virtual TextEditor::IAssistInterface *createAssistInterface(
- ProjectExplorer::Project *project, TextEditor::BaseTextEditor *editor,
+ ProjectExplorer::Project *project, const QString &filePath,
QTextDocument *document, bool isObjCEnabled, int position,
TextEditor::AssistReason reason) const;
diff --git a/src/plugins/clangcodemodel/clangeditordocumentparser.cpp b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp
new file mode 100644
index 0000000000..f5e40bf6e2
--- /dev/null
+++ b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangeditordocumentparser.h"
+#include "clangutils.h"
+#include "pchinfo.h"
+#include "pchmanager.h"
+
+#include <cpptools/cppmodelmanagerinterface.h>
+#include <cpptools/cppprojects.h>
+#include <cpptools/cppworkingcopy.h>
+
+#include <utils/hostosinfo.h>
+#include <utils/qtcassert.h>
+
+static const bool DebugTiming = qgetenv("QTC_CLANG_VERBOSE") == "1";
+
+namespace {
+
+QStringList createOptions(const QString &filePath, const CppTools::ProjectPart::Ptr &part)
+{
+ using namespace ClangCodeModel;
+
+ QStringList options;
+ if (part.isNull())
+ return options;
+
+ options += QLatin1String("-fspell-checking");
+ options += ClangCodeModel::Utils::createClangOptions(part, filePath);
+
+ if (Internal::PchInfo::Ptr pchInfo = Internal::PchManager::instance()->pchInfo(part))
+ options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
+
+ return options;
+}
+
+QString commandLine(const QStringList &options, const QString &fileName)
+{
+ const QStringList allOptions = QStringList(options)
+ << QLatin1String("-fsyntax-only") << fileName;
+ QStringList allOptionsQuoted;
+ foreach (const QString &option, allOptions)
+ allOptionsQuoted.append(QLatin1Char('\'') + option + QLatin1Char('\''));
+ return ::Utils::HostOsInfo::withExecutableSuffix(QLatin1String("clang"))
+ + QLatin1Char(' ') + allOptionsQuoted.join(QLatin1Char(' '));
+}
+
+} // anonymous namespace
+
+namespace ClangCodeModel {
+
+ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
+ : BaseEditorDocumentParser(filePath)
+ , m_marker(new ClangCodeModel::SemanticMarker)
+{
+}
+
+void ClangEditorDocumentParser::update(CppTools::WorkingCopy workingCopy)
+{
+ QTC_ASSERT(m_marker, return);
+ QMutexLocker lock(m_marker->mutex());
+ QMutexLocker lock2(&m_mutex);
+
+ updateProjectPart();
+ const QStringList options = createOptions(filePath(), projectPart());
+
+ QTime t;
+ if (DebugTiming) {
+ qDebug("*** Reparse options (cmd line equivalent): %s",
+ commandLine(options, filePath()).toUtf8().constData());
+ t.start();
+ }
+
+ m_marker->setFileName(filePath());
+ m_marker->setCompilationOptions(options);
+ const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(workingCopy);
+ m_marker->reparse(unsavedFiles);
+
+ if (DebugTiming)
+ qDebug() << "*** Reparse took" << t.elapsed() << "ms.";
+}
+
+QList<Diagnostic> ClangEditorDocumentParser::diagnostics() const
+{
+ QTC_ASSERT(m_marker, return QList<Diagnostic>());
+ QMutexLocker(m_marker->mutex());
+ return m_marker->diagnostics();
+}
+
+QList<SemanticMarker::Range> ClangEditorDocumentParser::ifdefedOutBlocks() const
+{
+ QTC_ASSERT(m_marker, return QList<SemanticMarker::Range>());
+ QMutexLocker(m_marker->mutex());
+ return m_marker->ifdefedOutBlocks();
+}
+
+SemanticMarker::Ptr ClangEditorDocumentParser::semanticMarker() const
+{
+ return m_marker;
+}
+
+} // namespace ClangCodeModel
diff --git a/src/plugins/clangcodemodel/clanghighlightingsupport.h b/src/plugins/clangcodemodel/clangeditordocumentparser.h
index 69b525f9f5..98017b6512 100644
--- a/src/plugins/clangcodemodel/clanghighlightingsupport.h
+++ b/src/plugins/clangcodemodel/clangeditordocumentparser.h
@@ -27,43 +27,42 @@
**
****************************************************************************/
-#ifndef CLANG_CLANGHIGHLIGHTINGSUPPORT_H
-#define CLANG_CLANGHIGHLIGHTINGSUPPORT_H
-#include "clangutils.h"
-#include "cppcreatemarkers.h"
-#include "fastindexer.h"
+#ifndef CLANGEDITORDOCUMENTPARSER_H
+#define CLANGEDITORDOCUMENTPARSER_H
-#include <cpptools/cpphighlightingsupport.h>
+#include "semanticmarker.h"
-#include <QObject>
-#include <QScopedPointer>
+#include <cpptools/baseeditordocumentparser.h>
+
+#include <utils/qtcoverride.h>
+
+namespace CppTools { class WorkingCopy; }
namespace ClangCodeModel {
-class ClangHighlightingSupport: public CppTools::CppHighlightingSupport
+class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
{
-public:
- ClangHighlightingSupport(TextEditor::BaseTextDocument *baseTextDocument,
- Internal::FastIndexer *fastIndexer);
- ~ClangHighlightingSupport();
+ Q_OBJECT
- virtual bool requiresSemanticInfo() const
- { return false; }
+public:
+ typedef QSharedPointer<ClangEditorDocumentParser> Ptr;
- virtual bool hightlighterHandlesDiagnostics() const
- { return true; }
+public:
+ ClangEditorDocumentParser(const QString &filePath);
- virtual bool hightlighterHandlesIfdefedOutBlocks() const;
+ void update(CppTools::WorkingCopy workingCopy) QTC_OVERRIDE;
- virtual QFuture<TextEditor::HighlightingResult> highlightingFuture(
- const CPlusPlus::Document::Ptr &doc, const CPlusPlus::Snapshot &snapshot) const;
+ QList<Diagnostic> diagnostics() const;
+ QList<SemanticMarker::Range> ifdefedOutBlocks() const;
+ SemanticMarker::Ptr semanticMarker() const;
private:
- Internal::FastIndexer *m_fastIndexer;
- ClangCodeModel::SemanticMarker::Ptr m_semanticMarker;
+ SemanticMarker::Ptr m_marker;
+ QStringList m_options;
+ Internal::UnsavedFiles m_unsavedFiles;
};
} // namespace ClangCodeModel
-#endif // CLANG_CLANGHIGHLIGHTINGSUPPORT_H
+#endif // CLANGEDITORDOCUMENTPARSER_H
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
new file mode 100644
index 0000000000..b73d1015c5
--- /dev/null
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangeditordocumentprocessor.h"
+
+#include "cppcreatemarkers.h"
+#include "diagnostic.h"
+#include "pchinfo.h"
+
+#include <cpptools/cpptoolsplugin.h>
+#include <cpptools/cppworkingcopy.h>
+
+#include <cplusplus/CppDocument.h>
+
+#include <utils/qtcassert.h>
+#include <utils/QtConcurrentTools>
+
+static const bool DebugTiming = qgetenv("QTC_CLANG_VERBOSE") == "1";
+
+namespace {
+
+typedef CPlusPlus::Document::DiagnosticMessage CppToolsDiagnostic;
+QList<CppToolsDiagnostic> toCppToolsDiagnostics(
+ const QString &filePath,
+ const QList<ClangCodeModel::Diagnostic> &diagnostics)
+{
+ using namespace ClangCodeModel;
+
+ QList<CppToolsDiagnostic> converted;
+ foreach (const ClangCodeModel::Diagnostic &d, diagnostics) {
+ if (DebugTiming)
+ qDebug() << d.severityAsString() << d.location() << d.spelling();
+
+ if (d.location().fileName() != filePath)
+ continue;
+
+ // TODO: retrieve fix-its for this diagnostic
+
+ int level;
+ switch (d.severity()) {
+ case Diagnostic::Fatal: level = CppToolsDiagnostic::Fatal; break;
+ case Diagnostic::Error: level = CppToolsDiagnostic::Error; break;
+ case Diagnostic::Warning: level = CppToolsDiagnostic::Warning; break;
+ default: continue;
+ }
+ converted.append(CppToolsDiagnostic(level, d.location().fileName(), d.location().line(),
+ d.location().column(), d.spelling(), d.length()));
+ }
+
+ return converted;
+}
+
+QList<TextEditor::BlockRange> toTextEditorBlocks(
+ const QList<ClangCodeModel::SemanticMarker::Range> &ranges)
+{
+ QList<TextEditor::BlockRange> result;
+ result.reserve(ranges.size());
+ foreach (const ClangCodeModel::SemanticMarker::Range &range, ranges)
+ result.append(TextEditor::BlockRange(range.first, range.last));
+ return result;
+}
+
+} // anonymous namespace
+
+namespace ClangCodeModel {
+
+ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(TextEditor::BaseTextDocument *document)
+ : BaseEditorDocumentProcessor(document)
+ , m_parser(new ClangEditorDocumentParser(document->filePath()))
+ , m_parserRevision(0)
+ , m_semanticHighlighter(document)
+ , m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
+{
+ // Forwarding the semantic info from the builtin processor enables us to provide all
+ // editor (widget) related features that are not yet implemented by the clang plugin.
+ connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::cppDocumentUpdated,
+ this, &ClangEditorDocumentProcessor::cppDocumentUpdated);
+ connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
+ this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
+
+ m_semanticHighlighter.setHighlightingRunner(
+ [this]() -> QFuture<TextEditor::HighlightingResult> {
+ const int firstLine = 1;
+ const int lastLine = baseTextDocument()->document()->blockCount();
+
+ CreateMarkers *createMarkers = CreateMarkers::create(m_parser->semanticMarker(),
+ baseTextDocument()->filePath(),
+ firstLine, lastLine);
+ return createMarkers->start();
+ });
+}
+
+ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
+{
+ m_parserWatcher.cancel();
+ m_parserWatcher.waitForFinished();
+}
+
+void ClangEditorDocumentProcessor::run()
+{
+ // Run clang parser
+ const CppTools::WorkingCopy workingCopy
+ = CppTools::CppModelManagerInterface::instance()->workingCopy();
+
+ disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
+ this, &ClangEditorDocumentProcessor::onParserFinished);
+ m_parserWatcher.cancel();
+ m_parserWatcher.setFuture(QFuture<void>());
+
+ m_parserRevision = revision();
+ connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
+ this, &ClangEditorDocumentProcessor::onParserFinished);
+ const QFuture<void> future = QtConcurrent::run(&runParser, parser(), workingCopy);
+ m_parserWatcher.setFuture(future);
+
+ // Run builtin processor
+ m_builtinProcessor.run();
+}
+
+void ClangEditorDocumentProcessor::semanticRehighlight(bool force)
+{
+ m_builtinProcessor.semanticRehighlight(force);
+}
+
+CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
+{
+ return m_builtinProcessor.recalculateSemanticInfo();
+}
+
+CppTools::BaseEditorDocumentParser *ClangEditorDocumentProcessor::parser()
+{
+ return m_parser.data();
+}
+
+bool ClangEditorDocumentProcessor::isParserRunning() const
+{
+ return m_parserWatcher.isRunning();
+}
+
+void ClangEditorDocumentProcessor::onParserFinished()
+{
+ if (revision() != m_parserRevision)
+ return;
+
+ // Emit ifdefed out blocks
+ const auto ifdefoutBlocks = toTextEditorBlocks(m_parser->ifdefedOutBlocks());
+ emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks);
+
+ // Emit code warnings
+ const auto diagnostics = toCppToolsDiagnostics(filePath(), m_parser->diagnostics());
+ const auto codeWarnings = toTextEditorSelections(diagnostics, textDocument());
+ emit codeWarningsUpdated(revision(), codeWarnings);
+
+ // Run semantic highlighter
+ m_semanticHighlighter.run();
+}
+
+} // namespace ClangCodeModel
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
new file mode 100644
index 0000000000..cffddbffd5
--- /dev/null
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGEDITORDOCUMENTPROCESSOR_H
+#define CLANGEDITORDOCUMENTPROCESSOR_H
+
+#include "clangeditordocumentparser.h"
+
+#include <cpptools/baseeditordocumentprocessor.h>
+#include <cpptools/builtineditordocumentprocessor.h>
+#include <cpptools/semantichighlighter.h>
+
+#include <utils/qtcoverride.h>
+
+#include <QFutureWatcher>
+
+namespace ClangCodeModel {
+
+class ClangEditorDocumentProcessor : public CppTools::BaseEditorDocumentProcessor
+{
+ Q_OBJECT
+
+public:
+ ClangEditorDocumentProcessor(TextEditor::BaseTextDocument *document);
+ ~ClangEditorDocumentProcessor();
+
+ // BaseEditorDocumentProcessor interface
+ void run() QTC_OVERRIDE;
+ void semanticRehighlight(bool force) QTC_OVERRIDE;
+ CppTools::SemanticInfo recalculateSemanticInfo() QTC_OVERRIDE;
+ CppTools::BaseEditorDocumentParser *parser() QTC_OVERRIDE;
+ bool isParserRunning() const QTC_OVERRIDE;
+
+private slots:
+ void onParserFinished();
+
+private:
+ QScopedPointer<ClangEditorDocumentParser> m_parser;
+ QFutureWatcher<void> m_parserWatcher;
+ unsigned m_parserRevision;
+
+ CppTools::SemanticHighlighter m_semanticHighlighter;
+ CppTools::BuiltinEditorDocumentProcessor m_builtinProcessor;
+};
+
+} // namespace ClangCodeModel
+
+#endif // CLANGEDITORDOCUMENTPROCESSOR_H
diff --git a/src/plugins/clangcodemodel/clanghighlightingsupport.cpp b/src/plugins/clangcodemodel/clanghighlightingsupport.cpp
deleted file mode 100644
index 85d2b559a3..0000000000
--- a/src/plugins/clangcodemodel/clanghighlightingsupport.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "clanghighlightingsupport.h"
-
-#include <texteditor/basetextdocument.h>
-
-#include <QTextBlock>
-#include <QTextEdit>
-#include "pchmanager.h"
-
-using namespace ClangCodeModel;
-using namespace ClangCodeModel::Internal;
-using namespace CppTools;
-
-ClangHighlightingSupport::ClangHighlightingSupport(TextEditor::BaseTextDocument *baseTextDocument,
- FastIndexer *fastIndexer)
- : CppHighlightingSupport(baseTextDocument)
- , m_fastIndexer(fastIndexer)
- , m_semanticMarker(new ClangCodeModel::SemanticMarker)
-{
-}
-
-ClangHighlightingSupport::~ClangHighlightingSupport()
-{
-}
-
-bool ClangHighlightingSupport::hightlighterHandlesIfdefedOutBlocks() const
-{
-#if CINDEX_VERSION_MINOR >= 21
- return true;
-#else
- return false;
-#endif
-}
-
-QFuture<TextEditor::HighlightingResult> ClangHighlightingSupport::highlightingFuture(
- const CPlusPlus::Document::Ptr &doc,
- const CPlusPlus::Snapshot &snapshot) const
-{
- Q_UNUSED(doc);
- Q_UNUSED(snapshot);
-
- int firstLine = 1;
- int lastLine = baseTextDocument()->document()->blockCount();
-
- const QString fileName = baseTextDocument()->filePath();
- CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
- QList<ProjectPart::Ptr> parts = modelManager->projectPart(fileName);
- if (parts.isEmpty())
- parts += modelManager->fallbackProjectPart();
- QStringList options;
- PchInfo::Ptr pchInfo;
- foreach (const ProjectPart::Ptr &part, parts) {
- if (part.isNull())
- continue;
- options = Utils::createClangOptions(part, fileName);
- pchInfo = PchManager::instance()->pchInfo(part);
- if (!pchInfo.isNull())
- options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
- if (!options.isEmpty())
- break;
- }
-
- CreateMarkers *createMarkers = CreateMarkers::create(m_semanticMarker,
- fileName, options,
- firstLine, lastLine,
- m_fastIndexer, pchInfo);
- return createMarkers->start();
-}
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
index 4f7430ee5a..289ab8bde4 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
@@ -28,7 +28,7 @@
****************************************************************************/
#include "clangcompletion.h"
-#include "clanghighlightingsupport.h"
+#include "clangeditordocumentprocessor.h"
#include "clangmodelmanagersupport.h"
#include <QCoreApplication>
@@ -36,9 +36,8 @@
using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal;
-ModelManagerSupport::ModelManagerSupport(FastIndexer *fastIndexer)
+ModelManagerSupport::ModelManagerSupport()
: m_completionAssistProvider(new ClangCompletionAssistProvider)
- , m_fastIndexer(fastIndexer)
{
}
@@ -63,8 +62,8 @@ CppTools::CppCompletionAssistProvider *ModelManagerSupport::completionAssistProv
return m_completionAssistProvider.data();
}
-CppTools::CppHighlightingSupport *ModelManagerSupport::highlightingSupport(
+CppTools::BaseEditorDocumentProcessor *ModelManagerSupport::editorDocumentProcessor(
TextEditor::BaseTextDocument *baseTextDocument)
{
- return new ClangHighlightingSupport(baseTextDocument, m_fastIndexer);
+ return new ClangCodeModel::ClangEditorDocumentProcessor(baseTextDocument);
}
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h
index ef1205be74..8855ecd514 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h
@@ -37,26 +37,23 @@
namespace ClangCodeModel {
namespace Internal {
-class FastIndexer;
-
class ModelManagerSupport: public CppTools::ModelManagerSupport
{
Q_DISABLE_COPY(ModelManagerSupport)
public:
- ModelManagerSupport(FastIndexer *fastIndexer);
+ ModelManagerSupport();
virtual ~ModelManagerSupport();
virtual QString id() const;
virtual QString displayName() const;
virtual CppTools::CppCompletionAssistProvider *completionAssistProvider();
- virtual CppTools::CppHighlightingSupport *highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument);
+ virtual CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument);
private:
QScopedPointer<CppTools::CppCompletionAssistProvider> m_completionAssistProvider;
- FastIndexer *m_fastIndexer;
};
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/cppcreatemarkers.cpp b/src/plugins/clangcodemodel/cppcreatemarkers.cpp
index b88849f3c5..2bfde48a8d 100644
--- a/src/plugins/clangcodemodel/cppcreatemarkers.cpp
+++ b/src/plugins/clangcodemodel/cppcreatemarkers.cpp
@@ -30,11 +30,7 @@
#include "clangutils.h"
#include "cppcreatemarkers.h"
-#include <cpptools/cppmodelmanagerinterface.h>
-#include <cpptools/cppworkingcopy.h>
-
#include <cplusplus/CppDocument.h>
-#include <utils/hostosinfo.h>
#include <utils/runextensions.h>
#include <QCoreApplication>
@@ -51,119 +47,52 @@ using namespace CppTools;
CreateMarkers *CreateMarkers::create(SemanticMarker::Ptr semanticMarker,
const QString &fileName,
- const QStringList &options,
- unsigned firstLine, unsigned lastLine,
- FastIndexer *fastIndexer,
- const Internal::PchInfo::Ptr &pchInfo)
+ unsigned firstLine, unsigned lastLine)
{
if (semanticMarker.isNull())
return 0;
else
- return new CreateMarkers(semanticMarker, fileName, options, firstLine, lastLine, fastIndexer, pchInfo);
+ return new CreateMarkers(semanticMarker, fileName, firstLine, lastLine);
}
CreateMarkers::CreateMarkers(SemanticMarker::Ptr semanticMarker,
const QString &fileName,
- const QStringList &options,
- unsigned firstLine, unsigned lastLine,
- FastIndexer *fastIndexer,
- const Internal::PchInfo::Ptr &pchInfo)
+ unsigned firstLine, unsigned lastLine)
: m_marker(semanticMarker)
- , m_pchInfo(pchInfo)
, m_fileName(fileName)
- , m_options(options)
, m_firstLine(firstLine)
, m_lastLine(lastLine)
- , m_fastIndexer(fastIndexer)
{
Q_ASSERT(!semanticMarker.isNull());
m_flushRequested = false;
m_flushLine = 0;
-
- m_unsavedFiles = Utils::createUnsavedFiles(CppModelManagerInterface::instance()->workingCopy());
}
CreateMarkers::~CreateMarkers()
{ }
-static QString commandLine(const QStringList &options, const QString &fileName)
-{
- const QStringList allOptions = QStringList(options)
- << QLatin1String("-fsyntax-only") << fileName;
- QStringList allOptionsQuoted;
- foreach (const QString &option, allOptions)
- allOptionsQuoted.append(QLatin1Char('\'') + option + QLatin1Char('\''));
- return ::Utils::HostOsInfo::withExecutableSuffix(QLatin1String("clang"))
- + QLatin1Char(' ') + allOptionsQuoted.join(QLatin1Char(' '));
-}
-
void CreateMarkers::run()
{
QMutexLocker lock(m_marker->mutex());
if (isCanceled())
return;
- m_options += QLatin1String("-fspell-checking");
-
QTime t;
if (DebugTiming) {
qDebug() << "*** Highlighting from" << m_firstLine << "to" << m_lastLine << "of" << m_fileName;
- qDebug("***** Options (cmd line equivalent): %s",
- commandLine(m_options, m_fileName).toUtf8().constData());
t.start();
}
m_usages.clear();
- m_marker->setFileName(m_fileName);
- m_marker->setCompilationOptions(m_options);
-
- m_marker->reparse(m_unsavedFiles);
-
- if (DebugTiming)
- qDebug() << "*** Reparse for highlighting took" << t.elapsed() << "ms.";
-
- m_pchInfo.clear();
-
- typedef CPlusPlus::Document::DiagnosticMessage OtherDiagnostic;
- QList<OtherDiagnostic> msgs;
- foreach (const ClangCodeModel::Diagnostic &d, m_marker->diagnostics()) {
- if (DebugTiming)
- qDebug() << d.severityAsString() << d.location() << d.spelling();
-
- if (d.location().fileName() != m_marker->fileName())
- continue;
- // TODO: retrieve fix-its for this diagnostic
-
- int level;
- switch (d.severity()) {
- case Diagnostic::Fatal: level = OtherDiagnostic::Fatal; break;
- case Diagnostic::Error: level = OtherDiagnostic::Error; break;
- case Diagnostic::Warning: level = OtherDiagnostic::Warning; break;
- default: continue;
- }
- msgs.append(OtherDiagnostic(level, d.location().fileName(), d.location().line(),
- d.location().column(), d.spelling(), d.length()));
- }
if (isCanceled()) {
reportFinished();
return;
}
- CppModelManagerInterface *mmi = CppModelManagerInterface::instance();
- static const QString key = QLatin1String("ClangCodeModel.Diagnostics");
- mmi->setExtraDiagnostics(m_marker->fileName(), key, msgs);
-#if CINDEX_VERSION_MINOR >= 21
- mmi->setIfdefedOutBlocks(m_marker->fileName(), m_marker->ifdefedOutBlocks());
-#endif
-
- if (isCanceled()) {
- reportFinished();
- return;
- }
-
- QList<ClangCodeModel::SourceMarker> markers = m_marker->sourceMarkersInRange(m_firstLine, m_lastLine);
+ const QList<ClangCodeModel::SourceMarker> markers
+ = m_marker->sourceMarkersInRange(m_firstLine, m_lastLine);
foreach (const ClangCodeModel::SourceMarker &m, markers)
addUse(SourceMarker(m.location().line(), m.location().column(), m.length(), m.kind()));
@@ -179,12 +108,6 @@ void CreateMarkers::run()
qDebug() << "*** Highlighting took" << t.elapsed() << "ms in total.";
t.restart();
}
-
- if (m_fastIndexer)
- m_fastIndexer->indexNow(m_marker->unit());
-
- if (DebugTiming)
- qDebug() << "*** Fast re-indexing took" << t.elapsed() << "ms in total.";
}
void CreateMarkers::addUse(const SourceMarker &marker)
diff --git a/src/plugins/clangcodemodel/cppcreatemarkers.h b/src/plugins/clangcodemodel/cppcreatemarkers.h
index c372e4b08e..e602161302 100644
--- a/src/plugins/clangcodemodel/cppcreatemarkers.h
+++ b/src/plugins/clangcodemodel/cppcreatemarkers.h
@@ -37,7 +37,6 @@
#include <texteditor/semantichighlighter.h>
-#include <QSet>
#include <QFuture>
#include <QtConcurrentRun>
@@ -70,35 +69,23 @@ public:
}
static CreateMarkers *create(ClangCodeModel::SemanticMarker::Ptr semanticMarker,
- const QString &fileName,
- const QStringList &options,
- unsigned firstLine, unsigned lastLine,
- Internal::FastIndexer *fastIndexer,
- const Internal::PchInfo::Ptr &pchInfo);
+ const QString &fileName, unsigned firstLine, unsigned lastLine);
void addUse(const SourceMarker &marker);
void flush();
protected:
CreateMarkers(ClangCodeModel::SemanticMarker::Ptr semanticMarker,
- const QString &fileName, const QStringList &options,
- unsigned firstLine, unsigned lastLine,
- Internal::FastIndexer *fastIndexer,
- const Internal::PchInfo::Ptr &pchInfo);
+ const QString &fileName, unsigned firstLine, unsigned lastLine);
private:
ClangCodeModel::SemanticMarker::Ptr m_marker;
- Internal::PchInfo::Ptr m_pchInfo;
QString m_fileName;
- QStringList m_options;
unsigned m_firstLine;
unsigned m_lastLine;
- Internal::FastIndexer *m_fastIndexer;
QVector<SourceMarker> m_usages;
bool m_flushRequested;
unsigned m_flushLine;
-
- ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles;
};
} // namespace ClangCodeModel
diff --git a/src/plugins/clangcodemodel/semanticmarker.cpp b/src/plugins/clangcodemodel/semanticmarker.cpp
index f1b9a71a25..e367c3a0f7 100644
--- a/src/plugins/clangcodemodel/semanticmarker.cpp
+++ b/src/plugins/clangcodemodel/semanticmarker.cpp
@@ -32,6 +32,8 @@
#include "utils_p.h"
#include "cxraii.h"
+#include <utils/qtcassert.h>
+
using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal;
@@ -74,7 +76,7 @@ void SemanticMarker::setFileName(const QString &fileName)
void SemanticMarker::setCompilationOptions(const QStringList &options)
{
- Q_ASSERT(m_unit);
+ QTC_ASSERT(m_unit, return);
if (m_unit->compilationOptions() == options)
return;
@@ -84,7 +86,7 @@ void SemanticMarker::setCompilationOptions(const QStringList &options)
void SemanticMarker::reparse(const UnsavedFiles &unsavedFiles)
{
- Q_ASSERT(m_unit);
+ QTC_ASSERT(m_unit, return);
m_unit->setUnsavedFiles(unsavedFiles);
if (m_unit->isLoaded())
@@ -169,9 +171,9 @@ QList<Diagnostic> SemanticMarker::diagnostics() const
return diagnostics;
}
-QList<TextEditor::BlockRange> SemanticMarker::ifdefedOutBlocks() const
+QList<SemanticMarker::Range> SemanticMarker::ifdefedOutBlocks() const
{
- QList<TextEditor::BlockRange> blocks;
+ QList<Range> blocks;
if (!m_unit || !m_unit->isLoaded())
return blocks;
@@ -188,7 +190,7 @@ QList<TextEditor::BlockRange> SemanticMarker::ifdefedOutBlocks() const
const SourceLocation &spellEnd = Internal::getSpellingLocation(clang_getRangeEnd(r));
const int begin = spellBegin.offset() + 1;
const int end = spellEnd.offset() - spellEnd.column();
- blocks.append(TextEditor::BlockRange(begin, end));
+ blocks.append(Range(begin, end));
}
clang_disposeSourceRangeList(skippedRanges);
#endif
@@ -322,9 +324,8 @@ static const QSet<QString> ObjcPseudoKeywords = QSet<QString>()
QList<SourceMarker> SemanticMarker::sourceMarkersInRange(unsigned firstLine,
unsigned lastLine)
{
- Q_ASSERT(m_unit);
-
QList<SourceMarker> result;
+ QTC_ASSERT(m_unit, return result);
if (!m_unit->isLoaded())
return result;
diff --git a/src/plugins/clangcodemodel/semanticmarker.h b/src/plugins/clangcodemodel/semanticmarker.h
index 744aece1c6..0ec3979ffc 100644
--- a/src/plugins/clangcodemodel/semanticmarker.h
+++ b/src/plugins/clangcodemodel/semanticmarker.h
@@ -36,8 +36,6 @@
#include "sourcemarker.h"
#include "utils.h"
-#include <texteditor/basetexteditor.h>
-
#include <QMutex>
#include <QScopedPointer>
#include <QSharedPointer>
@@ -53,6 +51,16 @@ class CLANG_EXPORT SemanticMarker
public:
typedef QSharedPointer<SemanticMarker> Ptr;
+ class Range
+ {
+ Range();
+ public:
+ Range(int first, int last) : first(first), last(last) {}
+
+ int first;
+ int last;
+ };
+
public:
SemanticMarker();
~SemanticMarker();
@@ -69,7 +77,7 @@ public:
QList<Diagnostic> diagnostics() const;
- QList<TextEditor::BlockRange> ifdefedOutBlocks() const;
+ QList<Range> ifdefedOutBlocks() const;
QList<SourceMarker> sourceMarkersInRange(unsigned firstLine,
unsigned lastLine);
diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
index 0cc424c567..892df8b246 100644
--- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
+++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
@@ -30,12 +30,13 @@
#include "cppcodemodelinspectordialog.h"
#include "ui_cppcodemodelinspectordialog.h"
#include "cppeditor.h"
+#include "cppeditordocument.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
+#include <cpptools/builtineditordocumentparser.h>
#include <cpptools/cppcodemodelinspectordumper.h>
#include <cpptools/cppmodelmanager.h>
-#include <cpptools/cpptoolseditorsupport.h>
#include <cpptools/cppworkingcopy.h>
#include <projectexplorer/project.h>
@@ -1358,11 +1359,13 @@ void CppCodeModelInspectorDialog::refresh()
dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true);
TextEditor::BaseTextEditor *editor = currentEditor();
- CppEditorSupport *editorSupport = 0;
+ EditorDocumentHandle *editorDocument = 0;
if (editor) {
- editorSupport = cmmi->cppEditorSupport(editor);
- if (editorSupport) {
- const CPlusPlus::Snapshot editorSnapshot = editorSupport->documentParser()->snapshot();
+ const QString editorFilePath = editor->document()->filePath();
+ editorDocument = cmmi->editorDocument(editorFilePath);
+ if (editorDocument) {
+ const CPlusPlus::Snapshot editorSnapshot
+ = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot();
m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot));
const QString editorSnapshotTitle
= QString::fromLatin1("Current Editor's Snapshot (%1 Documents)")
@@ -1412,8 +1415,8 @@ void CppCodeModelInspectorDialog::refresh()
onSnapshotSelected(snapshotIndex);
// Project Parts
- const ProjectPart::Ptr editorsProjectPart = editorSupport
- ? editorSupport->documentParser()->projectPart()
+ const ProjectPart::Ptr editorsProjectPart = editorDocument
+ ? editorDocument->processor()->parser()->projectPart()
: ProjectPart::Ptr();
const QList<ProjectInfo> projectInfos = cmmi->projectInfos();
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c832a33453..c133b3c3e3 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -33,6 +33,7 @@
#include "cppcanonicalsymbol.h"
#include "cppdocumentationcommenthelper.h"
#include "cppeditorconstants.h"
+#include "cppeditordocument.h"
#include "cppeditoroutline.h"
#include "cppeditorplugin.h"
#include "cppfollowsymbolundercursor.h"
@@ -40,18 +41,18 @@
#include "cpplocalrenaming.h"
#include "cpppreprocessordialog.h"
#include "cppquickfixassistant.h"
+#include "cppuseselectionsupdater.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <cpptools/cppchecksymbols.h>
+#include <cpptools/cppchecksymbols.h>
#include <cpptools/cppcodeformatter.h>
#include <cpptools/cppcompletionassistprovider.h>
-#include <cpptools/cpphighlightingsupport.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cppsemanticinfo.h>
#include <cpptools/cpptoolsconstants.h>
-#include <cpptools/cpptoolseditorsupport.h>
#include <cpptools/cpptoolsplugin.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/cppworkingcopy.h>
@@ -67,14 +68,11 @@
#include <texteditor/fontsettings.h>
#include <texteditor/refactoroverlay.h>
-#include <utils/qtcassert.h>
-
#include <cplusplus/ASTPath.h>
-#include <cplusplus/BackwardsScanner.h>
-#include <cplusplus/ExpressionUnderCursor.h>
-#include <cplusplus/OverviewModel.h>
+#include <utils/qtcassert.h>
#include <QAction>
+#include <QElapsedTimer>
#include <QFutureWatcher>
#include <QMenu>
#include <QPointer>
@@ -83,10 +81,7 @@
#include <QTimer>
#include <QToolButton>
-enum {
- UPDATE_USES_INTERVAL = 500,
- UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200
-};
+enum { UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200 };
using namespace CPlusPlus;
using namespace CppTools;
@@ -103,7 +98,9 @@ CPPEditor::CPPEditor()
setDuplicateSupported(true);
setCommentStyle(Utils::CommentDefinition::CppStyle);
setCompletionAssistProvider([this] () -> TextEditor::CompletionAssistProvider * {
- return CppModelManagerInterface::instance()->cppEditorSupport(this)->completionAssistProvider();
+ if (CPPEditorDocument *document = qobject_cast<CPPEditorDocument *>(textDocument()))
+ return document->completionAssistProvider();
+ return 0;
});
}
@@ -122,21 +119,14 @@ public:
CppDocumentationCommentHelper m_cppDocumentationCommentHelper;
- QTimer m_updateUsesTimer;
QTimer m_updateFunctionDeclDefLinkTimer;
- QHash<int, QTextCharFormat> m_semanticHighlightFormatMap;
CppLocalRenaming m_localRenaming;
CppTools::SemanticInfo m_lastSemanticInfo;
QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
- QScopedPointer<QFutureWatcher<TextEditor::HighlightingResult> > m_highlightWatcher;
- unsigned m_highlightRevision; // the editor revision that requested the highlight
-
- QScopedPointer<QFutureWatcher<QList<int> > > m_referencesWatcher;
- unsigned m_referencesRevision;
- int m_referencesCursorPosition;
+ CppUseSelectionsUpdater m_useSelectionsUpdater;
FunctionDeclDefLinkFinder *m_declDefLinkFinder;
QSharedPointer<FunctionDeclDefLink> m_declDefLink;
@@ -151,9 +141,7 @@ CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
, m_cppEditorOutline(new CppEditorOutline(q))
, m_cppDocumentationCommentHelper(q)
, m_localRenaming(q)
- , m_highlightRevision(0)
- , m_referencesRevision(0)
- , m_referencesCursorPosition(0)
+ , m_useSelectionsUpdater(q)
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
, m_preprocessorButton(0)
@@ -162,28 +150,27 @@ CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
CppEditorWidget::CppEditorWidget(TextEditor::BaseTextDocumentPtr doc, CPPEditor *editor)
{
+ qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
+
editor->setEditorWidget(this);
setTextDocument(doc);
d.reset(new CppEditorWidgetPrivate(this));
setAutoCompleter(new CppAutoCompleter);
-
- qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
-
- setParenthesesMatchingEnabled(true);
- setMarksVisible(true);
+ setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
setCodeFoldingSupported(true);
+ setMarksVisible(true);
+ setParenthesesMatchingEnabled(true);
setRevisionsVisible(true);
- if (d->m_modelManager) {
- CppEditorSupport *editorSupport = d->m_modelManager->cppEditorSupport(editor);
- connect(editorSupport, SIGNAL(documentUpdated()),
- this, SLOT(onDocumentUpdated()));
- connect(editorSupport, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
- this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
- connect(editorSupport, SIGNAL(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint)),
- this, SLOT(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint)));
- }
+ connect(d->m_cppEditorDocument, &CPPEditorDocument::codeWarningsUpdated,
+ this, &CppEditorWidget::onCodeWarningsUpdated);
+ connect(d->m_cppEditorDocument, &CPPEditorDocument::ifdefedOutBlocksUpdated,
+ this, &CppEditorWidget::onIfdefedOutBlocksUpdated);
+ connect(d->m_cppEditorDocument, SIGNAL(cppDocumentUpdated(CPlusPlus::Document::Ptr)),
+ this, SLOT(onCppDocumentUpdated()));
+ connect(d->m_cppEditorDocument, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
+ this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
connect(d->m_declDefLinkFinder, SIGNAL(foundLink(QSharedPointer<FunctionDeclDefLink>)),
this, SLOT(onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink>)));
@@ -191,39 +178,42 @@ CppEditorWidget::CppEditorWidget(TextEditor::BaseTextDocumentPtr doc, CPPEditor
connect(textDocument(), SIGNAL(filePathChanged(QString,QString)),
this, SLOT(onFilePathChanged()));
- connect(&d->m_localRenaming, SIGNAL(finished()),
- this, SLOT(onLocalRenamingFinished()));
- connect(&d->m_localRenaming, SIGNAL(processKeyPressNormally(QKeyEvent*)),
- this, SLOT(onLocalRenamingProcessKeyPressNormally(QKeyEvent*)));
-
- // Tool bar creation
- d->m_updateUsesTimer.setSingleShot(true);
- d->m_updateUsesTimer.setInterval(UPDATE_USES_INTERVAL);
-
- connect(&d->m_updateUsesTimer, &QTimer::timeout,
- this, &CppEditorWidget::updateUsesNow);
+ connect(&d->m_useSelectionsUpdater,
+ SIGNAL(selectionsForVariableUnderCursorUpdated(QList<QTextEdit::ExtraSelection>)),
+ &d->m_localRenaming,
+ SLOT(updateSelectionsForVariableUnderCursor(QList<QTextEdit::ExtraSelection>)));
- d->m_updateFunctionDeclDefLinkTimer.setSingleShot(true);
- d->m_updateFunctionDeclDefLinkTimer.setInterval(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
+ connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished,
+ [this] (CppTools::SemanticInfo::LocalUseMap localUses) {
+ QTC_CHECK(isSemanticInfoValidExceptLocalUses());
+ d->m_lastSemanticInfo.localUsesUpdated = true;
+ d->m_lastSemanticInfo.localUses = localUses;
+ });
- connect(&d->m_updateFunctionDeclDefLinkTimer, &QTimer::timeout,
- this, &CppEditorWidget::updateFunctionDeclDefLinkNow);
+ connect(&d->m_localRenaming, &CppLocalRenaming::finished, [this] {
+ cppEditorDocument()->semanticRehighlight();
+ });
+ connect(&d->m_localRenaming, &CppLocalRenaming::processKeyPressNormally,
+ this, &CppEditorWidget::processKeyNormally);
connect(this, SIGNAL(cursorPositionChanged()),
d->m_cppEditorOutline, SLOT(updateIndex()));
- // set up slots to document changes
- connect(document(), SIGNAL(contentsChange(int,int,int)),
- this, SLOT(onContentsChanged(int,int,int)));
-
// set up function declaration - definition link
+ d->m_updateFunctionDeclDefLinkTimer.setSingleShot(true);
+ d->m_updateFunctionDeclDefLinkTimer.setInterval(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
+ connect(&d->m_updateFunctionDeclDefLinkTimer, SIGNAL(timeout()),
+ this, SLOT(updateFunctionDeclDefLinkNow()));
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateFunctionDeclDefLink()));
connect(this, SIGNAL(textChanged()), this, SLOT(updateFunctionDeclDefLink()));
- // set up the semantic highlighter
- connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateUses()));
- connect(this, SIGNAL(textChanged()), this, SLOT(updateUses()));
+ // set up the use highlighitng
+ connect(this, &CppEditorWidget::cursorPositionChanged, [this]() {
+ if (!d->m_localRenaming.isActive())
+ d->m_useSelectionsUpdater.scheduleUpdate();
+ });
+ // Tool bar creation
d->m_preprocessorButton = new QToolButton(this);
d->m_preprocessorButton->setText(QLatin1String("#"));
Core::Command *cmd = Core::ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
@@ -232,13 +222,25 @@ CppEditorWidget::CppEditorWidget(TextEditor::BaseTextDocumentPtr doc, CPPEditor
connect(d->m_preprocessorButton, SIGNAL(clicked()), this, SLOT(showPreProcessorWidget()));
insertExtraToolBarWidget(TextEditor::BaseTextEditorWidget::Left, d->m_preprocessorButton);
insertExtraToolBarWidget(TextEditor::BaseTextEditorWidget::Left, d->m_cppEditorOutline->widget());
- setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
}
CppEditorWidget::~CppEditorWidget()
{
- if (d->m_modelManager)
- d->m_modelManager->deleteCppEditorSupport(editor());
+ // non-inline destructor, see section "Forward Declared Pointers" of QScopedPointer.
+}
+
+CppEditorWidget *CppEditorWidget::duplicate(CPPEditor *editor) const
+{
+ QTC_ASSERT(editor, return 0);
+
+ CppEditorWidget *widget = new CppEditorWidget(textDocumentPtr(), editor);
+ widget->updateSemanticInfo(semanticInfo());
+ widget->updateFunctionDeclDefLink();
+ widget->d->m_cppEditorOutline->update();
+ const ExtraSelectionKind selectionKind = CodeWarningsSelection;
+ widget->setExtraSelections(selectionKind, extraSelections(selectionKind));
+
+ return widget;
}
CPPEditorDocument *CppEditorWidget::cppEditorDocument() const
@@ -266,7 +268,7 @@ void CppEditorWidget::paste()
void CppEditorWidget::cut()
{
- if (d->m_localRenaming.handlePaste())
+ if (d->m_localRenaming.handleCut())
return;
BaseTextEditorWidget::cut();
@@ -280,13 +282,27 @@ void CppEditorWidget::selectAll()
BaseTextEditorWidget::selectAll();
}
-/// \brief Called by \c CppEditorSupport when the document corresponding to the
-/// file in this editor is updated.
-void CppEditorWidget::onDocumentUpdated()
+void CppEditorWidget::onCppDocumentUpdated()
{
d->m_cppEditorOutline->update();
}
+void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
+ const QList<QTextEdit::ExtraSelection> selections)
+{
+ if (revision != documentRevision())
+ return;
+ setExtraSelections(BaseTextEditorWidget::CodeWarningsSelection, selections);
+}
+
+void CppEditorWidget::onIfdefedOutBlocksUpdated(unsigned revision,
+ const QList<TextEditor::BlockRange> ifdefedOutBlocks)
+{
+ if (revision != documentRevision())
+ return;
+ setIfdefedOutBlocks(ifdefedOutBlocks);
+}
+
void CppEditorWidget::findUsages()
{
if (!d->m_modelManager)
@@ -325,140 +341,23 @@ void CppEditorWidget::renameUsages(const QString &replacement)
}
}
-void CppEditorWidget::markSymbolsNow()
-{
- QTC_ASSERT(d->m_referencesWatcher, return);
- if (!d->m_referencesWatcher->isCanceled()
- && d->m_referencesCursorPosition == position()
- && d->m_referencesRevision == editorRevision()) {
- const SemanticInfo info = d->m_lastSemanticInfo;
- TranslationUnit *unit = info.doc->translationUnit();
- const QList<int> result = d->m_referencesWatcher->result();
-
- QList<QTextEdit::ExtraSelection> selections;
-
- foreach (int index, result) {
- unsigned line, column;
- unit->getTokenPosition(index, &line, &column);
-
- if (column)
- --column; // adjust the column position.
-
- const int len = unit->tokenAt(index).utf16chars();
-
- QTextCursor cursor(document()->findBlockByNumber(line - 1));
- cursor.setPosition(cursor.position() + column);
- cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor);
-
- QTextEdit::ExtraSelection sel;
- sel.format = textCharFormat(TextEditor::C_OCCURRENCES);
- sel.cursor = cursor;
- selections.append(sel);
- }
-
- setExtraSelections(CodeSemanticsSelection, selections);
- }
- d->m_referencesWatcher.reset();
-}
-
-static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc,
- Snapshot snapshot)
-{
- TypeOfExpression typeOfExpression;
- snapshot.insert(doc);
- typeOfExpression.init(doc, snapshot);
- // make possible to instantiate templates
- typeOfExpression.setExpandTemplates(true);
- if (Symbol *canonicalSymbol = CanonicalSymbol::canonicalSymbol(scope, code, typeOfExpression))
- return CppModelManagerInterface::instance()->references(canonicalSymbol,
- typeOfExpression.context());
- return QList<int>();
-}
-
-void CppEditorWidget::markSymbols(const QTextCursor &tc, const SemanticInfo &info)
-{
- d->m_localRenaming.stop();
-
- if (!info.doc)
- return;
- const QTextCharFormat &occurrencesFormat = textCharFormat(TextEditor::C_OCCURRENCES);
- if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
- QList<QTextEdit::ExtraSelection> selections;
-
- //Macro definition
- if (macro->fileName() == info.doc->fileName()) {
- QTextCursor cursor(document());
- cursor.setPosition(macro->utf16CharOffset());
- cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
- macro->nameToQString().size());
-
- QTextEdit::ExtraSelection sel;
- sel.format = occurrencesFormat;
- sel.cursor = cursor;
- selections.append(sel);
- }
-
- //Other macro uses
- foreach (const Document::MacroUse &use, info.doc->macroUses()) {
- const Macro &useMacro = use.macro();
- if (useMacro.line() != macro->line()
- || useMacro.utf16CharOffset() != macro->utf16CharOffset()
- || useMacro.length() != macro->length()
- || useMacro.fileName() != macro->fileName())
- continue;
-
- QTextCursor cursor(document());
- cursor.setPosition(use.utf16charsBegin());
- cursor.setPosition(use.utf16charsEnd(), QTextCursor::KeepAnchor);
-
- QTextEdit::ExtraSelection sel;
- sel.format = occurrencesFormat;
- sel.cursor = cursor;
- selections.append(sel);
- }
-
- setExtraSelections(CodeSemanticsSelection, selections);
- } else {
- CanonicalSymbol cs(info.doc, info.snapshot);
- QString expression;
- if (Scope *scope = cs.getScopeAndExpression(tc, &expression)) {
- if (d->m_referencesWatcher)
- d->m_referencesWatcher->cancel();
- d->m_referencesWatcher.reset(new QFutureWatcher<QList<int> >);
- connect(d->m_referencesWatcher.data(), SIGNAL(finished()), SLOT(markSymbolsNow()));
-
- d->m_referencesRevision = info.revision;
- d->m_referencesCursorPosition = position();
- d->m_referencesWatcher->setFuture(
- QtConcurrent::run(&lazyFindReferences, scope, expression, info.doc, info.snapshot));
- } else {
- const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection);
-
- if (!selections.isEmpty())
- setExtraSelections(CodeSemanticsSelection, QList<QTextEdit::ExtraSelection>());
- }
- }
-}
-
void CppEditorWidget::renameSymbolUnderCursor()
{
- if (!d->m_modelManager)
- return;
+ updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo());
- CppEditorSupport *ces = d->m_modelManager->cppEditorSupport(editor());
- updateSemanticInfo(ces->recalculateSemanticInfo());
+ d->m_useSelectionsUpdater.abortSchedule();
- if (!d->m_localRenaming.start()) // Rename local symbol
- renameUsages(); // Rename non-local symbol or macro
-}
-
-void CppEditorWidget::onContentsChanged(int position, int charsRemoved, int charsAdded)
-{
- Q_UNUSED(position)
- Q_UNUSED(charsAdded)
+ // Trigger once the use selections updater is finished and thus has updated
+ // the use selections for the local renaming
+ QSharedPointer<QMetaObject::Connection> connection(new QMetaObject::Connection);
+ *connection.data() = connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished,
+ [this, connection] () {
+ QObject::disconnect(*connection);
+ if (!d->m_localRenaming.start()) // Rename local symbol
+ renameUsages(); // Rename non-local symbol or macro
+ });
- if (charsRemoved > 0)
- updateUses();
+ d->m_useSelectionsUpdater.update();
}
void CppEditorWidget::updatePreprocessorButtonTooltip()
@@ -469,80 +368,6 @@ void CppEditorWidget::updatePreprocessorButtonTooltip()
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
}
-QList<QTextEdit::ExtraSelection> CppEditorWidget::createSelectionsFromUses(
- const QList<SemanticInfo::Use> &uses)
-{
- QList<QTextEdit::ExtraSelection> result;
- const bool isUnused = uses.size() == 1;
-
- foreach (const SemanticInfo::Use &use, uses) {
- if (use.isInvalid())
- continue;
-
- QTextEdit::ExtraSelection sel;
- if (isUnused)
- sel.format = textCharFormat(TextEditor::C_OCCURRENCES_UNUSED);
- else
- sel.format = textCharFormat(TextEditor::C_OCCURRENCES);
-
- const int position = document()->findBlockByNumber(use.line - 1).position() + use.column - 1;
- const int anchor = position + use.length;
-
- sel.cursor = QTextCursor(document());
- sel.cursor.setPosition(anchor);
- sel.cursor.setPosition(position, QTextCursor::KeepAnchor);
-
- result.append(sel);
- }
-
- return result;
-}
-
-void CppEditorWidget::updateUses()
-{
- // Block premature semantic info calculation when editor is created.
- if (d->m_modelManager && d->m_modelManager->cppEditorSupport(editor())->initialized())
- d->m_updateUsesTimer.start();
-}
-
-void CppEditorWidget::updateUsesNow()
-{
- if (d->m_localRenaming.isActive())
- return;
-
- semanticRehighlight();
-}
-
-void CppEditorWidget::highlightSymbolUsages(int from, int to)
-{
- if (editorRevision() != d->m_highlightRevision)
- return; // outdated
-
- else if (!d->m_highlightWatcher || d->m_highlightWatcher->isCanceled())
- return; // aborted
-
- TextEditor::SyntaxHighlighter *highlighter = textDocument()->syntaxHighlighter();
- QTC_ASSERT(highlighter, return);
-
- TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
- highlighter, d->m_highlightWatcher->future(), from, to, d->m_semanticHighlightFormatMap);
-}
-
-void CppEditorWidget::finishHighlightSymbolUsages()
-{
- QTC_ASSERT(d->m_highlightWatcher, return);
- if (!d->m_highlightWatcher->isCanceled()
- && editorRevision() == d->m_highlightRevision
- && !d->m_lastSemanticInfo.doc.isNull()) {
- TextEditor::SyntaxHighlighter *highlighter = textDocument()->syntaxHighlighter();
- QTC_CHECK(highlighter);
- if (highlighter)
- TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(highlighter,
- d->m_highlightWatcher->future());
- }
- d->m_highlightWatcher.reset();
-}
-
void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit)
{
if (!d->m_modelManager)
@@ -624,17 +449,19 @@ CppEditorWidget::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor, boo
inNextSplit);
}
-unsigned CppEditorWidget::editorRevision() const
+unsigned CppEditorWidget::documentRevision() const
{
return document()->revision();
}
-bool CppEditorWidget::isOutdated() const
+bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
{
- if (d->m_lastSemanticInfo.revision != editorRevision())
- return true;
+ return d->m_lastSemanticInfo.doc && d->m_lastSemanticInfo.revision == documentRevision();
+}
- return false;
+bool CppEditorWidget::isSemanticInfoValid() const
+{
+ return isSemanticInfoValidExceptLocalUses() && d->m_lastSemanticInfo.localUsesUpdated;
}
SemanticInfo CppEditorWidget::semanticInfo() const
@@ -665,6 +492,11 @@ void CppEditorWidget::performQuickFix(int index)
op->perform();
}
+void CppEditorWidget::processKeyNormally(QKeyEvent *e)
+{
+ BaseTextEditorWidget::keyPressEvent(e);
+}
+
void CppEditorWidget::contextMenuEvent(QContextMenuEvent *e)
{
// ### enable
@@ -681,7 +513,7 @@ void CppEditorWidget::contextMenuEvent(QContextMenuEvent *e)
QSignalMapper mapper;
connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int)));
- if (!isOutdated()) {
+ if (isSemanticInfoValid()) {
TextEditor::IAssistInterface *interface =
createAssistInterface(TextEditor::QuickFix, TextEditor::ExplicitlyInvoked);
if (interface) {
@@ -735,7 +567,7 @@ void CppEditorWidget::keyPressEvent(QKeyEvent *e)
Core::IEditor *CPPEditor::duplicate()
{
CPPEditor *editor = new CPPEditor;
- CppEditorWidget *widget = new CppEditorWidget(editorWidget()->textDocumentPtr(), editor);
+ CppEditorWidget *widget = qobject_cast<CppEditorWidget *>(editorWidget())->duplicate(editor);
CppEditorPlugin::instance()->initializeEditor(widget);
editor->configureCodeAssistant();
return editor;
@@ -751,32 +583,8 @@ bool CPPEditor::open(QString *errorString, const QString &fileName, const QStrin
void CppEditorWidget::applyFontSettings()
{
- const TextEditor::FontSettings &fs = textDocument()->fontSettings();
-
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::TypeUse] =
- fs.toTextCharFormat(TextEditor::C_TYPE);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::LocalUse] =
- fs.toTextCharFormat(TextEditor::C_LOCAL);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::FieldUse] =
- fs.toTextCharFormat(TextEditor::C_FIELD);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::EnumerationUse] =
- fs.toTextCharFormat(TextEditor::C_ENUMERATION);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::VirtualMethodUse] =
- fs.toTextCharFormat(TextEditor::C_VIRTUAL_METHOD);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::LabelUse] =
- fs.toTextCharFormat(TextEditor::C_LABEL);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::MacroUse] =
- fs.toTextCharFormat(TextEditor::C_PREPROCESSOR);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::FunctionUse] =
- fs.toTextCharFormat(TextEditor::C_FUNCTION);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::PseudoKeywordUse] =
- fs.toTextCharFormat(TextEditor::C_KEYWORD);
- d->m_semanticHighlightFormatMap[CppHighlightingSupport::StringUse] =
- fs.toTextCharFormat(TextEditor::C_STRING);
-
- // this also makes the document apply font settings
+ // This also makes the document apply font settings
TextEditor::BaseTextEditorWidget::applyFontSettings();
- semanticRehighlight(true);
}
void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
@@ -820,84 +628,15 @@ bool CppEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit)
flags);
}
-void CppEditorWidget::semanticRehighlight(bool force)
-{
- if (d->m_modelManager) {
- const CppEditorSupport::ForceReason forceReason = force
- ? CppEditorSupport::ForceDueEditorRequest
- : CppEditorSupport::NoForce;
- d->m_modelManager->cppEditorSupport(editor())->recalculateSemanticInfoDetached(forceReason);
- }
-}
-
-void CppEditorWidget::highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter,
- unsigned revision)
-{
- d->m_highlightRevision = revision;
-
- d->m_highlightWatcher.reset(new QFutureWatcher<TextEditor::HighlightingResult>);
- connect(d->m_highlightWatcher.data(), SIGNAL(resultsReadyAt(int,int)),
- SLOT(highlightSymbolUsages(int,int)));
- connect(d->m_highlightWatcher.data(), SIGNAL(finished()),
- SLOT(finishHighlightSymbolUsages()));
-
- d->m_highlightWatcher->setFuture(QFuture<TextEditor::HighlightingResult>(*highlighter));
-}
-
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
{
- if (semanticInfo.revision != editorRevision()) {
- // got outdated semantic info
- semanticRehighlight();
+ if (semanticInfo.revision != documentRevision())
return;
- }
-
- d->m_lastSemanticInfo = semanticInfo; // update the semantic info
-
- int line = 0, column = 0;
- convertPosition(position(), &line, &column);
- QList<QTextEdit::ExtraSelection> unusedSelections;
- QList<QTextEdit::ExtraSelection> selections;
+ d->m_lastSemanticInfo = semanticInfo;
- // We can use the semanticInfo's snapshot (and avoid locking), but not its
- // document, since it doesn't contain expanded macros.
- LookupContext context(semanticInfo.snapshot.document(textDocument()->filePath()),
- semanticInfo.snapshot);
-
- SemanticInfo::LocalUseIterator it(semanticInfo.localUses);
- while (it.hasNext()) {
- it.next();
- const QList<SemanticInfo::Use> &uses = it.value();
-
- bool good = false;
- foreach (const SemanticInfo::Use &use, uses) {
- unsigned l = line;
- unsigned c = column + 1; // convertCursorPosition() returns a 0-based column number.
- if (l == use.line && c >= use.column && c <= (use.column + use.length)) {
- good = true;
- break;
- }
- }
-
- if (uses.size() == 1) {
- if (!CppTools::isOwnershipRAIIType(it.key(), context))
- unusedSelections << createSelectionsFromUses(uses); // unused declaration
- } else if (good && selections.isEmpty()) {
- selections << createSelectionsFromUses(uses);
- }
- }
-
- setExtraSelections(UnusedSymbolSelection, unusedSelections);
-
- if (!selections.isEmpty()) {
- setExtraSelections(CodeSemanticsSelection, selections);
- d->m_localRenaming.updateLocalUseSelections(selections);
- } else {
- markSymbols(textCursor(), semanticInfo);
- }
-
- d->m_lastSemanticInfo.forced = false; // clear the forced flag
+ if (!d->m_localRenaming.isActive())
+ d->m_useSelectionsUpdater.update();
// schedule a check for a decl/def link
updateFunctionDeclDefLink();
@@ -908,16 +647,17 @@ TextEditor::IAssistInterface *CppEditorWidget::createAssistInterface(
TextEditor::AssistReason reason) const
{
if (kind == TextEditor::Completion) {
- CppEditorSupport *ces = CppModelManagerInterface::instance()->cppEditorSupport(editor());
- CppCompletionAssistProvider *cap = ces->completionAssistProvider();
- if (cap) {
+ if (CppCompletionAssistProvider *cap = cppEditorDocument()->completionAssistProvider()) {
return cap->createAssistInterface(
ProjectExplorer::ProjectExplorerPlugin::currentProject(),
- editor(), document(), cppEditorDocument()->isObjCEnabled(), position(),
+ textDocument()->filePath(),
+ document(),
+ cppEditorDocument()->isObjCEnabled(),
+ position(),
reason);
}
} else if (kind == TextEditor::QuickFix) {
- if (!semanticInfo().doc || isOutdated())
+ if (!isSemanticInfoValid())
return 0;
return new CppQuickFixAssistInterface(const_cast<CppEditorWidget *>(this), reason);
} else {
@@ -967,8 +707,10 @@ void CppEditorWidget::updateFunctionDeclDefLinkNow()
{
if (Core::EditorManager::currentEditor() != editor())
return;
+
const Snapshot semanticSnapshot = d->m_lastSemanticInfo.snapshot;
const Document::Ptr semanticDoc = d->m_lastSemanticInfo.doc;
+
if (d->m_declDefLink) {
// update the change marker
const Utils::ChangeSet changes = d->m_declDefLink->changes(semanticSnapshot);
@@ -978,7 +720,8 @@ void CppEditorWidget::updateFunctionDeclDefLinkNow()
d->m_declDefLink->showMarker(this);
return;
}
- if (semanticDoc.isNull() || isOutdated())
+
+ if (!isSemanticInfoValidExceptLocalUses())
return;
Snapshot snapshot = CppModelManagerInterface::instance()->snapshot();
@@ -1012,8 +755,8 @@ void CppEditorWidget::onFilePathChanged()
additionalDirectives = ProjectExplorer::SessionManager::value(
projectFile + QLatin1Char(',') + filePath).toString().toUtf8();
- BuiltinEditorDocumentParser::Ptr parser
- = d->m_modelManager->cppEditorSupport(editor())->documentParser();
+ BaseEditorDocumentParser *parser = BaseEditorDocumentParser::get(filePath);
+ QTC_ASSERT(parser, return);
parser->setProjectPart(d->m_modelManager->projectPartForProjectFile(projectFile));
parser->setEditorDefines(additionalDirectives);
}
@@ -1052,21 +795,6 @@ void CppEditorWidget::abortDeclDefLink()
d->m_declDefLink.clear();
}
-void CppEditorWidget::onLocalRenamingFinished()
-{
- semanticRehighlight(true);
-}
-
-void CppEditorWidget::onLocalRenamingProcessKeyPressNormally(QKeyEvent *e)
-{
- BaseTextEditorWidget::keyPressEvent(e);
-}
-
-QTextCharFormat CppEditorWidget::textCharFormat(TextEditor::TextStyle category)
-{
- return textDocument()->fontSettings().toTextCharFormat(category);
-}
-
void CppEditorWidget::showPreProcessorWidget()
{
const QString &fileName = editor()->document()->filePath();
@@ -1080,8 +808,8 @@ void CppEditorWidget::showPreProcessorWidget()
CppPreProcessorDialog preProcessorDialog(this, textDocument()->filePath(), projectParts);
if (preProcessorDialog.exec() == QDialog::Accepted) {
- BuiltinEditorDocumentParser::Ptr parser
- = d->m_modelManager->cppEditorSupport(editor())->documentParser();
+ BaseEditorDocumentParser *parser = BaseEditorDocumentParser::get(fileName);
+ QTC_ASSERT(parser, return);
const QString &additionals = preProcessorDialog.additionalPreProcessorDirectives();
parser->setProjectPart(preProcessorDialog.projectPart());
parser->setEditorDefines(additionals.toUtf8());
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index d7c6df96f3..fcf09325b5 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -30,16 +30,11 @@
#ifndef CPPEDITOR_H
#define CPPEDITOR_H
-#include "cppeditordocument.h"
-
#include "cppfunctiondecldeflink.h"
#include <texteditor/basetexteditor.h>
-#include <texteditor/semantichighlighter.h>
-#include <texteditor/texteditorconstants.h>
#include <utils/qtcoverride.h>
-#include <utils/uncommentselection.h>
#include <QScopedPointer>
@@ -49,9 +44,11 @@ namespace CppTools { class SemanticInfo; }
namespace CppEditor {
namespace Internal {
+class CPPEditorDocument;
class CppEditorOutline;
class CppEditorWidgetPrivate;
class FollowSymbolUnderCursor;
+class FunctionDeclDefLink;
class CPPEditor : public TextEditor::BaseTextEditor
{
@@ -78,10 +75,14 @@ public:
CppEditorWidget(TextEditor::BaseTextDocumentPtr doc, CPPEditor *editor);
~CppEditorWidget();
+ CppEditorWidget *duplicate(CPPEditor *editor) const;
+
CPPEditorDocument *cppEditorDocument() const;
CppEditorOutline *outline() const;
CppTools::SemanticInfo semanticInfo() const;
+ bool isSemanticInfoValidExceptLocalUses() const;
+ bool isSemanticInfoValid() const;
QSharedPointer<FunctionDeclDefLink> declDefLink() const;
void applyDeclDefLinkChanges(bool jumpToMatch);
@@ -104,10 +105,6 @@ public slots:
void renameSymbolUnderCursor();
void renameUsages(const QString &replacement = QString());
- void semanticRehighlight(bool force = false);
- void highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter,
- unsigned revision);
-
protected:
bool event(QEvent *e) QTC_OVERRIDE;
void contextMenuEvent(QContextMenuEvent *) QTC_OVERRIDE;
@@ -126,40 +123,31 @@ protected slots:
void slotCodeStyleSettingsChanged(const QVariant &) QTC_OVERRIDE;
private slots:
- void updateUses();
- void updateUsesNow();
void updateFunctionDeclDefLink();
void updateFunctionDeclDefLinkNow();
+ void abortDeclDefLink();
+ void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker);
void onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link);
+
void onFilePathChanged();
- void onDocumentUpdated();
- void onContentsChanged(int position, int charsRemoved, int charsAdded);
- void updatePreprocessorButtonTooltip();
+ void onCppDocumentUpdated();
+
+ void onCodeWarningsUpdated(unsigned revision,
+ const QList<QTextEdit::ExtraSelection> selections);
+ void onIfdefedOutBlocksUpdated(unsigned revision,
+ const QList<TextEditor::BlockRange> ifdefedOutBlocks);
void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo);
- void highlightSymbolUsages(int from, int to);
- void finishHighlightSymbolUsages();
+ void updatePreprocessorButtonTooltip();
- void markSymbolsNow();
void performQuickFix(int index);
- void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker);
- void abortDeclDefLink();
- void onLocalRenamingFinished();
- void onLocalRenamingProcessKeyPressNormally(QKeyEvent *e);
+ void processKeyNormally(QKeyEvent *e);
private:
static bool openCppEditorAt(const Link &, bool inNextSplit = false);
- unsigned editorRevision() const;
- bool isOutdated() const;
-
- QTextCharFormat textCharFormat(TextEditor::TextStyle category);
-
- void markSymbols(const QTextCursor &tc, const CppTools::SemanticInfo &info);
-
- QList<QTextEdit::ExtraSelection> createSelectionsFromUses(
- const QList<TextEditor::HighlightingResult> &uses);
+ unsigned documentRevision() const;
private:
QScopedPointer<CppEditorWidgetPrivate> d;
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index f85c581fb9..cba69a39f3 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -33,6 +33,7 @@ HEADERS += \
cppquickfixes.h \
cppsnippetprovider.h \
cpptypehierarchy.h \
+ cppuseselectionsupdater.h \
cppvirtualfunctionassistprovider.h \
cppvirtualfunctionproposalitem.h
@@ -65,6 +66,7 @@ SOURCES += \
cppquickfixes.cpp \
cppsnippetprovider.cpp \
cpptypehierarchy.cpp \
+ cppuseselectionsupdater.cpp \
cppvirtualfunctionassistprovider.cpp \
cppvirtualfunctionproposalitem.cpp
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 5d6b52aa39..ea5ae12f04 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -52,6 +52,7 @@ QtcPlugin {
"cppquickfixes.cpp", "cppquickfixes.h",
"cppsnippetprovider.cpp", "cppsnippetprovider.h",
"cpptypehierarchy.cpp", "cpptypehierarchy.h",
+ "cppuseselectionsupdater.cpp", "cppuseselectionsupdater.h",
"cppvirtualfunctionassistprovider.cpp", "cppvirtualfunctionassistprovider.h",
"cppvirtualfunctionproposalitem.cpp", "cppvirtualfunctionproposalitem.h",
]
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp
index d91126f84b..2b79e2a991 100644
--- a/src/plugins/cppeditor/cppeditordocument.cpp
+++ b/src/plugins/cppeditor/cppeditordocument.cpp
@@ -32,25 +32,87 @@
#include "cppeditorconstants.h"
#include "cpphighlighter.h"
+#include <cpptools/builtineditordocumentprocessor.h>
#include <cpptools/cppcodeformatter.h>
+#include <cpptools/cppcodemodelsettings.h>
+#include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cppqtstyleindenter.h>
#include <cpptools/cpptoolsconstants.h>
+#include <cpptools/cpptoolsplugin.h>
+
+#include <utils/qtcassert.h>
+#include <utils/runextensions.h>
#include <QTextDocument>
+namespace {
+
+CppTools::CppModelManagerInterface *mm()
+{
+ return CppTools::CppModelManagerInterface::instance();
+}
+
+} // anonymous namespace
+
namespace CppEditor {
namespace Internal {
+enum { processDocumentIntervalInMs = 150 };
+
+class CppEditorDocumentHandle : public CppTools::EditorDocumentHandle
+{
+public:
+ CppEditorDocumentHandle(CppEditor::Internal::CPPEditorDocument *cppEditorDocument)
+ : m_cppEditorDocument(cppEditorDocument)
+ , m_registrationFilePath(cppEditorDocument->filePath())
+ {
+ mm()->registerEditorDocument(this);
+ }
+
+ ~CppEditorDocumentHandle() { mm()->unregisterEditorDocument(m_registrationFilePath); }
+
+ QString filePath() const { return m_cppEditorDocument->filePath(); }
+ QByteArray contents() const { return m_cppEditorDocument->contentsText(); }
+ unsigned revision() const { return m_cppEditorDocument->contentsRevision(); }
+
+ CppTools::BaseEditorDocumentProcessor *processor()
+ { return m_cppEditorDocument->processor(); }
+
+private:
+ CppEditor::Internal::CPPEditorDocument * const m_cppEditorDocument;
+ // The file path of the editor document can change (e.g. by "Save As..."), so make sure
+ // that un-registration happens with the path the document was registered.
+ const QString m_registrationFilePath;
+};
+
CPPEditorDocument::CPPEditorDocument()
+ : m_fileIsBeingReloaded(false)
+ , m_isObjCEnabled(false)
+ , m_cachedContentsRevision(-1)
+ , m_processorRevision(0)
+ , m_completionAssistProvider(0)
{
setId(CppEditor::Constants::CPPEDITOR_ID);
- connect(this, SIGNAL(tabSettingsChanged()),
- this, SLOT(invalidateFormatterCache()));
- connect(this, SIGNAL(mimeTypeChanged()),
- this, SLOT(onMimeTypeChanged()));
setSyntaxHighlighter(new CppHighlighter);
setIndenter(new CppTools::CppQtStyleIndenter);
- onMimeTypeChanged();
+
+ connect(this, SIGNAL(tabSettingsChanged()), this, SLOT(invalidateFormatterCache()));
+ connect(this, SIGNAL(mimeTypeChanged()), this, SLOT(onMimeTypeChanged()));
+
+ connect(this, SIGNAL(aboutToReload()), this, SLOT(onAboutToReload()));
+ connect(this, SIGNAL(reloadFinished(bool)), this, SLOT(onReloadFinished()));
+ connect(this, SIGNAL(filePathChanged(QString,QString)),
+ this, SLOT(onFilePathChanged(QString,QString)));
+
+ m_processorTimer.setSingleShot(true);
+ m_processorTimer.setInterval(processDocumentIntervalInMs);
+ connect(&m_processorTimer, SIGNAL(timeout()), this, SLOT(processDocument()));
+
+ // See also onFilePathChanged() for more initialization
+}
+
+CPPEditorDocument::~CPPEditorDocument()
+{
}
bool CPPEditorDocument::isObjCEnabled() const
@@ -58,6 +120,38 @@ bool CPPEditorDocument::isObjCEnabled() const
return m_isObjCEnabled;
}
+CppTools::CppCompletionAssistProvider *CPPEditorDocument::completionAssistProvider() const
+{
+ return m_completionAssistProvider;
+}
+
+void CPPEditorDocument::semanticRehighlight()
+{
+ CppTools::BaseEditorDocumentProcessor *p = processor();
+ QTC_ASSERT(p, return);
+ p->semanticRehighlight(true);
+}
+
+CppTools::SemanticInfo CPPEditorDocument::recalculateSemanticInfo()
+{
+ CppTools::BaseEditorDocumentProcessor *p = processor();
+ QTC_ASSERT(p, CppTools::SemanticInfo());
+ return p->recalculateSemanticInfo();
+}
+
+QByteArray CPPEditorDocument::contentsText() const
+{
+ QMutexLocker locker(&m_cachedContentsLock);
+
+ const int currentRevision = document()->revision();
+ if (m_cachedContentsRevision != currentRevision && !m_fileIsBeingReloaded) {
+ m_cachedContentsRevision = currentRevision;
+ m_cachedContents = plainText().toUtf8();
+ }
+
+ return m_cachedContents;
+}
+
void CPPEditorDocument::applyFontSettings()
{
if (TextEditor::SyntaxHighlighter *highlighter = syntaxHighlighter()) {
@@ -82,7 +176,94 @@ void CPPEditorDocument::onMimeTypeChanged()
{
const QString &mt = mimeType();
m_isObjCEnabled = (mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)
- || mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE));
+ || mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE));
+ m_completionAssistProvider = mm()->completionAssistProvider(mt);
+}
+
+void CPPEditorDocument::onAboutToReload()
+{
+ QTC_CHECK(!m_fileIsBeingReloaded);
+ m_fileIsBeingReloaded = true;
+}
+
+void CPPEditorDocument::onReloadFinished()
+{
+ QTC_CHECK(m_fileIsBeingReloaded);
+ m_fileIsBeingReloaded = false;
+}
+
+void CPPEditorDocument::onFilePathChanged(const QString &oldPath, const QString &newPath)
+{
+ Q_UNUSED(oldPath);
+
+ if (!newPath.isEmpty()) {
+ setMimeType(Core::MimeDatabase::findByFile(QFileInfo(newPath)).type());
+
+ disconnect(this, SIGNAL(contentsChanged()), this, SLOT(scheduleProcessDocument()));
+ connect(this, SIGNAL(contentsChanged()), this, SLOT(scheduleProcessDocument()));
+
+ // Un-Register/Register in ModelManager
+ m_editorDocumentHandle.reset(new CppEditorDocumentHandle(this));
+
+ resetProcessor();
+ m_processorRevision = document()->revision();
+ processDocument();
+ }
+}
+
+void CPPEditorDocument::scheduleProcessDocument()
+{
+ m_processorRevision = document()->revision();
+ m_processorTimer.start(processDocumentIntervalInMs);
+}
+
+void CPPEditorDocument::processDocument()
+{
+ if (processor()->isParserRunning() || m_processorRevision != contentsRevision()) {
+ m_processorTimer.start();
+ return;
+ }
+
+ m_processorTimer.stop();
+ if (m_fileIsBeingReloaded || filePath().isEmpty())
+ return;
+
+ processor()->run();
+}
+
+void CPPEditorDocument::resetProcessor()
+{
+ releaseResources();
+ processor(); // creates a new processor
+}
+
+unsigned CPPEditorDocument::contentsRevision() const
+{
+ return document()->revision();
+}
+
+void CPPEditorDocument::releaseResources()
+{
+ if (m_processor)
+ disconnect(m_processor.data(), 0, this, 0);
+ m_processor.reset();
+}
+
+CppTools::BaseEditorDocumentProcessor *CPPEditorDocument::processor()
+{
+ if (!m_processor) {
+ m_processor.reset(mm()->editorDocumentProcessor(this));
+ connect(m_processor.data(), &CppTools::BaseEditorDocumentProcessor::codeWarningsUpdated,
+ this, &CPPEditorDocument::codeWarningsUpdated);
+ connect(m_processor.data(), &CppTools::BaseEditorDocumentProcessor::ifdefedOutBlocksUpdated,
+ this, &CPPEditorDocument::ifdefedOutBlocksUpdated);
+ connect(m_processor.data(), &CppTools::BaseEditorDocumentProcessor::cppDocumentUpdated,
+ this, &CPPEditorDocument::cppDocumentUpdated);
+ connect(m_processor.data(), &CppTools::BaseEditorDocumentProcessor::semanticInfoUpdated,
+ this, &CPPEditorDocument::semanticInfoUpdated);
+ }
+
+ return m_processor.data();
}
} // namespace Internal
diff --git a/src/plugins/cppeditor/cppeditordocument.h b/src/plugins/cppeditor/cppeditordocument.h
index 8e2d8ec3f2..5db4c9375c 100644
--- a/src/plugins/cppeditor/cppeditordocument.h
+++ b/src/plugins/cppeditor/cppeditordocument.h
@@ -30,28 +30,85 @@
#ifndef CPPEDITORDOCUMENT_H
#define CPPEDITORDOCUMENT_H
+#include <cpptools/baseeditordocumentprocessor.h>
+#include <cpptools/cppcompletionassistprovider.h>
+#include <cpptools/cppmodelmanagerinterface.h>
+#include <cpptools/cppsemanticinfo.h>
+#include <cpptools/editordocumenthandle.h>
+
#include <texteditor/basetextdocument.h>
+#include <QMutex>
+#include <QTimer>
+
namespace CppEditor {
namespace Internal {
class CPPEditorDocument : public TextEditor::BaseTextDocument
{
Q_OBJECT
+
+ friend class CppEditorDocumentHandle;
+
public:
explicit CPPEditorDocument();
+ ~CPPEditorDocument();
bool isObjCEnabled() const;
+ CppTools::CppCompletionAssistProvider *completionAssistProvider() const;
+
+ void semanticRehighlight();
+ CppTools::SemanticInfo recalculateSemanticInfo(); // TODO: Remove me
+
+signals:
+ void codeWarningsUpdated(unsigned contentsRevision,
+ const QList<QTextEdit::ExtraSelection> selections);
+
+ void ifdefedOutBlocksUpdated(unsigned contentsRevision,
+ const QList<TextEditor::BlockRange> ifdefedOutBlocks);
+
+ void cppDocumentUpdated(const CPlusPlus::Document::Ptr document); // TODO: Remove me
+ void semanticInfoUpdated(const CppTools::SemanticInfo semanticInfo); // TODO: Remove me
protected:
void applyFontSettings();
private slots:
void invalidateFormatterCache();
+ void onFilePathChanged(const QString &oldPath, const QString &newPath);
void onMimeTypeChanged();
+ void onAboutToReload();
+ void onReloadFinished();
+
+ void scheduleProcessDocument();
+ void processDocument();
+
+private:
+ QByteArray contentsText() const;
+ unsigned contentsRevision() const;
+
+ CppTools::BaseEditorDocumentProcessor *processor();
+ void resetProcessor();
+ void releaseResources();
+
private:
+ bool m_fileIsBeingReloaded;
bool m_isObjCEnabled;
+
+ // Caching contents
+ mutable QMutex m_cachedContentsLock;
+ mutable QByteArray m_cachedContents;
+ mutable int m_cachedContentsRevision;
+
+ unsigned m_processorRevision;
+ QTimer m_processorTimer;
+ QScopedPointer<CppTools::BaseEditorDocumentProcessor> m_processor;
+
+ CppTools::CppCompletionAssistProvider *m_completionAssistProvider;
+
+ // (Un)Registration in CppModelManager
+ QScopedPointer<CppTools::EditorDocumentHandle> m_editorDocumentHandle;
};
} // namespace Internal
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp
index 81e5e81653..f9d3c71a78 100644
--- a/src/plugins/cppeditor/cppeditorplugin.cpp
+++ b/src/plugins/cppeditor/cppeditorplugin.cpp
@@ -32,6 +32,7 @@
#include "cppclasswizard.h"
#include "cppcodemodelinspectordialog.h"
#include "cppeditorconstants.h"
+#include "cppeditordocument.h"
#include "cppeditor.h"
#include "cppeditoroutline.h"
#include "cppfilewizard.h"
diff --git a/src/plugins/cppeditor/cppeditortestcase.cpp b/src/plugins/cppeditor/cppeditortestcase.cpp
index 4bb20eedcc..5fca9581e8 100644
--- a/src/plugins/cppeditor/cppeditortestcase.cpp
+++ b/src/plugins/cppeditor/cppeditortestcase.cpp
@@ -31,8 +31,10 @@
#include "cppeditortestcase.h"
#include "cppeditor.h"
+#include "cppeditordocument.h"
#include <coreplugin/editormanager/editormanager.h>
+#include <cpptools/baseeditordocumentprocessor.h>
#include <cpptools/cppsemanticinfo.h>
#include <cplusplus/CppDocument.h>
@@ -87,8 +89,10 @@ bool TestCase::openCppEditor(const QString &fileName,
CPlusPlus::Document::Ptr TestCase::waitForRehighlightedSemanticDocument(
Internal::CppEditorWidget *editorWidget)
{
- editorWidget->semanticRehighlight(true);
- while (editorWidget->semanticInfo().doc.isNull())
+ const QString filePath = editorWidget->textDocument()->filePath();
+ auto processor = CppTools::BaseEditorDocumentProcessor::get(filePath);
+ processor->semanticRehighlight(false);
+ while (!editorWidget->isSemanticInfoValid())
QCoreApplication::processEvents();
return editorWidget->semanticInfo().doc;
}
diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.cpp b/src/plugins/cppeditor/cppincludehierarchymodel.cpp
index ac5e2e26e6..0dfde59238 100644
--- a/src/plugins/cppeditor/cppincludehierarchymodel.cpp
+++ b/src/plugins/cppeditor/cppincludehierarchymodel.cpp
@@ -32,8 +32,9 @@
#include "cppincludehierarchyitem.h"
#include <coreplugin/fileiconprovider.h>
+#include <cpptools/builtineditordocumentparser.h>
#include <cpptools/cppmodelmanagerinterface.h>
-#include <cpptools/cpptoolseditorsupport.h>
+#include <cpptools/editordocumenthandle.h>
#include <texteditor/basetexteditor.h>
#include <cplusplus/CppDocument.h>
@@ -43,6 +44,15 @@
using namespace CPlusPlus;
using namespace CppTools;
+namespace {
+
+Snapshot globalSnapshot()
+{
+ return CppTools::CppModelManagerInterface::instance()->snapshot();
+}
+
+} // anonymous namespace
+
namespace CppEditor {
namespace Internal {
@@ -161,18 +171,24 @@ void CppIncludeHierarchyModel::fetchMore(const QModelIndex &parent)
return;
if (parentItem->needChildrenPopulate()) {
+ const QString editorFilePath = m_editor->document()->filePath();
QSet<QString> cyclic;
- cyclic << m_editor->document()->filePath();
+ cyclic << editorFilePath;
CppIncludeHierarchyItem *item = parentItem->parent();
while (!(item == m_includesItem || item == m_includedByItem)) {
cyclic << item->filePath();
item = item->parent();
}
- if (item == m_includesItem)
- buildHierarchyIncludes_helper(parentItem->filePath(), parentItem, &cyclic);
- else
- buildHierarchyIncludedBy_helper(parentItem->filePath(), parentItem, &cyclic);
+ if (item == m_includesItem) {
+ const Snapshot editorDocumentSnapshot
+ = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot();
+ buildHierarchyIncludes_helper(parentItem->filePath(), parentItem,
+ editorDocumentSnapshot, &cyclic);
+ } else {
+ buildHierarchyIncludedBy_helper(parentItem->filePath(), parentItem,
+ globalSnapshot(), &cyclic);
+ }
}
}
@@ -231,19 +247,21 @@ bool CppIncludeHierarchyModel::isEmpty() const
void CppIncludeHierarchyModel::buildHierarchyIncludes(const QString &currentFilePath)
{
+ if (!m_editor)
+ return;
+
+ const QString editorFilePath = m_editor->document()->filePath();
+ const Snapshot snapshot = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot();
QSet<QString> cyclic;
- buildHierarchyIncludes_helper(currentFilePath, m_includesItem, &cyclic);
+ buildHierarchyIncludes_helper(currentFilePath, m_includesItem, snapshot, &cyclic);
}
void CppIncludeHierarchyModel::buildHierarchyIncludes_helper(const QString &filePath,
CppIncludeHierarchyItem *parent,
- QSet<QString> *cyclic, bool recursive)
+ Snapshot snapshot,
+ QSet<QString> *cyclic,
+ bool recursive)
{
- if (!m_editor)
- return;
-
- CppModelManagerInterface *cppMM = CppModelManagerInterface::instance();
- const Snapshot &snapshot = cppMM->cppEditorSupport(m_editor)->documentParser()->snapshot();
Document::Ptr doc = snapshot.document(filePath);
if (!doc)
return;
@@ -265,7 +283,7 @@ void CppIncludeHierarchyModel::buildHierarchyIncludes_helper(const QString &file
}
item = new CppIncludeHierarchyItem(includedFilePath, parent);
parent->appendChild(item);
- buildHierarchyIncludes_helper(includedFilePath, item, cyclic, false);
+ buildHierarchyIncludes_helper(includedFilePath, item, snapshot, cyclic, false);
}
cyclic->remove(filePath);
@@ -274,16 +292,16 @@ void CppIncludeHierarchyModel::buildHierarchyIncludes_helper(const QString &file
void CppIncludeHierarchyModel::buildHierarchyIncludedBy(const QString &currentFilePath)
{
QSet<QString> cyclic;
- buildHierarchyIncludedBy_helper(currentFilePath, m_includedByItem, &cyclic);
+ buildHierarchyIncludedBy_helper(currentFilePath, m_includedByItem, globalSnapshot(), &cyclic);
}
void CppIncludeHierarchyModel::buildHierarchyIncludedBy_helper(const QString &filePath,
CppIncludeHierarchyItem *parent,
+ Snapshot snapshot,
QSet<QString> *cyclic,
bool recursive)
{
cyclic->insert(filePath);
- const Snapshot &snapshot = CppTools::CppModelManagerInterface::instance()->snapshot();
Snapshot::const_iterator citEnd = snapshot.end();
for (Snapshot::const_iterator cit = snapshot.begin(); cit != citEnd; ++cit) {
const QString filePathFromSnapshot = cit.key();
@@ -307,8 +325,9 @@ void CppIncludeHierarchyModel::buildHierarchyIncludedBy_helper(const QString &fi
if (isCyclic)
continue;
- else
- buildHierarchyIncludedBy_helper(filePathFromSnapshot, item, cyclic, false);
+
+ buildHierarchyIncludedBy_helper(filePathFromSnapshot, item, snapshot, cyclic,
+ false);
}
}
}
diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.h b/src/plugins/cppeditor/cppincludehierarchymodel.h
index 4a96cbe7a1..146c9fc031 100644
--- a/src/plugins/cppeditor/cppincludehierarchymodel.h
+++ b/src/plugins/cppeditor/cppincludehierarchymodel.h
@@ -41,6 +41,7 @@ enum ItemRole {
} // Anonymous
+namespace CPlusPlus { class Snapshot; }
namespace TextEditor { class BaseTextEditor; }
namespace CppEditor {
@@ -72,10 +73,12 @@ public:
private:
void buildHierarchyIncludes(const QString &currentFilePath);
void buildHierarchyIncludes_helper(const QString &filePath, CppIncludeHierarchyItem *parent,
+ CPlusPlus::Snapshot snapshot,
QSet<QString> *cyclic, bool recursive = true);
void buildHierarchyIncludedBy(const QString &currentFilePath);
void buildHierarchyIncludedBy_helper(const QString &filePath, CppIncludeHierarchyItem *parent,
- QSet<QString> *cyclic, bool recursive = true);
+ CPlusPlus::Snapshot snapshot, QSet<QString> *cyclic,
+ bool recursive = true);
CppIncludeHierarchyItem *m_rootItem;
CppIncludeHierarchyItem *m_includesItem;
diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp
index d2a0c02282..e81b8e66ae 100644
--- a/src/plugins/cppeditor/cpplocalrenaming.cpp
+++ b/src/plugins/cppeditor/cpplocalrenaming.cpp
@@ -72,7 +72,8 @@ CppLocalRenaming::CppLocalRenaming(TextEditor::BaseTextEditorWidget *editorWidge
this, SLOT(onContentsChangeOfEditorWidgetDocument(int,int,int)));
}
-void CppLocalRenaming::updateLocalUseSelections(const QList<QTextEdit::ExtraSelection> &selections)
+void CppLocalRenaming::updateSelectionsForVariableUnderCursor(
+ const QList<QTextEdit::ExtraSelection> &selections)
{
QTC_ASSERT(!isActive(), return);
m_selections = selections;
diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h
index 0e246321ed..72d4f2c2d4 100644
--- a/src/plugins/cppeditor/cpplocalrenaming.h
+++ b/src/plugins/cppeditor/cpplocalrenaming.h
@@ -47,8 +47,6 @@ class CppLocalRenaming : public QObject
public:
explicit CppLocalRenaming(TextEditor::BaseTextEditorWidget *editorWidget);
- void updateLocalUseSelections(const QList<QTextEdit::ExtraSelection> &selections);
-
bool start();
bool isActive() const;
void stop();
@@ -62,6 +60,9 @@ public:
// to BaseTextEditorWidget::keyPressEvent()
bool handleKeyPressEvent(QKeyEvent *e);
+public slots:
+ void updateSelectionsForVariableUnderCursor(const QList<QTextEdit::ExtraSelection> &selections);
+
signals:
void finished();
void processKeyPressNormally(QKeyEvent *e);
diff --git a/src/plugins/cppeditor/cppquickfixassistant.cpp b/src/plugins/cppeditor/cppquickfixassistant.cpp
index 5ccf31b71f..34a79a5f70 100644
--- a/src/plugins/cppeditor/cppquickfixassistant.cpp
+++ b/src/plugins/cppeditor/cppquickfixassistant.cpp
@@ -94,7 +94,9 @@ CppQuickFixAssistInterface::CppQuickFixAssistInterface(CppEditorWidget *editor,
, m_currentFile(CppRefactoringChanges::file(editor, m_semanticInfo.doc))
, m_context(m_semanticInfo.doc, m_snapshot)
{
- QTC_CHECK(!m_semanticInfo.doc.isNull());
+ QTC_CHECK(m_semanticInfo.doc);
+ QTC_CHECK(m_semanticInfo.doc->translationUnit());
+ QTC_CHECK(m_semanticInfo.doc->translationUnit()->ast());
CPlusPlus::ASTPath astPath(m_semanticInfo.doc);
m_path = astPath(editor->textCursor());
}
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 0165339b5a..c6b8001b53 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -30,6 +30,7 @@
#include "cppquickfixes.h"
#include "cppeditor.h"
+#include "cppeditordocument.h"
#include "cppfunctiondecldeflink.h"
#include "cppquickfixassistant.h"
#include "cppvirtualfunctionassistprovider.h"
diff --git a/src/plugins/cppeditor/cppuseselections_test.cpp b/src/plugins/cppeditor/cppuseselections_test.cpp
index c99a7a4c2b..e1408c3ade 100644
--- a/src/plugins/cppeditor/cppuseselections_test.cpp
+++ b/src/plugins/cppeditor/cppuseselections_test.cpp
@@ -135,7 +135,7 @@ SelectionList UseSelectionsTestCase::waitForUseSelections(bool *hasTimedOut) con
QList<QTextEdit::ExtraSelection> extraSelections = getExtraSelections();
while (extraSelections.isEmpty()) {
- if (timer.hasExpired(500)) {
+ if (timer.hasExpired(2500)) {
if (hasTimedOut)
*hasTimedOut = true;
break;
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.cpp b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
new file mode 100644
index 0000000000..e292ac4bcd
--- /dev/null
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
@@ -0,0 +1,451 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cppuseselectionsupdater.h"
+
+#include "cppcanonicalsymbol.h"
+#include "cppeditor.h"
+
+#include <cpptools/cpplocalsymbols.h>
+#include <cpptools/cppmodelmanagerinterface.h>
+#include <cpptools/cpptoolsreuse.h>
+#include <texteditor/basetexteditor.h>
+#include <texteditor/fontsettings.h>
+
+#include <cplusplus/Macro.h>
+#include <cplusplus/TranslationUnit.h>
+
+#include <utils/qtcassert.h>
+
+#include <QtConcurrentRun>
+#include <QTextBlock>
+#include <QTextCursor>
+#include <QTextEdit>
+
+using namespace CPlusPlus;
+
+enum { updateUseSelectionsInternalInMs = 500 };
+
+namespace {
+
+class FunctionDefinitionUnderCursor: protected ASTVisitor
+{
+ unsigned _line;
+ unsigned _column;
+ DeclarationAST *_functionDefinition;
+
+public:
+ FunctionDefinitionUnderCursor(TranslationUnit *translationUnit)
+ : ASTVisitor(translationUnit),
+ _line(0), _column(0)
+ { }
+
+ DeclarationAST *operator()(AST *ast, unsigned line, unsigned column)
+ {
+ _functionDefinition = 0;
+ _line = line;
+ _column = column;
+ accept(ast);
+ return _functionDefinition;
+ }
+
+protected:
+ virtual bool preVisit(AST *ast)
+ {
+ if (_functionDefinition)
+ return false;
+
+ if (FunctionDefinitionAST *def = ast->asFunctionDefinition())
+ return checkDeclaration(def);
+
+ if (ObjCMethodDeclarationAST *method = ast->asObjCMethodDeclaration()) {
+ if (method->function_body)
+ return checkDeclaration(method);
+ }
+
+ return true;
+ }
+
+private:
+ bool checkDeclaration(DeclarationAST *ast)
+ {
+ unsigned startLine, startColumn;
+ unsigned endLine, endColumn;
+ getTokenStartPosition(ast->firstToken(), &startLine, &startColumn);
+ getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn);
+
+ if (_line > startLine || (_line == startLine && _column >= startColumn)) {
+ if (_line < endLine || (_line == endLine && _column < endColumn)) {
+ _functionDefinition = ast;
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+QTextEdit::ExtraSelection extraSelection(const QTextCharFormat &format, const QTextCursor &cursor)
+{
+ QTextEdit::ExtraSelection selection;
+ selection.format = format;
+ selection.cursor = cursor;
+ return selection;
+}
+
+struct Params
+{
+ // Shared
+ Document::Ptr document;
+
+ // For local use calculation
+ int line;
+ int column;
+
+ // For references calculation
+ Scope *scope;
+ QString expression;
+ Snapshot snapshot;
+};
+
+using CppEditor::Internal::SemanticUses;
+
+void splitLocalUses(const CppTools::SemanticInfo::LocalUseMap &uses,
+ const Params &p,
+ SemanticUses *selectionsForLocalVariableUnderCursor,
+ SemanticUses *selectionsForLocalUnusedVariables)
+{
+ QTC_ASSERT(selectionsForLocalVariableUnderCursor, return);
+ QTC_ASSERT(selectionsForLocalUnusedVariables, return);
+
+ LookupContext context(p.document, p.snapshot);
+
+ CppTools::SemanticInfo::LocalUseIterator it(uses);
+ while (it.hasNext()) {
+ it.next();
+ const SemanticUses &uses = it.value();
+
+ bool good = false;
+ foreach (const CppTools::SemanticInfo::Use &use, uses) {
+ unsigned l = p.line;
+ unsigned c = p.column + 1; // convertCursorPosition() returns a 0-based column number.
+ if (l == use.line && c >= use.column && c <= (use.column + use.length)) {
+ good = true;
+ break;
+ }
+ }
+
+ if (uses.size() == 1) {
+ if (!CppTools::isOwnershipRAIIType(it.key(), context))
+ selectionsForLocalUnusedVariables->append(uses); // unused declaration
+ } else if (good && selectionsForLocalVariableUnderCursor->isEmpty()) {
+ selectionsForLocalVariableUnderCursor->append(uses);
+ }
+ }
+}
+
+CppTools::SemanticInfo::LocalUseMap findLocalUses(const Params &p)
+{
+ AST *ast = p.document->translationUnit()->ast();
+ FunctionDefinitionUnderCursor functionDefinitionUnderCursor(p.document->translationUnit());
+ DeclarationAST *declaration = functionDefinitionUnderCursor(ast, p.line, p.column);
+ return CppTools::LocalSymbols(p.document, declaration).uses;
+}
+
+QList<int> findReferences(const Params &p)
+{
+ QList<int> result;
+ if (!p.scope || p.expression.isEmpty())
+ return result;
+
+ TypeOfExpression typeOfExpression;
+ Snapshot snapshot = p.snapshot;
+ snapshot.insert(p.document);
+ typeOfExpression.init(p.document, snapshot);
+ typeOfExpression.setExpandTemplates(true);
+
+ using CppEditor::Internal::CanonicalSymbol;
+ if (Symbol *s = CanonicalSymbol::canonicalSymbol(p.scope, p.expression, typeOfExpression)) {
+ CppTools::CppModelManagerInterface *mmi = CppTools::CppModelManagerInterface::instance();
+ result = mmi->references(s, typeOfExpression.context());
+ }
+
+ return result;
+}
+
+CppEditor::Internal::UseSelectionsResult findUses(const Params p)
+{
+ CppEditor::Internal::UseSelectionsResult result;
+
+ const CppTools::SemanticInfo::LocalUseMap localUses = findLocalUses(p);
+ result.localUses = localUses;
+ splitLocalUses(localUses, p, &result.selectionsForLocalVariableUnderCursor,
+ &result.selectionsForLocalUnusedVariables);
+
+ if (!result.selectionsForLocalVariableUnderCursor.isEmpty())
+ return result;
+
+ result.references = findReferences(p);
+ return result; // OK, result.selectionsForLocalUnusedVariables will be passed on
+}
+
+} // anonymous namespace
+
+namespace CppEditor {
+namespace Internal {
+
+CppUseSelectionsUpdater::CppUseSelectionsUpdater(TextEditor::BaseTextEditorWidget *editorWidget)
+ : m_editorWidget(editorWidget)
+ , m_findUsesRevision(-1)
+{
+ m_timer.setSingleShot(true);
+ m_timer.setInterval(updateUseSelectionsInternalInMs);
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(update()));
+}
+
+void CppUseSelectionsUpdater::scheduleUpdate()
+{
+ m_timer.start();
+}
+
+void CppUseSelectionsUpdater::abortSchedule()
+{
+ m_timer.stop();
+}
+
+void CppUseSelectionsUpdater::update()
+{
+ CppEditorWidget *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
+ QTC_ASSERT(cppEditorWidget, return);
+ QTC_CHECK(cppEditorWidget->isSemanticInfoValidExceptLocalUses());
+ const CppTools::SemanticInfo semanticInfo = cppEditorWidget->semanticInfo();
+ const Document::Ptr document = semanticInfo.doc;
+ const Snapshot snapshot = semanticInfo.snapshot;
+
+ if (!document || document->editorRevision() != static_cast<unsigned>(textDocument()->revision()))
+ return;
+
+ QTC_ASSERT(document->translationUnit(), return);
+ QTC_ASSERT(document->translationUnit()->ast(), return);
+ QTC_ASSERT(!snapshot.isEmpty(), return);
+
+ QTextCursor textCursor = m_editorWidget->textCursor();
+
+ if (handleMacroCase(textCursor, document)) {
+ emit finished(CppTools::SemanticInfo::LocalUseMap());
+ return;
+ }
+
+ handleSymbolCase(textCursor, document, snapshot);
+}
+
+void CppUseSelectionsUpdater::onFindUsesFinished()
+{
+ QTC_ASSERT(m_findUsesWatcher, return);
+ if (m_findUsesWatcher->isCanceled())
+ return;
+ if (m_findUsesRevision != textDocument()->revision())
+ return;
+ // Optimizable: If the cursor is still on the same identifier the results are valid.
+ if (m_findUsesCursorPosition != m_editorWidget->position())
+ return;
+
+ const UseSelectionsResult result = m_findUsesWatcher->result();
+ const bool hasUsesForLocalVariable = !result.selectionsForLocalVariableUnderCursor.isEmpty();
+ const bool hasReferences = !result.references.isEmpty();
+
+ ExtraSelections localVariableSelections;
+ if (hasUsesForLocalVariable) {
+ localVariableSelections = toExtraSelections(result.selectionsForLocalVariableUnderCursor,
+ TextEditor::C_OCCURRENCES);
+ updateUseSelections(localVariableSelections);
+ } else if (hasReferences) {
+ const ExtraSelections selections = toExtraSelections(result.references,
+ TextEditor::C_OCCURRENCES);
+ updateUseSelections(selections);
+ } else {
+ if (!currentUseSelections().isEmpty())
+ updateUseSelections(ExtraSelections());
+ }
+
+ updateUnusedSelections(toExtraSelections(result.selectionsForLocalUnusedVariables,
+ TextEditor::C_OCCURRENCES_UNUSED));
+
+ m_findUsesWatcher.reset();
+ m_document.reset();
+ m_snapshot = Snapshot();
+
+ emit selectionsForVariableUnderCursorUpdated(localVariableSelections);
+ emit finished(result.localUses);
+}
+
+bool CppUseSelectionsUpdater::handleMacroCase(const QTextCursor &textCursor,
+ const Document::Ptr document)
+{
+ const Macro *macro = CppTools::findCanonicalMacro(textCursor, document);
+ if (!macro)
+ return false;
+
+ const QTextCharFormat &occurrencesFormat = textCharFormat(TextEditor::C_OCCURRENCES);
+ ExtraSelections selections;
+
+ // Macro definition
+ if (macro->fileName() == document->fileName()) {
+ QTextCursor cursor(textDocument());
+ cursor.setPosition(macro->utf16CharOffset());
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
+ macro->nameToQString().size());
+
+ selections.append(extraSelection(occurrencesFormat, cursor));
+ }
+
+ // Other macro uses
+ foreach (const Document::MacroUse &use, document->macroUses()) {
+ const Macro &useMacro = use.macro();
+ if (useMacro.line() != macro->line()
+ || useMacro.utf16CharOffset() != macro->utf16CharOffset()
+ || useMacro.length() != macro->length()
+ || useMacro.fileName() != macro->fileName())
+ continue;
+
+ QTextCursor cursor(textDocument());
+ cursor.setPosition(use.utf16charsBegin());
+ cursor.setPosition(use.utf16charsEnd(), QTextCursor::KeepAnchor);
+
+ selections.append(extraSelection(occurrencesFormat, cursor));
+ }
+
+ updateUseSelections(selections);
+ return true;
+}
+
+void CppUseSelectionsUpdater::handleSymbolCase(const QTextCursor &textCursor,
+ const Document::Ptr document,
+ const Snapshot &snapshot)
+{
+ m_document = document;
+ m_snapshot = snapshot;
+
+ if (m_findUsesWatcher)
+ m_findUsesWatcher->cancel();
+ m_findUsesWatcher.reset(new QFutureWatcher<UseSelectionsResult>);
+ connect(m_findUsesWatcher.data(), SIGNAL(finished()), this, SLOT(onFindUsesFinished()));
+
+ m_findUsesRevision = textDocument()->revision();
+ m_findUsesCursorPosition = m_editorWidget->position();
+
+ Params params;
+ params.document = document;
+ m_editorWidget->convertPosition(m_findUsesCursorPosition, &params.line, &params.column);
+ CanonicalSymbol canonicalSymbol(document, snapshot);
+ params.scope = canonicalSymbol.getScopeAndExpression(textCursor, &params.expression);
+ params.snapshot = snapshot;
+
+ m_findUsesWatcher->setFuture(QtConcurrent::run(&findUses, params));
+}
+
+ExtraSelections CppUseSelectionsUpdater::toExtraSelections(const SemanticUses &uses,
+ TextEditor::TextStyle style) const
+{
+ ExtraSelections result;
+
+ foreach (const CppTools::SemanticInfo::Use &use, uses) {
+ if (use.isInvalid())
+ continue;
+
+ QTextDocument *document = textDocument();
+ const int position = document->findBlockByNumber(use.line - 1).position() + use.column - 1;
+ const int anchor = position + use.length;
+
+ QTextEdit::ExtraSelection sel;
+ sel.format = textCharFormat(style);
+ sel.cursor = QTextCursor(document);
+ sel.cursor.setPosition(anchor);
+ sel.cursor.setPosition(position, QTextCursor::KeepAnchor);
+
+ result.append(sel);
+ }
+
+ return result;
+}
+
+ExtraSelections CppUseSelectionsUpdater::toExtraSelections(const QList<int> &references,
+ TextEditor::TextStyle style) const
+{
+ ExtraSelections selections;
+ foreach (int index, references) {
+ unsigned line, column;
+ TranslationUnit *unit = m_document->translationUnit();
+ unit->getTokenPosition(index, &line, &column);
+
+ if (column)
+ --column; // adjust the column position.
+
+ const int len = unit->tokenAt(index).utf16chars();
+
+ QTextCursor cursor(textDocument()->findBlockByNumber(line - 1));
+ cursor.setPosition(cursor.position() + column);
+ cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor);
+
+ selections.append(extraSelection(textCharFormat(style), cursor));
+ }
+
+ return selections;
+}
+
+QTextCharFormat CppUseSelectionsUpdater::textCharFormat(TextEditor::TextStyle category) const
+{
+ return m_editorWidget->textDocument()->fontSettings().toTextCharFormat(category);
+}
+
+QTextDocument *CppUseSelectionsUpdater::textDocument() const
+{
+ return m_editorWidget->document();
+}
+
+ExtraSelections CppUseSelectionsUpdater::currentUseSelections() const
+{
+ return m_editorWidget->extraSelections(
+ TextEditor::BaseTextEditorWidget::CodeSemanticsSelection);
+}
+
+void CppUseSelectionsUpdater::updateUseSelections(const ExtraSelections &selections)
+{
+ m_editorWidget->setExtraSelections(TextEditor::BaseTextEditorWidget::CodeSemanticsSelection,
+ selections);
+}
+
+void CppUseSelectionsUpdater::updateUnusedSelections(const ExtraSelections &selections)
+{
+ m_editorWidget->setExtraSelections(TextEditor::BaseTextEditorWidget::UnusedSymbolSelection,
+ selections);
+}
+
+} // namespace Internal
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.h b/src/plugins/cppeditor/cppuseselectionsupdater.h
new file mode 100644
index 0000000000..277785afa2
--- /dev/null
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CPPUSESELECTIONSUPDATER_H
+#define CPPUSESELECTIONSUPDATER_H
+
+#include <cpptools/cppsemanticinfo.h>
+#include <texteditor/texteditorconstants.h>
+
+#include <cplusplus/CppDocument.h>
+
+#include <QFutureWatcher>
+#include <QTextEdit>
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+class QTextCharFormat;
+class QTextCursor;
+QT_END_NAMESPACE
+
+namespace TextEditor { class BaseTextEditorWidget; }
+
+namespace CppEditor {
+namespace Internal {
+
+typedef QList<QTextEdit::ExtraSelection> ExtraSelections;
+typedef QList<CppTools::SemanticInfo::Use> SemanticUses;
+
+struct UseSelectionsResult
+{
+ CppTools::SemanticInfo::LocalUseMap localUses;
+ SemanticUses selectionsForLocalVariableUnderCursor;
+ SemanticUses selectionsForLocalUnusedVariables;
+ QList<int> references;
+};
+
+class CppUseSelectionsUpdater : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(CppUseSelectionsUpdater)
+
+public:
+ explicit CppUseSelectionsUpdater(TextEditor::BaseTextEditorWidget *editorWidget);
+
+public slots:
+ void scheduleUpdate();
+ void abortSchedule();
+ void update();
+
+signals:
+ void finished(CppTools::SemanticInfo::LocalUseMap localUses);
+ void selectionsForVariableUnderCursorUpdated(const QList<QTextEdit::ExtraSelection> &);
+
+private slots:
+ void onFindUsesFinished();
+
+private:
+ CppUseSelectionsUpdater();
+
+ bool handleMacroCase(const QTextCursor &textCursor,
+ const CPlusPlus::Document::Ptr document);
+ void handleSymbolCase(const QTextCursor &textCursor,
+ const CPlusPlus::Document::Ptr document,
+ const CPlusPlus::Snapshot &snapshot);
+
+ ExtraSelections toExtraSelections(const SemanticUses &uses, TextEditor::TextStyle style) const;
+ ExtraSelections toExtraSelections(const QList<int> &references,
+ TextEditor::TextStyle style) const;
+
+ // Convenience
+ ExtraSelections currentUseSelections() const;
+ void updateUseSelections(const ExtraSelections &selections);
+ void updateUnusedSelections(const ExtraSelections &selections);
+ QTextCharFormat textCharFormat(TextEditor::TextStyle category) const;
+ QTextDocument *textDocument() const;
+
+private:
+ TextEditor::BaseTextEditorWidget *m_editorWidget;
+
+ QTimer m_timer;
+
+ CPlusPlus::Document::Ptr m_document;
+ CPlusPlus::Snapshot m_snapshot;
+
+ QScopedPointer<QFutureWatcher<UseSelectionsResult>> m_findUsesWatcher;
+ int m_findUsesRevision;
+ int m_findUsesCursorPosition;
+};
+
+} // namespace Internal
+} // namespace CppEditor
+
+#endif // CPPUSESELECTIONSUPDATER_H
diff --git a/src/plugins/cpptools/baseeditordocumentparser.cpp b/src/plugins/cpptools/baseeditordocumentparser.cpp
index 058fae5b99..bcf7407415 100644
--- a/src/plugins/cpptools/baseeditordocumentparser.cpp
+++ b/src/plugins/cpptools/baseeditordocumentparser.cpp
@@ -29,6 +29,8 @@
#include "baseeditordocumentparser.h"
+#include "editordocumenthandle.h"
+
namespace CppTools {
/*!
@@ -101,6 +103,16 @@ void BaseEditorDocumentParser::setEditorDefines(const QByteArray &editorDefines)
}
}
+BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
+{
+ CppModelManagerInterface *cmmi = CppModelManagerInterface::instance();
+ if (EditorDocumentHandle *editorDocument = cmmi->editorDocument(filePath)) {
+ if (BaseEditorDocumentProcessor *processor = editorDocument->processor())
+ return processor->parser();
+ }
+ return 0;
+}
+
void BaseEditorDocumentParser::updateProjectPart()
{
if (m_manuallySetProjectPart) {
diff --git a/src/plugins/cpptools/baseeditordocumentparser.h b/src/plugins/cpptools/baseeditordocumentparser.h
index e62bbae4c6..d33b88a8ab 100644
--- a/src/plugins/cpptools/baseeditordocumentparser.h
+++ b/src/plugins/cpptools/baseeditordocumentparser.h
@@ -33,10 +33,13 @@
#include "cppmodelmanagerinterface.h"
#include "cpptools_global.h"
+#include <QObject>
+
namespace CppTools {
-class CPPTOOLS_EXPORT BaseEditorDocumentParser
+class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
{
+ Q_OBJECT
Q_DISABLE_COPY(BaseEditorDocumentParser)
BaseEditorDocumentParser();
@@ -57,6 +60,9 @@ public:
QByteArray editorDefines() const;
void setEditorDefines(const QByteArray &editorDefines);
+public:
+ static BaseEditorDocumentParser *get(const QString &filePath);
+
protected:
void updateProjectPart();
diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.cpp b/src/plugins/cpptools/baseeditordocumentprocessor.cpp
new file mode 100644
index 0000000000..e8992da58e
--- /dev/null
+++ b/src/plugins/cpptools/baseeditordocumentprocessor.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "baseeditordocumentprocessor.h"
+#include "cppworkingcopy.h"
+
+#include "editordocumenthandle.h"
+
+#include <utils/qtcassert.h>
+
+#include <QTextBlock>
+
+namespace CppTools {
+
+/*!
+ \class CppTools::BaseEditorDocumentProcessor
+
+ \brief The BaseEditorDocumentProcessor class controls and executes all
+ document relevant actions (reparsing, semantic highlighting, additional
+ semantic calculations) after a text document has changed.
+*/
+
+BaseEditorDocumentProcessor::BaseEditorDocumentProcessor(
+ TextEditor::BaseTextDocument *document)
+ : m_baseTextDocument(document)
+{
+ QTC_CHECK(document);
+}
+
+BaseEditorDocumentProcessor::~BaseEditorDocumentProcessor()
+{
+}
+
+TextEditor::BaseTextDocument *BaseEditorDocumentProcessor::baseTextDocument() const
+{
+ return m_baseTextDocument;
+}
+
+BaseEditorDocumentProcessor *BaseEditorDocumentProcessor::get(const QString &filePath)
+{
+ CppModelManagerInterface *cmmi = CppModelManagerInterface::instance();
+ if (EditorDocumentHandle *editorDocument = cmmi->editorDocument(filePath))
+ return editorDocument->processor();
+ return 0;
+}
+
+QList<QTextEdit::ExtraSelection> BaseEditorDocumentProcessor::toTextEditorSelections(
+ const QList<CPlusPlus::Document::DiagnosticMessage> &diagnostics,
+ QTextDocument *textDocument)
+{
+ // Format for errors
+ QTextCharFormat errorFormat;
+ errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ errorFormat.setUnderlineColor(Qt::red);
+
+ // Format for warnings
+ QTextCharFormat warningFormat;
+ warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ warningFormat.setUnderlineColor(Qt::darkYellow);
+
+ QList<QTextEdit::ExtraSelection> result;
+ foreach (const CPlusPlus::Document::DiagnosticMessage &m, diagnostics) {
+ QTextEdit::ExtraSelection sel;
+ if (m.isWarning())
+ sel.format = warningFormat;
+ else
+ sel.format = errorFormat;
+
+ QTextCursor c(textDocument->findBlockByNumber(m.line() - 1));
+ const QString text = c.block().text();
+ if (m.length() > 0 && m.column() + m.length() < (unsigned)text.size()) {
+ int column = m.column() > 0 ? m.column() - 1 : 0;
+ c.setPosition(c.position() + column);
+ c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, m.length());
+ } else {
+ for (int i = 0; i < text.size(); ++i) {
+ if (!text.at(i).isSpace()) {
+ c.setPosition(c.position() + i);
+ break;
+ }
+ }
+ c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ }
+ sel.cursor = c;
+ sel.format.setToolTip(m.text());
+ result.append(sel);
+ }
+
+ return result;
+}
+
+void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
+ BaseEditorDocumentParser *parser,
+ WorkingCopy workingCopy)
+{
+ future.setProgressRange(0, 1);
+ if (future.isCanceled()) {
+ future.setProgressValue(1);
+ return;
+ }
+
+ parser->update(workingCopy);
+ CppModelManagerInterface::instance()
+ ->finishedRefreshingSourceFiles(QStringList(parser->filePath()));
+
+ future.setProgressValue(1);
+}
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h
new file mode 100644
index 0000000000..a6ac2e8a31
--- /dev/null
+++ b/src/plugins/cpptools/baseeditordocumentprocessor.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BASEEDITORDOCUMENTPROCESSOR_H
+#define BASEEDITORDOCUMENTPROCESSOR_H
+
+#include "baseeditordocumentparser.h"
+#include "cppsemanticinfo.h"
+#include "cpptools_global.h"
+
+#include <texteditor/basetexteditor.h>
+
+#include <cplusplus/CppDocument.h>
+
+#include <QTextEdit>
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT BaseEditorDocumentProcessor : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(BaseEditorDocumentProcessor)
+ BaseEditorDocumentProcessor();
+
+public:
+ BaseEditorDocumentProcessor(TextEditor::BaseTextDocument *document);
+ virtual ~BaseEditorDocumentProcessor();
+
+ TextEditor::BaseTextDocument *baseTextDocument() const;
+
+ // Function interface to implement
+ virtual void run() = 0;
+ virtual void semanticRehighlight(bool force) = 0;
+ virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0;
+ virtual BaseEditorDocumentParser *parser() = 0;
+ virtual bool isParserRunning() const = 0;
+
+public:
+ static BaseEditorDocumentProcessor *get(const QString &filePath);
+
+signals:
+ // Signal interface to implement
+ void codeWarningsUpdated(unsigned revision,
+ const QList<QTextEdit::ExtraSelection> selections);
+
+ void ifdefedOutBlocksUpdated(unsigned revision,
+ const QList<TextEditor::BlockRange> ifdefedOutBlocks);
+
+ void cppDocumentUpdated(const CPlusPlus::Document::Ptr document); // TODO: Remove me
+ void semanticInfoUpdated(const CppTools::SemanticInfo semanticInfo); // TODO: Remove me
+
+protected:
+ static QList<QTextEdit::ExtraSelection> toTextEditorSelections(
+ const QList<CPlusPlus::Document::DiagnosticMessage> &diagnostics,
+ QTextDocument *textDocument);
+
+ static void runParser(QFutureInterface<void> &future,
+ CppTools::BaseEditorDocumentParser *parser,
+ CppTools::WorkingCopy workingCopy);
+
+ // Convenience
+ QString filePath() const { return m_baseTextDocument->filePath(); }
+ unsigned revision() const { return static_cast<unsigned>(textDocument()->revision()); }
+ QTextDocument *textDocument() const { return m_baseTextDocument->document(); }
+
+private:
+ TextEditor::BaseTextDocument *m_baseTextDocument;
+};
+
+} // namespace CppTools
+
+#endif // BASEEDITORDOCUMENTPROCESSOR_H
+
diff --git a/src/plugins/cpptools/builtineditordocumentparser.cpp b/src/plugins/cpptools/builtineditordocumentparser.cpp
index a52659d4c6..526664dc1e 100644
--- a/src/plugins/cpptools/builtineditordocumentparser.cpp
+++ b/src/plugins/cpptools/builtineditordocumentparser.cpp
@@ -29,6 +29,7 @@
#include "builtineditordocumentparser.h"
#include "cppsourceprocessor.h"
+#include "editordocumenthandle.h"
#include <utils/qtcassert.h>
@@ -221,8 +222,15 @@ void BuiltinEditorDocumentParser::setReleaseSourceAndAST(bool onoff)
m_releaseSourceAndAST = onoff;
}
+BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &filePath)
+{
+ if (BaseEditorDocumentParser *b = BaseEditorDocumentParser::get(filePath))
+ return qobject_cast<BuiltinEditorDocumentParser *>(b);
+ return 0;
+}
+
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<QString> *toRemove,
- const QString &fileName) const
+ const QString &fileName) const
{
toRemove->insert(fileName);
if (fileName != filePath()) {
@@ -230,4 +238,3 @@ void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<QString> *toRemove
toRemove->unite(QSet<QString>::fromList(deps));
}
}
-
diff --git a/src/plugins/cpptools/builtineditordocumentparser.h b/src/plugins/cpptools/builtineditordocumentparser.h
index b52e6596db..c7993c6a6b 100644
--- a/src/plugins/cpptools/builtineditordocumentparser.h
+++ b/src/plugins/cpptools/builtineditordocumentparser.h
@@ -45,8 +45,7 @@ namespace CppTools {
class CPPTOOLS_EXPORT BuiltinEditorDocumentParser : public BaseEditorDocumentParser
{
-public:
- typedef QSharedPointer<BuiltinEditorDocumentParser> Ptr;
+ Q_OBJECT
public:
BuiltinEditorDocumentParser(const QString &filePath);
@@ -60,6 +59,9 @@ public:
void setReleaseSourceAndAST(bool onoff);
+public:
+ static BuiltinEditorDocumentParser *get(const QString &filePath);
+
private:
void addFileAndDependencies(QSet<QString> *toRemove, const QString &fileName) const;
diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
new file mode 100644
index 0000000000..cd50c86609
--- /dev/null
+++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "builtineditordocumentprocessor.h"
+
+#include "cppchecksymbols.h"
+#include "cppcodemodelsettings.h"
+#include "cppmodelmanager.h"
+#include "cpptoolsplugin.h"
+#include "cpptoolsreuse.h"
+#include "cppworkingcopy.h"
+
+#include <texteditor/basetexteditor.h>
+#include <texteditor/convenience.h>
+
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/SimpleLexer.h>
+
+#include <utils/QtConcurrentTools>
+#include <utils/qtcassert.h>
+
+enum { debug = 0 };
+
+namespace {
+
+CppTools::Internal::CppModelManager *cmm()
+{
+ return CppTools::Internal::CppModelManager::instance();
+}
+
+QFuture<TextEditor::HighlightingResult> runHighlighter(const CPlusPlus::Document::Ptr &doc,
+ const CPlusPlus::Snapshot &snapshot,
+ QTextDocument *textDocument)
+{
+ QFuture<TextEditor::HighlightingResult> failed;
+ QTC_ASSERT(doc, return failed);
+ QTC_ASSERT(doc->translationUnit(), return failed);
+ QTC_ASSERT(doc->translationUnit()->ast(), return failed);
+ QTC_ASSERT(textDocument, return failed);
+
+ using namespace CPlusPlus;
+ using namespace CppTools;
+ typedef TextEditor::HighlightingResult Result;
+ QList<Result> macroUses;
+
+ using TextEditor::Convenience::convertPosition;
+
+ // Get macro definitions
+ foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) {
+ int line, column;
+ convertPosition(textDocument, macro.utf16CharOffset(), &line, &column);
+
+ ++column; //Highlighting starts at (column-1) --> compensate here
+ Result use(line, column, macro.nameToQString().size(), SemanticHighlighter::MacroUse);
+ macroUses.append(use);
+ }
+
+ // Get macro uses
+ foreach (const Document::MacroUse &macro, doc->macroUses()) {
+ const QString name = macro.macro().nameToQString();
+
+ //Filter out QtKeywords
+ if (isQtKeyword(QStringRef(&name)))
+ continue;
+
+ // Filter out C++ keywords
+ // FIXME: Check default values or get from document.
+ LanguageFeatures features;
+ features.cxx11Enabled = true;
+ features.c99Enabled = true;
+
+ SimpleLexer tokenize;
+ tokenize.setLanguageFeatures(features);
+
+ const QList<Token> tokens = tokenize(name);
+ if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword()))
+ continue;
+
+ int line, column;
+ convertPosition(textDocument, macro.utf16charsBegin(), &line, &column);
+ ++column; //Highlighting starts at (column-1) --> compensate here
+ Result use(line, column, name.size(), SemanticHighlighter::MacroUse);
+ macroUses.append(use);
+ }
+
+ LookupContext context(doc, snapshot);
+ return CheckSymbols::go(doc, context, macroUses);
+}
+
+QList<TextEditor::BlockRange> toTextEditorBlocks(
+ const QList<CPlusPlus::Document::Block> &skippedBlocks)
+{
+ QList<TextEditor::BlockRange> result;
+ result.reserve(skippedBlocks.size());
+ foreach (const CPlusPlus::Document::Block &block, skippedBlocks)
+ result.append(TextEditor::BlockRange(block.utf16charsBegin(), block.utf16charsEnd()));
+ return result;
+}
+
+} // anonymous namespace
+
+namespace CppTools {
+
+BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
+ TextEditor::BaseTextDocument *document,
+ bool enableSemanticHighlighter)
+ : BaseEditorDocumentProcessor(document)
+ , m_parser(new BuiltinEditorDocumentParser(document->filePath()))
+ , m_semanticInfoUpdater(m_parser.data())
+ , m_semanticHighlighter(enableSemanticHighlighter
+ ? new CppTools::SemanticHighlighter(document)
+ : 0)
+{
+ QSharedPointer<Internal::CppCodeModelSettings> cms
+ = Internal::CppToolsPlugin::instance()->codeModelSettings();
+ m_parser->setUsePrecompiledHeaders(
+ cms->pchUsage() != Internal::CppCodeModelSettings::PchUse_None);
+
+ if (m_semanticHighlighter) {
+ m_semanticHighlighter->setHighlightingRunner(
+ [this]() -> QFuture<TextEditor::HighlightingResult> {
+ const SemanticInfo semanticInfo = m_semanticInfoUpdater.semanticInfo();
+ return runHighlighter(semanticInfo.doc, semanticInfo.snapshot,
+ baseTextDocument()->document());
+ });
+ }
+
+ connect(cmm(), &Internal::CppModelManager::documentUpdated,
+ this, &BuiltinEditorDocumentProcessor::onDocumentUpdated);
+ connect(&m_semanticInfoUpdater, &SemanticInfoUpdater::updated,
+ this, &BuiltinEditorDocumentProcessor::onSemanticInfoUpdated);
+}
+
+BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor()
+{
+ m_parserFuture.cancel();
+ m_parserFuture.waitForFinished();
+}
+
+void BuiltinEditorDocumentProcessor::run()
+{
+ m_parserFuture = QtConcurrent::run(&runParser, parser(), cmm()->workingCopy());
+}
+
+BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser()
+{
+ return m_parser.data();
+}
+
+void BuiltinEditorDocumentProcessor::semanticRehighlight(bool force)
+{
+ const auto source = createSemanticInfoSource(force);
+ m_semanticInfoUpdater.updateDetached(source);
+}
+
+SemanticInfo BuiltinEditorDocumentProcessor::recalculateSemanticInfo()
+{
+ const auto source = createSemanticInfoSource(false);
+ return m_semanticInfoUpdater.update(source);
+}
+
+bool BuiltinEditorDocumentProcessor::isParserRunning() const
+{
+ return m_parserFuture.isRunning();
+}
+
+BuiltinEditorDocumentProcessor *BuiltinEditorDocumentProcessor::get(const QString &filePath)
+{
+ if (BaseEditorDocumentProcessor *b = BaseEditorDocumentProcessor::get(filePath))
+ return qobject_cast<BuiltinEditorDocumentProcessor *>(b);
+ return 0;
+}
+
+void BuiltinEditorDocumentProcessor::onDocumentUpdated(CPlusPlus::Document::Ptr document)
+{
+ if (document.isNull())
+ return;
+
+ if (document->fileName() != filePath())
+ return; // some other document got updated
+
+ if (document->editorRevision() != revision())
+ return; // outdated content, wait for a new document to be parsed
+
+ if (debug) {
+ qDebug() << "BuiltinEditorDocumentProcessor: document parsed" << document->fileName()
+ << document->editorRevision();
+ }
+
+ // Emit ifdefed out blocks
+ const auto ifdefoutBlocks = toTextEditorBlocks(document->skippedBlocks());
+ emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks);
+
+ // Emit code warnings
+ auto codeWarnings = toTextEditorSelections(document->diagnosticMessages(), textDocument());
+ emit codeWarningsUpdated(revision(), codeWarnings);
+
+ emit cppDocumentUpdated(document);
+
+ const auto source = createSemanticInfoSource(false);
+ m_semanticInfoUpdater.updateDetached(source);
+}
+
+void BuiltinEditorDocumentProcessor::onSemanticInfoUpdated(const SemanticInfo semanticInfo)
+{
+ if (debug) {
+ qDebug() << "BuiltinEditorDocumentProcessor: semantic info updated"
+ << semanticInfo.doc->fileName() << semanticInfo.revision << semanticInfo.complete;
+ }
+
+ emit semanticInfoUpdated(semanticInfo);
+
+ if (m_semanticHighlighter)
+ m_semanticHighlighter->run();
+}
+
+SemanticInfo::Source BuiltinEditorDocumentProcessor::createSemanticInfoSource(bool force) const
+{
+ const WorkingCopy workingCopy = cmm()->workingCopy();
+ const QString path = filePath();
+ return SemanticInfo::Source(path,
+ workingCopy.source(path),
+ workingCopy.revision(path),
+ force);
+}
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h
new file mode 100644
index 0000000000..402d5720ce
--- /dev/null
+++ b/src/plugins/cpptools/builtineditordocumentprocessor.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BUILTINEDITORDOCUMENTPROCESSOR_H
+#define BUILTINEDITORDOCUMENTPROCESSOR_H
+
+#include "baseeditordocumentprocessor.h"
+#include "builtineditordocumentparser.h"
+#include "cppsemanticinfoupdater.h"
+#include "cpptools_global.h"
+#include "semantichighlighter.h"
+
+#include <utils/qtcoverride.h>
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor
+{
+ Q_OBJECT
+ BuiltinEditorDocumentProcessor();
+
+public:
+ BuiltinEditorDocumentProcessor(TextEditor::BaseTextDocument *document,
+ bool enableSemanticHighlighter = true);
+ ~BuiltinEditorDocumentProcessor();
+
+ // BaseEditorDocumentProcessor interface
+ void run() QTC_OVERRIDE;
+ void semanticRehighlight(bool force) QTC_OVERRIDE;
+ CppTools::SemanticInfo recalculateSemanticInfo() QTC_OVERRIDE;
+ BaseEditorDocumentParser *parser() QTC_OVERRIDE;
+ bool isParserRunning() const QTC_OVERRIDE;
+
+public:
+ static BuiltinEditorDocumentProcessor *get(const QString &filePath);
+
+private slots:
+ void onDocumentUpdated(CPlusPlus::Document::Ptr document);
+ void onSemanticInfoUpdated(const CppTools::SemanticInfo semanticInfo);
+
+private:
+ SemanticInfo::Source createSemanticInfoSource(bool force) const;
+
+private:
+ QScopedPointer<BuiltinEditorDocumentParser> m_parser;
+ QFuture<void> m_parserFuture;
+
+ SemanticInfoUpdater m_semanticInfoUpdater;
+ QScopedPointer<SemanticHighlighter> m_semanticHighlighter;
+};
+
+} // namespace CppTools
+
+#endif // BUILTINEDITORDOCUMENTPROCESSOR_H
diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp
index 4f528d47d6..eb6974c470 100644
--- a/src/plugins/cpptools/cppchecksymbols.cpp
+++ b/src/plugins/cpptools/cppchecksymbols.cpp
@@ -298,6 +298,8 @@ static bool acceptName(NameAST *ast, unsigned *referenceToken)
CheckSymbols::Future CheckSymbols::go(Document::Ptr doc, const LookupContext &context, const QList<CheckSymbols::Result> &macroUses)
{
QTC_ASSERT(doc, return Future());
+ QTC_ASSERT(doc->translationUnit(), return Future());
+ QTC_ASSERT(doc->translationUnit()->ast(), return Future());
return (new CheckSymbols(doc, context, macroUses))->start();
}
@@ -477,7 +479,7 @@ bool CheckSymbols::visit(NamespaceAST *ast)
if (!tok.generated()) {
unsigned line, column;
getTokenStartPosition(ast->identifier_token, &line, &column);
- Result use(line, column, tok.utf16chars(), CppHighlightingSupport::TypeUse);
+ Result use(line, column, tok.utf16chars(), SemanticHighlighter::TypeUse);
addUse(use);
}
}
@@ -492,13 +494,13 @@ bool CheckSymbols::visit(UsingDirectiveAST *)
bool CheckSymbols::visit(EnumeratorAST *ast)
{
- addUse(ast->identifier_token, CppHighlightingSupport::EnumerationUse);
+ addUse(ast->identifier_token, SemanticHighlighter::EnumerationUse);
return true;
}
bool CheckSymbols::visit(DotDesignatorAST *ast)
{
- addUse(ast->identifier_token, CppHighlightingSupport::FieldUse);
+ addUse(ast->identifier_token, SemanticHighlighter::FieldUse);
return true;
}
@@ -513,7 +515,7 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast)
if (funTy->isVirtual()
|| (nameAST->asDestructorName()
&& hasVirtualDestructor(_context.lookupType(funTy->enclosingScope())))) {
- addUse(nameAST, CppHighlightingSupport::VirtualMethodUse);
+ addUse(nameAST, SemanticHighlighter::VirtualMethodUse);
declrIdNameAST = nameAST;
} else if (maybeAddFunction(_context.lookup(decl->name(),
decl->enclosingScope()),
@@ -521,7 +523,7 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast)
declrIdNameAST = nameAST;
// Add a diagnostic message if non-virtual function has override/final marker
- if ((_usages.back().kind != CppHighlightingSupport::VirtualMethodUse)) {
+ if ((_usages.back().kind != SemanticHighlighter::VirtualMethodUse)) {
if (funTy->isOverride())
warning(declrIdNameAST, QCoreApplication::translate(
"CPlusplus::CheckSymbols", "Only virtual functions can be marked 'override'"));
@@ -559,7 +561,7 @@ bool CheckSymbols::visit(ElaboratedTypeSpecifierAST *ast)
{
accept(ast->attribute_list);
accept(ast->name);
- addUse(ast->name, CppHighlightingSupport::TypeUse);
+ addUse(ast->name, SemanticHighlighter::TypeUse);
return false;
}
@@ -796,14 +798,14 @@ void CheckSymbols::checkName(NameAST *ast, Scope *scope)
if (klass) {
if (hasVirtualDestructor(_context.lookupType(klass))) {
- addUse(ast, CppHighlightingSupport::VirtualMethodUse);
+ addUse(ast, SemanticHighlighter::VirtualMethodUse);
} else {
bool added = false;
if (highlightCtorDtorAsType && maybeType(ast->name))
added = maybeAddTypeOrStatic(_context.lookup(ast->name, klass), ast);
if (!added)
- addUse(ast, CppHighlightingSupport::FunctionUse);
+ addUse(ast, SemanticHighlighter::FunctionUse);
}
}
} else if (maybeType(ast->name) || maybeStatic(ast->name)) {
@@ -853,14 +855,14 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
if (binding && ast->unqualified_name) {
if (ast->unqualified_name->asDestructorName() != 0) {
if (hasVirtualDestructor(binding)) {
- addUse(ast->unqualified_name, CppHighlightingSupport::VirtualMethodUse);
+ addUse(ast->unqualified_name, SemanticHighlighter::VirtualMethodUse);
} else {
bool added = false;
if (highlightCtorDtorAsType && maybeType(ast->name))
added = maybeAddTypeOrStatic(binding->find(ast->unqualified_name->name),
ast->unqualified_name);
if (!added)
- addUse(ast->unqualified_name, CppHighlightingSupport::FunctionUse);
+ addUse(ast->unqualified_name, SemanticHighlighter::FunctionUse);
}
} else {
QList<LookupItem> items = binding->find(ast->unqualified_name->name);
@@ -904,7 +906,7 @@ ClassOrNamespace *CheckSymbols::checkNestedName(QualifiedNameAST *ast)
if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
if (TemplateIdAST *template_id = class_or_namespace_name->asTemplateId()) {
if (template_id->template_token) {
- addUse(template_id, CppHighlightingSupport::TypeUse);
+ addUse(template_id, SemanticHighlighter::TypeUse);
binding = 0; // there's no way we can find a binding.
}
@@ -928,7 +930,7 @@ ClassOrNamespace *CheckSymbols::checkNestedName(QualifiedNameAST *ast)
bool CheckSymbols::visit(TypenameTypeParameterAST *ast)
{
- addUse(ast->name, CppHighlightingSupport::TypeUse);
+ addUse(ast->name, SemanticHighlighter::TypeUse);
accept(ast->type_id);
return false;
}
@@ -936,7 +938,7 @@ bool CheckSymbols::visit(TypenameTypeParameterAST *ast)
bool CheckSymbols::visit(TemplateTypeParameterAST *ast)
{
accept(ast->template_parameter_list);
- addUse(ast->name, CppHighlightingSupport::TypeUse);
+ addUse(ast->name, SemanticHighlighter::TypeUse);
accept(ast->type_id);
return false;
}
@@ -988,7 +990,7 @@ bool CheckSymbols::visit(MemInitializerAST *ast)
bool CheckSymbols::visit(GotoStatementAST *ast)
{
if (ast->identifier_token)
- addUse(ast->identifier_token, CppHighlightingSupport::LabelUse);
+ addUse(ast->identifier_token, SemanticHighlighter::LabelUse);
return false;
}
@@ -996,7 +998,7 @@ bool CheckSymbols::visit(GotoStatementAST *ast)
bool CheckSymbols::visit(LabeledStatementAST *ast)
{
if (ast->label_token && !tokenAt(ast->label_token).isKeyword())
- addUse(ast->label_token, CppHighlightingSupport::LabelUse);
+ addUse(ast->label_token, SemanticHighlighter::LabelUse);
accept(ast->statement);
return false;
@@ -1017,7 +1019,7 @@ bool CheckSymbols::visit(SimpleSpecifierAST *ast)
if (id.equalTo(_doc->control()->cpp11Override())
|| id.equalTo(_doc->control()->cpp11Final()))
{
- addUse(ast->specifier_token, CppHighlightingSupport::PseudoKeywordUse);
+ addUse(ast->specifier_token, SemanticHighlighter::PseudoKeywordUse);
}
}
}
@@ -1028,7 +1030,7 @@ bool CheckSymbols::visit(SimpleSpecifierAST *ast)
bool CheckSymbols::visit(ClassSpecifierAST *ast)
{
if (ast->final_token)
- addUse(ast->final_token, CppHighlightingSupport::PseudoKeywordUse);
+ addUse(ast->final_token, SemanticHighlighter::PseudoKeywordUse);
return true;
}
@@ -1053,7 +1055,7 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast)
if (fun->isVirtual()
|| (declId->asDestructorName()
&& hasVirtualDestructor(_context.lookupType(fun->enclosingScope())))) {
- addUse(declId, CppHighlightingSupport::VirtualMethodUse);
+ addUse(declId, SemanticHighlighter::VirtualMethodUse);
} else if (!maybeAddFunction(_context.lookup(fun->name(),
fun->enclosingScope()),
declId, fun->argumentCount())) {
@@ -1161,7 +1163,7 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
unsigned line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
- const Result use(line, column, length, CppHighlightingSupport::TypeUse);
+ const Result use(line, column, length, SemanticHighlighter::TypeUse);
addUse(use);
}
@@ -1203,12 +1205,12 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
- Kind kind = CppHighlightingSupport::TypeUse;
+ Kind kind = SemanticHighlighter::TypeUse;
if (c->enclosingEnum() != 0)
- kind = CppHighlightingSupport::EnumerationUse;
+ kind = SemanticHighlighter::EnumerationUse;
else if (c->isStatic())
// treat static variable as a field(highlighting)
- kind = CppHighlightingSupport::FieldUse;
+ kind = SemanticHighlighter::FieldUse;
const Result use(line, column, length, kind);
addUse(use);
@@ -1245,7 +1247,7 @@ bool CheckSymbols::maybeAddField(const QList<LookupItem> &candidates, NameAST *a
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
- const Result use(line, column, length, CppHighlightingSupport::FieldUse);
+ const Result use(line, column, length, SemanticHighlighter::FieldUse);
addUse(use);
return true;
@@ -1270,7 +1272,7 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
return false;
enum { Match_None, Match_TooManyArgs, Match_TooFewArgs, Match_Ok } matchType = Match_None;
- Kind kind = CppHighlightingSupport::FunctionUse;
+ Kind kind = SemanticHighlighter::FunctionUse;
foreach (const LookupItem &r, candidates) {
Symbol *c = r.declaration();
@@ -1297,21 +1299,21 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
if (argumentCount < funTy->minimumArgumentCount()) {
if (matchType != Match_Ok) {
- kind = funTy->isVirtual() ? CppHighlightingSupport::VirtualMethodUse : CppHighlightingSupport::FunctionUse;
+ kind = funTy->isVirtual() ? SemanticHighlighter::VirtualMethodUse : SemanticHighlighter::FunctionUse;
matchType = Match_TooFewArgs;
}
} else if (argumentCount > funTy->argumentCount() && !funTy->isVariadic()) {
if (matchType != Match_Ok) {
matchType = Match_TooManyArgs;
- kind = funTy->isVirtual() ? CppHighlightingSupport::VirtualMethodUse : CppHighlightingSupport::FunctionUse;
+ kind = funTy->isVirtual() ? SemanticHighlighter::VirtualMethodUse : SemanticHighlighter::FunctionUse;
}
} else if (!funTy->isVirtual()) {
matchType = Match_Ok;
- kind = CppHighlightingSupport::FunctionUse;
+ kind = SemanticHighlighter::FunctionUse;
//continue, to check if there is a matching candidate which is virtual
} else {
matchType = Match_Ok;
- kind = CppHighlightingSupport::VirtualMethodUse;
+ kind = SemanticHighlighter::VirtualMethodUse;
break;
}
}
@@ -1321,7 +1323,7 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
if (highlightCtorDtorAsType
&& (isConstructor || isDestructor)
&& maybeType(ast->name)
- && kind == CppHighlightingSupport::FunctionUse) {
+ && kind == SemanticHighlighter::FunctionUse) {
return false;
}
diff --git a/src/plugins/cpptools/cppchecksymbols.h b/src/plugins/cpptools/cppchecksymbols.h
index 5ccd2fe4cf..6c61275b6e 100644
--- a/src/plugins/cpptools/cppchecksymbols.h
+++ b/src/plugins/cpptools/cppchecksymbols.h
@@ -31,8 +31,8 @@
#define CPLUSPLUSCHECKSYMBOLS_H
#include "cpptools_global.h"
-#include "cpphighlightingsupport.h"
#include "cppsemanticinfo.h"
+#include "semantichighlighter.h"
#include <cplusplus/TypeOfExpression.h>
@@ -51,7 +51,7 @@ public:
virtual ~CheckSymbols();
typedef TextEditor::HighlightingResult Result;
- typedef CppHighlightingSupport::Kind Kind;
+ typedef SemanticHighlighter::Kind Kind;
virtual void run();
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp
index 19d262ae69..679e141b75 100644
--- a/src/plugins/cpptools/cppcompletion_test.cpp
+++ b/src/plugins/cpptools/cppcompletion_test.cpp
@@ -102,8 +102,8 @@ public:
{
QStringList completions;
CppCompletionAssistInterface *ai
- = new CppCompletionAssistInterface(m_editorWidget->document(), m_position,
- m_editorWidget->textDocument()->filePath(),
+ = new CppCompletionAssistInterface(m_editorWidget->textDocument()->filePath(),
+ m_editorWidget->document(), m_position,
ExplicitlyInvoked, m_snapshot,
ProjectPart::HeaderPaths());
CppCompletionAssistProcessor processor;
diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index 90fce585f8..a4866da361 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -34,8 +34,8 @@
#include "cppmodelmanager.h"
#include "cppmodelmanagerinterface.h"
#include "cpptoolsconstants.h"
-#include "cpptoolseditorsupport.h"
#include "cpptoolsreuse.h"
+#include "editordocumenthandle.h"
#include <coreplugin/icore.h>
#include <cppeditor/cppeditorconstants.h>
@@ -421,15 +421,14 @@ IAssistProcessor *InternalCompletionAssistProvider::createProcessor() const
}
TextEditor::IAssistInterface *InternalCompletionAssistProvider::createAssistInterface(
- ProjectExplorer::Project *project, BaseTextEditor *editor, QTextDocument *document,
+ ProjectExplorer::Project *project, const QString &filePath, QTextDocument *document,
bool isObjCEnabled, int position, TextEditor::AssistReason reason) const
{
Q_UNUSED(project);
- QTC_ASSERT(editor, return 0);
QTC_ASSERT(document, return 0);
CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
- return new CppTools::Internal::CppCompletionAssistInterface(editor, document, isObjCEnabled,
+ return new CppTools::Internal::CppCompletionAssistInterface(filePath, document, isObjCEnabled,
position, reason,
modelManager->workingCopy());
}
@@ -1957,12 +1956,9 @@ void CppCompletionAssistInterface::getCppSpecifics() const
return;
m_gotCppSpecifics = true;
- CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
- if (CppEditorSupport *supp = modelManager->cppEditorSupport(m_editor)) {
- if (BuiltinEditorDocumentParser::Ptr parser = supp->documentParser()) {
- parser->update(m_workingCopy);
- m_snapshot = parser->snapshot();
- m_headerPaths = parser->headerPaths();
- }
+ if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
+ parser->update(m_workingCopy);
+ m_snapshot = parser->snapshot();
+ m_headerPaths = parser->headerPaths();
}
}
diff --git a/src/plugins/cpptools/cppcompletionassist.h b/src/plugins/cpptools/cppcompletionassist.h
index a63ca76ad4..7fa602b4a5 100644
--- a/src/plugins/cpptools/cppcompletionassist.h
+++ b/src/plugins/cpptools/cppcompletionassist.h
@@ -96,7 +96,7 @@ public:
TextEditor::IAssistProcessor *createProcessor() const QTC_OVERRIDE;
TextEditor::IAssistInterface *createAssistInterface(ProjectExplorer::Project *project,
- TextEditor::BaseTextEditor *editor,
+ const QString &filePath,
QTextDocument *document,
bool isObjCEnabled,
int position,
@@ -173,28 +173,25 @@ private:
class CppCompletionAssistInterface : public TextEditor::DefaultAssistInterface
{
public:
- CppCompletionAssistInterface(TextEditor::BaseTextEditor *editor,
+ CppCompletionAssistInterface(const QString &filePath,
QTextDocument *textDocument,
bool isObjCEnabled,
int position,
TextEditor::AssistReason reason,
const WorkingCopy &workingCopy)
- : TextEditor::DefaultAssistInterface(textDocument, position, editor->document()->filePath(),
- reason)
- , m_editor(editor)
+ : TextEditor::DefaultAssistInterface(textDocument, position, filePath, reason)
, m_isObjCEnabled(isObjCEnabled)
, m_gotCppSpecifics(false)
, m_workingCopy(workingCopy)
{}
- CppCompletionAssistInterface(QTextDocument *textDocument,
+ CppCompletionAssistInterface(const QString &filePath,
+ QTextDocument *textDocument,
int position,
- const QString &fileName,
TextEditor::AssistReason reason,
const CPlusPlus::Snapshot &snapshot,
const ProjectPart::HeaderPaths &headerPaths)
- : TextEditor::DefaultAssistInterface(textDocument, position, fileName, reason)
- , m_editor(0)
+ : TextEditor::DefaultAssistInterface(textDocument, position, filePath, reason)
, m_isObjCEnabled(false)
, m_gotCppSpecifics(true)
, m_snapshot(snapshot)
@@ -210,7 +207,6 @@ public:
private:
void getCppSpecifics() const;
- TextEditor::BaseTextEditor *m_editor;
mutable bool m_isObjCEnabled;
mutable bool m_gotCppSpecifics;
WorkingCopy m_workingCopy;
diff --git a/src/plugins/cpptools/cppcompletionassistprovider.h b/src/plugins/cpptools/cppcompletionassistprovider.h
index 8873fd3518..f60c5bb102 100644
--- a/src/plugins/cpptools/cppcompletionassistprovider.h
+++ b/src/plugins/cpptools/cppcompletionassistprovider.h
@@ -61,7 +61,7 @@ public:
bool isContinuationChar(const QChar &c) const QTC_OVERRIDE;
virtual TextEditor::IAssistInterface *createAssistInterface(
- ProjectExplorer::Project *project, TextEditor::BaseTextEditor *editor,
+ ProjectExplorer::Project *project, const QString &filePath,
QTextDocument *document, bool isObjCEnabled, int position,
TextEditor::AssistReason reason) const = 0;
diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp
deleted file mode 100644
index 852868cc77..0000000000
--- a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "cpphighlightingsupportinternal.h"
-
-#include "cppchecksymbols.h"
-#include "cpptoolsreuse.h"
-
-#include <texteditor/basetextdocument.h>
-#include <texteditor/convenience.h>
-
-#include <cplusplus/SimpleLexer.h>
-
-using namespace CPlusPlus;
-using namespace CppTools;
-using namespace CppTools::Internal;
-
-CppHighlightingSupportInternal::CppHighlightingSupportInternal(
- TextEditor::BaseTextDocument *baseTextDocument)
- : CppHighlightingSupport(baseTextDocument)
-{
-}
-
-CppHighlightingSupportInternal::~CppHighlightingSupportInternal()
-{
-}
-
-QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highlightingFuture(
- const Document::Ptr &doc,
- const Snapshot &snapshot) const
-{
- typedef TextEditor::HighlightingResult Result;
- QList<Result> macroUses;
-
- QTextDocument *textDocument = baseTextDocument()->document();
- using TextEditor::Convenience::convertPosition;
-
- // Get macro definitions
- foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) {
- int line, column;
- convertPosition(textDocument, macro.utf16CharOffset(), &line, &column);
-
- ++column; //Highlighting starts at (column-1) --> compensate here
- Result use(line, column, macro.nameToQString().size(), MacroUse);
- macroUses.append(use);
- }
-
- // Get macro uses
- foreach (const Document::MacroUse &macro, doc->macroUses()) {
- const QString name = macro.macro().nameToQString();
-
- //Filter out QtKeywords
- if (isQtKeyword(QStringRef(&name)))
- continue;
-
- // Filter out C++ keywords
- // FIXME: Check default values or get from document.
- LanguageFeatures features;
- features.cxx11Enabled = true;
- features.c99Enabled = true;
-
- SimpleLexer tokenize;
- tokenize.setLanguageFeatures(features);
-
- const QList<Token> tokens = tokenize(name);
- if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword()))
- continue;
-
- int line, column;
- convertPosition(textDocument, macro.utf16charsBegin(), &line, &column);
- ++column; //Highlighting starts at (column-1) --> compensate here
- Result use(line, column, name.size(), MacroUse);
- macroUses.append(use);
- }
-
- LookupContext context(doc, snapshot);
- return CheckSymbols::go(doc, context, macroUses);
-}
diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp
index e491589fc6..f68fc9bdc7 100644
--- a/src/plugins/cpptools/cpplocalsymbols.cpp
+++ b/src/plugins/cpptools/cpplocalsymbols.cpp
@@ -27,8 +27,8 @@
**
****************************************************************************/
-#include "cpphighlightingsupport.h"
#include "cpplocalsymbols.h"
+#include "semantichighlighter.h"
#include "cppsemanticinfo.h"
@@ -86,7 +86,7 @@ protected:
getPosition(token.utf16charsBegin(), &line, &column);
localUses[member].append(
HighlightingResult(line, column, token.utf16chars(),
- CppHighlightingSupport::LocalUse));
+ SemanticHighlighter::LocalUse));
}
}
}
@@ -110,7 +110,7 @@ protected:
getTokenStartPosition(simpleName->identifier_token, &line, &column);
localUses[member].append(
HighlightingResult(line, column, token.utf16chars(),
- CppHighlightingSupport::LocalUse));
+ SemanticHighlighter::LocalUse));
return false;
}
}
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 83c642b5b9..796a052b95 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -34,13 +34,12 @@
#include "cppcodemodelinspectordumper.h"
#include "cppcodemodelsettings.h"
#include "cppfindreferences.h"
-#include "cpphighlightingsupport.h"
#include "cppindexingsupport.h"
#include "cppmodelmanagersupportinternal.h"
#include "cppsourceprocessor.h"
#include "cpptoolsconstants.h"
-#include "cpptoolseditorsupport.h"
#include "cpptoolsplugin.h"
+#include "editordocumenthandle.h"
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
@@ -399,47 +398,42 @@ void CppModelManager::removeExtraEditorSupport(AbstractEditorSupport *editorSupp
m_extraEditorSupports.remove(editorSupport);
}
-/// \brief Returns the \c CppEditorSupport for the given text editor. It will
-/// create one when none exists yet.
-CppEditorSupport *CppModelManager::cppEditorSupport(TextEditor::BaseTextEditor *textEditor)
+EditorDocumentHandle *CppModelManager::editorDocument(const QString &filePath)
{
- Q_ASSERT(textEditor);
+ QTC_ASSERT(!filePath.isEmpty(), return 0);
- QMutexLocker locker(&m_cppEditorSupportsMutex);
-
- CppEditorSupport *editorSupport = m_cppEditorSupports.value(textEditor, 0);
- if (!editorSupport && isCppEditor(textEditor)) {
- editorSupport = new CppEditorSupport(this, textEditor);
- m_cppEditorSupports.insert(textEditor, editorSupport);
- }
- return editorSupport;
+ QMutexLocker locker(&m_cppEditorsMutex);
+ return m_cppEditors.value(filePath, 0);
}
-/// \brief Removes the CppEditorSupport for the closed editor.
-void CppModelManager::deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor)
+void CppModelManager::registerEditorDocument(EditorDocumentHandle *editorDocument)
{
- static short numberOfClosedEditors = 0;
+ QTC_ASSERT(editorDocument, return);
+ const QString filePath = editorDocument->filePath();
+ QTC_ASSERT(!filePath.isEmpty(), return);
- QTC_ASSERT(textEditor, return);
+ QMutexLocker locker(&m_cppEditorsMutex);
+ QTC_ASSERT(m_cppEditors.value(filePath, 0) == 0, return);
+ m_cppEditors.insert(filePath, editorDocument);
+}
- if (!isCppEditor(textEditor))
- return;
+void CppModelManager::unregisterEditorDocument(const QString &filePath)
+{
+ QTC_ASSERT(!filePath.isEmpty(), return);
- CppEditorSupport *editorSupport;
- int numberOfOpenEditors = 0;
+ static short closedCppDocuments = 0;
+ int openCppDocuments = 0;
- { // Only lock the operations on m_cppEditorSupport
- QMutexLocker locker(&m_cppEditorSupportsMutex);
- editorSupport = m_cppEditorSupports.value(textEditor, 0);
- m_cppEditorSupports.remove(textEditor);
- numberOfOpenEditors = m_cppEditorSupports.size();
+ {
+ QMutexLocker locker(&m_cppEditorsMutex);
+ QTC_ASSERT(m_cppEditors.value(filePath, 0), return);
+ QTC_CHECK(m_cppEditors.remove(filePath) == 1);
+ openCppDocuments = m_cppEditors.size();
}
- delete editorSupport;
-
- ++numberOfClosedEditors;
- if (numberOfOpenEditors == 0 || numberOfClosedEditors == 5) {
- numberOfClosedEditors = 0;
+ ++closedCppDocuments;
+ if (openCppDocuments == 0 || closedCppDocuments == 5) {
+ closedCppDocuments = 0;
delayedGC();
}
}
@@ -483,10 +477,8 @@ WorkingCopy CppModelManager::buildWorkingCopyList()
{
WorkingCopy workingCopy;
- foreach (const CppEditorSupport *editorSupport, cppEditorSupportList()) {
- workingCopy.insert(editorSupport->fileName(), editorSupport->contents(),
- editorSupport->editorRevision());
- }
+ foreach (const EditorDocumentHandle *cppEditor, cppEditors())
+ workingCopy.insert(cppEditor->filePath(), cppEditor->contents(), cppEditor->revision());
QSetIterator<AbstractEditorSupport *> it(m_extraEditorSupports);
while (it.hasNext()) {
@@ -551,10 +543,10 @@ void CppModelManager::removeProjectInfoFilesAndIncludesFromSnapshot(const Projec
}
}
-QList<CppEditorSupport *> CppModelManager::cppEditorSupportList() const
+QList<EditorDocumentHandle *> CppModelManager::cppEditors() const
{
- QMutexLocker locker(&m_cppEditorSupportsMutex);
- return m_cppEditorSupports.values();
+ QMutexLocker locker(&m_cppEditorsMutex);
+ return m_cppEditors.values();
}
/// \brief Remove all given files from the snapshot.
@@ -832,8 +824,8 @@ void CppModelManager::GC()
// Collect files of CppEditorSupport and AbstractEditorSupport.
QStringList filesInEditorSupports;
- foreach (const CppEditorSupport *cppEditorSupport, cppEditorSupportList())
- filesInEditorSupports << cppEditorSupport->fileName();
+ foreach (const EditorDocumentHandle *cppEditor, cppEditors())
+ filesInEditorSupports << cppEditor->filePath();
QSetIterator<AbstractEditorSupport *> jt(m_extraEditorSupports);
while (jt.hasNext()) {
@@ -909,13 +901,13 @@ CppCompletionAssistProvider *CppModelManager::completionAssistProvider(const QSt
return cms->completionAssistProvider();
}
-CppHighlightingSupport *CppModelManager::highlightingSupport(
+BaseEditorDocumentProcessor *CppModelManager::editorDocumentProcessor(
TextEditor::BaseTextDocument *baseTextDocument) const
{
QTC_ASSERT(baseTextDocument, return 0);
ModelManagerSupport *cms = modelManagerSupportForMimeType(baseTextDocument->mimeType());
QTC_ASSERT(cms, return 0);
- return cms->highlightingSupport(baseTextDocument);
+ return cms->editorDocumentProcessor(baseTextDocument);
}
void CppModelManager::setIndexingSupport(CppIndexingSupport *indexingSupport)
@@ -934,27 +926,3 @@ void CppModelManager::enableGarbageCollector(bool enable)
m_delayedGcTimer->stop();
m_enableGC = enable;
}
-
-bool CppModelManager::setExtraDiagnostics(const QString &fileName,
- const QString &kind,
- const QList<Document::DiagnosticMessage> &diagnostics)
-{
- foreach (CppEditorSupport *editorSupport, cppEditorSupportList()) {
- if (editorSupport->fileName() == fileName) {
- editorSupport->setExtraDiagnostics(kind, diagnostics);
- return true;
- }
- }
- return false;
-}
-
-void CppModelManager::setIfdefedOutBlocks(const QString &fileName,
- const QList<TextEditor::BlockRange> &ifdeffedOutBlocks)
-{
- foreach (CppEditorSupport *editorSupport, cppEditorSupportList()) {
- if (editorSupport->fileName() == fileName) {
- editorSupport->setIfdefedOutBlocks(ifdeffedOutBlocks);
- break;
- }
- }
-}
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index c029bcb67e..490c9f803b 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -44,8 +44,6 @@ namespace TextEditor { class BaseTextEditorWidget; }
namespace CppTools {
-class CppEditorSupport;
-
namespace Internal {
class CppFindReferences;
@@ -94,8 +92,10 @@ public:
virtual void addExtraEditorSupport(AbstractEditorSupport *editorSupport);
virtual void removeExtraEditorSupport(AbstractEditorSupport *editorSupport);
- virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *textEditor);
- virtual void deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor);
+
+ virtual EditorDocumentHandle *editorDocument(const QString &filePath);
+ virtual void registerEditorDocument(EditorDocumentHandle *editorDocument);
+ virtual void unregisterEditorDocument(const QString &filePath);
virtual QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context);
@@ -106,18 +106,13 @@ public:
virtual void findMacroUsages(const CPlusPlus::Macro &macro);
virtual void renameMacroUsages(const CPlusPlus::Macro &macro, const QString &replacement);
- virtual bool setExtraDiagnostics(const QString &fileName, const QString &key,
- const QList<Document::DiagnosticMessage> &diagnostics);
- virtual void setIfdefedOutBlocks(const QString &fileName,
- const QList<TextEditor::BlockRange> &ifdeffedOutBlocks);
-
- void finishedRefreshingSourceFiles(const QStringList &files);
+ virtual void finishedRefreshingSourceFiles(const QStringList &files);
virtual void addModelManagerSupport(ModelManagerSupport *modelManagerSupport);
virtual ModelManagerSupport *modelManagerSupportForMimeType(const QString &mimeType) const;
virtual CppCompletionAssistProvider *completionAssistProvider(const QString &mimeType) const;
- virtual CppHighlightingSupport *highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument) const;
+ virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument) const;
virtual void setIndexingSupport(CppIndexingSupport *indexingSupport);
virtual CppIndexingSupport *indexingSupport();
@@ -176,7 +171,7 @@ private:
void removeFilesFromSnapshot(const QSet<QString> &removedFiles);
void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo);
- QList<CppEditorSupport *> cppEditorSupportList() const;
+ QList<EditorDocumentHandle *> cppEditors() const;
WorkingCopy buildWorkingCopyList();
@@ -208,8 +203,8 @@ private:
QByteArray m_definedMacros;
// Editor integration
- mutable QMutex m_cppEditorSupportsMutex;
- QMap<TextEditor::BaseTextEditor *, CppEditorSupport *> m_cppEditorSupports;
+ mutable QMutex m_cppEditorsMutex;
+ QMap<QString, EditorDocumentHandle *> m_cppEditors;
QSet<AbstractEditorSupport *> m_extraEditorSupports;
// Completion & highlighting
diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp
index b443f5ba5a..e4bce83d1d 100644
--- a/src/plugins/cpptools/cppmodelmanager_test.cpp
+++ b/src/plugins/cpptools/cppmodelmanager_test.cpp
@@ -27,10 +27,11 @@
**
****************************************************************************/
+#include "builtineditordocumentparser.h"
#include "cppsourceprocessor.h"
-#include "cpptoolseditorsupport.h"
#include "cpptoolsplugin.h"
#include "cpptoolstestcase.h"
+#include "editordocumenthandle.h"
#include "modelmanagertesthelper.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -865,10 +866,10 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
QVERIFY(mm->isCppEditor(editor));
- CppEditorSupport *sup = mm->cppEditorSupport(
- qobject_cast<TextEditor::BaseTextEditor *>(editor));
- while (sup->lastSemanticInfoDocument().isNull())
- QCoreApplication::processEvents();
+// CppEditorSupport *sup = mm->cppEditorSupport(
+// qobject_cast<TextEditor::BaseTextEditor *>(editor));
+// while (sup->lastSemanticInfoDocument().isNull())
+// QCoreApplication::processEvents();
Document::Ptr doc = mm->document(fileName);
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
@@ -942,20 +943,16 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
QVERIFY(mm->isCppEditor(editor));
- CppEditorSupport *sup = mm->cppEditorSupport(
- qobject_cast<TextEditor::BaseTextEditor *>(editor));
- while (sup->lastSemanticInfoDocument().isNull())
- QCoreApplication::processEvents();
-
- sup->documentParser()->setUsePrecompiledHeaders(true);
- sup->documentParser()->update(mm->workingCopy());
+ BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName);
+ parser->setUsePrecompiledHeaders(true);
+ parser->update(mm->workingCopy());
// Check if defines from pch are considered
Document::Ptr document = mm->document(fileName);
QCOMPARE(nameOfFirstDeclaration(document), firstDeclarationName);
// Check if declarations from pch are considered
- CPlusPlus::LookupContext context(document, sup->documentParser()->snapshot());
+ CPlusPlus::LookupContext context(document, parser->snapshot());
const CPlusPlus::Identifier *identifier
= document->control()->identifier(firstClassInPchFile.data());
const QList<CPlusPlus::LookupItem> results = context.lookup(identifier,
@@ -1025,13 +1022,10 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
QVERIFY(mm->isCppEditor(editor));
- CppEditorSupport *sup = mm->cppEditorSupport(
- qobject_cast<TextEditor::BaseTextEditor *>(editor));
- while (sup->lastSemanticInfoDocument().isNull())
- QCoreApplication::processEvents();
-
- sup->documentParser()->setEditorDefines(editorDefines.toUtf8());
- sup->documentParser()->update(mm->workingCopy());
+ const QString filePath = editor->document()->filePath();
+ BaseEditorDocumentParser *parser = BaseEditorDocumentParser::get(filePath);
+ parser->setEditorDefines(editorDefines.toUtf8());
+ parser->update(mm->workingCopy());
Document::Ptr doc = mm->document(main1File);
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h
index 53120715fd..f48950499f 100644
--- a/src/plugins/cpptools/cppmodelmanagerinterface.h
+++ b/src/plugins/cpptools/cppmodelmanagerinterface.h
@@ -52,9 +52,9 @@ namespace Utils { class FileName; }
namespace CppTools {
class AbstractEditorSupport;
+class BaseEditorDocumentProcessor;
class CppCompletionAssistProvider;
-class CppEditorSupport;
-class CppHighlightingSupport;
+class EditorDocumentHandle;
class CppIndexingSupport;
class ModelManagerSupport;
class WorkingCopy;
@@ -95,8 +95,10 @@ public:
virtual void addExtraEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0;
virtual void removeExtraEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0;
- virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *textEditor) = 0;
- virtual void deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor) = 0;
+
+ virtual EditorDocumentHandle *editorDocument(const QString &filePath) = 0;
+ virtual void registerEditorDocument(EditorDocumentHandle *editorDocument) = 0;
+ virtual void unregisterEditorDocument(const QString &filePath) = 0;
virtual QList<int> references(CPlusPlus::Symbol *symbol,
const CPlusPlus::LookupContext &context) = 0;
@@ -108,14 +110,13 @@ public:
virtual void renameMacroUsages(const CPlusPlus::Macro &macro, const QString &replacement = QString()) = 0;
virtual void findMacroUsages(const CPlusPlus::Macro &macro) = 0;
- virtual void setIfdefedOutBlocks(const QString &fileName,
- const QList<TextEditor::BlockRange> &ifdeffedOutBlocks) = 0;
+ virtual void finishedRefreshingSourceFiles(const QStringList &files) = 0;
virtual void addModelManagerSupport(ModelManagerSupport *modelManagerSupport) = 0;
virtual ModelManagerSupport *modelManagerSupportForMimeType(const QString &mimeType) const = 0;
virtual CppCompletionAssistProvider *completionAssistProvider(const QString &mimeType) const = 0;
- virtual CppHighlightingSupport *highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument) const = 0;
+ virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument) const = 0;
virtual void setIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0;
virtual CppIndexingSupport *indexingSupport() = 0;
diff --git a/src/plugins/cpptools/cppmodelmanagersupport.h b/src/plugins/cpptools/cppmodelmanagersupport.h
index 556f34cbf8..423b096415 100644
--- a/src/plugins/cpptools/cppmodelmanagersupport.h
+++ b/src/plugins/cpptools/cppmodelmanagersupport.h
@@ -38,8 +38,8 @@ namespace TextEditor { class BaseTextDocument; }
namespace CppTools {
+class BaseEditorDocumentProcessor;
class CppCompletionAssistProvider;
-class CppHighlightingSupport;
class CPPTOOLS_EXPORT ModelManagerSupport
{
@@ -50,8 +50,8 @@ public:
virtual QString displayName() const = 0;
virtual CppCompletionAssistProvider *completionAssistProvider() = 0;
- virtual CppHighlightingSupport *highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument) = 0;
+ virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument) = 0;
};
} // CppTools namespace
diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
index bf43cf7908..9074a499b2 100644
--- a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
+++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
@@ -28,8 +28,8 @@
****************************************************************************/
#include "cppcompletionassist.h"
-#include "cpphighlightingsupportinternal.h"
#include "cppmodelmanagersupportinternal.h"
+#include "builtineditordocumentprocessor.h"
#include <QCoreApplication>
@@ -56,13 +56,13 @@ QString ModelManagerSupportInternal::displayName() const
"Qt Creator Built-in");
}
-CppCompletionAssistProvider *ModelManagerSupportInternal::completionAssistProvider()
+BaseEditorDocumentProcessor *ModelManagerSupportInternal::editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument)
{
- return m_completionAssistProvider.data();
+ return new BuiltinEditorDocumentProcessor(baseTextDocument);
}
-CppHighlightingSupport *ModelManagerSupportInternal::highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument)
+CppCompletionAssistProvider *ModelManagerSupportInternal::completionAssistProvider()
{
- return new CppHighlightingSupportInternal(baseTextDocument);
+ return m_completionAssistProvider.data();
}
diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.h b/src/plugins/cpptools/cppmodelmanagersupportinternal.h
index a55280af9d..2e9a335ba5 100644
--- a/src/plugins/cpptools/cppmodelmanagersupportinternal.h
+++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.h
@@ -49,8 +49,8 @@ public:
virtual QString displayName() const;
virtual CppCompletionAssistProvider *completionAssistProvider();
- virtual CppHighlightingSupport *highlightingSupport(
- TextEditor::BaseTextDocument *baseTextDocument);
+ virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::BaseTextDocument *baseTextDocument);
private:
QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider;
diff --git a/src/plugins/cpptools/cppsemanticinfo.cpp b/src/plugins/cpptools/cppsemanticinfo.cpp
index 09407681c3..5ab57d0ca1 100644
--- a/src/plugins/cpptools/cppsemanticinfo.cpp
+++ b/src/plugins/cpptools/cppsemanticinfo.cpp
@@ -32,6 +32,6 @@
using namespace CppTools;
SemanticInfo::SemanticInfo()
- : revision(0), forced(false), complete(true)
+ : revision(0), complete(true), localUsesUpdated(false)
{
}
diff --git a/src/plugins/cpptools/cppsemanticinfo.h b/src/plugins/cpptools/cppsemanticinfo.h
index c0968edb3a..4066bfef40 100644
--- a/src/plugins/cpptools/cppsemanticinfo.h
+++ b/src/plugins/cpptools/cppsemanticinfo.h
@@ -45,28 +45,22 @@ class CPPTOOLS_EXPORT SemanticInfo
public:
struct Source
{
- const CPlusPlus::Snapshot snapshot;
const QString fileName;
const QByteArray code;
- const int line;
- const int column;
const unsigned revision;
const bool force;
- Source()
- : line(0), column(0), revision(0), force(false)
- { }
+ Source() : revision(0), force(false) {}
- Source(const CPlusPlus::Snapshot &snapshot,
- const QString &fileName,
+ Source(const QString &fileName,
const QByteArray &code,
- int line, int column,
unsigned revision,
bool force)
- : snapshot(snapshot), fileName(fileName),
- code(code), line(line), column(column),
- revision(revision), force(force)
- { }
+ : fileName(fileName)
+ , code(code)
+ , revision(revision)
+ , force(force)
+ {}
};
public:
@@ -78,10 +72,12 @@ public:
SemanticInfo();
unsigned revision;
- bool forced;
bool complete;
CPlusPlus::Snapshot snapshot;
CPlusPlus::Document::Ptr doc;
+
+ // Widget specific (e.g. related to cursor position)
+ bool localUsesUpdated;
LocalUseMap localUses;
};
diff --git a/src/plugins/cpptools/cppsemanticinfoupdater.cpp b/src/plugins/cpptools/cppsemanticinfoupdater.cpp
new file mode 100644
index 0000000000..71fbb16e46
--- /dev/null
+++ b/src/plugins/cpptools/cppsemanticinfoupdater.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "builtineditordocumentparser.h"
+#include "cpplocalsymbols.h"
+#include "cppsemanticinfoupdater.h"
+
+#include <utils/qtcassert.h>
+#include <utils/qtcoverride.h>
+#include <utils/runextensions.h>
+
+#include <cplusplus/Control.h>
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/TranslationUnit.h>
+
+enum { debug = 0 };
+
+using namespace CPlusPlus;
+using namespace CppTools;
+
+namespace CppTools {
+
+class SemanticInfoUpdaterPrivate
+{
+public:
+ class FuturizedTopLevelDeclarationProcessor: public CPlusPlus::TopLevelDeclarationProcessor
+ {
+ public:
+ FuturizedTopLevelDeclarationProcessor(QFutureInterface<void> &future): m_future(future) {}
+ bool processDeclaration(CPlusPlus::DeclarationAST *) { return !isCanceled(); }
+ bool isCanceled() { return m_future.isCanceled(); }
+ private:
+ QFutureInterface<void> m_future;
+ };
+
+public:
+ SemanticInfoUpdaterPrivate(SemanticInfoUpdater *q, BuiltinEditorDocumentParser *m_parser);
+ ~SemanticInfoUpdaterPrivate();
+
+ SemanticInfo semanticInfo() const;
+ void setSemanticInfo(const SemanticInfo &semanticInfo, bool emitSignal);
+
+ SemanticInfo update(const SemanticInfo::Source &source,
+ bool emitSignalWhenFinished,
+ FuturizedTopLevelDeclarationProcessor *processor);
+
+ bool reuseCurrentSemanticInfo(const SemanticInfo::Source &source, bool emitSignalWhenFinished);
+
+ void update_helper(QFutureInterface<void> &future, const SemanticInfo::Source source);
+
+public:
+ SemanticInfoUpdater *q;
+ mutable QMutex m_lock;
+ SemanticInfo m_semanticInfo;
+ QFuture<void> m_future;
+ BuiltinEditorDocumentParser *m_parser;
+};
+
+SemanticInfoUpdaterPrivate::SemanticInfoUpdaterPrivate(SemanticInfoUpdater *q,
+ BuiltinEditorDocumentParser *parser)
+ : q(q)
+ , m_parser(parser)
+{
+}
+
+SemanticInfoUpdaterPrivate::~SemanticInfoUpdaterPrivate()
+{
+ m_future.cancel();
+ m_future.waitForFinished();
+}
+
+SemanticInfo SemanticInfoUpdaterPrivate::semanticInfo() const
+{
+ QMutexLocker locker(&m_lock);
+ return m_semanticInfo;
+}
+
+void SemanticInfoUpdaterPrivate::setSemanticInfo(const SemanticInfo &semanticInfo, bool emitSignal)
+{
+ {
+ QMutexLocker locker(&m_lock);
+ m_semanticInfo = semanticInfo;
+ }
+ if (emitSignal) {
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: emiting new info";
+ emit q->updated(semanticInfo);
+ }
+}
+
+SemanticInfo SemanticInfoUpdaterPrivate::update(const SemanticInfo::Source &source,
+ bool emitSignalWhenFinished,
+ FuturizedTopLevelDeclarationProcessor *processor)
+{
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: update() - source revision" << source.revision;
+
+ SemanticInfo newSemanticInfo;
+ newSemanticInfo.revision = source.revision;
+
+ QTC_ASSERT(m_parser, return newSemanticInfo);
+ newSemanticInfo.snapshot = m_parser->snapshot();
+ QTC_ASSERT(newSemanticInfo.snapshot.contains(source.fileName), return newSemanticInfo);
+
+ Document::Ptr doc = newSemanticInfo.snapshot.preprocessedDocument(source.code, source.fileName);
+ if (processor)
+ doc->control()->setTopLevelDeclarationProcessor(processor);
+ doc->check();
+ if (processor && processor->isCanceled())
+ newSemanticInfo.complete = false;
+ newSemanticInfo.doc = doc;
+
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: update() - re-calculated document. Canceled ="
+ << !newSemanticInfo.complete;
+
+ setSemanticInfo(newSemanticInfo, emitSignalWhenFinished);
+ return newSemanticInfo;
+}
+
+bool SemanticInfoUpdaterPrivate::reuseCurrentSemanticInfo(const SemanticInfo::Source &source,
+ bool emitSignalWhenFinished)
+{
+ const SemanticInfo currentSemanticInfo = semanticInfo();
+
+ if (!source.force
+ && currentSemanticInfo.complete
+ && currentSemanticInfo.revision == source.revision
+ && currentSemanticInfo.doc
+ && currentSemanticInfo.doc->translationUnit()->ast()
+ && currentSemanticInfo.doc->fileName() == source.fileName) {
+ SemanticInfo newSemanticInfo;
+ newSemanticInfo.revision = source.revision;
+ newSemanticInfo.doc = currentSemanticInfo.doc;
+ newSemanticInfo.snapshot = currentSemanticInfo.snapshot; // ### TODO: use the new snapshot.
+ setSemanticInfo(newSemanticInfo, emitSignalWhenFinished);
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: re-using current semantic info - source.revision"
+ << source.revision;
+ return true;
+ }
+
+ return false;
+}
+
+void SemanticInfoUpdaterPrivate::update_helper(QFutureInterface<void> &future,
+ const SemanticInfo::Source source)
+{
+ FuturizedTopLevelDeclarationProcessor processor(future);
+ update(source, true, &processor);
+}
+
+SemanticInfoUpdater::SemanticInfoUpdater(BuiltinEditorDocumentParser *parser)
+ : d(new SemanticInfoUpdaterPrivate(this, parser))
+{
+}
+
+SemanticInfoUpdater::~SemanticInfoUpdater()
+{
+ d->m_future.cancel();
+ d->m_future.waitForFinished();
+}
+
+SemanticInfo SemanticInfoUpdater::update(const SemanticInfo::Source &source)
+{
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: update() - synchronous";
+ d->m_future.cancel();
+
+ const bool emitSignalWhenFinished = false;
+ if (d->reuseCurrentSemanticInfo(source, emitSignalWhenFinished)) {
+ d->m_future = QFuture<void>();
+ return semanticInfo();
+ }
+
+ return d->update(source, emitSignalWhenFinished, 0);
+}
+
+void SemanticInfoUpdater::updateDetached(const SemanticInfo::Source source)
+{
+ if (debug)
+ qDebug() << "SemanticInfoUpdater: updateDetached() - asynchronous";
+ d->m_future.cancel();
+
+ const bool emitSignalWhenFinished = true;
+ if (d->reuseCurrentSemanticInfo(source, emitSignalWhenFinished)) {
+ d->m_future = QFuture<void>();
+ return;
+ }
+
+ d->m_future = QtConcurrent::run<SemanticInfoUpdaterPrivate, void, const SemanticInfo::Source>
+ (&SemanticInfoUpdaterPrivate::update_helper, d.data(), source);
+}
+
+SemanticInfo SemanticInfoUpdater::semanticInfo() const
+{
+ return d->semanticInfo();
+}
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.h b/src/plugins/cpptools/cppsemanticinfoupdater.h
index 14fb8236ce..0436bf1846 100644
--- a/src/plugins/cpptools/cpphighlightingsupportinternal.h
+++ b/src/plugins/cpptools/cppsemanticinfoupdater.h
@@ -27,37 +27,40 @@
**
****************************************************************************/
-#ifndef CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
-#define CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
+#ifndef CPPSEMANTICINFOUPDATER_H
+#define CPPSEMANTICINFOUPDATER_H
-#include "cpphighlightingsupport.h"
+#include "cppsemanticinfo.h"
-#include <QFuture>
+#include <QObject>
+#include <QScopedPointer>
namespace CppTools {
-namespace Internal {
-class CppHighlightingSupportInternal: public CppHighlightingSupport
+class BuiltinEditorDocumentParser;
+class SemanticInfoUpdaterPrivate;
+
+class SemanticInfoUpdater : public QObject
{
+ Q_OBJECT
+ Q_DISABLE_COPY(SemanticInfoUpdater)
+
public:
- CppHighlightingSupportInternal(TextEditor::BaseTextDocument *baseTextDocument);
- virtual ~CppHighlightingSupportInternal();
+ explicit SemanticInfoUpdater(BuiltinEditorDocumentParser *parser);
+ ~SemanticInfoUpdater();
- virtual bool requiresSemanticInfo() const
- { return true; }
+ SemanticInfo semanticInfo() const;
- virtual bool hightlighterHandlesDiagnostics() const
- { return false; }
+ SemanticInfo update(const SemanticInfo::Source &source);
+ void updateDetached(const SemanticInfo::Source source);
- virtual bool hightlighterHandlesIfdefedOutBlocks() const
- { return false; }
+signals:
+ void updated(CppTools::SemanticInfo semanticInfo);
- virtual QFuture<TextEditor::HighlightingResult> highlightingFuture(
- const CPlusPlus::Document::Ptr &doc,
- const CPlusPlus::Snapshot &snapshot) const;
+private:
+ QScopedPointer<SemanticInfoUpdaterPrivate> d;
};
-} // namespace Internal
} // namespace CppTools
-#endif // CPPTOOLS_CPPHIGHLIGHTINGSUPPORTINTERNAL_H
+#endif // CPPSEMANTICINFOUPDATER_H
diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp
index af59cd8334..9b14594954 100644
--- a/src/plugins/cpptools/cppsourceprocessor_test.cpp
+++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp
@@ -33,8 +33,8 @@
#include "cppmodelmanager.h"
#include "cppsourceprocessertesthelper.h"
#include "cppsourceprocessor.h"
-#include "cpptoolseditorsupport.h"
#include "cpptoolstestcase.h"
+#include "editordocumenthandle.h"
#include <texteditor/basetexteditor.h>
@@ -140,13 +140,11 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic()
QVERIFY(testCase.openBaseTextEditor(fileName1, &editor));
testCase.closeEditorAtEndOfTestCase(editor);
- // Get editor snapshot
- CppEditorSupport *cppEditorSupport = CppModelManagerInterface::instance()
- ->cppEditorSupport(editor);
- QVERIFY(cppEditorSupport);
- BuiltinEditorDocumentParser::Ptr documentParser = cppEditorSupport->documentParser();
- QVERIFY(documentParser);
- Snapshot snapshot = documentParser->snapshot();
+ // Check editor snapshot
+ const QString filePath = editor->document()->filePath();
+ BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(filePath);
+ QVERIFY(parser);
+ Snapshot snapshot = parser->snapshot();
QCOMPARE(snapshot.size(), 3); // Configuration file included
// Check includes
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index a0e45d6000..941784703b 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -5,7 +5,9 @@ include(../../qtcreatorplugin.pri)
HEADERS += \
abstracteditorsupport.h \
baseeditordocumentparser.h \
+ baseeditordocumentprocessor.h \
builtineditordocumentparser.h \
+ builtineditordocumentprocessor.h \
builtinindexingsupport.h \
commentssettings.h \
completionsettingspage.h \
@@ -26,8 +28,6 @@ HEADERS += \
cppfilesettingspage.h \
cppfindreferences.h \
cppfunctionsfilter.h \
- cpphighlightingsupport.h \
- cpphighlightingsupportinternal.h \
cppindexingsupport.h \
cpplocalsymbols.h \
cpplocatordata.h \
@@ -42,20 +42,22 @@ HEADERS += \
cppqtstyleindenter.h \
cpprefactoringchanges.h \
cppsemanticinfo.h \
+ cppsemanticinfoupdater.h \
cppsourceprocessor.h \
cpptools_global.h \
cpptoolsconstants.h \
- cpptoolseditorsupport.h \
cpptoolsplugin.h \
cpptoolsreuse.h \
cpptoolssettings.h \
cppworkingcopy.h \
doxygengenerator.h \
+ editordocumenthandle.h \
functionutils.h \
includeutils.h \
indexitem.h \
insertionpointlocator.h \
searchsymbols.h \
+ semantichighlighter.h \
stringtable.h \
symbolfinder.h \
symbolsfindfilter.h \
@@ -64,7 +66,9 @@ HEADERS += \
SOURCES += \
abstracteditorsupport.cpp \
baseeditordocumentparser.cpp \
+ baseeditordocumentprocessor.cpp \
builtineditordocumentparser.cpp \
+ builtineditordocumentprocessor.cpp \
builtinindexingsupport.cpp \
commentssettings.cpp \
completionsettingspage.cpp \
@@ -85,8 +89,6 @@ SOURCES += \
cppfilesettingspage.cpp \
cppfindreferences.cpp \
cppfunctionsfilter.cpp \
- cpphighlightingsupport.cpp \
- cpphighlightingsupportinternal.cpp \
cppindexingsupport.cpp \
cpplocalsymbols.cpp \
cpplocatordata.cpp \
@@ -101,18 +103,20 @@ SOURCES += \
cppqtstyleindenter.cpp \
cpprefactoringchanges.cpp \
cppsemanticinfo.cpp \
+ cppsemanticinfoupdater.cpp \
cppsourceprocessor.cpp \
- cpptoolseditorsupport.cpp \
cpptoolsplugin.cpp \
cpptoolsreuse.cpp \
cpptoolssettings.cpp \
cppworkingcopy.cpp \
doxygengenerator.cpp \
+ editordocumenthandle.cpp \
functionutils.cpp \
includeutils.cpp \
indexitem.cpp \
insertionpointlocator.cpp \
searchsymbols.cpp \
+ semantichighlighter.cpp \
stringtable.cpp \
symbolfinder.cpp \
symbolsfindfilter.cpp \
diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs
index 1c47b7ab60..d3f8681b9d 100644
--- a/src/plugins/cpptools/cpptools.qbs
+++ b/src/plugins/cpptools/cpptools.qbs
@@ -25,7 +25,9 @@ QtcPlugin {
files: [
"abstracteditorsupport.cpp", "abstracteditorsupport.h",
"baseeditordocumentparser.cpp", "baseeditordocumentparser.h",
+ "baseeditordocumentprocessor.cpp", "baseeditordocumentprocessor.h",
"builtineditordocumentparser.cpp", "builtineditordocumentparser.h",
+ "builtineditordocumentprocessor.cpp", "builtineditordocumentprocessor.h",
"builtinindexingsupport.cpp", "builtinindexingsupport.h",
"commentssettings.cpp", "commentssettings.h",
"completionsettingspage.cpp", "completionsettingspage.h", "completionsettingspage.ui",
@@ -46,8 +48,6 @@ QtcPlugin {
"cppfilesettingspage.cpp", "cppfilesettingspage.h", "cppfilesettingspage.ui",
"cppfindreferences.cpp", "cppfindreferences.h",
"cppfunctionsfilter.cpp", "cppfunctionsfilter.h",
- "cpphighlightingsupport.cpp", "cpphighlightingsupport.h",
- "cpphighlightingsupportinternal.cpp", "cpphighlightingsupportinternal.h",
"cppindexingsupport.cpp", "cppindexingsupport.h",
"cpplocalsymbols.cpp", "cpplocalsymbols.h",
"cpplocatordata.cpp", "cpplocatordata.h",
@@ -62,21 +62,23 @@ QtcPlugin {
"cppqtstyleindenter.cpp", "cppqtstyleindenter.h",
"cpprefactoringchanges.cpp", "cpprefactoringchanges.h",
"cppsemanticinfo.cpp", "cppsemanticinfo.h",
+ "cppsemanticinfoupdater.cpp", "cppsemanticinfoupdater.h",
"cppsourceprocessor.cpp", "cppsourceprocessor.h",
"cpptools.qrc",
"cpptools_global.h",
"cpptoolsconstants.h",
- "cpptoolseditorsupport.cpp", "cpptoolseditorsupport.h",
"cpptoolsplugin.cpp", "cpptoolsplugin.h",
"cpptoolsreuse.cpp", "cpptoolsreuse.h",
"cpptoolssettings.cpp", "cpptoolssettings.h",
"cppworkingcopy.cpp", "cppworkingcopy.h",
"doxygengenerator.cpp", "doxygengenerator.h",
+ "editordocumenthandle.cpp", "editordocumenthandle.h",
"functionutils.cpp", "functionutils.h",
"includeutils.cpp", "includeutils.h",
"indexitem.cpp", "indexitem.h",
"insertionpointlocator.cpp", "insertionpointlocator.h",
"searchsymbols.cpp", "searchsymbols.h",
+ "semantichighlighter.cpp", "semantichighlighter.h",
"stringtable.cpp", "stringtable.h",
"symbolfinder.cpp", "symbolfinder.h",
"symbolsfindfilter.cpp", "symbolsfindfilter.h",
diff --git a/src/plugins/cpptools/cppworkingcopy.h b/src/plugins/cpptools/cppworkingcopy.h
index 3775838885..df20c57bb2 100644
--- a/src/plugins/cpptools/cppworkingcopy.h
+++ b/src/plugins/cpptools/cppworkingcopy.h
@@ -52,6 +52,9 @@ public:
QByteArray source(const QString &fileName) const
{ return _elements.value(fileName).first; }
+ unsigned revision(const QString &fileName) const
+ { return _elements.value(fileName).second; }
+
QPair<QByteArray, unsigned> get(const QString &fileName) const
{ return _elements.value(fileName); }
diff --git a/src/plugins/cpptools/cpphighlightingsupport.cpp b/src/plugins/cpptools/editordocumenthandle.cpp
index 9c3bcd3dd5..d30e1c773d 100644
--- a/src/plugins/cpptools/cpphighlightingsupport.cpp
+++ b/src/plugins/cpptools/editordocumenthandle.cpp
@@ -27,16 +27,23 @@
**
****************************************************************************/
-#include "cpphighlightingsupport.h"
+#include "editordocumenthandle.h"
-using namespace CppTools;
+namespace CppTools {
-CppHighlightingSupport::CppHighlightingSupport(TextEditor::BaseTextDocument *baseTextDocument)
- : m_baseTextDocument(baseTextDocument)
+/*!
+ \class CppTools::EditorDocumentHandle
+
+ \brief The EditorDocumentHandle class provides an interface to an opened
+ C++ editor document.
+*/
+
+EditorDocumentHandle::EditorDocumentHandle()
{
- Q_ASSERT(baseTextDocument);
}
-CppHighlightingSupport::~CppHighlightingSupport()
+EditorDocumentHandle::~EditorDocumentHandle()
{
}
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/editordocumenthandle.h b/src/plugins/cpptools/editordocumenthandle.h
new file mode 100644
index 0000000000..81ba868922
--- /dev/null
+++ b/src/plugins/cpptools/editordocumenthandle.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef EDITORDOCUMENTHANDLE_H
+#define EDITORDOCUMENTHANDLE_H
+
+#include "baseeditordocumentprocessor.h"
+#include "cpptools_global.h"
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT EditorDocumentHandle
+{
+public:
+ EditorDocumentHandle();
+ virtual ~EditorDocumentHandle();
+
+ // For the Working Copy
+ virtual QString filePath() const = 0;
+ virtual QByteArray contents() const = 0;
+ virtual unsigned revision() const = 0;
+
+ // For updating if new project info is set
+ virtual BaseEditorDocumentProcessor *processor() = 0;
+};
+
+} // namespace CppTools
+
+#endif // EDITORDOCUMENTHANDLE_H
diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp
new file mode 100644
index 0000000000..33a77261a6
--- /dev/null
+++ b/src/plugins/cpptools/semantichighlighter.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "semantichighlighter.h"
+
+#include <texteditor/fontsettings.h>
+#include <texteditor/syntaxhighlighter.h>
+
+#include <utils/qtcassert.h>
+
+enum { debug = 0 };
+
+using namespace CPlusPlus;
+using TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats;
+using TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd;
+
+namespace CppTools {
+
+SemanticHighlighter::SemanticHighlighter(TextEditor::BaseTextDocument *baseTextDocument)
+ : QObject(baseTextDocument)
+ , m_baseTextDocument(baseTextDocument)
+ , m_revision(0)
+{
+ QTC_CHECK(m_baseTextDocument);
+
+ connect(baseTextDocument, &TextEditor::BaseTextDocument::fontSettingsChanged,
+ this, &SemanticHighlighter::onDocumentFontSettingsChanged);
+
+ updateFormatMapFromFontSettings();
+}
+
+SemanticHighlighter::~SemanticHighlighter()
+{
+ if (m_watcher) {
+ disconnectWatcher();
+ m_watcher->cancel();
+ m_watcher->waitForFinished();
+ }
+}
+
+void SemanticHighlighter::setHighlightingRunner(HighlightingRunner highlightingRunner)
+{
+ m_highlightingRunner = highlightingRunner;
+}
+
+void SemanticHighlighter::run()
+{
+ QTC_ASSERT(m_highlightingRunner, return);
+
+ if (debug)
+ qDebug() << "SemanticHighlighter: run()";
+
+ if (m_watcher) {
+ disconnectWatcher();
+ m_watcher->cancel();
+ }
+ m_watcher.reset(new QFutureWatcher<TextEditor::HighlightingResult>);
+ connectWatcher();
+
+ m_revision = documentRevision();
+ m_watcher->setFuture(m_highlightingRunner());
+}
+
+void SemanticHighlighter::onDocumentFontSettingsChanged()
+{
+ updateFormatMapFromFontSettings();
+ run();
+}
+
+void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
+{
+ if (documentRevision() != m_revision)
+ return; // outdated
+ else if (!m_watcher || m_watcher->isCanceled())
+ return; // aborted
+
+ if (debug)
+ qDebug() << "SemanticHighlighter: onHighlighterResultAvailable()" << from << to;
+
+ TextEditor::SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter();
+ QTC_ASSERT(highlighter, return);
+ incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap);
+}
+
+void SemanticHighlighter::onHighlighterFinished()
+{
+ QTC_ASSERT(m_watcher, return);
+ if (!m_watcher->isCanceled() && documentRevision() == m_revision) {
+ TextEditor::SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter();
+ QTC_CHECK(highlighter);
+ if (highlighter) {
+ if (debug)
+ qDebug() << "SemanticHighlighter: onHighlighterFinished() - clearing formats";
+ clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
+ }
+ }
+ m_watcher.reset();
+}
+
+void SemanticHighlighter::connectWatcher()
+{
+ typedef QFutureWatcher<TextEditor::HighlightingResult> Watcher;
+ connect(m_watcher.data(), &Watcher::resultsReadyAt,
+ this, &SemanticHighlighter::onHighlighterResultAvailable);
+ connect(m_watcher.data(), &Watcher::finished,
+ this, &SemanticHighlighter::onHighlighterFinished);
+}
+
+void SemanticHighlighter::disconnectWatcher()
+{
+ typedef QFutureWatcher<TextEditor::HighlightingResult> Watcher;
+ disconnect(m_watcher.data(), &Watcher::resultsReadyAt,
+ this, &SemanticHighlighter::onHighlighterResultAvailable);
+ disconnect(m_watcher.data(), &Watcher::finished,
+ this, &SemanticHighlighter::onHighlighterFinished);
+}
+
+unsigned SemanticHighlighter::documentRevision() const
+{
+ return m_baseTextDocument->document()->revision();
+}
+
+void SemanticHighlighter::updateFormatMapFromFontSettings()
+{
+ const TextEditor::FontSettings &fs = m_baseTextDocument->fontSettings();
+
+ m_formatMap[TypeUse] = fs.toTextCharFormat(TextEditor::C_TYPE);
+ m_formatMap[LocalUse] = fs.toTextCharFormat(TextEditor::C_LOCAL);
+ m_formatMap[FieldUse] = fs.toTextCharFormat(TextEditor::C_FIELD);
+ m_formatMap[EnumerationUse] = fs.toTextCharFormat(TextEditor::C_ENUMERATION);
+ m_formatMap[VirtualMethodUse] = fs.toTextCharFormat(TextEditor::C_VIRTUAL_METHOD);
+ m_formatMap[LabelUse] = fs.toTextCharFormat(TextEditor::C_LABEL);
+ m_formatMap[MacroUse] = fs.toTextCharFormat(TextEditor::C_PREPROCESSOR);
+ m_formatMap[FunctionUse] = fs.toTextCharFormat(TextEditor::C_FUNCTION);
+ m_formatMap[PseudoKeywordUse] = fs.toTextCharFormat(TextEditor::C_KEYWORD);
+ m_formatMap[StringUse] = fs.toTextCharFormat(TextEditor::C_STRING);
+}
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpphighlightingsupport.h b/src/plugins/cpptools/semantichighlighter.h
index d4be6b1416..fb12bf34e6 100644
--- a/src/plugins/cpptools/cpphighlightingsupport.h
+++ b/src/plugins/cpptools/semantichighlighter.h
@@ -27,23 +27,28 @@
**
****************************************************************************/
-#ifndef CPPTOOLS_CPPHIGHLIGHTINGSUPPORT_H
-#define CPPTOOLS_CPPHIGHLIGHTINGSUPPORT_H
+#ifndef SEMANTICHIGHLIGHTER_H
+#define SEMANTICHIGHLIGHTER_H
+#include "cppsemanticinfo.h"
#include "cpptools_global.h"
+#include <texteditor/basetextdocument.h>
#include <texteditor/semantichighlighter.h>
-#include <cplusplus/CppDocument.h>
+#include <QFutureWatcher>
+#include <QScopedPointer>
+#include <QTextEdit>
-#include <QFuture>
-
-namespace TextEditor { class BaseTextDocument; }
+#include <functional>
namespace CppTools {
-class CPPTOOLS_EXPORT CppHighlightingSupport
+class CPPTOOLS_EXPORT SemanticHighlighter : public QObject
{
+ Q_OBJECT
+ Q_DISABLE_COPY(SemanticHighlighter)
+
public:
enum Kind {
Unknown = 0,
@@ -59,27 +64,39 @@ public:
StringUse
};
+ typedef std::function<QFuture<TextEditor::HighlightingResult> ()> HighlightingRunner;
+
public:
- CppHighlightingSupport(TextEditor::BaseTextDocument *baseTextDocument);
- virtual ~CppHighlightingSupport() = 0;
+ explicit SemanticHighlighter(TextEditor::BaseTextDocument *baseTextDocument);
+ ~SemanticHighlighter();
+
+ void setHighlightingRunner(HighlightingRunner highlightingRunner);
- virtual bool requiresSemanticInfo() const = 0;
+ void run();
- virtual bool hightlighterHandlesDiagnostics() const = 0;
- virtual bool hightlighterHandlesIfdefedOutBlocks() const = 0;
+private slots:
+ void onDocumentFontSettingsChanged();
- virtual QFuture<TextEditor::HighlightingResult> highlightingFuture(
- const CPlusPlus::Document::Ptr &doc,
- const CPlusPlus::Snapshot &snapshot) const = 0;
+ void onHighlighterResultAvailable(int from, int to);
+ void onHighlighterFinished();
-protected:
- TextEditor::BaseTextDocument *baseTextDocument() const
- { return m_baseTextDocument; }
+private:
+ void connectWatcher();
+ void disconnectWatcher();
+
+ unsigned documentRevision() const;
+ void updateFormatMapFromFontSettings();
private:
TextEditor::BaseTextDocument *m_baseTextDocument;
+
+ unsigned m_revision;
+ QScopedPointer<QFutureWatcher<TextEditor::HighlightingResult>> m_watcher;
+ QHash<int, QTextCharFormat> m_formatMap;
+
+ HighlightingRunner m_highlightingRunner;
};
} // namespace CppTools
-#endif // CPPTOOLS_CPPHIGHLIGHTINGSUPPORT_H
+#endif // SEMANTICHIGHLIGHTER_H
diff --git a/src/plugins/designer/gotoslot_test.cpp b/src/plugins/designer/gotoslot_test.cpp
index def152e985..7814af028d 100644
--- a/src/plugins/designer/gotoslot_test.cpp
+++ b/src/plugins/designer/gotoslot_test.cpp
@@ -33,9 +33,10 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/testdatadir.h>
+#include <cpptools/builtineditordocumentprocessor.h>
#include <cpptools/cppmodelmanager.h>
-#include <cpptools/cpptoolseditorsupport.h>
#include <cpptools/cpptoolstestcase.h>
+#include <cpptools/editordocumenthandle.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/Overview.h>
@@ -163,8 +164,6 @@ public:
closeEditorAtEndOfTestCase(editor);
editors << e;
}
- TextEditor::BaseTextEditor *cppFileEditor = editors.at(0);
- TextEditor::BaseTextEditor *hFileEditor = editors.at(1);
const QString cppFile = files.at(0);
const QString hFile = files.at(1);
@@ -184,18 +183,22 @@ public:
// Wait for updated documents
foreach (TextEditor::BaseTextEditor *editor, editors) {
- if (CppEditorSupport *editorSupport = m_modelManager->cppEditorSupport(editor)) {
- while (editorSupport->isUpdatingDocument())
+ const QString filePath = editor->document()->filePath();
+ if (auto parser = BuiltinEditorDocumentParser::get(filePath)) {
+ forever {
+ if (Document::Ptr document = parser->document()) {
+ if (document->editorRevision() == 2)
+ break;
+ }
QApplication::processEvents();
+ }
}
}
// Compare
- const Document::Ptr cppDocument
- = m_modelManager->cppEditorSupport(cppFileEditor)->documentParser()->document();
+ const Document::Ptr cppDocument = BuiltinEditorDocumentParser::get(cppFile)->document();
QVERIFY(checkDiagsnosticMessages(cppDocument));
- const Document::Ptr hDocument
- = m_modelManager->cppEditorSupport(hFileEditor)->documentParser()->document();
+ const Document::Ptr hDocument = BuiltinEditorDocumentParser::get(hFile)->document();
QVERIFY(checkDiagsnosticMessages(hDocument));
QVERIFY(documentContainsFunctionDefinition(cppDocument,