diff options
author | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2014-10-21 10:52:03 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2014-10-21 13:33:24 +0200 |
commit | 4fc5eeb97b5c2f32a07f5eab037918dd4fe7fd2c (patch) | |
tree | 45fa55f4ec385e9f159500a073fa31d9aeeefa40 /src | |
parent | 22c15b3ea83eda0c06a7bea5668b3d4b233fc72a (diff) | |
download | qt-creator-4fc5eeb97b5c2f32a07f5eab037918dd4fe7fd2c.tar.gz |
CppTools: Remove last traces of CppEditorSupport
Superseded by commit
commit 89bd4ee3c4e4be4b39dee9ef12e798d21be3d2cb
C++: Base parsing on editor document instead of widget
Change-Id: Iffa6e47bddc0fa3de1eab9b65fe8f711520d2d7f
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager_test.cpp | 5 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolseditorsupport.cpp | 632 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolseditorsupport.h | 253 |
4 files changed, 1 insertions, 891 deletions
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index a33e595a72..1980bf8258 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -934,7 +934,7 @@ void CppModelManager::GC() if (!d->m_enableGC) return; - // Collect files of CppEditorSupport and AbstractEditorSupport. + // Collect files of opened editors and editor supports (e.g. ui code model) QStringList filesInEditorSupports; foreach (const EditorDocumentHandle *cppEditor, cppEditors()) filesInEditorSupports << cppEditor->filePath(); diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 2805a0b299..cb51113d39 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -873,11 +873,6 @@ 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(); - Document::Ptr doc = mm->document(fileName); QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName); } diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp deleted file mode 100644 index 83556117b2..0000000000 --- a/src/plugins/cpptools/cpptoolseditorsupport.cpp +++ /dev/null @@ -1,632 +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://www.qt.io/licensing. For further information -** use the contact form at http://www.qt.io/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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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 "cppcodemodelsettings.h" -#include "cppcompletionassistprovider.h" -#include "cpptoolseditorsupport.h" -#include "cpptoolsplugin.h" -#include "cppmodelmanager.h" -#include "cpplocalsymbols.h" - -#include <coreplugin/editormanager/editormanager.h> -#include <cpptools/cppworkingcopy.h> - -#include <utils/qtcassert.h> -#include <utils/runextensions.h> - -#include <QList> -#include <QMutexLocker> -#include <QTextBlock> -#include <QTimer> - -using namespace CppTools; -using namespace CppTools::Internal; -using namespace CPlusPlus; -using namespace TextEditor; - -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; - } -}; - -} // anonymous namespace - -CppEditorSupport::CppEditorSupport(CppModelManager *modelManager, BaseTextEditor *textEditor) - : QObject(modelManager) - , m_modelManager(modelManager) - , m_textEditor(textEditor) - , m_updateDocumentInterval(UpdateDocumentDefaultInterval) - , m_revision(0) - , m_editorVisible(textEditor->widget()->isVisible()) - , m_cachedContentsEditorRevision(-1) - , m_fileIsBeingReloaded(false) - , m_initialized(false) - , m_lastHighlightRevision(0) - , m_lastHighlightOnCompleteSemanticInfo(true) - , m_highlightingSupport(modelManager->highlightingSupport(textEditor->textDocument())) - , m_completionAssistProvider( - modelManager->completionAssistProvider(textEditor->document()->mimeType())) -{ - m_editorDocument = qobject_cast<BaseTextDocument*>(m_textEditor->document()); - QTC_CHECK(m_editorDocument); - - connect(m_modelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), - this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr))); - - if (m_highlightingSupport && m_highlightingSupport->requiresSemanticInfo()) { - connect(this, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)), - this, SLOT(startHighlighting())); - } - - m_updateDocumentTimer = new QTimer(this); - m_updateDocumentTimer->setObjectName(QLatin1String("CppEditorSupport::m_updateDocumentTimer")); - m_updateDocumentTimer->setSingleShot(true); - m_updateDocumentTimer->setInterval(m_updateDocumentInterval); - connect(m_updateDocumentTimer, SIGNAL(timeout()), this, SLOT(updateDocumentNow())); - - m_updateEditorTimer = new QTimer(this); - m_updateEditorTimer->setObjectName(QLatin1String("CppEditorSupport::m_updateEditorTimer")); - m_updateEditorTimer->setInterval(UpdateEditorInterval); - m_updateEditorTimer->setSingleShot(true); - connect(m_updateEditorTimer, SIGNAL(timeout()), - this, SLOT(updateEditorNow())); - - connect(m_editorDocument, SIGNAL(contentsChanged()), this, SLOT(updateDocument())); - connect(this, SIGNAL(diagnosticsChanged()), this, SLOT(onDiagnosticsChanged())); - - connect(m_editorDocument, SIGNAL(mimeTypeChanged()), - this, SLOT(onMimeTypeChanged())); - - connect(m_editorDocument, SIGNAL(aboutToReload()), - this, SLOT(onAboutToReload())); - connect(m_editorDocument, SIGNAL(reloadFinished(bool)), - this, SLOT(onReloadFinished())); - - connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), - this, SLOT(onCurrentEditorChanged())); - m_editorGCTimer = new QTimer(this); - m_editorGCTimer->setObjectName(QLatin1String("CppEditorSupport::m_editorGCTimer")); - m_editorGCTimer->setSingleShot(true); - m_editorGCTimer->setInterval(EditorHiddenGCTimeout); - connect(m_editorGCTimer, SIGNAL(timeout()), this, SLOT(releaseResources())); - - updateDocument(); -} - -CppEditorSupport::~CppEditorSupport() -{ - m_documentParserFuture.cancel(); - m_highlighter.cancel(); - m_futureSemanticInfo.cancel(); - - m_documentParserFuture.waitForFinished(); - m_highlighter.waitForFinished(); - m_futureSemanticInfo.waitForFinished(); -} - -QString CppEditorSupport::fileName() const -{ - return m_editorDocument->filePath(); -} - -QByteArray CppEditorSupport::contents() const -{ - QMutexLocker locker(&m_cachedContentsLock); - - const int editorRev = editorRevision(); - if (m_cachedContentsEditorRevision != editorRev && !m_fileIsBeingReloaded) { - m_cachedContentsEditorRevision = editorRev; - m_cachedContents = m_editorDocument->plainText().toUtf8(); - } - - return m_cachedContents; -} - -unsigned CppEditorSupport::editorRevision() const -{ - return m_editorDocument->document()->revision(); -} - -void CppEditorSupport::setExtraDiagnostics(const QString &key, - const QList<Document::DiagnosticMessage> &messages) -{ - { - QMutexLocker locker(&m_diagnosticsMutex); - m_allDiagnostics.insert(key, messages); - } - - emit diagnosticsChanged(); -} - -void CppEditorSupport::setIfdefedOutBlocks(const QList<BlockRange> &ifdefedOutBlocks) -{ - m_editorUpdates.ifdefedOutBlocks = ifdefedOutBlocks; - - emit diagnosticsChanged(); -} - -bool CppEditorSupport::initialized() -{ - return m_initialized; -} - -SemanticInfo CppEditorSupport::recalculateSemanticInfo() -{ - m_futureSemanticInfo.cancel(); - return recalculateSemanticInfoNow(currentSource(false), /*emitSignalWhenFinished=*/ false); -} - -Document::Ptr CppEditorSupport::lastSemanticInfoDocument() const -{ - return semanticInfo().doc; -} - -void CppEditorSupport::recalculateSemanticInfoDetached(ForceReason forceReason) -{ - // Block premature calculation caused by CppEditorPlugin::currentEditorChanged - // when the editor is created. - if (!m_initialized) - return; - - m_futureSemanticInfo.cancel(); - const bool force = forceReason != NoForce; - SemanticInfo::Source source = currentSource(force); - m_futureSemanticInfo = QtConcurrent::run<CppEditorSupport, void>( - &CppEditorSupport::recalculateSemanticInfoDetached_helper, this, source); - - if (force && m_highlightingSupport && !m_highlightingSupport->requiresSemanticInfo()) - startHighlighting(forceReason); -} - -CppCompletionAssistProvider *CppEditorSupport::completionAssistProvider() const -{ - return m_completionAssistProvider; -} - -BuiltinEditorDocumentParser::Ptr CppEditorSupport::documentParser() -{ - BuiltinEditorDocumentParser::Ptr updater = documentParser_internal(); - if (!updater || updater->filePath() != fileName()) { - updater = BuiltinEditorDocumentParser::Ptr(new BuiltinEditorDocumentParser(fileName())); - setDocumentParser_internal(updater); - - QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings(); - updater->setUsePrecompiledHeaders(cms->pchUsage() != CppCodeModelSettings::PchUse_None); - } - return updater; -} - -void CppEditorSupport::updateDocument() -{ - m_revision = editorRevision(); - - if (qobject_cast<BaseTextEditorWidget*>(m_textEditor->widget()) != 0) - m_updateEditorTimer->stop(); - - m_updateDocumentTimer->start(m_updateDocumentInterval); -} - -static void parse(QFutureInterface<void> &future, BuiltinEditorDocumentParser::Ptr updater, - WorkingCopy workingCopy) -{ - future.setProgressRange(0, 1); - if (future.isCanceled()) { - future.setProgressValue(1); - return; - } - - CppModelManager *cmm = qobject_cast<CppModelManager *>(CppModelManager::instance()); - updater->update(workingCopy); - cmm->finishedRefreshingSourceFiles(QStringList(updater->filePath())); - - future.setProgressValue(1); -} - -void CppEditorSupport::updateDocumentNow() -{ - if (m_documentParserFuture.isRunning() || m_revision != editorRevision()) { - m_updateDocumentTimer->start(m_updateDocumentInterval); - } else { - m_updateDocumentTimer->stop(); - - if (m_fileIsBeingReloaded || fileName().isEmpty()) - return; - - if (m_highlightingSupport && !m_highlightingSupport->requiresSemanticInfo()) - startHighlighting(); - - m_documentParserFuture = QtConcurrent::run(&parse, documentParser(), - CppModelManager::instance()->workingCopy()); - } -} - -bool CppEditorSupport::isUpdatingDocument() -{ - return m_updateDocumentTimer->isActive() || m_documentParserFuture.isRunning(); -} - -void CppEditorSupport::onDocumentUpdated(Document::Ptr doc) -{ - if (doc.isNull()) - return; - - if (doc->fileName() != fileName()) - return; // some other document got updated - - if (doc->editorRevision() != editorRevision()) - return; // outdated content, wait for a new document to be parsed - - // Update the ifdeffed-out blocks: - if (m_highlightingSupport && !m_highlightingSupport->hightlighterHandlesIfdefedOutBlocks()) { - QList<Document::Block> skippedBlocks = doc->skippedBlocks(); - QList<BlockRange> ifdefedOutBlocks; - ifdefedOutBlocks.reserve(skippedBlocks.size()); - foreach (const Document::Block &block, skippedBlocks) - ifdefedOutBlocks.append(BlockRange(block.utf16charsBegin(), block.utf16charsEnd())); - setIfdefedOutBlocks(ifdefedOutBlocks); - } - - if (m_highlightingSupport && !m_highlightingSupport->hightlighterHandlesDiagnostics()) { - // Update the parser errors/warnings: - static const QString key = QLatin1String("CppTools.ParserDiagnostics"); - setExtraDiagnostics(key, doc->diagnosticMessages()); - } - - // Update semantic info if necessary - if (!m_initialized || (m_textEditor->widget()->isVisible() && !isSemanticInfoValid())) { - m_initialized = true; - recalculateSemanticInfoDetached(ForceDueToInvalidSemanticInfo); - } - - // Notify the editor that the document is updated - emit documentUpdated(); -} - -void CppEditorSupport::startHighlighting(ForceReason forceReason) -{ - if (!m_highlightingSupport) - return; - - if (m_highlightingSupport->requiresSemanticInfo()) { - const SemanticInfo info = semanticInfo(); - if (info.doc.isNull()) - return; - - const bool forced = info.forced || !m_lastHighlightOnCompleteSemanticInfo; - if (!forced && m_lastHighlightRevision == info.revision) - return; - - m_highlighter.cancel(); - m_highlighter = m_highlightingSupport->highlightingFuture(info.doc, info.snapshot); - m_lastHighlightRevision = info.revision; - m_lastHighlightOnCompleteSemanticInfo = info.complete; - emit highlighterStarted(&m_highlighter, m_lastHighlightRevision); - } else { - const unsigned revision = editorRevision(); - if (forceReason != ForceDueEditorRequest && m_lastHighlightRevision == revision) - return; - - m_highlighter.cancel(); - static const Document::Ptr dummyDoc; - static const Snapshot dummySnapshot; - m_highlighter = m_highlightingSupport->highlightingFuture(dummyDoc, dummySnapshot); - m_lastHighlightRevision = revision; - emit highlighterStarted(&m_highlighter, m_lastHighlightRevision); - } -} - -/// \brief This slot puts the new diagnostics into the editorUpdates. This function has to be called -/// on the UI thread. -void CppEditorSupport::onDiagnosticsChanged() -{ - QList<Document::DiagnosticMessage> allDiagnostics; - { - QMutexLocker locker(&m_diagnosticsMutex); - foreach (const QList<Document::DiagnosticMessage> &msgs, m_allDiagnostics) - allDiagnostics.append(msgs); - } - - if (!m_textEditor) - return; - - // set up the format for the errors - QTextCharFormat errorFormat; - errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); - errorFormat.setUnderlineColor(Qt::red); - - // set up the format for the warnings. - QTextCharFormat warningFormat; - warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); - warningFormat.setUnderlineColor(Qt::darkYellow); - - QTextDocument *doc = m_editorDocument->document(); - - m_editorUpdates.selections.clear(); - foreach (const Document::DiagnosticMessage &m, allDiagnostics) { - QTextEdit::ExtraSelection sel; - if (m.isWarning()) - sel.format = warningFormat; - else - sel.format = errorFormat; - - QTextCursor c(doc->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()); - m_editorUpdates.selections.append(sel); - } - - m_editorUpdates.revision = doc->revision(); - - updateEditor(); -} -void CppEditorSupport::updateEditor() -{ - m_updateEditorTimer->start(UpdateEditorInterval); -} - -void CppEditorSupport::updateEditorNow() -{ - if (!m_textEditor || m_editorUpdates.revision == -1) - return; - - if (editorRevision() != (unsigned) m_editorUpdates.revision) - return; // outdated - - BaseTextEditorWidget *editorWidget = m_textEditor->editorWidget(); - editorWidget->setExtraSelections(BaseTextEditorWidget::CodeWarningsSelection, - m_editorUpdates.selections); - editorWidget->setIfdefedOutBlocks(m_editorUpdates.ifdefedOutBlocks); -} - -void CppEditorSupport::onCurrentEditorChanged() -{ - bool editorVisible = m_textEditor->widget()->isVisible(); - - if (m_editorVisible != editorVisible) { - m_editorVisible = editorVisible; - if (editorVisible) { - m_editorGCTimer->stop(); - if (!lastSemanticInfoDocument()) - updateDocumentNow(); - } else { - m_editorGCTimer->start(EditorHiddenGCTimeout); - } - } -} - -void CppEditorSupport::releaseResources() -{ - m_highlighter.cancel(); - m_highlighter = QFuture<TextEditor::HighlightingResult>(); - documentParser()->releaseResources(); - setSemanticInfo(SemanticInfo(), /*emitSignal=*/ false); - m_lastHighlightOnCompleteSemanticInfo = true; -} - -SemanticInfo::Source CppEditorSupport::currentSource(bool force) -{ - int line = 0, column = 0; - m_textEditor->convertPosition(m_textEditor->editorWidget()->position(), &line, &column); - - return SemanticInfo::Source(Snapshot(), fileName(), contents(), line, column, editorRevision(), - force); -} - -SemanticInfo CppEditorSupport::recalculateSemanticInfoNow(const SemanticInfo::Source &source, - bool emitSignalWhenFinished, - FuturizedTopLevelDeclarationProcessor *processor) -{ - const SemanticInfo lastSemanticInfo = semanticInfo(); - SemanticInfo newSemanticInfo; - - newSemanticInfo.forced = source.force; - newSemanticInfo.revision = source.revision; - - // Try to reuse as much as possible from the last semantic info - if (!source.force - && lastSemanticInfo.complete - && lastSemanticInfo.revision == source.revision - && lastSemanticInfo.doc - && lastSemanticInfo.doc->translationUnit()->ast() - && lastSemanticInfo.doc->fileName() == source.fileName) { - newSemanticInfo.snapshot = lastSemanticInfo.snapshot; // ### TODO: use the new snapshot. - newSemanticInfo.doc = lastSemanticInfo.doc; - - // Otherwise reprocess document - } else { - const BuiltinEditorDocumentParser::Ptr documentParser = documentParser_internal(); - QTC_ASSERT(documentParser, return newSemanticInfo); - newSemanticInfo.snapshot = documentParser->snapshot(); - if (!newSemanticInfo.snapshot.contains(source.fileName)) - return newSemanticInfo; // BuiltinEditorDocumentParser::update() not yet started. - 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; - } - - // Update local uses for the document - TranslationUnit *translationUnit = newSemanticInfo.doc->translationUnit(); - AST *ast = translationUnit->ast(); - FunctionDefinitionUnderCursor functionDefinitionUnderCursor(newSemanticInfo.doc->translationUnit()); - const LocalSymbols useTable(newSemanticInfo.doc, - functionDefinitionUnderCursor(ast, source.line, source.column)); - newSemanticInfo.localUses = useTable.uses; - - // Update semantic info - setSemanticInfo(newSemanticInfo, emitSignalWhenFinished); - - return newSemanticInfo; -} - -void CppEditorSupport::recalculateSemanticInfoDetached_helper(QFutureInterface<void> &future, SemanticInfo::Source source) -{ - FuturizedTopLevelDeclarationProcessor processor(future); - recalculateSemanticInfoNow(source, true, &processor); -} - -bool CppEditorSupport::isSemanticInfoValid() const -{ - const Document::Ptr document = lastSemanticInfoDocument(); - return document - && document->translationUnit()->ast() - && document->fileName() == fileName(); -} - -SemanticInfo CppEditorSupport::semanticInfo() const -{ - QMutexLocker locker(&m_lastSemanticInfoLock); - return m_lastSemanticInfo; -} - -void CppEditorSupport::setSemanticInfo(const SemanticInfo &semanticInfo, bool emitSignal) -{ - { - QMutexLocker locker(&m_lastSemanticInfoLock); - m_lastSemanticInfo = semanticInfo; - } - if (emitSignal) - emit semanticInfoUpdated(semanticInfo); -} - -BuiltinEditorDocumentParser::Ptr CppEditorSupport::documentParser_internal() const -{ - QMutexLocker locker(&m_documentParserLock); - return m_documentParser; -} - -void CppEditorSupport::setDocumentParser_internal(const BuiltinEditorDocumentParser::Ptr &updater) -{ - QMutexLocker locker(&m_documentParserLock); - m_documentParser = updater; -} - -void CppEditorSupport::onMimeTypeChanged() -{ - m_highlighter.cancel(); - m_highlighter.waitForFinished(); - - m_highlightingSupport.reset(m_modelManager->highlightingSupport(m_editorDocument)); - - disconnect(this, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)), - this, SLOT(startHighlighting())); - if (m_highlightingSupport && m_highlightingSupport->requiresSemanticInfo()) - connect(this, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)), - this, SLOT(startHighlighting())); - - m_completionAssistProvider - = m_modelManager->completionAssistProvider(m_editorDocument->mimeType()); - - updateDocumentNow(); -} - -void CppEditorSupport::onAboutToReload() -{ - QTC_CHECK(!m_fileIsBeingReloaded); - m_fileIsBeingReloaded = true; -} - -void CppEditorSupport::onReloadFinished() -{ - QTC_CHECK(m_fileIsBeingReloaded); - m_fileIsBeingReloaded = false; - updateDocument(); -} diff --git a/src/plugins/cpptools/cpptoolseditorsupport.h b/src/plugins/cpptools/cpptoolseditorsupport.h deleted file mode 100644 index f3e4306647..0000000000 --- a/src/plugins/cpptools/cpptoolseditorsupport.h +++ /dev/null @@ -1,253 +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://www.qt.io/licensing. For further information -** use the contact form at http://www.qt.io/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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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 CPPTOOLSEDITORSUPPORT_H -#define CPPTOOLSEDITORSUPPORT_H - -#include "builtineditordocumentparser.h" -#include "cpphighlightingsupport.h" -#include "cppmodelmanager.h" -#include "cppsemanticinfo.h" - -#include <cplusplus/Control.h> -#include <cplusplus/CppDocument.h> - -#include <QFuture> -#include <QObject> -#include <QPointer> -#include <QSharedPointer> -#include <QTimer> - -namespace CPlusPlus { -class AST; -class DeclarationAST; -} // namespace CPlusPlus - -namespace TextEditor { -class BaseTextEditor; -class TextMark; -} // namespace TextEditor - -namespace CppTools { - -class CppCompletionAssistProvider; - -/** - * \brief The CppEditorSupport class oversees the actions that happen when a C++ text editor updates - * its document. - * - * The following steps are taken: - * 1. the text editor document fires a contentsChanged() signal that triggers updateDocument - * 2. update document will start a timer, or reset the timer if it was already running. This way - * subsequent updates (e.g. keypresses) get bunched together instead of running the subsequent - * actions for every key press - * 3. when the timer from step 2 fires, updateDocumentNow() is triggered. That tells the - * model-manager to update the CPlusPlus::Document by re-indexing it. - * 4. when the model-manager finishes, it fires a documentUpdated(CPlusPlus::Document::Ptr) signal, - * that is connected to onDocumentUpdated(CPlusPlus::Document::Ptr), which does 4 things: - * a) updates the ifdeffed-out blocks in the EditorUpdate - * b) calls setExtraDiagnostics with the diagnostics from the parser, which in turn calls - * onDiagnosticsChanged on the UI thread, and that schedules an editor update timer. When this - * timer fires, updateEditorNow() is called, which will apply the updates to the editor. - * c) a semantic-info recalculation is started in a future - * d) the documentUpdated() signal is emitted, which can be used by a widget to do things - * 5. semantic-info calculation from 4c is done by a future that calls recalculateSemanticInfoNow(), - * which emits semanticInfoUpdated() when it is finished. Editors can also listen in on this - * signal to do things like highlighting the local usages. - * 6. the semanticInfoUpdated() is connected to the startHighlighting() slot, which will start - * another future for doing the semantic highlighting. The highlighterStarted signal is emitted, - * with the highlighting future as a parameter, so editors can hook it up to a QFutureWatcher - * and get notifications. - * - * Both the semantic info calculation and the highlighting calculation will cancel an already running - * future. They will also check that the result of a previous step is not already outdated, meaning - * that they check the revision of the editor document to see if a user changed the document while - * the calculation was running. - */ -class CPPTOOLS_EXPORT CppEditorSupport: public QObject -{ - Q_OBJECT - - typedef TextEditor::BlockRange BlockRange; - -public: - CppEditorSupport(Internal::CppModelManager *modelManager, TextEditor::BaseTextEditor *textEditor); - virtual ~CppEditorSupport(); - - QString fileName() const; - - QByteArray contents() const; - unsigned editorRevision() const; - - void setExtraDiagnostics(const QString &key, - const QList<CPlusPlus::Document::DiagnosticMessage> &messages); - void setIfdefedOutBlocks(const QList<BlockRange> &ifdefedOutBlocks); - - /// True after the document was parsed/updated for the first time - /// and the first semantic info calculation was started. - bool initialized(); - - /// Retrieve the semantic info, which will get recalculated on the current - /// thread if it is outdate. Will not emit the semanticInfoUpdated() signal. - SemanticInfo recalculateSemanticInfo(); - - CPlusPlus::Document::Ptr lastSemanticInfoDocument() const; - - enum ForceReason { - NoForce, - ForceDueToInvalidSemanticInfo, - ForceDueEditorRequest - }; - - /// Recalculates the semantic info in a future, and will emit the - /// semanticInfoUpdated() signal when finished. - /// Requires that initialized() is true. - /// \param forceReason the reason to force, if any - void recalculateSemanticInfoDetached(ForceReason forceReason); - - CppCompletionAssistProvider *completionAssistProvider() const; - - BuiltinEditorDocumentParser::Ptr documentParser(); - - /// Checks whether the document is (re)parsed or about to be (re)parsed. - bool isUpdatingDocument(); - -signals: - void documentUpdated(); - void diagnosticsChanged(); - void semanticInfoUpdated(CppTools::SemanticInfo); - void highlighterStarted(QFuture<TextEditor::HighlightingResult> *, unsigned revision); - -private slots: - void onMimeTypeChanged(); - - void onAboutToReload(); - void onReloadFinished(); - - void updateDocument(); - void updateDocumentNow(); - - void onDocumentUpdated(CPlusPlus::Document::Ptr doc); - void startHighlighting(ForceReason forceReason = NoForce); - - void onDiagnosticsChanged(); - - void updateEditor(); - void updateEditorNow(); - - void onCurrentEditorChanged(); - void releaseResources(); - -private: - struct EditorUpdates { - EditorUpdates() - : revision(-1) - {} - int revision; - QList<QTextEdit::ExtraSelection> selections; - QList<BlockRange> ifdefedOutBlocks; - }; - - enum { - UpdateDocumentDefaultInterval = 150, - UpdateEditorInterval = 300, - EditorHiddenGCTimeout = 2 * 60 * 1000 // 2 minutes - }; - -private: - 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; - }; - - SemanticInfo::Source currentSource(bool force); - SemanticInfo recalculateSemanticInfoNow(const SemanticInfo::Source &source, - bool emitSignalWhenFinished, - FuturizedTopLevelDeclarationProcessor *processor = 0); - void recalculateSemanticInfoDetached_helper(QFutureInterface<void> &future, - SemanticInfo::Source source); - - bool isSemanticInfoValid() const; - SemanticInfo semanticInfo() const; - void setSemanticInfo(const SemanticInfo &semanticInfo, bool emitSignal = true); - - BuiltinEditorDocumentParser::Ptr documentParser_internal() const; - void setDocumentParser_internal(const BuiltinEditorDocumentParser::Ptr &updater); - -private: - Internal::CppModelManager *m_modelManager; - QPointer<TextEditor::BaseTextEditor> m_textEditor; - TextEditor::BaseTextDocument *m_editorDocument; - QTimer *m_updateDocumentTimer; - int m_updateDocumentInterval; - unsigned m_revision; - - QTimer *m_editorGCTimer; - bool m_editorVisible; - - // content caching - mutable QMutex m_cachedContentsLock; - mutable QByteArray m_cachedContents; - mutable int m_cachedContentsEditorRevision; - bool m_fileIsBeingReloaded; - - QTimer *m_updateEditorTimer; - EditorUpdates m_editorUpdates; - - QMutex m_diagnosticsMutex; - QHash<QString, QList<CPlusPlus::Document::DiagnosticMessage> > m_allDiagnostics; - - // Semantic info: - bool m_initialized; - mutable QMutex m_lastSemanticInfoLock; - SemanticInfo m_lastSemanticInfo; - QFuture<void> m_futureSemanticInfo; - mutable QMutex m_documentParserLock; - BuiltinEditorDocumentParser::Ptr m_documentParser; - QFuture<void> m_documentParserFuture; - - // Highlighting: - unsigned m_lastHighlightRevision; - bool m_lastHighlightOnCompleteSemanticInfo; - QFuture<TextEditor::HighlightingResult> m_highlighter; - QScopedPointer<CppTools::CppHighlightingSupport> m_highlightingSupport; - - // Completion: - CppCompletionAssistProvider *m_completionAssistProvider; -}; - -} // namespace CppTools - -#endif // CPPTOOLSEDITORSUPPORT_H |