forked from qt-creator/qt-creator
QmlJSEditor: Display code model warnings as annotations
Change-Id: Ief6ed8fe551846f5e788c14a49269231462ea40a Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Marco Benelli <marco.benelli@qt.io>
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include "qmljshighlighter.h"
|
#include "qmljshighlighter.h"
|
||||||
#include "qmljshoverhandler.h"
|
#include "qmljshoverhandler.h"
|
||||||
#include "qmljsquickfixassist.h"
|
#include "qmljsquickfixassist.h"
|
||||||
|
#include "qmljstextmark.h"
|
||||||
#include "qmloutlinemodel.h"
|
#include "qmloutlinemodel.h"
|
||||||
|
|
||||||
#include <qmljs/qmljsbind.h>
|
#include <qmljs/qmljsbind.h>
|
||||||
@@ -68,6 +69,7 @@
|
|||||||
#include <texteditor/codeassist/genericproposal.h>
|
#include <texteditor/codeassist/genericproposal.h>
|
||||||
#include <texteditor/codeassist/genericproposalmodel.h>
|
#include <texteditor/codeassist/genericproposalmodel.h>
|
||||||
#include <texteditor/texteditoractionhandler.h>
|
#include <texteditor/texteditoractionhandler.h>
|
||||||
|
#include <texteditor/textmark.h>
|
||||||
|
|
||||||
#include <utils/annotateditemdelegate.h>
|
#include <utils/annotateditemdelegate.h>
|
||||||
#include <utils/changeset.h>
|
#include <utils/changeset.h>
|
||||||
@@ -201,12 +203,14 @@ static void appendExtraSelectionsForMessages(
|
|||||||
|
|
||||||
void QmlJSEditorWidget::updateCodeWarnings(Document::Ptr doc)
|
void QmlJSEditorWidget::updateCodeWarnings(Document::Ptr doc)
|
||||||
{
|
{
|
||||||
|
cleanDiagnosticMarks();
|
||||||
if (doc->ast()) {
|
if (doc->ast()) {
|
||||||
setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
|
setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
|
||||||
} else if (doc->language().isFullySupportedLanguage()) {
|
} else if (doc->language().isFullySupportedLanguage()) {
|
||||||
// show parsing errors
|
// show parsing errors
|
||||||
QList<QTextEdit::ExtraSelection> selections;
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document());
|
appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document());
|
||||||
|
createTextMarks(doc->diagnosticMessages());
|
||||||
setExtraSelections(CodeWarningsSelection, selections);
|
setExtraSelections(CodeWarningsSelection, selections);
|
||||||
} else {
|
} else {
|
||||||
setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
|
setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
|
||||||
@@ -923,6 +927,8 @@ void QmlJSEditorWidget::semanticInfoUpdated(const SemanticInfo &semanticInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createTextMarks(semanticInfo);
|
||||||
|
|
||||||
updateUses();
|
updateUses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,6 +970,61 @@ bool QmlJSEditorWidget::hideContextPane()
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorWidget::createTextMarks(const QList<DiagnosticMessage> &diagnostics)
|
||||||
|
{
|
||||||
|
for (const DiagnosticMessage &diagnostic : diagnostics) {
|
||||||
|
const auto onMarkRemoved = [this](QmlJSTextMark *mark) {
|
||||||
|
m_diagnosticMarks.removeAll(mark);
|
||||||
|
delete mark;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto mark = new QmlJSTextMark(textDocument()->filePath().toString(),
|
||||||
|
diagnostic, onMarkRemoved);
|
||||||
|
m_diagnosticMarks.append(mark);
|
||||||
|
textDocument()->addMark(mark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cleanMarks(QVector<TextMark *> *marks, TextDocument *doc)
|
||||||
|
{
|
||||||
|
for (TextEditor::TextMark *mark : *marks) {
|
||||||
|
doc->removeMark(mark);
|
||||||
|
delete mark;
|
||||||
|
}
|
||||||
|
marks->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorWidget::cleanDiagnosticMarks()
|
||||||
|
{
|
||||||
|
cleanMarks(&m_diagnosticMarks, textDocument());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorWidget::createTextMarks(const SemanticInfo &info)
|
||||||
|
{
|
||||||
|
cleanSemanticMarks();
|
||||||
|
const auto onMarkRemoved = [this](QmlJSTextMark *mark) {
|
||||||
|
m_semanticMarks.removeAll(mark);
|
||||||
|
delete mark;
|
||||||
|
};
|
||||||
|
for (const DiagnosticMessage &diagnostic : info.semanticMessages) {
|
||||||
|
auto mark = new QmlJSTextMark(textDocument()->filePath().toString(),
|
||||||
|
diagnostic, onMarkRemoved);
|
||||||
|
m_semanticMarks.append(mark);
|
||||||
|
textDocument()->addMark(mark);
|
||||||
|
}
|
||||||
|
for (const QmlJS::StaticAnalysis::Message &message : info.staticAnalysisMessages) {
|
||||||
|
auto mark = new QmlJSTextMark(textDocument()->filePath().toString(),
|
||||||
|
message, onMarkRemoved);
|
||||||
|
m_semanticMarks.append(mark);
|
||||||
|
textDocument()->addMark(mark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorWidget::cleanSemanticMarks()
|
||||||
|
{
|
||||||
|
cleanMarks(&m_semanticMarks, textDocument());
|
||||||
|
}
|
||||||
|
|
||||||
AssistInterface *QmlJSEditorWidget::createAssistInterface(
|
AssistInterface *QmlJSEditorWidget::createAssistInterface(
|
||||||
AssistKind assistKind,
|
AssistKind assistKind,
|
||||||
AssistReason reason) const
|
AssistReason reason) const
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ namespace QmlJS {
|
|||||||
namespace AST { class UiObjectMember; }
|
namespace AST { class UiObjectMember; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace TextEditor { class TextMark; }
|
||||||
|
|
||||||
namespace QmlJSEditor {
|
namespace QmlJSEditor {
|
||||||
|
|
||||||
class QmlJSEditorDocument;
|
class QmlJSEditorDocument;
|
||||||
@@ -127,6 +129,14 @@ private:
|
|||||||
QmlJS::IContextPane *m_contextPane = nullptr;
|
QmlJS::IContextPane *m_contextPane = nullptr;
|
||||||
int m_oldCursorPosition = -1;
|
int m_oldCursorPosition = -1;
|
||||||
|
|
||||||
|
void createTextMarks(const QList<QmlJS::DiagnosticMessage> &diagnostics);
|
||||||
|
void cleanDiagnosticMarks();
|
||||||
|
QVector<TextEditor::TextMark *> m_diagnosticMarks;
|
||||||
|
|
||||||
|
void createTextMarks(const QmlJSTools::SemanticInfo &info);
|
||||||
|
void cleanSemanticMarks();
|
||||||
|
QVector<TextEditor::TextMark *> m_semanticMarks;
|
||||||
|
|
||||||
FindReferences *m_findReferences;
|
FindReferences *m_findReferences;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ HEADERS += \
|
|||||||
qmljssemantichighlighter.h \
|
qmljssemantichighlighter.h \
|
||||||
qmljswrapinloader.h \
|
qmljswrapinloader.h \
|
||||||
qmljseditordocument.h \
|
qmljseditordocument.h \
|
||||||
qmljseditordocument_p.h
|
qmljseditordocument_p.h \
|
||||||
|
qmljstextmark.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
qmljseditor.cpp \
|
qmljseditor.cpp \
|
||||||
@@ -57,7 +58,8 @@ SOURCES += \
|
|||||||
qmljssemanticinfoupdater.cpp \
|
qmljssemanticinfoupdater.cpp \
|
||||||
qmljssemantichighlighter.cpp \
|
qmljssemantichighlighter.cpp \
|
||||||
qmljswrapinloader.cpp \
|
qmljswrapinloader.cpp \
|
||||||
qmljseditordocument.cpp
|
qmljseditordocument.cpp \
|
||||||
|
qmljstextmark.cpp
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
qmljseditingsettingspage.ui \
|
qmljseditingsettingspage.ui \
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ QtcPlugin {
|
|||||||
"qmljssemantichighlighter.h",
|
"qmljssemantichighlighter.h",
|
||||||
"qmljssemanticinfoupdater.cpp",
|
"qmljssemanticinfoupdater.cpp",
|
||||||
"qmljssemanticinfoupdater.h",
|
"qmljssemanticinfoupdater.h",
|
||||||
|
"qmljstextmark.cpp",
|
||||||
|
"qmljstextmark.h",
|
||||||
"qmljswrapinloader.cpp",
|
"qmljswrapinloader.cpp",
|
||||||
"qmljswrapinloader.h",
|
"qmljswrapinloader.h",
|
||||||
"qmloutlinemodel.cpp",
|
"qmloutlinemodel.cpp",
|
||||||
|
|||||||
100
src/plugins/qmljseditor/qmljstextmark.cpp
Normal file
100
src/plugins/qmljseditor/qmljstextmark.cpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "qmljstextmark.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
using namespace QmlJSEditor;
|
||||||
|
using namespace QmlJSEditor::Internal;
|
||||||
|
|
||||||
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
const char QMLJS_ERROR[] = "QmlJS.Error";
|
||||||
|
const char QMLJS_WARNING[] = "QmlJS.Warning";
|
||||||
|
|
||||||
|
static bool isWarning(QmlJS::Severity::Enum kind)
|
||||||
|
{
|
||||||
|
switch (kind) {
|
||||||
|
case QmlJS::Severity::Hint:
|
||||||
|
case QmlJS::Severity::MaybeWarning:
|
||||||
|
case QmlJS::Severity::Warning:
|
||||||
|
case QmlJS::Severity::ReadingTypeInfoWarning:
|
||||||
|
return true;
|
||||||
|
case QmlJS::Severity::MaybeError:
|
||||||
|
case QmlJS::Severity::Error:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Core::Id cartegoryForSeverity(QmlJS::Severity::Enum kind)
|
||||||
|
{
|
||||||
|
return isWarning(kind) ? QMLJS_WARNING : QMLJS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlJSTextMark::QmlJSTextMark(const QString &fileName,
|
||||||
|
const QmlJS::DiagnosticMessage &diagnostic,
|
||||||
|
const QmlJSTextMark::RemovedFromEditorHandler &removedHandler)
|
||||||
|
: TextEditor::TextMark(fileName, int(diagnostic.loc.startLine),
|
||||||
|
cartegoryForSeverity(diagnostic.kind))
|
||||||
|
, m_removedFromEditorHandler(removedHandler)
|
||||||
|
|
||||||
|
{
|
||||||
|
init(isWarning(diagnostic.kind), diagnostic.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlJSTextMark::QmlJSTextMark(const QString &fileName,
|
||||||
|
const QmlJS::StaticAnalysis::Message &message,
|
||||||
|
const QmlJSTextMark::RemovedFromEditorHandler &removedHandler)
|
||||||
|
: TextEditor::TextMark(fileName, int(message.location.startLine),
|
||||||
|
cartegoryForSeverity(message.severity))
|
||||||
|
, m_removedFromEditorHandler(removedHandler)
|
||||||
|
{
|
||||||
|
init(isWarning(message.severity), message.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSTextMark::removedFromEditor()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_removedFromEditorHandler, return);
|
||||||
|
m_removedFromEditorHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSTextMark::init(bool warning, const QString message)
|
||||||
|
{
|
||||||
|
setIcon(warning ? Utils::Icons::CODEMODEL_WARNING.icon()
|
||||||
|
: Utils::Icons::CODEMODEL_ERROR.icon());
|
||||||
|
setColor(warning ? Utils::Theme::ClangCodeModel_Warning_TextMarkColor
|
||||||
|
: Utils::Theme::ClangCodeModel_Error_TextMarkColor);
|
||||||
|
setDefaultToolTip(warning ? QApplication::translate("QmlJS Code Model Marks", "Code Model Warning")
|
||||||
|
: QApplication::translate("QmlJS Code Model Marks", "Code Model Error"));
|
||||||
|
setToolTip(message);
|
||||||
|
setPriority(warning ? TextEditor::TextMark::NormalPriority
|
||||||
|
: TextEditor::TextMark::HighPriority);
|
||||||
|
setLineAnnotation(message);
|
||||||
|
}
|
||||||
57
src/plugins/qmljseditor/qmljstextmark.h
Normal file
57
src/plugins/qmljseditor/qmljstextmark.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <qmljs/qmljsdocument.h>
|
||||||
|
#include <qmljs/qmljsstaticanalysismessage.h>
|
||||||
|
|
||||||
|
#include <texteditor/textmark.h>
|
||||||
|
|
||||||
|
namespace QmlJSEditor {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class QmlJSTextMark : public TextEditor::TextMark
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using RemovedFromEditorHandler = std::function<void(QmlJSTextMark *)>;
|
||||||
|
|
||||||
|
QmlJSTextMark(const QString &fileName,
|
||||||
|
const QmlJS::DiagnosticMessage &diagnostic,
|
||||||
|
const RemovedFromEditorHandler &removedHandler);
|
||||||
|
QmlJSTextMark(const QString &fileName,
|
||||||
|
const QmlJS::StaticAnalysis::Message &message,
|
||||||
|
const RemovedFromEditorHandler &removedHandler);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void removedFromEditor() override;
|
||||||
|
void init(bool warning, const QString message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RemovedFromEditorHandler m_removedFromEditorHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlJSEditor
|
||||||
Reference in New Issue
Block a user