aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-10-24 12:03:52 +0200
committerEike Ziller <eike.ziller@qt.io>2019-10-24 12:31:14 +0000
commitd59eb32ce6271f8f7069b4d526ba767ae59c8aed (patch)
tree5a36f4ba921cac301751d05d91d7b0eefaa66340 /plugins
parent126fe0fa0b58e3d70ca1109336f784d5659c846f (diff)
Remove support for ghc-mod
ghc-mod is no longer active and doesn't even compile against newer GHC versions. Use haskell-ide-engine and Qt Creator's language protocol client instead. Change-Id: I5776ec8375c732b8066d09e629148ae222e981c5 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/haskell/CMakeLists.txt7
-rw-r--r--plugins/haskell/filecache.cpp139
-rw-r--r--plugins/haskell/filecache.h61
-rw-r--r--plugins/haskell/followsymbol.cpp141
-rw-r--r--plugins/haskell/followsymbol.h94
-rw-r--r--plugins/haskell/ghcmod.cpp408
-rw-r--r--plugins/haskell/ghcmod.h150
-rw-r--r--plugins/haskell/haskell.pro14
-rw-r--r--plugins/haskell/haskell.qbs7
-rw-r--r--plugins/haskell/haskellcompletionassist.cpp44
-rw-r--r--plugins/haskell/haskellcompletionassist.h45
-rw-r--r--plugins/haskell/haskelldocument.cpp51
-rw-r--r--plugins/haskell/haskelldocument.h51
-rw-r--r--plugins/haskell/haskelleditorfactory.cpp9
-rw-r--r--plugins/haskell/haskelleditorwidget.cpp113
-rw-r--r--plugins/haskell/haskelleditorwidget.h60
-rw-r--r--plugins/haskell/haskellhoverhandler.cpp166
-rw-r--r--plugins/haskell/haskellhoverhandler.h57
-rw-r--r--plugins/haskell/haskellmanager.cpp23
-rw-r--r--plugins/haskell/haskellmanager.h5
-rw-r--r--plugins/haskell/haskellplugin.cpp3
21 files changed, 1 insertions, 1647 deletions
diff --git a/plugins/haskell/CMakeLists.txt b/plugins/haskell/CMakeLists.txt
index d2e08af..1b5ec8f 100644
--- a/plugins/haskell/CMakeLists.txt
+++ b/plugins/haskell/CMakeLists.txt
@@ -6,19 +6,12 @@ add_qtc_plugin(Haskell
QtCreator::Core QtCreator::TextEditor QtCreator::ProjectExplorer
DEPENDS Qt5::Widgets
SOURCES
- filecache.cpp filecache.h
- followsymbol.cpp followsymbol.h
- ghcmod.cpp ghcmod.h
haskell.qrc
haskell_global.h
haskellbuildconfiguration.cpp haskellbuildconfiguration.h
- haskellcompletionassist.cpp haskellcompletionassist.h
haskellconstants.h
- haskelldocument.cpp haskelldocument.h
haskelleditorfactory.cpp haskelleditorfactory.h
- haskelleditorwidget.cpp haskelleditorwidget.h
haskellhighlighter.cpp haskellhighlighter.h
- haskellhoverhandler.cpp haskellhoverhandler.h
haskellmanager.cpp haskellmanager.h
haskellplugin.cpp haskellplugin.h
haskellproject.cpp haskellproject.h
diff --git a/plugins/haskell/filecache.cpp b/plugins/haskell/filecache.cpp
deleted file mode 100644
index 5d931c9..0000000
--- a/plugins/haskell/filecache.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "filecache.h"
-
-#include <coreplugin/idocument.h>
-#include <texteditor/textdocument.h>
-#include <utils/algorithm.h>
-
-#include <QFile>
-#include <QLoggingCategory>
-#include <QTemporaryFile>
-#include <QTextDocument>
-
-Q_LOGGING_CATEGORY(cacheLog, "qtc.haskell.filecache", QtWarningMsg)
-
-using namespace Core;
-using namespace TextEditor;
-using namespace Utils;
-
-namespace Haskell {
-namespace Internal {
-
-FileCache::FileCache(const QString &id,
- const std::function<QList<Core::IDocument *>()> &documentsToUpdate)
- : m_tempDir(id),
- m_documentsToUpdate(documentsToUpdate)
-{
- qCDebug(cacheLog) << "creating cache path at" << m_tempDir.path();
-}
-
-
-void FileCache::update()
-{
- const QList<IDocument *> documents = m_documentsToUpdate();
- for (IDocument *document : documents) {
- const Utils::FilePath filePath = document->filePath();
- if (m_fileMap.contains(filePath)) {
- // update the existing cached file
- // check revision if possible
- if (auto textDocument = qobject_cast<TextDocument *>(document)) {
- if (m_fileRevision.value(filePath) != textDocument->document()->revision())
- writeFile(document);
- } else {
- writeFile(document);
- }
- } else {
- // save file if it is modified
- if (document->isModified())
- writeFile(document);
- }
- }
- cleanUp(documents);
-}
-
-QHash<FilePath, FilePath> FileCache::fileMap() const
-{
- return m_fileMap;
-}
-
-void FileCache::writeFile(IDocument *document)
-{
- FilePath cacheFilePath = m_fileMap.value(document->filePath());
- if (cacheFilePath.isEmpty()) {
- cacheFilePath = createCacheFile(document->filePath());
- m_fileMap.insert(document->filePath(), cacheFilePath);
- }
- qCDebug(cacheLog) << "writing" << cacheFilePath;
- if (auto baseTextDocument = qobject_cast<BaseTextDocument *>(document)) {
- QString errorMessage;
- if (baseTextDocument->write(cacheFilePath.toString(),
- QString::fromUtf8(baseTextDocument->contents()),
- &errorMessage)) {
- if (auto textDocument = qobject_cast<TextDocument *>(document)) {
- m_fileRevision.insert(document->filePath(), textDocument->document()->revision());
- } else {
- m_fileRevision.insert(document->filePath(), -1);
- }
- } else {
- qCDebug(cacheLog) << "!!! writing file failed:" << errorMessage;
- }
-
- } else {
- QFile file(cacheFilePath.toString());
- if (file.open(QIODevice::WriteOnly)) {
- file.write(document->contents());
- } else {
- qCDebug(cacheLog) << "!!! opening file for writing failed";
- }
- }
-}
-
-void FileCache::cleanUp(const QList<IDocument *> &documents)
-{
- const QSet<FilePath> files = Utils::transform<QSet>(documents, &IDocument::filePath);
- auto it = QMutableHashIterator<FilePath, FilePath>(m_fileMap);
- while (it.hasNext()) {
- it.next();
- if (!files.contains(it.key())) {
- qCDebug(cacheLog) << "deleting" << it.value();
- QFile::remove(it.value().toString());
- m_fileRevision.remove(it.key());
- it.remove();
- }
- }
-}
-
-FilePath FileCache::createCacheFile(const FilePath &filePath)
-{
- QTemporaryFile tempFile(m_tempDir.path() + "/XXXXXX-" + filePath.fileName());
- tempFile.setAutoRemove(false);
- tempFile.open();
- return FilePath::fromString(tempFile.fileName());
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/filecache.h b/plugins/haskell/filecache.h
deleted file mode 100644
index 3c53d40..0000000
--- a/plugins/haskell/filecache.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <utils/fileutils.h>
-#include <utils/temporarydirectory.h>
-
-#include <QHash>
-
-#include <functional>
-
-namespace Core { class IDocument; }
-
-namespace Haskell {
-namespace Internal {
-
-class FileCache
-{
-public:
- FileCache(const QString &id,
- const std::function<QList<Core::IDocument *>()> &documentsToUpdate);
-
- void update();
- QHash<Utils::FilePath, Utils::FilePath> fileMap() const;
-
-private:
- void writeFile(Core::IDocument *document);
- void cleanUp(const QList<Core::IDocument *> &documents);
- Utils::FilePath createCacheFile(const Utils::FilePath &filePath);
-
- Utils::TemporaryDirectory m_tempDir;
- QHash<Utils::FilePath, Utils::FilePath> m_fileMap;
- QHash<Utils::FilePath, int> m_fileRevision;
- std::function<QList<Core::IDocument *>()> m_documentsToUpdate;
-};
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/followsymbol.cpp b/plugins/haskell/followsymbol.cpp
deleted file mode 100644
index ab32614..0000000
--- a/plugins/haskell/followsymbol.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "followsymbol.h"
-
-#include "haskelleditorwidget.h"
-#include "haskellmanager.h"
-#include "haskelltokenizer.h"
-
-#include <coreplugin/editormanager/editormanager.h>
-#include <texteditor/codeassist/assistinterface.h>
-#include <texteditor/codeassist/assistproposalitem.h>
-#include <texteditor/codeassist/genericproposal.h>
-#include <texteditor/codeassist/genericproposalmodel.h>
-
-#include <utils/qtcassert.h>
-
-using namespace TextEditor;
-using namespace Utils;
-
-namespace Haskell {
-namespace Internal {
-
-IAssistProvider::RunType FollowSymbolAssistProvider::runType() const
-{
- return AsynchronousWithThread;
-}
-
-IAssistProcessor *FollowSymbolAssistProvider::createProcessor() const
-{
- return new FollowSymbolAssistProcessor(m_inNextSplit);
-}
-
-void FollowSymbolAssistProvider::setOpenInNextSplit(bool inNextSplit)
-{
- m_inNextSplit = inNextSplit;
-}
-
-FollowSymbolAssistProcessor::FollowSymbolAssistProcessor(bool inNextSplit)
- : m_inNextSplit(inNextSplit)
-{
-}
-
-IAssistProposal *FollowSymbolAssistProcessor::immediateProposal(const AssistInterface *interface)
-{
- int line, column;
- const optional<Token> symbol
- = HaskellEditorWidget::symbolAt(interface->textDocument(), interface->position(),
- &line, &column);
- QTC_ASSERT(symbol, return nullptr); // should have been checked before
- const auto filePath = FilePath::fromString(interface->fileName());
- m_ghcmod = HaskellManager::ghcModForFile(filePath);
- m_symbolFuture = m_ghcmod->findSymbol(filePath, symbol->text.toString());
-
- auto item = new AssistProposalItem();
- item->setText(HaskellManager::trLookingUp(symbol->text.toString()));
- item->setData(QString());
- item->setOrder(-1000);
-
- const QList<TextEditor::AssistProposalItemInterface *> list = {item};
- auto proposal = new GenericProposal(interface->position(), list);
- proposal->setFragile(true);
- return proposal;
-}
-
-IAssistProposal *FollowSymbolAssistProcessor::perform(const AssistInterface *interface)
-{
- const int position = interface->position();
- delete interface;
- const SymbolInfoOrError info = m_symbolFuture.result();
- auto item = new FollowSymbolAssistProposalItem(m_ghcmod->basePath(), info, m_inNextSplit);
- return new InstantProposal(position, {item});
-}
-
-FollowSymbolAssistProposalItem::FollowSymbolAssistProposalItem(const FilePath &basePath,
- const SymbolInfoOrError &info,
- bool inNextSplit)
- : m_basePath(basePath),
- m_inNextSplit(inNextSplit)
-{
- const SymbolInfo *info_p = Utils::get_if<SymbolInfo>(&info);
- if (info_p && !info_p->file.isEmpty()) {
- m_info = info;
- setText(m_basePath.toString() + '/' + info_p->file.toString());
- }
-}
-
-void FollowSymbolAssistProposalItem::apply(TextDocumentManipulatorInterface &, int) const
-{
- const SymbolInfo *info_p = Utils::get_if<SymbolInfo>(&m_info);
- if (info_p)
- Core::EditorManager::openEditorAt(m_basePath.toString() + '/' + info_p->file.toString(),
- info_p->line, info_p->col - 1, Core::Id(),
- m_inNextSplit ? Core::EditorManager::OpenInOtherSplit
- : Core::EditorManager::NoFlags);
-}
-
-void InstantActivationProposalWidget::showProposal(const QString &prefix)
-{
- if (model() && model()->size() == 1) {
- emit proposalItemActivated(model()->proposalItem(0));
- deleteLater();
- return;
- }
- GenericProposalWidget::showProposal(prefix);
-}
-
-InstantProposal::InstantProposal(int cursorPos, const QList<AssistProposalItemInterface *> &items)
- : GenericProposal(cursorPos, items)
-{
-}
-
-IAssistProposalWidget *InstantProposal::createWidget() const
-{
- return new InstantActivationProposalWidget();
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/followsymbol.h b/plugins/haskell/followsymbol.h
deleted file mode 100644
index a4f9051..0000000
--- a/plugins/haskell/followsymbol.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "ghcmod.h"
-
-#include <texteditor/codeassist/assistproposalitem.h>
-#include <texteditor/codeassist/genericproposal.h>
-#include <texteditor/codeassist/genericproposalwidget.h>
-#include <texteditor/codeassist/iassistprocessor.h>
-#include <texteditor/codeassist/iassistprovider.h>
-
-namespace Haskell {
-namespace Internal {
-
-class FollowSymbolAssistProposalItem : public TextEditor::AssistProposalItem
-{
-public:
- FollowSymbolAssistProposalItem(const Utils::FilePath &basePath,
- const SymbolInfoOrError &info,
- bool inNextSplit);
-
- void apply(TextEditor::TextDocumentManipulatorInterface &, int) const override;
-
-private:
- Utils::FilePath m_basePath;
- SymbolInfoOrError m_info;
- bool m_inNextSplit;
-};
-
-class InstantActivationProposalWidget : public TextEditor::GenericProposalWidget
-{
-protected:
- void showProposal(const QString &prefix) override;
-};
-
-class InstantProposal : public TextEditor::GenericProposal
-{
-public:
- InstantProposal(int cursorPos, const QList<TextEditor::AssistProposalItemInterface *> &items);
-
- TextEditor::IAssistProposalWidget *createWidget() const override;
-};
-
-class FollowSymbolAssistProvider : public TextEditor::IAssistProvider
-{
-public:
- RunType runType() const override;
- TextEditor::IAssistProcessor *createProcessor() const override;
- void setOpenInNextSplit(bool inNextSplit);
-
-private:
- bool m_inNextSplit = false;
-};
-
-class FollowSymbolAssistProcessor : public TextEditor::IAssistProcessor
-{
-public:
- FollowSymbolAssistProcessor(bool inNextSplit);
-
- TextEditor::IAssistProposal *immediateProposal(const TextEditor::AssistInterface *interface) override;
- TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override;
-
-private:
- std::shared_ptr<AsyncGhcMod> m_ghcmod;
- QFuture<SymbolInfoOrError> m_symbolFuture;
- bool m_inNextSplit;
-};
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/ghcmod.cpp b/plugins/haskell/ghcmod.cpp
deleted file mode 100644
index 1ca7713..0000000
--- a/plugins/haskell/ghcmod.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "ghcmod.h"
-
-#include <coreplugin/editormanager/documentmodel.h>
-#include <coreplugin/idocument.h>
-#include <utils/algorithm.h>
-#include <utils/environment.h>
-#include <utils/qtcassert.h>
-
-#include <QFileInfo>
-#include <QFutureWatcher>
-#include <QLoggingCategory>
-#include <QMetaObject>
-#include <QMutexLocker>
-#include <QProcess>
-#include <QRegularExpression>
-#include <QTime>
-#include <QTimer>
-
-#include <functional>
-
-Q_LOGGING_CATEGORY(ghcModLog, "qtc.haskell.ghcmod", QtWarningMsg)
-Q_LOGGING_CATEGORY(asyncGhcModLog, "qtc.haskell.ghcmod.async", QtWarningMsg)
-
-// TODO do not hardcode
-const int kTimeoutMS = 10 * 1000;
-
-using namespace Utils;
-
-namespace Haskell {
-namespace Internal {
-
-FilePath GhcMod::m_stackExecutable = Utils::FilePath::fromString("stack");
-QMutex GhcMod::m_mutex;
-
-GhcMod::GhcMod(const Utils::FilePath &path)
- : m_path(path)
-{
-}
-
-GhcMod::~GhcMod()
-{
- shutdown();
-}
-
-FilePath GhcMod::basePath() const
-{
- return m_path;
-}
-
-void GhcMod::setFileMap(const QHash<FilePath, FilePath> &fileMap)
-{
- if (fileMap != m_fileMap) {
- log("setting new file map");
- m_fileMap = fileMap;
- shutdown();
- }
-}
-
-static QString toUnicode(QByteArray data)
-{
- // clean zero bytes which let QString think that the string ends there
- data.replace('\x0', QByteArray());
- return QString::fromUtf8(data);
-}
-
-SymbolInfoOrError GhcMod::findSymbol(const FilePath &filePath, const QString &symbol)
-{
- return parseFindSymbol(runFindSymbol(filePath, symbol));
-}
-
-QStringOrError GhcMod::typeInfo(const FilePath &filePath, int line, int col)
-{
- return parseTypeInfo(runTypeInfo(filePath, line, col));
-}
-
-static QStringList fileMapArgs(const QHash<FilePath, FilePath> &map)
-{
- QStringList result;
- const auto end = map.cend();
- for (auto it = map.cbegin(); it != end; ++it)
- result << "--map-file" << it.key().toString() + "=" + it.value().toString();
- return result;
-}
-
-Utils::optional<Error> GhcMod::ensureStarted()
-{
- m_mutex.lock();
- const FilePath plainStackExecutable = m_stackExecutable;
- m_mutex.unlock();
- Environment env = Environment::systemEnvironment();
- const FilePath stackExecutable = env.searchInPath(plainStackExecutable.toString());
- if (m_process) {
- if (m_process->state() == QProcess::NotRunning) {
- log("is no longer running");
- m_process.reset();
- } else if (FilePath::fromString(m_process->program()) != stackExecutable) {
- log("stack settings changed");
- shutdown();
- }
- }
- if (m_process)
- return Utils::nullopt;
- log("starting");
- // for ghc-mod finding stack back:
- env.prependOrSetPath(stackExecutable.toFileInfo().absolutePath());
- m_process.reset(new QProcess);
- m_process->setWorkingDirectory(m_path.toString());
- m_process->setEnvironment(env.toStringList());
- m_process->start(stackExecutable.toString(),
- QStringList{"exec", "ghc-mod", "--"} + fileMapArgs(m_fileMap)
- << "legacy-interactive");
- if (!m_process->waitForStarted(kTimeoutMS)) {
- log("failed to start");
- m_process.reset();
- return Error({Error::Type::FailedToStartStack, plainStackExecutable.toUserOutput()});
- }
- log("started");
- m_process->setReadChannel(QProcess::StandardOutput);
- return Utils::nullopt;
-}
-
-void GhcMod::shutdown()
-{
- if (!m_process)
- return;
- log("shutting down");
- m_process->write("\n");
- m_process->closeWriteChannel();
- m_process->waitForFinished(300);
- m_process.reset();
-}
-
-void GhcMod::log(const QString &message)
-{
- qCDebug(ghcModLog) << "ghcmod for" << m_path.toString() << ":" << qPrintable(message);
-}
-
-QByteArrayOrError GhcMod::runQuery(const QString &query)
-{
- const Utils::optional<Error> error = ensureStarted();
- if (error)
- return error.value();
- log("query \"" + query + "\"");
- m_process->write(query.toUtf8() + "\n");
- bool ok = false;
- QByteArray response;
- QTime readTime;
- readTime.start();
- while (!ok && readTime.elapsed() < kTimeoutMS) {
- m_process->waitForReadyRead(kTimeoutMS - readTime.elapsed() + 10);
- response += m_process->read(2048);
- ok = response.endsWith("OK\n") || response.endsWith("OK\r\n");
- }
- if (ghcModLog().isDebugEnabled())
- qCDebug(ghcModLog) << "response" << QTextCodec::codecForLocale()->toUnicode(response);
- if (!ok) {
- log("failed");
- shutdown();
- return Error({Error::Type::Other, QString()});
- }
- log("success");
- // convert to unix line endings
- response.replace("\r\n", "\n");
- response.chop(3); // cut off "OK\n"
- return response;
-}
-
-QByteArrayOrError GhcMod::runFindSymbol(const FilePath &filePath, const QString &symbol)
-{
- return runQuery(QString("info %1 %2").arg(filePath.toString()) // TODO toNative? quoting?
- .arg(symbol));
-}
-
-QByteArrayOrError GhcMod::runTypeInfo(const FilePath &filePath, int line, int col)
-{
- return runQuery(QString("type %1 %2 %3").arg(filePath.toString()) // TODO toNative? quoting?
- .arg(line)
- .arg(col + 1));
-}
-
-SymbolInfoOrError GhcMod::parseFindSymbol(const QByteArrayOrError &response)
-{
- QRegularExpression infoRegEx("^\\s*(.*?)\\s+--\\sDefined ((at (.+?)(:(\\d+):(\\d+))?)|(in ‘(.+)’.*))$");
- const QByteArray *bytes = Utils::get_if<QByteArray>(&response);
- if (!bytes)
- return Utils::get<Error>(response);
- SymbolInfo info;
- bool hasFileOrModule = false;
- const QString str = toUnicode(QByteArray(*bytes).replace('\x0', '\n'));
- for (const QString &line : str.split('\n')) {
- if (hasFileOrModule) {
- info.additionalInfo += line;
- } else {
- QRegularExpressionMatch result = infoRegEx.match(line);
- if (result.hasMatch()) {
- hasFileOrModule = true;
- info.definition += result.captured(1);
- if (result.lastCapturedIndex() == 7) { // Defined at <file:line:col>
- info.file = FilePath::fromString(result.captured(4));
- bool ok;
- int num = result.captured(6).toInt(&ok);
- if (ok)
- info.line = num;
- num = result.captured(7).toInt(&ok);
- if (ok)
- info.col = num;
- } else if (result.lastCapturedIndex() == 9) { // Defined in <module>
- info.module = result.captured(9);
- }
- } else {
- info.definition += line;
- }
- }
- }
- if (hasFileOrModule)
- return info;
- return Error({Error::Type::Other, QString()});
-}
-
-QStringOrError GhcMod::parseTypeInfo(const QByteArrayOrError &response)
-{
- QRegularExpression typeRegEx("^\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\"(.*)\"$",
- QRegularExpression::MultilineOption);
- const QByteArray *bytes = Utils::get_if<QByteArray>(&response);
- if (!bytes)
- return Utils::get<Error>(response);
- QRegularExpressionMatch result = typeRegEx.match(toUnicode(*bytes));
- if (result.hasMatch())
- return result.captured(1);
- return Error({Error::Type::Other, QString()});
-}
-
-void GhcMod::setStackExecutable(const FilePath &filePath)
-{
- QMutexLocker lock(&m_mutex);
- m_stackExecutable = filePath;
-}
-
-static QList<Core::IDocument *> getOpenDocuments(const FilePath &path)
-{
- return Utils::filtered(Core::DocumentModel::openedDocuments(), [path] (Core::IDocument *doc) {
- return path.isEmpty() || doc->filePath().isChildOf(path);
- });
-}
-
-AsyncGhcMod::AsyncGhcMod(const FilePath &path)
- : m_ghcmod(path),
- m_fileCache("haskell", std::bind(getOpenDocuments, path))
-{
- qCDebug(asyncGhcModLog) << "starting thread for" << m_ghcmod.basePath().toString();
- m_thread.start();
- m_threadTarget.moveToThread(&m_thread);
-}
-
-AsyncGhcMod::~AsyncGhcMod()
-{
- qCDebug(asyncGhcModLog) << "stopping thread for" << m_ghcmod.basePath().toString();
- m_mutex.lock();
- for (Operation &op : m_queue)
- op.fi.cancel();
- m_queue.clear();
- m_mutex.unlock();
- m_thread.quit();
- m_thread.wait();
-}
-
-FilePath AsyncGhcMod::basePath() const
-{
- return m_ghcmod.basePath();
-}
-
-template <typename Result>
-QFuture<Result> createFuture(AsyncGhcMod::Operation op,
- const std::function<Result(const QByteArrayOrError &)> &postOp)
-{
- auto fi = new QFutureInterface<Result>;
- fi->reportStarted();
-
- // propagate inner events to outside future
- auto opWatcher = new QFutureWatcher<QByteArrayOrError>();
- QObject::connect(opWatcher, &QFutureWatcherBase::canceled, [fi] { fi->cancel(); });
- QObject::connect(opWatcher, &QFutureWatcherBase::finished, opWatcher, &QObject::deleteLater);
- QObject::connect(opWatcher, &QFutureWatcherBase::finished, [fi] {
- fi->reportFinished();
- delete fi;
- });
- QObject::connect(opWatcher, &QFutureWatcherBase::resultReadyAt,
- [fi, opWatcher, postOp](int index) {
- fi->reportResult(postOp(opWatcher->future().resultAt(index)));
- });
- opWatcher->setFuture(op.fi.future());
-
- // propagate cancel from outer future to inner future
- auto fiWatcher = new QFutureWatcher<Result>();
- QObject::connect(fiWatcher, &QFutureWatcherBase::canceled, [op] { op.fi.cancel(); });
- QObject::connect(fiWatcher, &QFutureWatcherBase::finished, fiWatcher, &QObject::deleteLater);
- fiWatcher->setFuture(fi->future());
-
- return fi->future();
-}
-
-/*!
- Asynchronously looks up the \a symbol in the context of \a filePath.
-
- Returns a QFuture handle for the asynchronous operation. You may not block the main event loop
- while waiting for it to finish - doing so will result in a deadlock.
-*/
-QFuture<SymbolInfoOrError> AsyncGhcMod::findSymbol(const FilePath &filePath,
- const QString &symbol)
-{
- QMutexLocker lock(&m_mutex);
- Operation op([this, filePath, symbol] { return m_ghcmod.runFindSymbol(filePath, symbol); });
- m_queue.append(op);
- QTimer::singleShot(0, &m_threadTarget, [this] { reduceQueue(); });
- return createFuture<SymbolInfoOrError>(op, &GhcMod::parseFindSymbol);
-}
-
-/*!
- Asynchronously looks up the type at \a line and \a col in \a filePath.
-
- Returns a QFuture handle for the asynchronous operation. You may not block the main event loop
- while waiting for it to finish - doing so will result in a deadlock.
-*/
-QFuture<QStringOrError> AsyncGhcMod::typeInfo(const FilePath &filePath, int line, int col)
-{
- QMutexLocker lock(&m_mutex);
- Operation op([this, filePath, line, col] { return m_ghcmod.runTypeInfo(filePath, line, col); });
- m_queue.append(op);
- QTimer::singleShot(0, &m_threadTarget, [this] { reduceQueue(); });
- return createFuture<QStringOrError>(op, &GhcMod::parseTypeInfo);
-}
-
-/*!
- Synchronously runs an update of the cache of modified files.
- This must be run on the main thread.
-
- \internal
-*/
-void AsyncGhcMod::updateCache()
-{
- m_fileCache.update();
-}
-
-/*!
- Takes operations from the queue and executes them, until the queue is empty.
- This must be run within the internal thread whenever an operation is added to the queue.
- Canceled operations are not executed, but removed from the queue.
- Before each operation, the cache of modified files is updated on the main thread.
-
- \internal
-*/
-void AsyncGhcMod::reduceQueue()
-{
- QTC_ASSERT(QThread::currentThread() != thread(), return);
- const auto takeFirst = [this]() {
- Operation op;
- m_mutex.lock();
- if (!m_queue.isEmpty())
- op = m_queue.takeFirst();
- m_mutex.unlock();
- return op;
- };
-
- Operation op;
- while ((op = takeFirst()).op) {
- if (!op.fi.isCanceled()) {
- QMetaObject::invokeMethod(this, "updateCache", Qt::BlockingQueuedConnection);
- m_ghcmod.setFileMap(m_fileCache.fileMap());
- QByteArrayOrError result = op.op();
- op.fi.reportResult(result);
- }
- op.fi.reportFinished();
- }
-}
-
-AsyncGhcMod::Operation::Operation(const std::function<QByteArrayOrError()> &op)
- : op(op)
-{
- fi.reportStarted();
-}
-
-} // Internal
-} // Haskell
diff --git a/plugins/haskell/ghcmod.h b/plugins/haskell/ghcmod.h
deleted file mode 100644
index fb3dd3f..0000000
--- a/plugins/haskell/ghcmod.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "filecache.h"
-
-#include <utils/fileutils.h>
-#include <utils/optional.h>
-#include <utils/synchronousprocess.h>
-#include <utils/variant.h>
-
-#include <QFuture>
-#include <QMutex>
-#include <QThread>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-class QProcess;
-QT_END_NAMESPACE
-
-namespace Haskell {
-namespace Internal {
-
-class Error {
-public:
- enum class Type {
- FailedToStartStack,
- Other // TODO get rid of it
- };
- Type type;
- QString details;
-};
-
-class SymbolInfo {
-public:
- QStringList definition;
- QStringList additionalInfo;
- Utils::FilePath file;
- int line = -1;
- int col = -1;
- QString module;
-};
-
-using QByteArrayOrError = Utils::variant<QByteArray, Error>;
-using QStringOrError = Utils::variant<QString, Error>;
-using SymbolInfoOrError = Utils::variant<SymbolInfo, Error>;
-
-template <typename T> class ghcmod_deleter;
-template <> class ghcmod_deleter<QProcess>
-{
-public:
- void operator()(QProcess *p) { Utils::SynchronousProcess::stopProcess(*p); delete p; }
-};
-using unique_ghcmod_process = std::unique_ptr<QProcess, ghcmod_deleter<QProcess>>;
-
-class GhcMod
-{
-public:
- GhcMod(const Utils::FilePath &path);
- ~GhcMod();
-
- Utils::FilePath basePath() const;
- void setFileMap(const QHash<Utils::FilePath, Utils::FilePath> &fileMap);
-
- SymbolInfoOrError findSymbol(const Utils::FilePath &filePath, const QString &symbol);
- QStringOrError typeInfo(const Utils::FilePath &filePath, int line, int col);
-
- QByteArrayOrError runQuery(const QString &query);
-
- QByteArrayOrError runFindSymbol(const Utils::FilePath &filePath, const QString &symbol);
- QByteArrayOrError runTypeInfo(const Utils::FilePath &filePath, int line, int col);
-
- static SymbolInfoOrError parseFindSymbol(const QByteArrayOrError &response);
- static QStringOrError parseTypeInfo(const QByteArrayOrError &response);
-
- static void setStackExecutable(const Utils::FilePath &filePath);
-
-private:
- Utils::optional<Error> ensureStarted();
- void shutdown();
- void log(const QString &message);
-
- static Utils::FilePath m_stackExecutable;
- static QMutex m_mutex;
-
- Utils::FilePath m_path;
- unique_ghcmod_process m_process; // kills process on reset
- QHash<Utils::FilePath, Utils::FilePath> m_fileMap;
-};
-
-class AsyncGhcMod : public QObject
-{
- Q_OBJECT
-
-public:
- struct Operation {
- Operation() = default;
- Operation(const std::function<QByteArrayOrError()> &op);
- mutable QFutureInterface<QByteArrayOrError> fi;
- std::function<QByteArrayOrError()> op;
- };
-
- AsyncGhcMod(const Utils::FilePath &path);
- ~AsyncGhcMod();
-
- Utils::FilePath basePath() const;
-
- QFuture<SymbolInfoOrError> findSymbol(const Utils::FilePath &filePath, const QString &symbol);
- QFuture<QStringOrError> typeInfo(const Utils::FilePath &filePath, int line, int col);
-
-private slots:
- void updateCache(); // called through QMetaObject::invokeMethod
-
-private:
- void reduceQueue();
-
- QThread m_thread;
- QObject m_threadTarget; // used to run methods in m_thread
- GhcMod m_ghcmod; // only use in m_thread
- FileCache m_fileCache; // only update through reduceQueue
- QVector<Operation> m_queue;
- QMutex m_mutex;
-};
-
-} // Internal
-} // Haskell
diff --git a/plugins/haskell/haskell.pro b/plugins/haskell/haskell.pro
index 92d0307..df46a27 100644
--- a/plugins/haskell/haskell.pro
+++ b/plugins/haskell/haskell.pro
@@ -3,19 +3,12 @@ DEFINES += HASKELL_LIBRARY
# Haskell files
SOURCES += \
- haskellcompletionassist.cpp \
haskelleditorfactory.cpp \
- haskellhoverhandler.cpp \
haskellplugin.cpp \
haskellhighlighter.cpp \
haskelltokenizer.cpp \
- ghcmod.cpp \
haskellmanager.cpp \
- haskelldocument.cpp \
optionspage.cpp \
- filecache.cpp \
- haskelleditorwidget.cpp \
- followsymbol.cpp \
haskellproject.cpp \
haskellbuildconfiguration.cpp \
stackbuildstep.cpp \
@@ -23,20 +16,13 @@ SOURCES += \
HEADERS += \
haskell_global.h \
- haskellcompletionassist.h \
haskellconstants.h \
haskelleditorfactory.h \
- haskellhoverhandler.h \
haskellplugin.h \
haskellhighlighter.h \
haskelltokenizer.h \
- ghcmod.h \
haskellmanager.h \
- haskelldocument.h \
optionspage.h \
- filecache.h \
- haskelleditorwidget.h \
- followsymbol.h \
haskellproject.h \
haskellbuildconfiguration.h \
stackbuildstep.h \
diff --git a/plugins/haskell/haskell.qbs b/plugins/haskell/haskell.qbs
index d2296a9..30eb832 100644
--- a/plugins/haskell/haskell.qbs
+++ b/plugins/haskell/haskell.qbs
@@ -11,19 +11,12 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
files: [
- "filecache.cpp", "filecache.h",
- "followsymbol.cpp", "followsymbol.h",
- "ghcmod.cpp", "ghcmod.h",
"haskell.qrc",
"haskellbuildconfiguration.cpp", "haskellbuildconfiguration.h",
- "haskellcompletionassist.cpp", "haskellcompletionassist.h",
"haskellconstants.h",
- "haskelldocument.cpp", "haskelldocument.h",
"haskelleditorfactory.cpp", "haskelleditorfactory.h",
- "haskelleditorwidget.cpp", "haskelleditorwidget.h",
"haskell_global.h",
"haskellhighlighter.cpp", "haskellhighlighter.h",
- "haskellhoverhandler.cpp", "haskellhoverhandler.h",
"haskellmanager.cpp", "haskellmanager.h",
"haskellplugin.cpp", "haskellplugin.h",
"haskellproject.cpp", "haskellproject.h",
diff --git a/plugins/haskell/haskellcompletionassist.cpp b/plugins/haskell/haskellcompletionassist.cpp
deleted file mode 100644
index aa053f5..0000000
--- a/plugins/haskell/haskellcompletionassist.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "haskellcompletionassist.h"
-
-#include "haskellconstants.h"
-
-#include <coreplugin/id.h>
-#include <texteditor/codeassist/keywordscompletionassist.h>
-
-namespace Haskell {
-namespace Internal {
-
-TextEditor::IAssistProcessor *HaskellCompletionAssistProvider::createProcessor() const
-{
- auto processor = new TextEditor::KeywordsCompletionAssistProcessor(TextEditor::Keywords());
- processor->setSnippetGroup(Constants::C_HASKELLSNIPPETSGROUP_ID);
- return processor;
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskellcompletionassist.h b/plugins/haskell/haskellcompletionassist.h
deleted file mode 100644
index 9b3f0ca..0000000
--- a/plugins/haskell/haskellcompletionassist.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#ifndef HASKELLCOMPLETIONASSIST_H
-#define HASKELLCOMPLETIONASSIST_H
-
-#include <texteditor/codeassist/completionassistprovider.h>
-
-namespace Haskell {
-namespace Internal {
-
-class HaskellCompletionAssistProvider : public TextEditor::CompletionAssistProvider
-{
- Q_OBJECT
-
-public:
- TextEditor::IAssistProcessor *createProcessor() const override;
-};
-
-} // namespace Internal
-} // namespace Haskell
-
-#endif // HASKELLCOMPLETIONASSIST_H
diff --git a/plugins/haskell/haskelldocument.cpp b/plugins/haskell/haskelldocument.cpp
deleted file mode 100644
index b2cc8e0..0000000
--- a/plugins/haskell/haskelldocument.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "haskelldocument.h"
-
-#include "haskellconstants.h"
-#include "haskellmanager.h"
-
-using namespace TextEditor;
-using namespace Utils;
-
-namespace Haskell {
-namespace Internal {
-
-HaskellDocument::HaskellDocument()
- : TextDocument(Constants::C_HASKELLEDITOR_ID)
-{
- connect(this, &IDocument::filePathChanged, this, [this](const FilePath &, const FilePath &fn) {
- m_ghcmod = HaskellManager::ghcModForFile(fn);
- });
-}
-
-std::shared_ptr<AsyncGhcMod> HaskellDocument::ghcMod() const
-{
- return m_ghcmod;
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskelldocument.h b/plugins/haskell/haskelldocument.h
deleted file mode 100644
index 72af5e9..0000000
--- a/plugins/haskell/haskelldocument.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <texteditor/textdocument.h>
-
-#include <memory>
-
-namespace Haskell {
-namespace Internal {
-
-class AsyncGhcMod;
-
-class HaskellDocument : public TextEditor::TextDocument
-{
- Q_OBJECT
-
-public:
- HaskellDocument();
-
- std::shared_ptr<AsyncGhcMod> ghcMod() const;
-
-private:
- std::shared_ptr<AsyncGhcMod> m_ghcmod;
-};
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskelleditorfactory.cpp b/plugins/haskell/haskelleditorfactory.cpp
index 8e5d837..6570d22 100644
--- a/plugins/haskell/haskelleditorfactory.cpp
+++ b/plugins/haskell/haskelleditorfactory.cpp
@@ -25,12 +25,8 @@
#include "haskelleditorfactory.h"
-#include "haskellcompletionassist.h"
#include "haskellconstants.h"
-#include "haskelldocument.h"
-#include "haskelleditorwidget.h"
#include "haskellhighlighter.h"
-#include "haskellhoverhandler.h"
#include <texteditor/textdocument.h>
#include <texteditor/texteditoractionhandler.h>
@@ -47,13 +43,10 @@ HaskellEditorFactory::HaskellEditorFactory()
addMimeType("text/x-haskell");
setEditorActionHandlers(TextEditor::TextEditorActionHandler::UnCommentSelection
| TextEditor::TextEditorActionHandler::FollowSymbolUnderCursor);
- addHoverHandler(new HaskellHoverHandler);
- setDocumentCreator([] { return new HaskellDocument(); });
- setEditorWidgetCreator([] { return new HaskellEditorWidget; });
+ setDocumentCreator([] { return new TextEditor::TextDocument(Constants::C_HASKELLEDITOR_ID); });
setCommentDefinition(Utils::CommentDefinition("--", "{-", "-}"));
setParenthesesMatchingEnabled(true);
setMarksVisible(true);
- setCompletionAssistProvider(new HaskellCompletionAssistProvider);
setSyntaxHighlighterCreator([] { return new HaskellHighlighter(); });
}
diff --git a/plugins/haskell/haskelleditorwidget.cpp b/plugins/haskell/haskelleditorwidget.cpp
deleted file mode 100644
index d4154ae..0000000
--- a/plugins/haskell/haskelleditorwidget.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "haskelleditorwidget.h"
-
-#include "haskellconstants.h"
-#include "haskelltokenizer.h"
-
-#include <coreplugin/icore.h>
-#include <coreplugin/infobar.h>
-#include <texteditor/textdocument.h>
-#include <utils/textutils.h>
-
-#include <QTextBlock>
-#include <QTimer>
-
-using namespace TextEditor;
-
-namespace Haskell {
-namespace Internal {
-
-HaskellEditorWidget::HaskellEditorWidget(QWidget *parent)
- : TextEditorWidget(parent)
-{
-}
-
-Utils::optional<Token> HaskellEditorWidget::symbolAt(QTextDocument *doc, int position,
- int *line, int *column)
-{
- Utils::Text::convertPosition(doc, position, line, column);
- if (*line < 0 || *column < 0)
- return Utils::nullopt;
- const QTextBlock block = doc->findBlockByNumber(*line - 1);
- if (block.text().isEmpty())
- return Utils::nullopt;
- const int startState = block.previous().isValid() ? block.previous().userState() : -1;
- const Tokens tokens = HaskellTokenizer::tokenize(block.text(), startState);
- const Token token = tokens.tokenAtColumn(*column);
- if (token.isValid()
- && (token.type == TokenType::Variable
- || token.type == TokenType::Operator
- || token.type == TokenType::Constructor
- || token.type == TokenType::OperatorConstructor)) {
- return token;
- }
- return Utils::nullopt;
-}
-
-void HaskellEditorWidget::showFailedToStartStackError(const QString &stackExecutable,
- TextEditorWidget *widget)
-{
- static const char id[] = "Haskell.FailedToStartStack";
- Core::IDocument *document = widget->textDocument();
- if (!document->infoBar()->containsInfo(id)) {
- Core::InfoBarEntry info(
- id,
- tr("Failed to start Haskell Stack \"%1\". Make sure you have stack installed and configured in the options.")
- .arg(stackExecutable));
- info.setCustomButtonInfo(Core::ICore::msgShowOptionsDialog(), [document] {
- QTimer::singleShot(0, Core::ICore::instance(), [document] {
- document->infoBar()->removeInfo(id);
- Core::ICore::showOptionsDialog(Constants::OPTIONS_GENERAL);
- });
- });
- document->infoBar()->addInfo(info);
- }
-}
-
-void HaskellEditorWidget::findLinkAt(const QTextCursor &cursor,
- Utils::ProcessLinkCallback &&processLinkCallback,
- bool resolveTarget,
- bool inNextSplit)
-{
- Utils::Link link;
- int line, column;
- const Utils::optional<Token> symbol = symbolAt(document(), cursor.position(), &line, &column);
- if (symbol) {
- const QTextBlock block = document()->findBlockByNumber(line - 1);
- Utils::Link link;
- link.linkTextStart = block.position() + symbol->startCol;
- link.linkTextEnd = link.linkTextStart + symbol->length;
- if (resolveTarget) {
- m_followSymbolAssistProvider.setOpenInNextSplit(inNextSplit);
- invokeAssist(FollowSymbol, &m_followSymbolAssistProvider);
- }
- }
- processLinkCallback(link);
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskelleditorwidget.h b/plugins/haskell/haskelleditorwidget.h
deleted file mode 100644
index 24af561..0000000
--- a/plugins/haskell/haskelleditorwidget.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "followsymbol.h"
-
-#include <texteditor/texteditor.h>
-#include <utils/optional.h>
-
-namespace Haskell {
-namespace Internal {
-
-class Token;
-
-class HaskellEditorWidget : public TextEditor::TextEditorWidget
-{
-public:
- HaskellEditorWidget(QWidget *parent = 0);
-
- static Utils::optional<Token> symbolAt(QTextDocument *doc, int position,
- int *line, int *column);
-
- static void showFailedToStartStackError(const QString &stackExecutable,
- TextEditor::TextEditorWidget *widget);
-
-protected:
- void findLinkAt(const QTextCursor &cursor,
- Utils::ProcessLinkCallback &&processLinkCallback,
- bool resolveTarget = true,
- bool inNextSplit = false) override;
-
-private:
- FollowSymbolAssistProvider m_followSymbolAssistProvider;
-};
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskellhoverhandler.cpp b/plugins/haskell/haskellhoverhandler.cpp
deleted file mode 100644
index 1719297..0000000
--- a/plugins/haskell/haskellhoverhandler.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "haskellhoverhandler.h"
-
-#include "haskelldocument.h"
-#include "haskelleditorwidget.h"
-#include "haskellmanager.h"
-#include "haskelltokenizer.h"
-
-#include <texteditor/textdocument.h>
-#include <texteditor/texteditor.h>
-#include <utils/qtcassert.h>
-#include <utils/runextensions.h>
-#include <utils/synchronousprocess.h>
-#include <utils/tooltip/tooltip.h>
-
-using namespace Utils;
-
-static QString toCode(const QString &s)
-{
- if (s.isEmpty())
- return s;
- return "<pre>" + s.toHtmlEscaped() + "</pre>";
-}
-
-namespace Haskell {
-namespace Internal {
-
-QString symbolToHtml(const SymbolInfo &info)
-{
- if (info.definition.isEmpty())
- return QString();
- QString result = "<pre>" + info.definition.join("\n") + "</pre>";
- if (!info.file.isEmpty()) {
- result += "<div align=\"right\"><i>-- " + info.file.toString();
- if (info.line >= 0) {
- result += ":" + QString::number(info.line);
- if (info.col >= 0)
- result += ":" + QString::number(info.col);
- }
- result += "</i></div>";
- } else if (!info.module.isEmpty()) {
- result += "<div align=\"right\"><i>-- Module \"" + info.module + "\"</i></div>";
- }
- if (!info.additionalInfo.isEmpty())
- result += "<pre>" + info.additionalInfo.join("\n") + "</pre>";
- return result;
-}
-
-void HaskellHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
- int pos,
- ReportPriority report)
-{
- cancel();
- m_name.clear();
- m_filePath.clear();
- const Utils::optional<Token> token = HaskellEditorWidget::symbolAt(editorWidget->document(),
- pos, &m_line, &m_col);
- if (token) {
- m_filePath = editorWidget->textDocument()->filePath();
- m_name = token->text.toString();
- setPriority(Priority_Tooltip);
- } else {
- setPriority(-1);
- }
- report(priority());
-}
-
-static void showError(const QPointer<TextEditor::TextEditorWidget> &widget,
- const Error &typeError, const Error &infoError)
-{
- if (typeError.type == Error::Type::FailedToStartStack
- || infoError.type == Error::Type::FailedToStartStack) {
- const QString stackExecutable = typeError.type == Error::Type::FailedToStartStack
- ? typeError.details
- : infoError.details;
- HaskellEditorWidget::showFailedToStartStackError(stackExecutable, widget);
- }
-}
-
-static void tryShowToolTip(const QPointer<TextEditor::TextEditorWidget> &widget, const QPoint &point,
- QFuture<QStringOrError> typeFuture,
- QFuture<SymbolInfoOrError> symbolFuture)
-{
- if (Utils::ToolTip::isVisible() && widget
- && symbolFuture.isResultReadyAt(0) && typeFuture.isResultReadyAt(0)) {
- const QStringOrError typeOrError = typeFuture.result();
- const SymbolInfoOrError infoOrError = symbolFuture.result();
- if (const Error *typeError = Utils::get_if<Error>(&typeOrError))
- if (const Error *infoError = Utils::get_if<Error>(&infoOrError))
- showError(widget, *typeError, *infoError);
- const QString *type = Utils::get_if<QString>(&typeOrError);
- const SymbolInfo *info = Utils::get_if<SymbolInfo>(&infoOrError);
- const QString typeString = !type || type->isEmpty()
- ? QString()
- : toCode(":: " + *type);
- const QString infoString = info ? symbolToHtml(*info) : QString();
- const QString tip = typeString + infoString;
- Utils::ToolTip::show(point, tip, widget);
- }
-}
-
-void HaskellHoverHandler::operateTooltip(TextEditor::TextEditorWidget *editorWidget,
- const QPoint &point)
-{
- cancel();
- if (m_name.isEmpty()) {
- Utils::ToolTip::hide();
- return;
- }
- Utils::ToolTip::show(point, HaskellManager::trLookingUp(m_name), editorWidget);
-
- QPointer<TextEditor::TextEditorWidget> widget = editorWidget;
- std::shared_ptr<AsyncGhcMod> ghcmod;
- auto doc = qobject_cast<HaskellDocument *>(editorWidget->textDocument());
- QTC_ASSERT(doc, return);
- ghcmod = doc->ghcMod();
- m_typeFuture = ghcmod->typeInfo(m_filePath, m_line, m_col);
- m_symbolFuture = ghcmod->findSymbol(m_filePath, m_name);
- Utils::onResultReady(m_typeFuture,
- [typeFuture = m_typeFuture, symbolFuture = m_symbolFuture,
- ghcmod, widget, point] // hold shared ghcmod pointer
- (const QStringOrError &) {
- tryShowToolTip(widget, point, typeFuture, symbolFuture);
- });
- Utils::onResultReady(m_symbolFuture,
- [typeFuture = m_typeFuture, symbolFuture = m_symbolFuture,
- ghcmod, widget, point] // hold shared ghcmod pointer
- (const SymbolInfoOrError &) {
- tryShowToolTip(widget, point, typeFuture, symbolFuture);
- });
-}
-
-void HaskellHoverHandler::cancel()
-{
- if (m_symbolFuture.isRunning())
- m_symbolFuture.cancel();
- if (m_typeFuture.isRunning())
- m_typeFuture.cancel();
-}
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskellhoverhandler.h b/plugins/haskell/haskellhoverhandler.h
deleted file mode 100644
index a85da8e..0000000
--- a/plugins/haskell/haskellhoverhandler.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "ghcmod.h"
-
-#include <texteditor/basehoverhandler.h>
-#include <utils/fileutils.h>
-#include <utils/optional.h>
-
-namespace Haskell {
-namespace Internal {
-
-class HaskellHoverHandler : public TextEditor::BaseHoverHandler
-{
-private:
- void identifyMatch(TextEditor::TextEditorWidget *editorWidget,
- int pos,
- ReportPriority report) override;
- void operateTooltip(TextEditor::TextEditorWidget *editorWidget, const QPoint &point) override;
-
- void cancel();
-
- Utils::FilePath m_filePath;
- int m_line = -1;
- int m_col = -1;
- QString m_name;
-
- QFuture<SymbolInfoOrError> m_symbolFuture;
- QFuture<QStringOrError> m_typeFuture;
-};
-
-} // namespace Internal
-} // namespace Haskell
diff --git a/plugins/haskell/haskellmanager.cpp b/plugins/haskell/haskellmanager.cpp
index a2eadc6..9e18b51 100644
--- a/plugins/haskell/haskellmanager.cpp
+++ b/plugins/haskell/haskellmanager.cpp
@@ -25,8 +25,6 @@
#include "haskellmanager.h"
-#include "ghcmod.h"
-
#include <utils/hostosinfo.h>
#include <QCoreApplication>
@@ -46,7 +44,6 @@ namespace Internal {
class HaskellManagerPrivate
{
public:
- std::unordered_map<FilePath, std::weak_ptr<AsyncGhcMod>> ghcModCache;
FilePath stackExecutable;
};
@@ -74,21 +71,6 @@ FilePath HaskellManager::findProjectDirectory(const FilePath &filePath)
return {};
}
-std::shared_ptr<AsyncGhcMod> HaskellManager::ghcModForFile(const FilePath &filePath)
-{
- const FilePath projectPath = findProjectDirectory(filePath);
- const auto cacheEntry = m_d->ghcModCache.find(projectPath);
- if (cacheEntry != m_d->ghcModCache.cend()) {
- if (cacheEntry->second.expired())
- m_d->ghcModCache.erase(cacheEntry);
- else
- return cacheEntry->second.lock();
- }
- auto ghcmod = std::make_shared<AsyncGhcMod>(projectPath);
- m_d->ghcModCache.insert(std::make_pair(projectPath, ghcmod));
- return ghcmod;
-}
-
FilePath defaultStackExecutable()
{
// stack from brew or the installer script from https://docs.haskellstack.org
@@ -127,10 +109,5 @@ void HaskellManager::writeSettings(QSettings *settings)
settings->setValue(kStackExecutableKey, m_d->stackExecutable.toString());
}
-QString HaskellManager::trLookingUp(const QString &name)
-{
- return QCoreApplication::translate("HaskellManager", "Looking up \"%1\"...").arg(name);
-}
-
} // namespace Internal
} // namespace Haskell
diff --git a/plugins/haskell/haskellmanager.h b/plugins/haskell/haskellmanager.h
index b4a2e35..63013c9 100644
--- a/plugins/haskell/haskellmanager.h
+++ b/plugins/haskell/haskellmanager.h
@@ -36,8 +36,6 @@ QT_END_NAMESPACE
namespace Haskell {
namespace Internal {
-class AsyncGhcMod;
-
class HaskellManager : public QObject
{
Q_OBJECT
@@ -46,14 +44,11 @@ public:
static HaskellManager *instance();
static Utils::FilePath findProjectDirectory(const Utils::FilePath &filePath);
- static std::shared_ptr<AsyncGhcMod> ghcModForFile(const Utils::FilePath &filePath);
static Utils::FilePath stackExecutable();
static void setStackExecutable(const Utils::FilePath &filePath);
static void readSettings(QSettings *settings);
static void writeSettings(QSettings *settings);
- static QString trLookingUp(const QString &name);
-
signals:
void stackExecutableChanged(const Utils::FilePath &filePath);
};
diff --git a/plugins/haskell/haskellplugin.cpp b/plugins/haskell/haskellplugin.cpp
index d92c4f8..0aa187f 100644
--- a/plugins/haskell/haskellplugin.cpp
+++ b/plugins/haskell/haskellplugin.cpp
@@ -25,7 +25,6 @@
#include "haskellplugin.h"
-#include "ghcmod.h"
#include "haskellbuildconfiguration.h"
#include "haskellconstants.h"
#include "haskelleditorfactory.h"
@@ -72,8 +71,6 @@ bool HaskellPlugin::initialize(const QStringList &arguments, QString *errorStrin
connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, this, [] {
HaskellManager::writeSettings(Core::ICore::settings());
});
- connect(HaskellManager::instance(), &HaskellManager::stackExecutableChanged,
- &GhcMod::setStackExecutable);
HaskellManager::readSettings(Core::ICore::settings());
return true;