forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.6'
Conflicts: src/plugins/projectexplorer/toolchainmanager.cpp src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp Change-Id: Id736c6922670c921c689219cb817b1541eaaf304
This commit is contained in:
@@ -47,6 +47,9 @@
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
For examples of adding connections, see
|
||||||
|
\l{Creating Scalable Buttons and Borders}.
|
||||||
|
|
||||||
\section1 Connecting Objects to Signals
|
\section1 Connecting Objects to Signals
|
||||||
|
|
||||||
To connect objects to signals in QML, create \l{Connections} objects.
|
To connect objects to signals in QML, create \l{Connections} objects.
|
||||||
|
1
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
1
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "cppassert.h"
|
#include "cppassert.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
1
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
1
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "cppassert.h"
|
#include "cppassert.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace CPlusPlus;
|
using namespace CPlusPlus;
|
||||||
|
|
||||||
|
4
src/libs/3rdparty/sqlite/sqlite.pri
vendored
4
src/libs/3rdparty/sqlite/sqlite.pri
vendored
@@ -4,12 +4,8 @@ HEADERS += $$PWD/okapi_bm25.h \
|
|||||||
$$PWD/sqlite3.h \
|
$$PWD/sqlite3.h \
|
||||||
$$PWD/sqlite3ext.h
|
$$PWD/sqlite3ext.h
|
||||||
|
|
||||||
|
|
||||||
SOURCES += $$PWD/sqlite3.c
|
SOURCES += $$PWD/sqlite3.c
|
||||||
|
|
||||||
win32:DEFINES += SQLITE_API=__declspec(dllexport)
|
|
||||||
unix:DEFINES += SQLITE_API=\"__attribute__((visibility(\\\"default\\\")))\"
|
|
||||||
|
|
||||||
gcc {
|
gcc {
|
||||||
QMAKE_CFLAGS_WARN_ON = -w
|
QMAKE_CFLAGS_WARN_ON = -w
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,6 @@ contains(CONFIG, dll) {
|
|||||||
|
|
||||||
QT += network
|
QT += network
|
||||||
|
|
||||||
DEFINES += CLANGBACKENDIPC_LIBRARY
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
SOURCES += $$PWD/ipcserverinterface.cpp \
|
SOURCES += $$PWD/ipcserverinterface.cpp \
|
||||||
@@ -44,10 +42,13 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
|
|||||||
$$PWD/sourcelocationcontainer.cpp \
|
$$PWD/sourcelocationcontainer.cpp \
|
||||||
$$PWD/fixitcontainer.cpp \
|
$$PWD/fixitcontainer.cpp \
|
||||||
$$PWD/requestdiagnosticsmessage.cpp \
|
$$PWD/requestdiagnosticsmessage.cpp \
|
||||||
|
$$PWD/requesthighlightingmessage.cpp \
|
||||||
$$PWD/registerunsavedfilesforeditormessage.cpp \
|
$$PWD/registerunsavedfilesforeditormessage.cpp \
|
||||||
$$PWD/unregisterunsavedfilesforeditormessage.cpp \
|
$$PWD/unregisterunsavedfilesforeditormessage.cpp \
|
||||||
$$PWD/updatetranslationunitsforeditormessage.cpp \
|
$$PWD/updatetranslationunitsforeditormessage.cpp \
|
||||||
$$PWD/updatevisibletranslationunitsmessage.cpp
|
$$PWD/updatevisibletranslationunitsmessage.cpp \
|
||||||
|
$$PWD/highlightingchangedmessage.cpp \
|
||||||
|
$$PWD/highlightingmarkcontainer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/ipcserverinterface.h \
|
$$PWD/ipcserverinterface.h \
|
||||||
@@ -86,9 +87,12 @@ HEADERS += \
|
|||||||
$$PWD/sourcelocationcontainer.h \
|
$$PWD/sourcelocationcontainer.h \
|
||||||
$$PWD/fixitcontainer.h \
|
$$PWD/fixitcontainer.h \
|
||||||
$$PWD/requestdiagnosticsmessage.h \
|
$$PWD/requestdiagnosticsmessage.h \
|
||||||
|
$$PWD/requesthighlightingmessage.h \
|
||||||
$$PWD/registerunsavedfilesforeditormessage.h \
|
$$PWD/registerunsavedfilesforeditormessage.h \
|
||||||
$$PWD/unregisterunsavedfilesforeditormessage.h \
|
$$PWD/unregisterunsavedfilesforeditormessage.h \
|
||||||
$$PWD/updatetranslationunitsforeditormessage.h \
|
$$PWD/updatetranslationunitsforeditormessage.h \
|
||||||
$$PWD/updatevisibletranslationunitsmessage.h
|
$$PWD/updatevisibletranslationunitsmessage.h \
|
||||||
|
$$PWD/highlightingchangedmessage.h \
|
||||||
|
$$PWD/highlightingmarkcontainer.h
|
||||||
|
|
||||||
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
||||||
|
@@ -33,8 +33,10 @@
|
|||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
#if defined(CLANGBACKENDIPC_LIBRARY)
|
#if defined(CLANGBACKENDIPC_BUILD_LIB)
|
||||||
# define CMBIPC_EXPORT Q_DECL_EXPORT
|
# define CMBIPC_EXPORT Q_DECL_EXPORT
|
||||||
|
#elif defined(CLANGBACKENDIPC_BUILD_STATIC_LIB)
|
||||||
|
# define CMBIPC_EXPORT
|
||||||
#else
|
#else
|
||||||
# define CMBIPC_EXPORT Q_DECL_IMPORT
|
# define CMBIPC_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
@@ -43,6 +43,9 @@
|
|||||||
#include "diagnosticschangedmessage.h"
|
#include "diagnosticschangedmessage.h"
|
||||||
#include "registerunsavedfilesforeditormessage.h"
|
#include "registerunsavedfilesforeditormessage.h"
|
||||||
#include "requestdiagnosticsmessage.h"
|
#include "requestdiagnosticsmessage.h"
|
||||||
|
#include "requesthighlightingmessage.h"
|
||||||
|
#include "highlightingchangedmessage.h"
|
||||||
|
#include "highlightingmarkcontainer.h"
|
||||||
#include "projectpartsdonotexistmessage.h"
|
#include "projectpartsdonotexistmessage.h"
|
||||||
#include "sourcelocationcontainer.h"
|
#include "sourcelocationcontainer.h"
|
||||||
#include "sourcerangecontainer.h"
|
#include "sourcerangecontainer.h"
|
||||||
@@ -83,6 +86,9 @@ void Messages::registerMessages()
|
|||||||
registerMetaType<RequestDiagnosticsMessage>();
|
registerMetaType<RequestDiagnosticsMessage>();
|
||||||
registerMetaType<DiagnosticsChangedMessage>();
|
registerMetaType<DiagnosticsChangedMessage>();
|
||||||
|
|
||||||
|
registerMetaType<RequestHighlightingMessage>();
|
||||||
|
registerMetaType<HighlightingChangedMessage>();
|
||||||
|
|
||||||
registerMetaType<UpdateVisibleTranslationUnitsMessage>();
|
registerMetaType<UpdateVisibleTranslationUnitsMessage>();
|
||||||
|
|
||||||
registerMetaType<CompleteCodeMessage>();
|
registerMetaType<CompleteCodeMessage>();
|
||||||
@@ -94,6 +100,7 @@ void Messages::registerMessages()
|
|||||||
|
|
||||||
// Containers
|
// Containers
|
||||||
registerMetaType<DiagnosticContainer>();
|
registerMetaType<DiagnosticContainer>();
|
||||||
|
registerMetaType<HighlightingMarkContainer>();
|
||||||
registerMetaType<FileContainer>();
|
registerMetaType<FileContainer>();
|
||||||
registerMetaType<ProjectPartContainer>();
|
registerMetaType<ProjectPartContainer>();
|
||||||
registerMetaType<SourceLocationContainer>();
|
registerMetaType<SourceLocationContainer>();
|
||||||
|
@@ -39,8 +39,12 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
RegisterTranslationUnitForEditorMessage::RegisterTranslationUnitForEditorMessage(const QVector<FileContainer> &fileContainers)
|
RegisterTranslationUnitForEditorMessage::RegisterTranslationUnitForEditorMessage(const QVector<FileContainer> &fileContainers,
|
||||||
: fileContainers_(fileContainers)
|
const Utf8String ¤tEditorFilePath,
|
||||||
|
const Utf8StringVector &visibleEditorFilePaths)
|
||||||
|
: fileContainers_(fileContainers),
|
||||||
|
currentEditorFilePath_(currentEditorFilePath),
|
||||||
|
visibleEditorFilePaths_(visibleEditorFilePaths)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,28 +53,45 @@ const QVector<FileContainer> &RegisterTranslationUnitForEditorMessage::fileConta
|
|||||||
return fileContainers_;
|
return fileContainers_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Utf8String &RegisterTranslationUnitForEditorMessage::currentEditorFilePath() const
|
||||||
|
{
|
||||||
|
return currentEditorFilePath_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Utf8StringVector &RegisterTranslationUnitForEditorMessage::visibleEditorFilePaths() const
|
||||||
|
{
|
||||||
|
return visibleEditorFilePaths_;
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message)
|
QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message)
|
||||||
{
|
{
|
||||||
out << message.fileContainers_;
|
out << message.fileContainers_;
|
||||||
|
out << message.currentEditorFilePath_;
|
||||||
|
out << message.visibleEditorFilePaths_;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream &operator>>(QDataStream &in, RegisterTranslationUnitForEditorMessage &message)
|
QDataStream &operator>>(QDataStream &in, RegisterTranslationUnitForEditorMessage &message)
|
||||||
{
|
{
|
||||||
in >> message.fileContainers_;
|
in >> message.fileContainers_;
|
||||||
|
in >> message.currentEditorFilePath_;
|
||||||
|
in >> message.visibleEditorFilePaths_;
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second)
|
bool operator==(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second)
|
||||||
{
|
{
|
||||||
return first.fileContainers_ == second.fileContainers_;
|
return first.fileContainers_ == second.fileContainers_
|
||||||
|
&& first.currentEditorFilePath_ == second.currentEditorFilePath_
|
||||||
|
&& first.visibleEditorFilePaths_ == second.visibleEditorFilePaths_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second)
|
bool operator<(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second)
|
||||||
{
|
{
|
||||||
return compareContainer(first.fileContainers_, second.fileContainers_);
|
return compareContainer(first.fileContainers_, second.fileContainers_)
|
||||||
|
&& first.currentEditorFilePath_ < second.currentEditorFilePath_
|
||||||
|
&& compareContainer(first.visibleEditorFilePaths_, second.visibleEditorFilePaths_);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const RegisterTranslationUnitForEditorMessage &message)
|
QDebug operator<<(QDebug debug, const RegisterTranslationUnitForEditorMessage &message)
|
||||||
@@ -80,6 +101,11 @@ QDebug operator<<(QDebug debug, const RegisterTranslationUnitForEditorMessage &m
|
|||||||
for (const FileContainer &fileContainer : message.fileContainers())
|
for (const FileContainer &fileContainer : message.fileContainers())
|
||||||
debug.nospace() << fileContainer<< ", ";
|
debug.nospace() << fileContainer<< ", ";
|
||||||
|
|
||||||
|
debug.nospace() << message.currentEditorFilePath() << ", ";
|
||||||
|
|
||||||
|
for (const Utf8String &visibleEditorFilePath : message.visibleEditorFilePaths())
|
||||||
|
debug.nospace() << visibleEditorFilePath << ", ";
|
||||||
|
|
||||||
debug.nospace() << ")";
|
debug.nospace() << ")";
|
||||||
|
|
||||||
return debug;
|
return debug;
|
||||||
@@ -92,6 +118,12 @@ void PrintTo(const RegisterTranslationUnitForEditorMessage &message, ::std::ostr
|
|||||||
for (const FileContainer &fileContainer : message.fileContainers())
|
for (const FileContainer &fileContainer : message.fileContainers())
|
||||||
PrintTo(fileContainer, os);
|
PrintTo(fileContainer, os);
|
||||||
|
|
||||||
|
*os << message.currentEditorFilePath().constData() << ", ";
|
||||||
|
|
||||||
|
auto visiblePaths = message.visibleEditorFilePaths();
|
||||||
|
|
||||||
|
std::copy(visiblePaths.cbegin(), visiblePaths.cend(), std::ostream_iterator<Utf8String>(*os, ", "));
|
||||||
|
|
||||||
*os << ")";
|
*os << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,12 +47,18 @@ class CMBIPC_EXPORT RegisterTranslationUnitForEditorMessage
|
|||||||
friend void PrintTo(const RegisterTranslationUnitForEditorMessage &message, ::std::ostream* os);
|
friend void PrintTo(const RegisterTranslationUnitForEditorMessage &message, ::std::ostream* os);
|
||||||
public:
|
public:
|
||||||
RegisterTranslationUnitForEditorMessage() = default;
|
RegisterTranslationUnitForEditorMessage() = default;
|
||||||
RegisterTranslationUnitForEditorMessage(const QVector<FileContainer> &fileContainers);
|
RegisterTranslationUnitForEditorMessage(const QVector<FileContainer> &fileContainers,
|
||||||
|
const Utf8String ¤tEditorFilePath,
|
||||||
|
const Utf8StringVector &visibleEditorFilePaths);
|
||||||
|
|
||||||
const QVector<FileContainer> &fileContainers() const;
|
const QVector<FileContainer> &fileContainers() const;
|
||||||
|
const Utf8String ¤tEditorFilePath() const;
|
||||||
|
const Utf8StringVector &visibleEditorFilePaths() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<FileContainer> fileContainers_;
|
QVector<FileContainer> fileContainers_;
|
||||||
|
Utf8String currentEditorFilePath_;
|
||||||
|
Utf8StringVector visibleEditorFilePaths_;
|
||||||
};
|
};
|
||||||
|
|
||||||
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message);
|
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message);
|
||||||
|
@@ -37,11 +37,19 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QTemporaryDir>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
const QTemporaryDir &temporaryDirectory()
|
||||||
|
{
|
||||||
|
static QTemporaryDir temporaryDirectory(QDir::tempPath() + QStringLiteral("/qtc-clang-XXXXXX"));
|
||||||
|
|
||||||
|
return temporaryDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
QString currentProcessId()
|
QString currentProcessId()
|
||||||
{
|
{
|
||||||
return QString::number(QCoreApplication::applicationPid());
|
return QString::number(QCoreApplication::applicationPid());
|
||||||
@@ -49,7 +57,7 @@ QString currentProcessId()
|
|||||||
|
|
||||||
QString connectionName()
|
QString connectionName()
|
||||||
{
|
{
|
||||||
return QStringLiteral("ClangBackEnd-") + currentProcessId();
|
return temporaryDirectory().path() + QStringLiteral("/ClangBackEnd-") + currentProcessId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +136,20 @@ void ConnectionClient::setProcessAliveTimerInterval(int processTimerInterval)
|
|||||||
processAliveTimer.setInterval(processTimerInterval);
|
processAliveTimer.setInterval(processTimerInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QProcessEnvironment ConnectionClient::processEnvironment() const
|
||||||
|
{
|
||||||
|
auto processEnvironment = QProcessEnvironment::systemEnvironment();
|
||||||
|
|
||||||
|
if (temporaryDirectory().isValid()) {
|
||||||
|
const QString temporaryDirectoryPath = temporaryDirectory().path();
|
||||||
|
processEnvironment.insert(QStringLiteral("TMPDIR"), temporaryDirectoryPath);
|
||||||
|
processEnvironment.insert(QStringLiteral("TMP"), temporaryDirectoryPath);
|
||||||
|
processEnvironment.insert(QStringLiteral("TEMP"), temporaryDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return processEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionClient::startProcess()
|
void ConnectionClient::startProcess()
|
||||||
{
|
{
|
||||||
TIME_SCOPE_DURATION("ConnectionClient::startProcess");
|
TIME_SCOPE_DURATION("ConnectionClient::startProcess");
|
||||||
@@ -135,6 +157,7 @@ void ConnectionClient::startProcess()
|
|||||||
if (!isProcessIsRunning()) {
|
if (!isProcessIsRunning()) {
|
||||||
connectProcessFinished();
|
connectProcessFinished();
|
||||||
connectStandardOutputAndError();
|
connectStandardOutputAndError();
|
||||||
|
process()->setProcessEnvironment(processEnvironment());
|
||||||
process()->start(processPath(), {connectionName()});
|
process()->start(processPath(), {connectionName()});
|
||||||
process()->waitForStarted();
|
process()->waitForStarted();
|
||||||
resetProcessAliveTimer();
|
resetProcessAliveTimer();
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "lineprefixer.h"
|
#include "lineprefixer.h"
|
||||||
|
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -100,6 +101,8 @@ private:
|
|||||||
|
|
||||||
void ensureMessageIsWritten();
|
void ensureMessageIsWritten();
|
||||||
|
|
||||||
|
QProcessEnvironment processEnvironment() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::unique_ptr<QProcess> process_;
|
mutable std::unique_ptr<QProcess> process_;
|
||||||
QLocalSocket localSocket;
|
QLocalSocket localSocket;
|
||||||
|
119
src/libs/clangbackendipc/highlightingchangedmessage.cpp
Normal file
119
src/libs/clangbackendipc/highlightingchangedmessage.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "highlightingchangedmessage.h"
|
||||||
|
|
||||||
|
#include "container_common.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
HighlightingChangedMessage::HighlightingChangedMessage(const FileContainer &file,
|
||||||
|
const QVector<HighlightingMarkContainer> &highlightingMarks,
|
||||||
|
const QVector<SourceRangeContainer> &skippedPreprocessorRanges)
|
||||||
|
: file_(file),
|
||||||
|
highlightingMarks_(highlightingMarks),
|
||||||
|
skippedPreprocessorRanges_(skippedPreprocessorRanges)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileContainer &HighlightingChangedMessage::file() const
|
||||||
|
{
|
||||||
|
return file_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVector<HighlightingMarkContainer> &HighlightingChangedMessage::highlightingMarks() const
|
||||||
|
{
|
||||||
|
return highlightingMarks_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVector<SourceRangeContainer> &HighlightingChangedMessage::skippedPreprocessorRanges() const
|
||||||
|
{
|
||||||
|
return skippedPreprocessorRanges_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
out << message.file_;
|
||||||
|
out << message.highlightingMarks_;
|
||||||
|
out << message.skippedPreprocessorRanges_;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
in >> message.file_;
|
||||||
|
in >> message.highlightingMarks_;
|
||||||
|
in >> message.skippedPreprocessorRanges_;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second)
|
||||||
|
{
|
||||||
|
return first.file_ == second.file_
|
||||||
|
&& first.highlightingMarks_ == second.highlightingMarks_
|
||||||
|
&& first.skippedPreprocessorRanges_ == second.skippedPreprocessorRanges_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second)
|
||||||
|
{
|
||||||
|
return first.file_ < second.file_
|
||||||
|
&& compareContainer(first.highlightingMarks_, second.highlightingMarks_)
|
||||||
|
&& compareContainer(first.skippedPreprocessorRanges_, second.skippedPreprocessorRanges_);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
debug.nospace() << "HighlightingChangedMessage("
|
||||||
|
<< message.file_
|
||||||
|
<< ", " << message.highlightingMarks_.size()
|
||||||
|
<< ", " << message.skippedPreprocessorRanges_.size()
|
||||||
|
<< ")";
|
||||||
|
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os)
|
||||||
|
{
|
||||||
|
*os << "HighlightingChangedMessage(";
|
||||||
|
PrintTo(message.file(), os);
|
||||||
|
*os << "," << message.highlightingMarks().size();
|
||||||
|
*os << "," << message.skippedPreprocessorRanges().size();
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
|
|
80
src/libs/clangbackendipc/highlightingchangedmessage.h
Normal file
80
src/libs/clangbackendipc/highlightingchangedmessage.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H
|
||||||
|
#define CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H
|
||||||
|
|
||||||
|
#include "clangbackendipc_global.h"
|
||||||
|
#include "filecontainer.h"
|
||||||
|
#include "highlightingmarkcontainer.h"
|
||||||
|
#include "sourcerangecontainer.h"
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class CMBIPC_EXPORT HighlightingChangedMessage
|
||||||
|
{
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message);
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message);
|
||||||
|
friend CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
|
||||||
|
friend CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
|
||||||
|
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message);
|
||||||
|
friend void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HighlightingChangedMessage() = default;
|
||||||
|
HighlightingChangedMessage(const FileContainer &file,
|
||||||
|
const QVector<HighlightingMarkContainer> &highlightingMarks,
|
||||||
|
const QVector<SourceRangeContainer> &skippedPreprocessorRanges);
|
||||||
|
|
||||||
|
const FileContainer &file() const;
|
||||||
|
const QVector<HighlightingMarkContainer> &highlightingMarks() const;
|
||||||
|
const QVector<SourceRangeContainer> &skippedPreprocessorRanges() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileContainer file_;
|
||||||
|
QVector<HighlightingMarkContainer> highlightingMarks_;
|
||||||
|
QVector<SourceRangeContainer> skippedPreprocessorRanges_;
|
||||||
|
};
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message);
|
||||||
|
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message);
|
||||||
|
CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
|
||||||
|
CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message);
|
||||||
|
void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os);
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ClangBackEnd::HighlightingChangedMessage)
|
||||||
|
|
||||||
|
#endif // CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H
|
173
src/libs/clangbackendipc/highlightingmarkcontainer.cpp
Normal file
173
src/libs/clangbackendipc/highlightingmarkcontainer.cpp
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "highlightingmarkcontainer.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
HighlightingMarkContainer::HighlightingMarkContainer(uint line,
|
||||||
|
uint column,
|
||||||
|
uint length,
|
||||||
|
HighlightingType type)
|
||||||
|
: line_(line),
|
||||||
|
column_(column),
|
||||||
|
length_(length),
|
||||||
|
type_(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint HighlightingMarkContainer::line() const
|
||||||
|
{
|
||||||
|
return line_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint HighlightingMarkContainer::column() const
|
||||||
|
{
|
||||||
|
return column_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint HighlightingMarkContainer::length() const
|
||||||
|
{
|
||||||
|
return length_;
|
||||||
|
}
|
||||||
|
|
||||||
|
HighlightingType HighlightingMarkContainer::type() const
|
||||||
|
{
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 &HighlightingMarkContainer::typeAsInt()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<quint32&>(type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container)
|
||||||
|
{
|
||||||
|
out << container.line_;
|
||||||
|
out << container.column_;
|
||||||
|
out << container.length_;
|
||||||
|
out << quint32(container.type_);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container)
|
||||||
|
{
|
||||||
|
in >> container.line_;
|
||||||
|
in >> container.column_;
|
||||||
|
in >> container.length_;
|
||||||
|
in >> container.typeAsInt();
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second)
|
||||||
|
{
|
||||||
|
return first.line_ == second.line_
|
||||||
|
&& first.column_ == second.column_
|
||||||
|
&& first.length_ == second.length_
|
||||||
|
&& first.type_ == second.type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second)
|
||||||
|
{
|
||||||
|
if (first.line() == second.line()) {
|
||||||
|
if (first.column() == second.column()) {
|
||||||
|
if (first.length() == second.length())
|
||||||
|
return first.type() < second.type();
|
||||||
|
return first.length() < second.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return first.column() < second.column();
|
||||||
|
}
|
||||||
|
|
||||||
|
return first.line() < second.line();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RETURN_TEXT_FOR_CASE(enumValue) case HighlightingType::enumValue: return #enumValue
|
||||||
|
static const char *highlightingTypeToCStringLiteral(HighlightingType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
RETURN_TEXT_FOR_CASE(Invalid);
|
||||||
|
RETURN_TEXT_FOR_CASE(Comment);
|
||||||
|
RETURN_TEXT_FOR_CASE(Keyword);
|
||||||
|
RETURN_TEXT_FOR_CASE(StringLiteral);
|
||||||
|
RETURN_TEXT_FOR_CASE(NumberLiteral);
|
||||||
|
RETURN_TEXT_FOR_CASE(Function);
|
||||||
|
RETURN_TEXT_FOR_CASE(VirtualFunction);
|
||||||
|
RETURN_TEXT_FOR_CASE(Type);
|
||||||
|
RETURN_TEXT_FOR_CASE(LocalVariable);
|
||||||
|
RETURN_TEXT_FOR_CASE(GlobalVariable);
|
||||||
|
RETURN_TEXT_FOR_CASE(Field);
|
||||||
|
RETURN_TEXT_FOR_CASE(Enumeration);
|
||||||
|
RETURN_TEXT_FOR_CASE(Operator);
|
||||||
|
RETURN_TEXT_FOR_CASE(Preprocessor);
|
||||||
|
RETURN_TEXT_FOR_CASE(Label);
|
||||||
|
RETURN_TEXT_FOR_CASE(OutputArgument);
|
||||||
|
RETURN_TEXT_FOR_CASE(PreprocessorDefinition);
|
||||||
|
RETURN_TEXT_FOR_CASE(PreprocessorExpansion);
|
||||||
|
default: return "UnhandledHighlightingType";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef RETURN_TEXT_FOR_CASE
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container)
|
||||||
|
{
|
||||||
|
debug.nospace() << "HighlightingMarkContainer("
|
||||||
|
<< container.line() << ", "
|
||||||
|
<< container.column() << ", "
|
||||||
|
<< container.length() << ", "
|
||||||
|
<< highlightingTypeToCStringLiteral(container.type()) << ", "
|
||||||
|
<< ")";
|
||||||
|
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(HighlightingType highlightingType, std::ostream *os)
|
||||||
|
{
|
||||||
|
*os << highlightingTypeToCStringLiteral(highlightingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(const HighlightingMarkContainer& container, ::std::ostream *os)
|
||||||
|
{
|
||||||
|
*os << "HighlightingMarkContainer("
|
||||||
|
<< container.line() << ", "
|
||||||
|
<< container.column() << ", "
|
||||||
|
<< container.length() << ", ";
|
||||||
|
PrintTo(container.type(), os);
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
79
src/libs/clangbackendipc/highlightingmarkcontainer.h
Normal file
79
src/libs/clangbackendipc/highlightingmarkcontainer.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H
|
||||||
|
#define CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H
|
||||||
|
|
||||||
|
#include "clangbackendipc_global.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class CMBIPC_EXPORT HighlightingMarkContainer
|
||||||
|
{
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container);
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container);
|
||||||
|
friend CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
|
||||||
|
friend CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HighlightingMarkContainer() = default;
|
||||||
|
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingType type);
|
||||||
|
|
||||||
|
uint line() const;
|
||||||
|
uint column() const;
|
||||||
|
uint length() const;
|
||||||
|
HighlightingType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint32 &typeAsInt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint line_;
|
||||||
|
uint column_;
|
||||||
|
uint length_;
|
||||||
|
HighlightingType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container);
|
||||||
|
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container);
|
||||||
|
CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
|
||||||
|
CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container);
|
||||||
|
CMBIPC_EXPORT void PrintTo(HighlightingType highlightingType, ::std::ostream *os);
|
||||||
|
void PrintTo(const HighlightingMarkContainer &container, ::std::ostream *os);
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ClangBackEnd::HighlightingMarkContainer)
|
||||||
|
|
||||||
|
#endif // CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H
|
@@ -80,5 +80,11 @@ void IpcClientDispatcher::diagnosticsChanged(const DiagnosticsChangedMessage &me
|
|||||||
client->diagnosticsChanged(message);
|
client->diagnosticsChanged(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcClientDispatcher::highlightingChanged(const HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
for (auto *client : clients)
|
||||||
|
client->highlightingChanged(message);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
|
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
|
||||||
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
|
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
|
||||||
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
|
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
|
||||||
|
void highlightingChanged(const HighlightingChangedMessage &message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<IpcClientInterface*> clients;
|
QVector<IpcClientInterface*> clients;
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "projectpartsdonotexistmessage.h"
|
#include "projectpartsdonotexistmessage.h"
|
||||||
#include "translationunitdoesnotexistmessage.h"
|
#include "translationunitdoesnotexistmessage.h"
|
||||||
#include "diagnosticschangedmessage.h"
|
#include "diagnosticschangedmessage.h"
|
||||||
|
#include "highlightingchangedmessage.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -50,6 +51,7 @@ void IpcClientInterface::dispatch(const QVariant &message)
|
|||||||
static const int translationUnitDoesNotExistMessage = QMetaType::type("ClangBackEnd::TranslationUnitDoesNotExistMessage");
|
static const int translationUnitDoesNotExistMessage = QMetaType::type("ClangBackEnd::TranslationUnitDoesNotExistMessage");
|
||||||
static const int projectPartsDoNotExistMessage = QMetaType::type("ClangBackEnd::ProjectPartsDoNotExistMessage");
|
static const int projectPartsDoNotExistMessage = QMetaType::type("ClangBackEnd::ProjectPartsDoNotExistMessage");
|
||||||
static const int diagnosticsChangedMessage = QMetaType::type("ClangBackEnd::DiagnosticsChangedMessage");
|
static const int diagnosticsChangedMessage = QMetaType::type("ClangBackEnd::DiagnosticsChangedMessage");
|
||||||
|
static const int highlightingChangedMessage = QMetaType::type("ClangBackEnd::HighlightingChangedMessage");
|
||||||
|
|
||||||
int type = message.userType();
|
int type = message.userType();
|
||||||
|
|
||||||
@@ -65,6 +67,8 @@ void IpcClientInterface::dispatch(const QVariant &message)
|
|||||||
projectPartsDoNotExist(message.value<ProjectPartsDoNotExistMessage>());
|
projectPartsDoNotExist(message.value<ProjectPartsDoNotExistMessage>());
|
||||||
else if (type == diagnosticsChangedMessage)
|
else if (type == diagnosticsChangedMessage)
|
||||||
diagnosticsChanged(message.value<DiagnosticsChangedMessage>());
|
diagnosticsChanged(message.value<DiagnosticsChangedMessage>());
|
||||||
|
else if (type == highlightingChangedMessage)
|
||||||
|
highlightingChanged(message.value<HighlightingChangedMessage>());
|
||||||
else
|
else
|
||||||
qWarning() << "Unknown IpcClientMessage";
|
qWarning() << "Unknown IpcClientMessage";
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,8 @@ class RequestDiagnosticsMessage;
|
|||||||
class RegisterUnsavedFilesForEditorMessage;
|
class RegisterUnsavedFilesForEditorMessage;
|
||||||
class UnregisterUnsavedFilesForEditorMessage;
|
class UnregisterUnsavedFilesForEditorMessage;
|
||||||
class UpdateVisibleTranslationUnitsMessage;
|
class UpdateVisibleTranslationUnitsMessage;
|
||||||
|
class RequestHighlightingMessage;
|
||||||
|
class HighlightingChangedMessage;
|
||||||
|
|
||||||
class CMBIPC_EXPORT IpcClientInterface : public IpcInterface
|
class CMBIPC_EXPORT IpcClientInterface : public IpcInterface
|
||||||
{
|
{
|
||||||
@@ -63,6 +65,7 @@ public:
|
|||||||
virtual void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) = 0;
|
virtual void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) = 0;
|
||||||
virtual void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) = 0;
|
virtual void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) = 0;
|
||||||
virtual void diagnosticsChanged(const DiagnosticsChangedMessage &message) = 0;
|
virtual void diagnosticsChanged(const DiagnosticsChangedMessage &message) = 0;
|
||||||
|
virtual void highlightingChanged(const HighlightingChangedMessage &message) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "cmbechomessage.h"
|
#include "cmbechomessage.h"
|
||||||
#include "cmbregistertranslationunitsforeditormessage.h"
|
#include "cmbregistertranslationunitsforeditormessage.h"
|
||||||
#include "diagnosticschangedmessage.h"
|
#include "diagnosticschangedmessage.h"
|
||||||
|
#include "highlightingchangedmessage.h"
|
||||||
#include "ipcserverinterface.h"
|
#include "ipcserverinterface.h"
|
||||||
#include "projectpartsdonotexistmessage.h"
|
#include "projectpartsdonotexistmessage.h"
|
||||||
#include "translationunitdoesnotexistmessage.h"
|
#include "translationunitdoesnotexistmessage.h"
|
||||||
@@ -104,6 +105,11 @@ void IpcClientProxy::diagnosticsChanged(const DiagnosticsChangedMessage &message
|
|||||||
writeMessageBlock.write(QVariant::fromValue(message));
|
writeMessageBlock.write(QVariant::fromValue(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcClientProxy::highlightingChanged(const HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
writeMessageBlock.write(QVariant::fromValue(message));
|
||||||
|
}
|
||||||
|
|
||||||
void IpcClientProxy::readMessages()
|
void IpcClientProxy::readMessages()
|
||||||
{
|
{
|
||||||
for (const QVariant &message : readMessageBlock.readAll())
|
for (const QVariant &message : readMessageBlock.readAll())
|
||||||
|
@@ -63,6 +63,7 @@ public:
|
|||||||
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
|
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
|
||||||
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
|
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
|
||||||
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
|
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
|
||||||
|
void highlightingChanged(const HighlightingChangedMessage &message) override;
|
||||||
|
|
||||||
void readMessages();
|
void readMessages();
|
||||||
|
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include "cmbunregistertranslationunitsforeditormessage.h"
|
#include "cmbunregistertranslationunitsforeditormessage.h"
|
||||||
#include "registerunsavedfilesforeditormessage.h"
|
#include "registerunsavedfilesforeditormessage.h"
|
||||||
#include "requestdiagnosticsmessage.h"
|
#include "requestdiagnosticsmessage.h"
|
||||||
|
#include "requesthighlightingmessage.h"
|
||||||
#include "unregisterunsavedfilesforeditormessage.h"
|
#include "unregisterunsavedfilesforeditormessage.h"
|
||||||
#include "updatetranslationunitsforeditormessage.h"
|
#include "updatetranslationunitsforeditormessage.h"
|
||||||
#include "updatevisibletranslationunitsmessage.h"
|
#include "updatevisibletranslationunitsmessage.h"
|
||||||
@@ -58,9 +59,9 @@ void IpcServerInterface::dispatch(const QVariant &message)
|
|||||||
static const int unregisterUnsavedFilesForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterUnsavedFilesForEditorMessage");
|
static const int unregisterUnsavedFilesForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterUnsavedFilesForEditorMessage");
|
||||||
static const int completeCodeMessageType = QMetaType::type("ClangBackEnd::CompleteCodeMessage");
|
static const int completeCodeMessageType = QMetaType::type("ClangBackEnd::CompleteCodeMessage");
|
||||||
static const int requestDiagnosticsMessageType = QMetaType::type("ClangBackEnd::RequestDiagnosticsMessage");
|
static const int requestDiagnosticsMessageType = QMetaType::type("ClangBackEnd::RequestDiagnosticsMessage");
|
||||||
|
static const int requestHighlightingTypeMessage = QMetaType::type("ClangBackEnd::RequestHighlightingMessage");
|
||||||
static const int updateVisibleTranslationUnitsMessageType = QMetaType::type("ClangBackEnd::UpdateVisibleTranslationUnitsMessage");
|
static const int updateVisibleTranslationUnitsMessageType = QMetaType::type("ClangBackEnd::UpdateVisibleTranslationUnitsMessage");
|
||||||
|
|
||||||
|
|
||||||
int type = message.userType();
|
int type = message.userType();
|
||||||
|
|
||||||
if (type == endMessageType)
|
if (type == endMessageType)
|
||||||
@@ -83,6 +84,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
|
|||||||
completeCode(message.value<CompleteCodeMessage>());
|
completeCode(message.value<CompleteCodeMessage>());
|
||||||
else if (type == requestDiagnosticsMessageType)
|
else if (type == requestDiagnosticsMessageType)
|
||||||
requestDiagnostics(message.value<RequestDiagnosticsMessage>());
|
requestDiagnostics(message.value<RequestDiagnosticsMessage>());
|
||||||
|
else if (type == requestHighlightingTypeMessage)
|
||||||
|
requestHighlighting(message.value<RequestHighlightingMessage>());
|
||||||
else if (type == updateVisibleTranslationUnitsMessageType)
|
else if (type == updateVisibleTranslationUnitsMessageType)
|
||||||
updateVisibleTranslationUnits(message.value<UpdateVisibleTranslationUnitsMessage>());
|
updateVisibleTranslationUnits(message.value<UpdateVisibleTranslationUnitsMessage>());
|
||||||
else
|
else
|
||||||
|
@@ -54,6 +54,7 @@ public:
|
|||||||
virtual void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) = 0;
|
virtual void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) = 0;
|
||||||
virtual void completeCode(const CompleteCodeMessage &message) = 0;
|
virtual void completeCode(const CompleteCodeMessage &message) = 0;
|
||||||
virtual void requestDiagnostics(const RequestDiagnosticsMessage &message) = 0;
|
virtual void requestDiagnostics(const RequestDiagnosticsMessage &message) = 0;
|
||||||
|
virtual void requestHighlighting(const RequestHighlightingMessage &message) = 0;
|
||||||
virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0;
|
virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0;
|
||||||
|
|
||||||
void addClient(IpcClientInterface *client);
|
void addClient(IpcClientInterface *client);
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include <ipcclientinterface.h>
|
#include <ipcclientinterface.h>
|
||||||
#include <registerunsavedfilesforeditormessage.h>
|
#include <registerunsavedfilesforeditormessage.h>
|
||||||
#include <requestdiagnosticsmessage.h>
|
#include <requestdiagnosticsmessage.h>
|
||||||
|
#include <requesthighlightingmessage.h>
|
||||||
#include <unregisterunsavedfilesforeditormessage.h>
|
#include <unregisterunsavedfilesforeditormessage.h>
|
||||||
#include <updatetranslationunitsforeditormessage.h>
|
#include <updatetranslationunitsforeditormessage.h>
|
||||||
#include <updatevisibletranslationunitsmessage.h>
|
#include <updatevisibletranslationunitsmessage.h>
|
||||||
@@ -120,6 +121,11 @@ void IpcServerProxy::requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMe
|
|||||||
writeMessageBlock.write(QVariant::fromValue(message));
|
writeMessageBlock.write(QVariant::fromValue(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcServerProxy::requestHighlighting(const RequestHighlightingMessage &message)
|
||||||
|
{
|
||||||
|
writeMessageBlock.write(QVariant::fromValue(message));
|
||||||
|
}
|
||||||
|
|
||||||
void IpcServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
|
void IpcServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
|
||||||
{
|
{
|
||||||
writeMessageBlock.write(QVariant::fromValue(message));
|
writeMessageBlock.write(QVariant::fromValue(message));
|
||||||
|
@@ -65,7 +65,9 @@ public:
|
|||||||
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
|
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
|
||||||
void completeCode(const CompleteCodeMessage &message) override;
|
void completeCode(const CompleteCodeMessage &message) override;
|
||||||
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
|
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
|
||||||
|
void requestHighlighting(const RequestHighlightingMessage &message) override;
|
||||||
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
|
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
|
||||||
|
|
||||||
void readMessages();
|
void readMessages();
|
||||||
|
|
||||||
void resetCounter();
|
void resetCounter();
|
||||||
|
@@ -28,51 +28,62 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef INDEXEDSYMBOLINFO_H
|
#include "requesthighlightingmessage.h"
|
||||||
#define INDEXEDSYMBOLINFO_H
|
|
||||||
|
|
||||||
#include "sourcelocation.h"
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QIcon>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
#include <ostream>
|
||||||
|
|
||||||
class Symbol
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
RequestHighlightingMessage::RequestHighlightingMessage(const FileContainer &file)
|
||||||
|
: fileContainer_(file)
|
||||||
{
|
{
|
||||||
public:
|
}
|
||||||
enum Kind {
|
|
||||||
Enum,
|
|
||||||
Class,
|
|
||||||
Method, // A member-function.
|
|
||||||
Function, // A free-function (global or within a namespace).
|
|
||||||
Declaration,
|
|
||||||
Constructor,
|
|
||||||
Destructor,
|
|
||||||
Unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
Symbol();
|
const FileContainer RequestHighlightingMessage::fileContainer() const
|
||||||
Symbol(const QString &name,
|
{
|
||||||
const QString &qualification,
|
return fileContainer_;
|
||||||
Kind type,
|
}
|
||||||
const SourceLocation &location);
|
|
||||||
|
|
||||||
QString m_name;
|
QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message)
|
||||||
QString m_qualification;
|
{
|
||||||
SourceLocation m_location;
|
out << message.fileContainer_;
|
||||||
Kind m_kind;
|
|
||||||
|
|
||||||
QIcon iconForSymbol() const;
|
return out;
|
||||||
};
|
}
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &stream, const Symbol &symbol);
|
QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message)
|
||||||
QDataStream &operator>>(QDataStream &stream, Symbol &symbol);
|
{
|
||||||
|
in >> message.fileContainer_;
|
||||||
|
|
||||||
bool operator==(const Symbol &a, const Symbol &b);
|
return in;
|
||||||
bool operator!=(const Symbol &a, const Symbol &b);
|
}
|
||||||
|
|
||||||
} // Clang
|
bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second)
|
||||||
|
{
|
||||||
|
return first.fileContainer_ == second.fileContainer_;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // INDEXEDSYMBOLINFO_H
|
bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second)
|
||||||
|
{
|
||||||
|
return first.fileContainer_ < second.fileContainer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message)
|
||||||
|
{
|
||||||
|
debug.nospace() << "RequestHighlightingMessage("
|
||||||
|
<< message.fileContainer()
|
||||||
|
<< ")";
|
||||||
|
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os)
|
||||||
|
{
|
||||||
|
*os << message.fileContainer().filePath().constData()
|
||||||
|
<< "(" << message.fileContainer().projectPartId().constData() << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
69
src/libs/clangbackendipc/requesthighlightingmessage.h
Normal file
69
src/libs/clangbackendipc/requesthighlightingmessage.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CLANGBACKEND_REQUESTHIGHLIGHTING_H
|
||||||
|
#define CLANGBACKEND_REQUESTHIGHLIGHTING_H
|
||||||
|
|
||||||
|
#include "filecontainer.h"
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class CMBIPC_EXPORT RequestHighlightingMessage
|
||||||
|
{
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message);
|
||||||
|
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message);
|
||||||
|
friend CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
|
||||||
|
friend CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
|
||||||
|
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message);
|
||||||
|
friend void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os);
|
||||||
|
|
||||||
|
public:
|
||||||
|
RequestHighlightingMessage() = default;
|
||||||
|
RequestHighlightingMessage(const FileContainer &fileContainer);
|
||||||
|
|
||||||
|
const FileContainer fileContainer() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileContainer fileContainer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message);
|
||||||
|
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message);
|
||||||
|
CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
|
||||||
|
CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
|
||||||
|
|
||||||
|
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message);
|
||||||
|
void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os);
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ClangBackEnd::RequestHighlightingMessage)
|
||||||
|
|
||||||
|
#endif // CLANGBACKEND_REQUESTHIGHLIGHTING_H
|
@@ -31,6 +31,7 @@
|
|||||||
#ifndef CPLUSPLUS_MATCHINGTEXT_H
|
#ifndef CPLUSPLUS_MATCHINGTEXT_H
|
||||||
#define CPLUSPLUS_MATCHINGTEXT_H
|
#define CPLUSPLUS_MATCHINGTEXT_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
#include <cplusplus/CPlusPlusForwardDeclarations.h>
|
#include <cplusplus/CPlusPlusForwardDeclarations.h>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QTextCursor)
|
QT_FORWARD_DECLARE_CLASS(QTextCursor)
|
||||||
|
@@ -2,4 +2,8 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O2
|
|||||||
win32:QMAKE_CXXFLAGS_DEBUG += -O2
|
win32:QMAKE_CXXFLAGS_DEBUG += -O2
|
||||||
|
|
||||||
include(../../qtcreatorlibrary.pri)
|
include(../../qtcreatorlibrary.pri)
|
||||||
|
|
||||||
|
win32:DEFINES += SQLITE_API=__declspec(dllexport)
|
||||||
|
unix:DEFINES += SQLITE_API=\"__attribute__((visibility(\\\"default\\\")))\"
|
||||||
|
|
||||||
include(sqlite-lib.pri)
|
include(sqlite-lib.pri)
|
||||||
|
@@ -280,7 +280,7 @@ QString AndroidManager::loadLocalJarsInitClasses(ProjectExplorer::Target *target
|
|||||||
|
|
||||||
QPair<int, int> AndroidManager::apiLevelRange()
|
QPair<int, int> AndroidManager::apiLevelRange()
|
||||||
{
|
{
|
||||||
return qMakePair(9, 22);
|
return qMakePair(9, 23);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AndroidManager::androidNameForApiLevel(int x)
|
QString AndroidManager::androidNameForApiLevel(int x)
|
||||||
@@ -324,6 +324,8 @@ QString AndroidManager::androidNameForApiLevel(int x)
|
|||||||
return QLatin1String("Android 5.0");
|
return QLatin1String("Android 5.0");
|
||||||
case 22:
|
case 22:
|
||||||
return QLatin1String("Android 5.1");
|
return QLatin1String("Android 5.1");
|
||||||
|
case 23:
|
||||||
|
return QLatin1String("Android 6.0");
|
||||||
default:
|
default:
|
||||||
return tr("Unknown Android version. API Level: %1").arg(QString::number(x));
|
return tr("Unknown Android version. API Level: %1").arg(QString::number(x));
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@
|
|||||||
#include "bookmarkmanager.h"
|
#include "bookmarkmanager.h"
|
||||||
#include "bookmarks_global.h"
|
#include "bookmarks_global.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
|
|
||||||
|
@@ -46,7 +46,6 @@
|
|||||||
#include <texteditor/texteditorconstants.h>
|
#include <texteditor/texteditorconstants.h>
|
||||||
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CLANG_GLOBAL_H
|
|
||||||
#define CLANG_GLOBAL_H
|
|
||||||
|
|
||||||
#include <qglobal.h>
|
|
||||||
|
|
||||||
#if defined(CLANGCODEMODEL_LIBRARY)
|
|
||||||
# define CLANG_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
# define CLANG_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CLANG_GLOBAL_H
|
|
@@ -28,9 +28,9 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "activationsequencecontextprocessor.h"
|
#include "clangactivationsequencecontextprocessor.h"
|
||||||
|
|
||||||
#include "activationsequenceprocessor.h"
|
#include "clangactivationsequenceprocessor.h"
|
||||||
|
|
||||||
#include <cplusplus/BackwardsScanner.h>
|
#include <cplusplus/BackwardsScanner.h>
|
||||||
#include <cplusplus/ExpressionUnderCursor.h>
|
#include <cplusplus/ExpressionUnderCursor.h>
|
@@ -28,7 +28,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "activationsequenceprocessor.h"
|
#include "clangactivationsequenceprocessor.h"
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
@@ -42,7 +42,7 @@ ClangAssistProposal::ClangAssistProposal(int cursorPos, TextEditor::GenericPropo
|
|||||||
|
|
||||||
bool ClangAssistProposal::isCorrective() const
|
bool ClangAssistProposal::isCorrective() const
|
||||||
{
|
{
|
||||||
return ClangAssistProposalModel::replaceDotForArrow(model());
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangAssistProposal::makeCorrection(TextEditor::TextEditorWidget *editorWidget)
|
void ClangAssistProposal::makeCorrection(TextEditor::TextEditorWidget *editorWidget)
|
||||||
|
@@ -45,9 +45,6 @@ public:
|
|||||||
|
|
||||||
virtual bool isCorrective() const;
|
virtual bool isCorrective() const;
|
||||||
virtual void makeCorrection(TextEditor::TextEditorWidget *editorWidget);
|
virtual void makeCorrection(TextEditor::TextEditorWidget *editorWidget);
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_replaceDotForArrow;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "clangassistproposalitem.h"
|
#include "clangassistproposalitem.h"
|
||||||
|
|
||||||
#include "completionchunkstotextconverter.h"
|
#include "clangcompletionchunkstotextconverter.h"
|
||||||
|
|
||||||
#include <cplusplus/MatchingText.h>
|
#include <cplusplus/MatchingText.h>
|
||||||
#include <cplusplus/Token.h>
|
#include <cplusplus/Token.h>
|
||||||
|
@@ -39,13 +39,6 @@
|
|||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
bool ClangAssistProposalModel::replaceDotForArrow(TextEditor::IAssistProposalModel *model)
|
|
||||||
{
|
|
||||||
auto clangAssistProposalModel = static_cast<ClangAssistProposalModel*>(model);
|
|
||||||
|
|
||||||
return clangAssistProposalModel->m_replaceDotForArrow;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClangAssistProposalModel::isSortable(const QString &/*prefix*/) const
|
bool ClangAssistProposalModel::isSortable(const QString &/*prefix*/) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@@ -41,21 +41,8 @@ namespace Internal {
|
|||||||
class ClangAssistProposalModel : public TextEditor::GenericProposalModel
|
class ClangAssistProposalModel : public TextEditor::GenericProposalModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClangAssistProposalModel()
|
|
||||||
: m_sortable(false)
|
|
||||||
, m_completionOperator(CPlusPlus::T_EOF_SYMBOL)
|
|
||||||
, m_replaceDotForArrow(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool isSortable(const QString &prefix) const override;
|
bool isSortable(const QString &prefix) const override;
|
||||||
void sort(const QString &prefix) override;
|
void sort(const QString &prefix) override;
|
||||||
|
|
||||||
static bool replaceDotForArrow(IAssistProposalModel *model);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_sortable;
|
|
||||||
unsigned m_completionOperator;
|
|
||||||
bool m_replaceDotForArrow;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
#include "clangmodelmanagersupport.h"
|
#include "clangmodelmanagersupport.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
#include "pchmanager.h"
|
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -48,6 +47,7 @@
|
|||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
#include <clangbackendipc/diagnosticschangedmessage.h>
|
#include <clangbackendipc/diagnosticschangedmessage.h>
|
||||||
|
#include <clangbackendipc/highlightingchangedmessage.h>
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -62,11 +62,13 @@
|
|||||||
#include <clangbackendipc/cmbmessages.h>
|
#include <clangbackendipc/cmbmessages.h>
|
||||||
#include <clangbackendipc/registerunsavedfilesforeditormessage.h>
|
#include <clangbackendipc/registerunsavedfilesforeditormessage.h>
|
||||||
#include <clangbackendipc/requestdiagnosticsmessage.h>
|
#include <clangbackendipc/requestdiagnosticsmessage.h>
|
||||||
|
#include <clangbackendipc/requesthighlightingmessage.h>
|
||||||
#include <clangbackendipc/filecontainer.h>
|
#include <clangbackendipc/filecontainer.h>
|
||||||
#include <clangbackendipc/projectpartsdonotexistmessage.h>
|
#include <clangbackendipc/projectpartsdonotexistmessage.h>
|
||||||
#include <clangbackendipc/translationunitdoesnotexistmessage.h>
|
#include <clangbackendipc/translationunitdoesnotexistmessage.h>
|
||||||
#include <clangbackendipc/unregisterunsavedfilesforeditormessage.h>
|
#include <clangbackendipc/unregisterunsavedfilesforeditormessage.h>
|
||||||
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
|
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
|
||||||
|
#include <clangbackendipc/updatevisibletranslationunitsmessage.h>
|
||||||
|
|
||||||
#include <cplusplus/Icons.h>
|
#include <cplusplus/Icons.h>
|
||||||
|
|
||||||
@@ -135,6 +137,11 @@ void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IpcReceiver::isExpectingCodeCompletedMessage() const
|
||||||
|
{
|
||||||
|
return !m_assistProcessorsTable.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
void IpcReceiver::alive()
|
void IpcReceiver::alive()
|
||||||
{
|
{
|
||||||
qCDebug(log) << "<<< AliveMessage";
|
qCDebug(log) << "<<< AliveMessage";
|
||||||
@@ -174,6 +181,24 @@ void IpcReceiver::diagnosticsChanged(const DiagnosticsChangedMessage &message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcReceiver::highlightingChanged(const HighlightingChangedMessage &message)
|
||||||
|
{
|
||||||
|
qCDebug(log) << "<<< HighlightingChangedMessage with"
|
||||||
|
<< message.highlightingMarks().size() << "items";
|
||||||
|
|
||||||
|
auto processor = ClangEditorDocumentProcessor::get(message.file().filePath());
|
||||||
|
|
||||||
|
if (processor && processor->projectPart()) {
|
||||||
|
const QString highlightingProjectPartId = message.file().projectPartId();
|
||||||
|
const QString documentProjectPartId = processor->projectPart()->id();
|
||||||
|
if (highlightingProjectPartId == documentProjectPartId) {
|
||||||
|
processor->updateHighlighting(message.highlightingMarks(),
|
||||||
|
message.skippedPreprocessorRanges(),
|
||||||
|
message.file().documentRevision());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message)
|
void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message)
|
||||||
{
|
{
|
||||||
QTC_CHECK(!"Got TranslationUnitDoesNotExistMessage");
|
QTC_CHECK(!"Got TranslationUnitDoesNotExistMessage");
|
||||||
@@ -203,6 +228,8 @@ public:
|
|||||||
void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override;
|
void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override;
|
||||||
void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override;
|
void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override;
|
||||||
void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override;
|
void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override;
|
||||||
|
void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) override;
|
||||||
|
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClangBackEnd::ConnectionClient &m_connection;
|
ClangBackEnd::ConnectionClient &m_connection;
|
||||||
@@ -268,6 +295,18 @@ void IpcSender::requestDiagnostics(const RequestDiagnosticsMessage &message)
|
|||||||
m_connection.serverProxy().requestDiagnostics(message);
|
m_connection.serverProxy().requestDiagnostics(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcSender::requestHighlighting(const RequestHighlightingMessage &message)
|
||||||
|
{
|
||||||
|
QTC_CHECK(m_connection.isConnected());
|
||||||
|
m_connection.serverProxy().requestHighlighting(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
|
||||||
|
{
|
||||||
|
QTC_CHECK(m_connection.isConnected());
|
||||||
|
m_connection.serverProxy().updateVisibleTranslationUnits(message);
|
||||||
|
}
|
||||||
|
|
||||||
IpcCommunicator::IpcCommunicator()
|
IpcCommunicator::IpcCommunicator()
|
||||||
: m_connection(&m_ipcReceiver)
|
: m_connection(&m_ipcReceiver)
|
||||||
, m_ipcSender(new IpcSender(m_connection))
|
, m_ipcSender(new IpcSender(m_connection))
|
||||||
@@ -308,10 +347,8 @@ void IpcCommunicator::initializeBackend()
|
|||||||
|
|
||||||
static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart)
|
static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart)
|
||||||
{
|
{
|
||||||
QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart,
|
const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart,
|
||||||
CppTools::ProjectFile::Unclassified); // No language option
|
CppTools::ProjectFile::Unclassified); // No language option
|
||||||
if (PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart))
|
|
||||||
options += ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName());
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
@@ -346,6 +383,90 @@ void IpcCommunicator::registerFallbackProjectPart()
|
|||||||
registerProjectPartsForEditor({projectPartContainer});
|
registerProjectPartsForEditor({projectPartContainer});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Utf8String currentCppEditorDocumentFilePath()
|
||||||
|
{
|
||||||
|
Utf8String currentCppEditorDocumentFilePath;
|
||||||
|
|
||||||
|
const auto currentEditor = Core::EditorManager::currentEditor();
|
||||||
|
if (currentEditor && CppTools::CppModelManager::isCppEditor(currentEditor)) {
|
||||||
|
const auto currentDocument = currentEditor->document();
|
||||||
|
if (currentDocument)
|
||||||
|
currentCppEditorDocumentFilePath = currentDocument->filePath().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentCppEditorDocumentFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeDuplicates(Utf8StringVector &visibleEditorDocumentsFilePaths)
|
||||||
|
{
|
||||||
|
std::sort(visibleEditorDocumentsFilePaths.begin(),
|
||||||
|
visibleEditorDocumentsFilePaths.end());
|
||||||
|
const auto end = std::unique(visibleEditorDocumentsFilePaths.begin(),
|
||||||
|
visibleEditorDocumentsFilePaths.end());
|
||||||
|
visibleEditorDocumentsFilePaths.erase(end,
|
||||||
|
visibleEditorDocumentsFilePaths.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeNonCppEditors(QList<Core::IEditor*> &visibleEditors)
|
||||||
|
{
|
||||||
|
const auto isNotCppEditor = [] (Core::IEditor *editor) {
|
||||||
|
return !CppTools::CppModelManager::isCppEditor(editor);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto end = std::remove_if(visibleEditors.begin(),
|
||||||
|
visibleEditors.end(),
|
||||||
|
isNotCppEditor);
|
||||||
|
|
||||||
|
visibleEditors.erase(end, visibleEditors.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
Utf8StringVector visibleCppEditorDocumentsFilePaths()
|
||||||
|
{
|
||||||
|
auto visibleEditors = Core::EditorManager::visibleEditors();
|
||||||
|
|
||||||
|
removeNonCppEditors(visibleEditors);
|
||||||
|
|
||||||
|
Utf8StringVector visibleCppEditorDocumentsFilePaths;
|
||||||
|
visibleCppEditorDocumentsFilePaths.reserve(visibleEditors.size());
|
||||||
|
|
||||||
|
const auto editorFilePaths = [] (Core::IEditor *editor) {
|
||||||
|
return Utf8String(editor->document()->filePath().toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
std::transform(visibleEditors.begin(),
|
||||||
|
visibleEditors.end(),
|
||||||
|
std::back_inserter(visibleCppEditorDocumentsFilePaths),
|
||||||
|
editorFilePaths);
|
||||||
|
|
||||||
|
removeDuplicates(visibleCppEditorDocumentsFilePaths);
|
||||||
|
|
||||||
|
return visibleCppEditorDocumentsFilePaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::updateTranslationUnitVisiblity()
|
||||||
|
{
|
||||||
|
updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IpcCommunicator::isNotWaitingForCompletion() const
|
||||||
|
{
|
||||||
|
return !m_ipcReceiver.isExpectingCodeCompletedMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath,
|
||||||
|
const Utf8StringVector &visibleEditorsFilePaths)
|
||||||
|
{
|
||||||
|
if (m_sendMode == IgnoreSendRequests)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths);
|
||||||
|
qCDebug(log) << ">>>" << message;
|
||||||
|
m_ipcSender->updateVisibleTranslationUnits(message);
|
||||||
|
}
|
||||||
|
|
||||||
void IpcCommunicator::registerCurrentProjectParts()
|
void IpcCommunicator::registerCurrentProjectParts()
|
||||||
{
|
{
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
@@ -355,15 +476,24 @@ void IpcCommunicator::registerCurrentProjectParts()
|
|||||||
registerProjectsParts(projectInfo.projectParts());
|
registerProjectsParts(projectInfo.projectParts());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcCommunicator::registerCurrentCppEditorDocuments()
|
void IpcCommunicator::restoreCppEditorDocuments()
|
||||||
|
{
|
||||||
|
resetCppEditorDocumentProcessors();
|
||||||
|
registerVisibleCppEditorDocumentAndMarkInvisibleDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::resetCppEditorDocumentProcessors()
|
||||||
{
|
{
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
|
|
||||||
const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments();
|
const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments();
|
||||||
foreach (const CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) {
|
foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments)
|
||||||
if (cppEditorDocument->processor()->baseTextDocument()->isModified())
|
cppEditorDocument->resetProcessor();
|
||||||
updateTranslationUnitFromCppEditorDocument(cppEditorDocument->filePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty()
|
||||||
|
{
|
||||||
|
CppTools::CppModelManager::instance()->updateCppEditorDocuments();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcCommunicator::registerCurrentCodeModelUiHeaders()
|
void IpcCommunicator::registerCurrentCodeModelUiHeaders()
|
||||||
@@ -401,12 +531,13 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
|||||||
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool documentHasChanged(const QString &filePath)
|
bool documentHasChanged(const QString &filePath,
|
||||||
|
uint revision)
|
||||||
{
|
{
|
||||||
auto *document = cppDocument(filePath);
|
auto *document = cppDocument(filePath);
|
||||||
|
|
||||||
if (document)
|
if (document)
|
||||||
return document->sendTracker().shouldSendRevision(document->revision());
|
return document->sendTracker().shouldSendRevision(revision);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -446,30 +577,39 @@ void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArra
|
|||||||
documentRevision}});
|
documentRevision}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
|
void IpcCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer)
|
||||||
{
|
{
|
||||||
if (m_sendMode == IgnoreSendRequests)
|
if (m_sendMode == IgnoreSendRequests)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (documentHasChanged(fileContainer.filePath())) {
|
if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) {
|
||||||
updateTranslationUnitsForEditor({fileContainer});
|
updateTranslationUnitsForEditor({fileContainer});
|
||||||
|
|
||||||
const RequestDiagnosticsMessage message(fileContainer);
|
|
||||||
qCDebug(log) << ">>>" << message;
|
|
||||||
m_ipcSender->requestDiagnostics(message);
|
|
||||||
|
|
||||||
setLastSentDocumentRevision(fileContainer.filePath(),
|
setLastSentDocumentRevision(fileContainer.filePath(),
|
||||||
fileContainer.documentRevision());
|
fileContainer.documentRevision());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcCommunicator::requestDiagnostics(Core::IDocument *document)
|
void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
|
||||||
|
{
|
||||||
|
const RequestDiagnosticsMessage message(fileContainer);
|
||||||
|
qCDebug(log) << ">>>" << message;
|
||||||
|
m_ipcSender->requestDiagnostics(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::requestHighlighting(const FileContainer &fileContainer)
|
||||||
|
{
|
||||||
|
const RequestHighlightingMessage message(fileContainer);
|
||||||
|
qCDebug(log) << ">>>" << message;
|
||||||
|
m_ipcSender->requestHighlighting(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document)
|
||||||
{
|
{
|
||||||
const auto textDocument = qobject_cast<TextDocument*>(document);
|
const auto textDocument = qobject_cast<TextDocument*>(document);
|
||||||
const auto filePath = textDocument->filePath().toString();
|
const auto filePath = textDocument->filePath().toString();
|
||||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||||
|
|
||||||
requestDiagnostics(FileContainer(filePath,
|
updateTranslationUnitWithRevisionCheck(FileContainer(filePath,
|
||||||
projectPartId,
|
projectPartId,
|
||||||
Utf8StringVector(),
|
Utf8StringVector(),
|
||||||
textDocument->document()->revision()));
|
textDocument->document()->revision()));
|
||||||
@@ -526,8 +666,9 @@ void IpcCommunicator::initializeBackendWithCurrentData()
|
|||||||
{
|
{
|
||||||
registerFallbackProjectPart();
|
registerFallbackProjectPart();
|
||||||
registerCurrentProjectParts();
|
registerCurrentProjectParts();
|
||||||
registerCurrentCppEditorDocuments();
|
|
||||||
registerCurrentCodeModelUiHeaders();
|
registerCurrentCodeModelUiHeaders();
|
||||||
|
restoreCppEditorDocuments();
|
||||||
|
updateTranslationUnitVisiblity();
|
||||||
|
|
||||||
emit backendReinitialized();
|
emit backendReinitialized();
|
||||||
}
|
}
|
||||||
@@ -549,7 +690,9 @@ void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fi
|
|||||||
if (m_sendMode == IgnoreSendRequests)
|
if (m_sendMode == IgnoreSendRequests)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const RegisterTranslationUnitForEditorMessage message(fileContainers);
|
const RegisterTranslationUnitForEditorMessage message(fileContainers,
|
||||||
|
currentCppEditorDocumentFilePath(),
|
||||||
|
visibleCppEditorDocumentsFilePaths());
|
||||||
qCDebug(log) << ">>>" << message;
|
qCDebug(log) << ">>>" << message;
|
||||||
m_ipcSender->registerTranslationUnitsForEditor(message);
|
m_ipcSender->registerTranslationUnitsForEditor(message);
|
||||||
}
|
}
|
||||||
|
@@ -76,11 +76,14 @@ public:
|
|||||||
void deleteAndClearWaitingAssistProcessors();
|
void deleteAndClearWaitingAssistProcessors();
|
||||||
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
|
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
|
||||||
|
|
||||||
|
bool isExpectingCodeCompletedMessage() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void alive() override;
|
void alive() override;
|
||||||
void echo(const ClangBackEnd::EchoMessage &message) override;
|
void echo(const ClangBackEnd::EchoMessage &message) override;
|
||||||
void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override;
|
void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override;
|
||||||
void diagnosticsChanged(const ClangBackEnd::DiagnosticsChangedMessage &message) override;
|
void diagnosticsChanged(const ClangBackEnd::DiagnosticsChangedMessage &message) override;
|
||||||
|
void highlightingChanged(const ClangBackEnd::HighlightingChangedMessage &message) override;
|
||||||
|
|
||||||
void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &message) override;
|
void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &message) override;
|
||||||
void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &message) override;
|
void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &message) override;
|
||||||
@@ -105,6 +108,8 @@ public:
|
|||||||
virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0;
|
virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0;
|
||||||
virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0;
|
virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0;
|
||||||
virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0;
|
virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0;
|
||||||
|
virtual void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) = 0;
|
||||||
|
virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IpcCommunicator : public QObject
|
class IpcCommunicator : public QObject
|
||||||
@@ -126,6 +131,8 @@ public:
|
|||||||
void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
|
void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
|
||||||
void registerUnsavedFilesForEditor(const FileContainers &fileContainers);
|
void registerUnsavedFilesForEditor(const FileContainers &fileContainers);
|
||||||
void unregisterUnsavedFilesForEditor(const FileContainers &fileContainers);
|
void unregisterUnsavedFilesForEditor(const FileContainers &fileContainers);
|
||||||
|
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
|
||||||
|
void requestHighlighting(const ClangBackEnd::FileContainer &fileContainer);
|
||||||
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
|
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
@@ -140,11 +147,14 @@ public:
|
|||||||
void updateUnsavedFileFromCppEditorDocument(const QString &filePath);
|
void updateUnsavedFileFromCppEditorDocument(const QString &filePath);
|
||||||
void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||||
void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||||
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
|
void updateTranslationUnitWithRevisionCheck(const ClangBackEnd::FileContainer &fileContainer);
|
||||||
void requestDiagnostics(Core::IDocument *document);
|
void updateTranslationUnitWithRevisionCheck(Core::IDocument *document);
|
||||||
void updateChangeContentStartPosition(const QString &filePath, int position);
|
void updateChangeContentStartPosition(const QString &filePath, int position);
|
||||||
|
|
||||||
void registerFallbackProjectPart();
|
void registerFallbackProjectPart();
|
||||||
|
void updateTranslationUnitVisiblity();
|
||||||
|
|
||||||
|
bool isNotWaitingForCompletion() const;
|
||||||
|
|
||||||
public: // for tests
|
public: // for tests
|
||||||
IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender);
|
IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender);
|
||||||
@@ -159,13 +169,19 @@ private:
|
|||||||
void initializeBackend();
|
void initializeBackend();
|
||||||
void initializeBackendWithCurrentData();
|
void initializeBackendWithCurrentData();
|
||||||
void registerCurrentProjectParts();
|
void registerCurrentProjectParts();
|
||||||
void registerCurrentCppEditorDocuments();
|
void restoreCppEditorDocuments();
|
||||||
|
void resetCppEditorDocumentProcessors();
|
||||||
|
void registerVisibleCppEditorDocumentAndMarkInvisibleDirty();
|
||||||
void registerCurrentCodeModelUiHeaders();
|
void registerCurrentCodeModelUiHeaders();
|
||||||
|
|
||||||
|
|
||||||
void onBackendRestarted();
|
void onBackendRestarted();
|
||||||
void onEditorAboutToClose(Core::IEditor *editor);
|
void onEditorAboutToClose(Core::IEditor *editor);
|
||||||
void onCoreAboutToClose();
|
void onCoreAboutToClose();
|
||||||
|
|
||||||
|
void updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath,
|
||||||
|
const Utf8StringVector &visibleEditorsFilePaths);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IpcReceiver m_ipcReceiver;
|
IpcReceiver m_ipcReceiver;
|
||||||
ClangBackEnd::ConnectionClient m_connection;
|
ClangBackEnd::ConnectionClient m_connection;
|
||||||
|
@@ -1,19 +1,13 @@
|
|||||||
include(../../qtcreatorplugin.pri)
|
include(../../qtcreatorplugin.pri)
|
||||||
include(../../shared/clang/clang_installation.pri)
|
include(../../shared/clang/clang_installation.pri)
|
||||||
|
|
||||||
LIBS += $$LLVM_LIBS
|
# The following defines are used to determine the clang include path for intrinsics.
|
||||||
INCLUDEPATH += $$LLVM_INCLUDEPATH
|
|
||||||
DEFINES += CLANGCODEMODEL_LIBRARY
|
|
||||||
|
|
||||||
# The following defines are used to determine the clang include path for intrinsics
|
|
||||||
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
|
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
|
||||||
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\""
|
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\""
|
||||||
|
|
||||||
unix:QMAKE_LFLAGS += -Wl,-rpath,\'$$LLVM_LIBDIR\'
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
activationsequencecontextprocessor.cpp \
|
clangactivationsequencecontextprocessor.cpp \
|
||||||
activationsequenceprocessor.cpp \
|
clangactivationsequenceprocessor.cpp \
|
||||||
clangassistproposal.cpp \
|
clangassistproposal.cpp \
|
||||||
clangassistproposalitem.cpp \
|
clangassistproposalitem.cpp \
|
||||||
clangassistproposalmodel.cpp \
|
clangassistproposalmodel.cpp \
|
||||||
@@ -22,6 +16,7 @@ SOURCES += \
|
|||||||
clangcompletionassistinterface.cpp \
|
clangcompletionassistinterface.cpp \
|
||||||
clangcompletionassistprocessor.cpp \
|
clangcompletionassistprocessor.cpp \
|
||||||
clangcompletionassistprovider.cpp \
|
clangcompletionassistprovider.cpp \
|
||||||
|
clangcompletionchunkstotextconverter.cpp \
|
||||||
clangcompletioncontextanalyzer.cpp \
|
clangcompletioncontextanalyzer.cpp \
|
||||||
clangdiagnosticfilter.cpp \
|
clangdiagnosticfilter.cpp \
|
||||||
clangdiagnosticmanager.cpp \
|
clangdiagnosticmanager.cpp \
|
||||||
@@ -30,32 +25,16 @@ SOURCES += \
|
|||||||
clangfixitoperation.cpp \
|
clangfixitoperation.cpp \
|
||||||
clangfixitoperationsextractor.cpp \
|
clangfixitoperationsextractor.cpp \
|
||||||
clangfunctionhintmodel.cpp \
|
clangfunctionhintmodel.cpp \
|
||||||
|
clanghighlightingmarksreporter.cpp \
|
||||||
clangmodelmanagersupport.cpp \
|
clangmodelmanagersupport.cpp \
|
||||||
clangprojectsettings.cpp \
|
clangprojectsettings.cpp \
|
||||||
clangprojectsettingspropertiespage.cpp \
|
clangprojectsettingspropertiespage.cpp \
|
||||||
clangtextmark.cpp \
|
clangtextmark.cpp \
|
||||||
clangutils.cpp \
|
clangutils.cpp
|
||||||
completionchunkstotextconverter.cpp \
|
|
||||||
cppcreatemarkers.cpp \
|
|
||||||
cxprettyprinter.cpp \
|
|
||||||
diagnostic.cpp \
|
|
||||||
fastindexer.cpp \
|
|
||||||
pchinfo.cpp \
|
|
||||||
pchmanager.cpp \
|
|
||||||
raii/scopedclangoptions.cpp \
|
|
||||||
semanticmarker.cpp \
|
|
||||||
sourcelocation.cpp \
|
|
||||||
sourcemarker.cpp \
|
|
||||||
symbol.cpp \
|
|
||||||
unit.cpp \
|
|
||||||
unsavedfiledata.cpp \
|
|
||||||
utils.cpp \
|
|
||||||
utils_p.cpp
|
|
||||||
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
activationsequencecontextprocessor.h \
|
clangactivationsequencecontextprocessor.h \
|
||||||
activationsequenceprocessor.h \
|
clangactivationsequenceprocessor.h \
|
||||||
clangassistproposal.h \
|
clangassistproposal.h \
|
||||||
clangassistproposalitem.h \
|
clangassistproposalitem.h \
|
||||||
clangassistproposalmodel.h \
|
clangassistproposalmodel.h \
|
||||||
@@ -64,7 +43,9 @@ HEADERS += \
|
|||||||
clangcompletionassistinterface.h \
|
clangcompletionassistinterface.h \
|
||||||
clangcompletionassistprocessor.h \
|
clangcompletionassistprocessor.h \
|
||||||
clangcompletionassistprovider.h \
|
clangcompletionassistprovider.h \
|
||||||
|
clangcompletionchunkstotextconverter.h \
|
||||||
clangcompletioncontextanalyzer.h \
|
clangcompletioncontextanalyzer.h \
|
||||||
|
clangconstants.h \
|
||||||
clangdiagnosticfilter.h \
|
clangdiagnosticfilter.h \
|
||||||
clangdiagnosticmanager.h \
|
clangdiagnosticmanager.h \
|
||||||
clangeditordocumentparser.h \
|
clangeditordocumentparser.h \
|
||||||
@@ -72,45 +53,12 @@ HEADERS += \
|
|||||||
clangfixitoperation.h \
|
clangfixitoperation.h \
|
||||||
clangfixitoperationsextractor.h \
|
clangfixitoperationsextractor.h \
|
||||||
clangfunctionhintmodel.h \
|
clangfunctionhintmodel.h \
|
||||||
clang_global.h \
|
clanghighlightingmarksreporter.h \
|
||||||
clangmodelmanagersupport.h \
|
clangmodelmanagersupport.h \
|
||||||
clangprojectsettings.h \
|
clangprojectsettings.h \
|
||||||
clangprojectsettingspropertiespage.h \
|
clangprojectsettingspropertiespage.h \
|
||||||
clangtextmark.h \
|
clangtextmark.h \
|
||||||
clangutils.h \
|
clangutils.h \
|
||||||
completionchunkstotextconverter.h \
|
|
||||||
constants.h \
|
|
||||||
cppcreatemarkers.h \
|
|
||||||
cxprettyprinter.h \
|
|
||||||
cxraii.h \
|
|
||||||
diagnostic.h \
|
|
||||||
fastindexer.h \
|
|
||||||
pchinfo.h \
|
|
||||||
pchmanager.h \
|
|
||||||
raii/scopedclangoptions.h \
|
|
||||||
semanticmarker.h \
|
|
||||||
sourcelocation.h \
|
|
||||||
sourcemarker.h \
|
|
||||||
symbol.h \
|
|
||||||
unit.h \
|
|
||||||
unsavedfiledata.h \
|
|
||||||
utils.h \
|
|
||||||
utils_p.h
|
|
||||||
|
|
||||||
|
|
||||||
contains(DEFINES, CLANG_INDEXING) {
|
|
||||||
HEADERS += \
|
|
||||||
clangindexer.h \
|
|
||||||
index.h \
|
|
||||||
indexer.h
|
|
||||||
# dependencygraph.h \
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
clangindexer.cpp \
|
|
||||||
index.cpp \
|
|
||||||
indexer.cpp
|
|
||||||
# dependencygraph.cpp \
|
|
||||||
}
|
|
||||||
|
|
||||||
FORMS += clangprojectsettingspropertiespage.ui
|
FORMS += clangprojectsettingspropertiespage.ui
|
||||||
|
|
||||||
|
@@ -20,84 +20,75 @@ QtcPlugin {
|
|||||||
"QmakeProjectManager",
|
"QmakeProjectManager",
|
||||||
]
|
]
|
||||||
|
|
||||||
property bool clangCompletion: true
|
|
||||||
property bool clangHighlighting: true
|
|
||||||
property bool clangIndexing: false
|
|
||||||
|
|
||||||
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader)
|
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader)
|
||||||
property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
|
property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
|
||||||
property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
|
property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
|
||||||
property string llvmLibs: Clang.libraries(qbs.targetOS)
|
|
||||||
property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader)
|
property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader)
|
||||||
|
|
||||||
condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h"))
|
condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h"))
|
||||||
|
|
||||||
cpp.includePaths: base.concat(llvmIncludeDir)
|
|
||||||
cpp.libraryPaths: base.concat(llvmLibDir)
|
|
||||||
cpp.rpaths: cpp.libraryPaths
|
|
||||||
cpp.dynamicLibraries: base.concat(llvmLibs)
|
|
||||||
|
|
||||||
cpp.defines: {
|
cpp.defines: {
|
||||||
var defines = base;
|
var defines = base;
|
||||||
|
// The following defines are used to determine the clang include path for intrinsics.
|
||||||
defines.push('CLANG_VERSION="' + llvmVersion + '"');
|
defines.push('CLANG_VERSION="' + llvmVersion + '"');
|
||||||
defines.push('CLANG_RESOURCE_DIR="' + llvmLibDir + '/clang/' + llvmVersion + '/include"');
|
defines.push('CLANG_RESOURCE_DIR="' + llvmLibDir + '/clang/' + llvmVersion + '/include"');
|
||||||
if (clangCompletion)
|
|
||||||
defines.push("CLANG_COMPLETION");
|
|
||||||
if (clangHighlighting)
|
|
||||||
defines.push("CLANG_HIGHLIGHTING");
|
|
||||||
if (clangIndexing)
|
|
||||||
defines.push("CLANG_INDEXING");
|
|
||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
Group {
|
|
||||||
name: "Completion support"
|
|
||||||
condition: product.clangCompletion
|
|
||||||
files: [
|
files: [
|
||||||
"activationsequencecontextprocessor.cpp",
|
"clangactivationsequencecontextprocessor.cpp",
|
||||||
"activationsequencecontextprocessor.h",
|
"clangactivationsequencecontextprocessor.h",
|
||||||
"activationsequenceprocessor.cpp",
|
"clangactivationsequenceprocessor.cpp",
|
||||||
"activationsequenceprocessor.h",
|
"clangactivationsequenceprocessor.h",
|
||||||
"clangassistproposal.cpp",
|
"clangassistproposal.cpp",
|
||||||
"clangassistproposal.h",
|
"clangassistproposal.h",
|
||||||
"clangassistproposalitem.cpp",
|
"clangassistproposalitem.cpp",
|
||||||
"clangassistproposalitem.h",
|
"clangassistproposalitem.h",
|
||||||
"clangassistproposalmodel.cpp",
|
"clangassistproposalmodel.cpp",
|
||||||
"clangassistproposalmodel.h",
|
"clangassistproposalmodel.h",
|
||||||
|
"clangbackendipcintegration.cpp",
|
||||||
|
"clangbackendipcintegration.h",
|
||||||
|
"clangcodemodelplugin.cpp",
|
||||||
|
"clangcodemodelplugin.h",
|
||||||
"clangcompletionassistinterface.cpp",
|
"clangcompletionassistinterface.cpp",
|
||||||
"clangcompletionassistinterface.h",
|
"clangcompletionassistinterface.h",
|
||||||
"clangcompletionassistprocessor.cpp",
|
"clangcompletionassistprocessor.cpp",
|
||||||
"clangcompletionassistprocessor.h",
|
"clangcompletionassistprocessor.h",
|
||||||
"clangcompletionassistprovider.cpp",
|
"clangcompletionassistprovider.cpp",
|
||||||
"clangcompletionassistprovider.h",
|
"clangcompletionassistprovider.h",
|
||||||
|
"clangcompletionchunkstotextconverter.cpp",
|
||||||
|
"clangcompletionchunkstotextconverter.h",
|
||||||
|
"clangcompletioncontextanalyzer.cpp",
|
||||||
|
"clangcompletioncontextanalyzer.h",
|
||||||
|
"clangconstants.h",
|
||||||
|
"clangdiagnosticfilter.cpp",
|
||||||
|
"clangdiagnosticfilter.h",
|
||||||
|
"clangdiagnosticmanager.cpp",
|
||||||
|
"clangdiagnosticmanager.h",
|
||||||
|
"clangeditordocumentparser.cpp",
|
||||||
|
"clangeditordocumentparser.h",
|
||||||
|
"clangeditordocumentprocessor.cpp",
|
||||||
|
"clangeditordocumentprocessor.h",
|
||||||
|
"clangfixitoperation.cpp",
|
||||||
|
"clangfixitoperation.h",
|
||||||
|
"clangfixitoperationsextractor.cpp",
|
||||||
|
"clangfixitoperationsextractor.h",
|
||||||
"clangfunctionhintmodel.cpp",
|
"clangfunctionhintmodel.cpp",
|
||||||
"clangfunctionhintmodel.h",
|
"clangfunctionhintmodel.h",
|
||||||
|
"clanghighlightingmarksreporter.cpp",
|
||||||
|
"clanghighlightingmarksreporter.h",
|
||||||
|
"clangmodelmanagersupport.cpp",
|
||||||
|
"clangmodelmanagersupport.h",
|
||||||
|
"clangprojectsettings.cpp",
|
||||||
|
"clangprojectsettings.h",
|
||||||
|
"clangprojectsettingspropertiespage.cpp",
|
||||||
|
"clangprojectsettingspropertiespage.h",
|
||||||
|
"clangprojectsettingspropertiespage.ui",
|
||||||
|
"clangtextmark.cpp",
|
||||||
|
"clangtextmark.h",
|
||||||
|
"clangutils.cpp",
|
||||||
|
"clangutils.h",
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
Group {
|
|
||||||
name: "Highlighting support"
|
|
||||||
condition: product.clangHighlighting
|
|
||||||
files: [
|
|
||||||
"cppcreatemarkers.cpp",
|
|
||||||
"cppcreatemarkers.h",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Group {
|
|
||||||
name: "Indexing support"
|
|
||||||
condition: product.clangIndexing
|
|
||||||
files: [
|
|
||||||
"clangindexer.cpp",
|
|
||||||
"clangindexer.h",
|
|
||||||
"index.cpp",
|
|
||||||
"index.h",
|
|
||||||
"indexer.cpp",
|
|
||||||
"indexer.h",
|
|
||||||
// "dependencygraph.h",
|
|
||||||
// "dependencygraph.cpp"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
name: "Tests"
|
name: "Tests"
|
||||||
@@ -117,69 +108,4 @@ QtcPlugin {
|
|||||||
files: [ "*" ]
|
files: [ "*" ]
|
||||||
excludeFiles: "clangtestdata.qrc"
|
excludeFiles: "clangtestdata.qrc"
|
||||||
}
|
}
|
||||||
|
|
||||||
files: [
|
|
||||||
"clang_global.h",
|
|
||||||
"clangcompletioncontextanalyzer.cpp",
|
|
||||||
"clangcompletioncontextanalyzer.h",
|
|
||||||
"clangeditordocumentparser.cpp",
|
|
||||||
"clangeditordocumentparser.h",
|
|
||||||
"clangeditordocumentprocessor.cpp",
|
|
||||||
"clangeditordocumentprocessor.h",
|
|
||||||
"clangdiagnosticfilter.cpp",
|
|
||||||
"clangdiagnosticfilter.h",
|
|
||||||
"clangdiagnosticmanager.cpp",
|
|
||||||
"clangdiagnosticmanager.h",
|
|
||||||
"clangfixitoperation.cpp",
|
|
||||||
"clangfixitoperation.h",
|
|
||||||
"clangfixitoperationsextractor.cpp",
|
|
||||||
"clangfixitoperationsextractor.h",
|
|
||||||
"clangmodelmanagersupport.cpp",
|
|
||||||
"clangmodelmanagersupport.h",
|
|
||||||
"clangcodemodelplugin.cpp",
|
|
||||||
"clangcodemodelplugin.h",
|
|
||||||
"clangprojectsettings.cpp",
|
|
||||||
"clangprojectsettings.h",
|
|
||||||
"clangprojectsettingspropertiespage.cpp",
|
|
||||||
"clangprojectsettingspropertiespage.h",
|
|
||||||
"clangprojectsettingspropertiespage.ui",
|
|
||||||
"clangtextmark.cpp",
|
|
||||||
"clangtextmark.h",
|
|
||||||
"clangutils.cpp",
|
|
||||||
"clangutils.h",
|
|
||||||
"clangbackendipcintegration.cpp",
|
|
||||||
"clangbackendipcintegration.h",
|
|
||||||
"completionchunkstotextconverter.cpp",
|
|
||||||
"completionchunkstotextconverter.h",
|
|
||||||
"constants.h",
|
|
||||||
"cxprettyprinter.cpp",
|
|
||||||
"cxprettyprinter.h",
|
|
||||||
"cxraii.h",
|
|
||||||
"diagnostic.cpp",
|
|
||||||
"diagnostic.h",
|
|
||||||
"fastindexer.cpp",
|
|
||||||
"fastindexer.h",
|
|
||||||
"pchinfo.cpp",
|
|
||||||
"pchinfo.h",
|
|
||||||
"pchmanager.cpp",
|
|
||||||
"pchmanager.h",
|
|
||||||
"semanticmarker.cpp",
|
|
||||||
"semanticmarker.h",
|
|
||||||
"sourcelocation.cpp",
|
|
||||||
"sourcelocation.h",
|
|
||||||
"sourcemarker.cpp",
|
|
||||||
"sourcemarker.h",
|
|
||||||
"symbol.cpp",
|
|
||||||
"symbol.h",
|
|
||||||
"unit.cpp",
|
|
||||||
"unit.h",
|
|
||||||
"unsavedfiledata.cpp",
|
|
||||||
"unsavedfiledata.h",
|
|
||||||
"utils.cpp",
|
|
||||||
"utils.h",
|
|
||||||
"utils_p.cpp",
|
|
||||||
"utils_p.h",
|
|
||||||
"raii/scopedclangoptions.cpp",
|
|
||||||
"raii/scopedclangoptions.h",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@@ -30,10 +30,8 @@
|
|||||||
|
|
||||||
#include "clangcodemodelplugin.h"
|
#include "clangcodemodelplugin.h"
|
||||||
|
|
||||||
|
#include "clangconstants.h"
|
||||||
#include "clangprojectsettingspropertiespage.h"
|
#include "clangprojectsettingspropertiespage.h"
|
||||||
#include "constants.h"
|
|
||||||
#include "pchmanager.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
# include "test/clangcodecompletion_test.h"
|
# include "test/clangcodecompletion_test.h"
|
||||||
@@ -50,7 +48,9 @@
|
|||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static void initializeTextMarks()
|
namespace {
|
||||||
|
|
||||||
|
void initializeTextMarks()
|
||||||
{
|
{
|
||||||
TextEditor::TextMark::setCategoryColor(Core::Id(Constants::CLANG_WARNING),
|
TextEditor::TextMark::setCategoryColor(Core::Id(Constants::CLANG_WARNING),
|
||||||
Utils::Theme::ClangCodeModel_Warning_TextMarkColor);
|
Utils::Theme::ClangCodeModel_Warning_TextMarkColor);
|
||||||
@@ -58,10 +58,7 @@ static void initializeTextMarks()
|
|||||||
Utils::Theme::ClangCodeModel_Error_TextMarkColor);
|
Utils::Theme::ClangCodeModel_Error_TextMarkColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangCodeModelPlugin::ClangCodeModelPlugin()
|
} // anonymous namespace
|
||||||
{
|
|
||||||
qRegisterMetaType<CppTools::ProjectPart::Ptr>();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||||
{
|
{
|
||||||
@@ -75,25 +72,8 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
|
|||||||
panelFactory->setSimpleCreateWidgetFunction<ClangProjectSettingsWidget>(QIcon());
|
panelFactory->setSimpleCreateWidgetFunction<ClangProjectSettingsWidget>(QIcon());
|
||||||
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
|
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
|
||||||
|
|
||||||
// Initialize Clang
|
|
||||||
ClangCodeModel::Internal::initializeClang();
|
|
||||||
|
|
||||||
// Set up Indexer
|
|
||||||
auto cppModelManager = CppTools::CppModelManager::instance();
|
|
||||||
#ifdef CLANG_INDEXING
|
|
||||||
m_indexer.reset(new ClangIndexer);
|
|
||||||
cppModelManager->setIndexingSupport(m_indexer->indexingSupport());
|
|
||||||
#endif // CLANG_INDEXING
|
|
||||||
|
|
||||||
// Set up PchManager
|
|
||||||
PchManager *pchManager = new PchManager(this);
|
|
||||||
ProjectExplorer::SessionManager *sessionManager = ProjectExplorer::SessionManager::instance();
|
|
||||||
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
|
|
||||||
pchManager, &PchManager::onAboutToRemoveProject);
|
|
||||||
connect(cppModelManager, &CppTools::CppModelManager::projectPartsUpdated,
|
|
||||||
pchManager, &PchManager::onProjectPartsUpdated);
|
|
||||||
|
|
||||||
// Register ModelManagerSupportProvider
|
// Register ModelManagerSupportProvider
|
||||||
|
auto cppModelManager = CppTools::CppModelManager::instance();
|
||||||
cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider);
|
cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider);
|
||||||
|
|
||||||
initializeTextMarks();
|
initializeTextMarks();
|
||||||
|
@@ -33,14 +33,8 @@
|
|||||||
|
|
||||||
#include "clangmodelmanagersupport.h"
|
#include "clangmodelmanagersupport.h"
|
||||||
|
|
||||||
#ifdef CLANG_INDEXING
|
|
||||||
# include "clangindexer.h"
|
|
||||||
#endif // CLANG_INDEXING
|
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
#include <QScopedPointer>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -50,16 +44,11 @@ class ClangCodeModelPlugin: public ExtensionSystem::IPlugin
|
|||||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ClangCodeModel.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ClangCodeModel.json")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClangCodeModelPlugin();
|
|
||||||
|
|
||||||
bool initialize(const QStringList &arguments, QString *errorMessage);
|
bool initialize(const QStringList &arguments, QString *errorMessage);
|
||||||
void extensionsInitialized();
|
void extensionsInitialized();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModelManagerSupportProviderClang m_modelManagerSupportProvider;
|
ModelManagerSupportProviderClang m_modelManagerSupportProvider;
|
||||||
#ifdef CLANG_INDEXING
|
|
||||||
QScopedPointer<ClangIndexer> m_indexer;
|
|
||||||
#endif // CLANG_INDEXING
|
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
QList<QObject *> createTestObjects() const;
|
QList<QObject *> createTestObjects() const;
|
||||||
|
@@ -1,15 +1,19 @@
|
|||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
SOURCES += $$PWD/completionchunkstotextconverter.cpp \
|
SOURCES += \
|
||||||
$$PWD/activationsequenceprocessor.cpp \
|
$$PWD/clangactivationsequencecontextprocessor.cpp \
|
||||||
$$PWD/activationsequencecontextprocessor.cpp \
|
$$PWD/clangactivationsequenceprocessor.cpp \
|
||||||
|
$$PWD/clangcompletionchunkstotextconverter.cpp \
|
||||||
$$PWD/clangcompletioncontextanalyzer.cpp \
|
$$PWD/clangcompletioncontextanalyzer.cpp \
|
||||||
$$PWD/clangdiagnosticfilter.cpp \
|
$$PWD/clangdiagnosticfilter.cpp \
|
||||||
$$PWD/clangfixitoperation.cpp
|
$$PWD/clangfixitoperation.cpp \
|
||||||
|
$$PWD/clanghighlightingmarksreporter.cpp
|
||||||
|
|
||||||
HEADERS += $$PWD/completionchunkstotextconverter.h \
|
HEADERS += \
|
||||||
$$PWD/activationsequenceprocessor.h \
|
$$PWD/clangactivationsequencecontextprocessor.h \
|
||||||
$$PWD/activationsequencecontextprocessor.h \
|
$$PWD/clangactivationsequenceprocessor.h \
|
||||||
|
$$PWD/clangcompletionchunkstotextconverter.h \
|
||||||
$$PWD/clangcompletioncontextanalyzer.h \
|
$$PWD/clangcompletioncontextanalyzer.h \
|
||||||
$$PWD/clangdiagnosticfilter.h \
|
$$PWD/clangdiagnosticfilter.h \
|
||||||
$$PWD/clangfixitoperation.h
|
$$PWD/clangfixitoperation.h \
|
||||||
|
$$PWD/clanghighlightingmarksreporter.h
|
||||||
|
@@ -32,14 +32,10 @@
|
|||||||
|
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
#include <cpptools/cpptoolsreuse.h>
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
#include <cpptools/cppworkingcopy.h>
|
|
||||||
|
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
#include <cplusplus/Token.h>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -50,18 +46,13 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(
|
|||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
TextEditor::AssistReason reason,
|
TextEditor::AssistReason reason,
|
||||||
const CppTools::ProjectPart::HeaderPaths &headerPaths,
|
const CppTools::ProjectPart::HeaderPaths &headerPaths,
|
||||||
const PchInfo::Ptr &pchInfo,
|
|
||||||
const CPlusPlus::LanguageFeatures &features)
|
const CPlusPlus::LanguageFeatures &features)
|
||||||
: AssistInterface(textEditorWidget->document(), position, fileName, reason)
|
: AssistInterface(textEditorWidget->document(), position, fileName, reason)
|
||||||
, m_ipcCommunicator(ipcCommunicator)
|
, m_ipcCommunicator(ipcCommunicator)
|
||||||
, m_headerPaths(headerPaths)
|
, m_headerPaths(headerPaths)
|
||||||
, m_savedPchPointer(pchInfo)
|
|
||||||
, m_languageFeatures(features)
|
, m_languageFeatures(features)
|
||||||
, m_textEditorWidget(textEditorWidget)
|
, m_textEditorWidget(textEditorWidget)
|
||||||
{
|
{
|
||||||
m_unsavedFiles = Utils::createUnsavedFiles(
|
|
||||||
CppTools::CppModelManager::instance()->workingCopy(),
|
|
||||||
CppTools::modifiedFiles());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangCompletionAssistInterface::objcEnabled() const
|
bool ClangCompletionAssistInterface::objcEnabled() const
|
||||||
@@ -94,11 +85,6 @@ IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const
|
|||||||
return m_ipcCommunicator;
|
return m_ipcCommunicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const
|
|
||||||
{
|
|
||||||
return m_unsavedFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
|
||||||
|
@@ -32,8 +32,7 @@
|
|||||||
#define CLANGCODEMODEL_INTERNAL_CLANGCOMPLETIONASSISTINTERFACE_H
|
#define CLANGCODEMODEL_INTERNAL_CLANGCOMPLETIONASSISTINTERFACE_H
|
||||||
|
|
||||||
#include "clangbackendipcintegration.h"
|
#include "clangbackendipcintegration.h"
|
||||||
#include "pchinfo.h"
|
#include "clangutils.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppcompletionassistprovider.h>
|
#include <cpptools/cppcompletionassistprovider.h>
|
||||||
|
|
||||||
@@ -51,11 +50,9 @@ public:
|
|||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
TextEditor::AssistReason reason,
|
TextEditor::AssistReason reason,
|
||||||
const CppTools::ProjectPart::HeaderPaths &headerPaths,
|
const CppTools::ProjectPart::HeaderPaths &headerPaths,
|
||||||
const PchInfo::Ptr &pchInfo,
|
|
||||||
const CPlusPlus::LanguageFeatures &features);
|
const CPlusPlus::LanguageFeatures &features);
|
||||||
|
|
||||||
IpcCommunicator &ipcCommunicator() const;
|
IpcCommunicator &ipcCommunicator() const;
|
||||||
const UnsavedFiles &unsavedFiles() const;
|
|
||||||
bool objcEnabled() const;
|
bool objcEnabled() const;
|
||||||
const CppTools::ProjectPart::HeaderPaths &headerPaths() const;
|
const CppTools::ProjectPart::HeaderPaths &headerPaths() const;
|
||||||
CPlusPlus::LanguageFeatures languageFeatures() const;
|
CPlusPlus::LanguageFeatures languageFeatures() const;
|
||||||
@@ -65,10 +62,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IpcCommunicator &m_ipcCommunicator;
|
IpcCommunicator &m_ipcCommunicator;
|
||||||
UnsavedFiles m_unsavedFiles;
|
|
||||||
QStringList m_options;
|
QStringList m_options;
|
||||||
CppTools::ProjectPart::HeaderPaths m_headerPaths;
|
CppTools::ProjectPart::HeaderPaths m_headerPaths;
|
||||||
Internal::PchInfo::Ptr m_savedPchPointer;
|
|
||||||
CPlusPlus::LanguageFeatures m_languageFeatures;
|
CPlusPlus::LanguageFeatures m_languageFeatures;
|
||||||
const TextEditor::TextEditorWidget *m_textEditorWidget;
|
const TextEditor::TextEditorWidget *m_textEditorWidget;
|
||||||
};
|
};
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "clangassistproposalitem.h"
|
#include "clangassistproposalitem.h"
|
||||||
|
|
||||||
#include "activationsequenceprocessor.h"
|
#include "clangactivationsequenceprocessor.h"
|
||||||
#include "clangassistproposal.h"
|
#include "clangassistproposal.h"
|
||||||
#include "clangassistproposalmodel.h"
|
#include "clangassistproposalmodel.h"
|
||||||
#include "clangcompletionassistprocessor.h"
|
#include "clangcompletionassistprocessor.h"
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
#include "clangfunctionhintmodel.h"
|
#include "clangfunctionhintmodel.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
#include "completionchunkstotextconverter.h"
|
#include "clangcompletionchunkstotextconverter.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -342,13 +342,16 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
|||||||
case ClangCompletionContextAnalyzer::PassThroughToLibClang: {
|
case ClangCompletionContextAnalyzer::PassThroughToLibClang: {
|
||||||
m_addSnippets = m_completionOperator == T_EOF_SYMBOL;
|
m_addSnippets = m_completionOperator == T_EOF_SYMBOL;
|
||||||
m_sentRequestType = NormalCompletion;
|
m_sentRequestType = NormalCompletion;
|
||||||
sendCompletionRequest(analyzer.positionForClang(), modifiedFileContent);
|
const bool requestSent = sendCompletionRequest(analyzer.positionForClang(),
|
||||||
|
modifiedFileContent);
|
||||||
|
setPerformWasApplicable(requestSent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
|
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
|
||||||
m_sentRequestType = FunctionHintCompletion;
|
m_sentRequestType = FunctionHintCompletion;
|
||||||
m_functionName = analyzer.functionName();
|
m_functionName = analyzer.functionName();
|
||||||
sendCompletionRequest(analyzer.positionForClang(), QByteArray());
|
const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray());
|
||||||
|
setPerformWasApplicable(requestSent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -702,15 +705,34 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLastCompletionPositionAndDocumentRevision(const QString &filePath,
|
bool shouldSendCodeCompletion(const QString &filePath,
|
||||||
int completionPosition)
|
int completionPosition)
|
||||||
{
|
{
|
||||||
auto *document = cppDocument(filePath);
|
auto *document = cppDocument(filePath);
|
||||||
|
|
||||||
if (document) {
|
if (document) {
|
||||||
document->sendTracker().setLastCompletionPosition(completionPosition);
|
auto &sendTracker = document->sendTracker();
|
||||||
document->sendTracker().setLastSentRevision(document->revision());
|
return sendTracker.shouldSendCompletion(completionPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastDocumentRevision(const QString &filePath)
|
||||||
|
{
|
||||||
|
auto *document = cppDocument(filePath);
|
||||||
|
|
||||||
|
if (document)
|
||||||
|
document->sendTracker().setLastSentRevision(int(document->revision()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastCompletionPosition(const QString &filePath,
|
||||||
|
int completionPosition)
|
||||||
|
{
|
||||||
|
auto *document = cppDocument(filePath);
|
||||||
|
|
||||||
|
if (document)
|
||||||
|
document->sendTracker().setLastCompletionPosition(completionPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString projectPartIdForEditorDocument(const QString &filePath)
|
QString projectPartIdForEditorDocument(const QString &filePath)
|
||||||
@@ -726,7 +748,7 @@ QString projectPartIdForEditorDocument(const QString &filePath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
|
bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
|
||||||
const QByteArray &customFileContent)
|
const QByteArray &customFileContent)
|
||||||
{
|
{
|
||||||
int line, column;
|
int line, column;
|
||||||
@@ -735,17 +757,22 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
|
|||||||
|
|
||||||
const QString filePath = m_interface->fileName();
|
const QString filePath = m_interface->fileName();
|
||||||
|
|
||||||
|
auto &ipcCommunicator = m_interface->ipcCommunicator();
|
||||||
|
|
||||||
|
if (shouldSendCodeCompletion(filePath, position)
|
||||||
|
|| ipcCommunicator.isNotWaitingForCompletion()) {
|
||||||
if (shouldSendDocumentForCompletion(filePath, position)) {
|
if (shouldSendDocumentForCompletion(filePath, position)) {
|
||||||
sendFileContent(customFileContent);
|
sendFileContent(customFileContent);
|
||||||
setLastCompletionPositionAndDocumentRevision(filePath, position);
|
setLastDocumentRevision(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
||||||
m_interface->ipcCommunicator().completeCode(this,
|
ipcCommunicator.completeCode(this, filePath, uint(line), uint(column), projectPartId);
|
||||||
filePath,
|
setLastCompletionPosition(filePath, position);
|
||||||
uint(line),
|
return true;
|
||||||
uint(column),
|
}
|
||||||
projectPartId);
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const
|
TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const
|
||||||
|
@@ -84,7 +84,7 @@ private:
|
|||||||
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
|
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
|
||||||
|
|
||||||
void sendFileContent(const QByteArray &customFileContent);
|
void sendFileContent(const QByteArray &customFileContent);
|
||||||
void sendCompletionRequest(int position, const QByteArray &customFileContent);
|
bool sendCompletionRequest(int position, const QByteArray &customFileContent);
|
||||||
|
|
||||||
void handleAvailableCompletions(const CodeCompletions &completions);
|
void handleAvailableCompletions(const CodeCompletions &completions);
|
||||||
bool handleAvailableFunctionHintCompletions(const CodeCompletions &completions);
|
bool handleAvailableFunctionHintCompletions(const CodeCompletions &completions);
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#include "clangcompletionassistprocessor.h"
|
#include "clangcompletionassistprocessor.h"
|
||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
#include "pchmanager.h"
|
|
||||||
|
|
||||||
#include <cplusplus/Token.h>
|
#include <cplusplus/Token.h>
|
||||||
#include <cpptools/cppcompletionassistprocessor.h>
|
#include <cpptools/cppcompletionassistprocessor.h>
|
||||||
@@ -73,14 +72,12 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
|
|||||||
{
|
{
|
||||||
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath);
|
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath);
|
||||||
if (projectPart) {
|
if (projectPart) {
|
||||||
const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart);
|
|
||||||
return new ClangCompletionAssistInterface(m_ipcCommunicator,
|
return new ClangCompletionAssistInterface(m_ipcCommunicator,
|
||||||
textEditorWidget,
|
textEditorWidget,
|
||||||
position,
|
position,
|
||||||
filePath,
|
filePath,
|
||||||
reason,
|
reason,
|
||||||
projectPart->headerPaths,
|
projectPart->headerPaths,
|
||||||
pchInfo,
|
|
||||||
projectPart->languageFeatures);
|
projectPart->languageFeatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "completionchunkstotextconverter.h"
|
#include "clangcompletionchunkstotextconverter.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
@@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
#include "clangcompletioncontextanalyzer.h"
|
#include "clangcompletioncontextanalyzer.h"
|
||||||
|
|
||||||
#include "activationsequenceprocessor.h"
|
#include "clangactivationsequencecontextprocessor.h"
|
||||||
#include "activationsequencecontextprocessor.h"
|
#include "clangactivationsequenceprocessor.h"
|
||||||
|
|
||||||
#include <texteditor/codeassist/assistinterface.h>
|
#include <texteditor/codeassist/assistinterface.h>
|
||||||
|
|
||||||
|
@@ -28,23 +28,17 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef FASTINDEXER_H
|
#ifndef CLANGCONSTANTS_H
|
||||||
#define FASTINDEXER_H
|
#define CLANGCONSTANTS_H
|
||||||
|
|
||||||
#include "unit.h"
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Constants {
|
||||||
|
|
||||||
class FastIndexer
|
const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeModel.ClangCodeModel";
|
||||||
{
|
const char CLANG_ERROR[] = "Clang.Error";
|
||||||
public:
|
const char CLANG_WARNING[] = "Clang.Warning";
|
||||||
virtual ~FastIndexer() = 0;
|
|
||||||
|
|
||||||
virtual void indexNow(Unit::Ptr unit) = 0;
|
} // namespace Constants
|
||||||
};
|
} // namespace ClangCodeModel
|
||||||
|
|
||||||
} // Internal namespace
|
#endif // CLANGCONSTANTS_H
|
||||||
} // ClangCodeModel namespace
|
|
||||||
|
|
||||||
#endif // FASTINDEXER_H
|
|
@@ -31,7 +31,9 @@
|
|||||||
#include "clangdiagnosticfilter.h"
|
#include "clangdiagnosticfilter.h"
|
||||||
#include "clangdiagnosticmanager.h"
|
#include "clangdiagnosticmanager.h"
|
||||||
|
|
||||||
|
#include <texteditor/fontsettings.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -53,7 +55,7 @@ QTextEdit::ExtraSelection createExtraSelections(const QTextCharFormat &mainforma
|
|||||||
|
|
||||||
void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||||
QTextDocument *textDocument,
|
QTextDocument *textDocument,
|
||||||
const QTextCharFormat &rangeFormat,
|
const QTextCharFormat &contextFormat,
|
||||||
const QString &diagnosticText,
|
const QString &diagnosticText,
|
||||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||||
{
|
{
|
||||||
@@ -62,7 +64,7 @@ void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
|||||||
cursor.setPosition(int(range.start().offset()));
|
cursor.setPosition(int(range.start().offset()));
|
||||||
cursor.setPosition(int(range.end().offset()), QTextCursor::KeepAnchor);
|
cursor.setPosition(int(range.end().offset()), QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
auto extraSelection = createExtraSelections(rangeFormat, cursor, diagnosticText);
|
auto extraSelection = createExtraSelections(contextFormat, cursor, diagnosticText);
|
||||||
|
|
||||||
extraSelections.push_back(std::move(extraSelection));
|
extraSelections.push_back(std::move(extraSelection));
|
||||||
}
|
}
|
||||||
@@ -116,7 +118,7 @@ QString diagnosticText(const ClangBackEnd::DiagnosticContainer &diagnostic)
|
|||||||
void addSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void addSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
QTextDocument *textDocument,
|
QTextDocument *textDocument,
|
||||||
const QTextCharFormat &mainFormat,
|
const QTextCharFormat &mainFormat,
|
||||||
const QTextCharFormat &rangeFormat,
|
const QTextCharFormat &contextFormat,
|
||||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||||
{
|
{
|
||||||
for (auto &&diagnostic : diagnostics) {
|
for (auto &&diagnostic : diagnostics) {
|
||||||
@@ -125,7 +127,7 @@ void addSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics
|
|||||||
auto text = diagnosticText(diagnostic);
|
auto text = diagnosticText(diagnostic);
|
||||||
auto extraSelection = createExtraSelections(mainFormat, cursor, text);
|
auto extraSelection = createExtraSelections(mainFormat, cursor, text);
|
||||||
|
|
||||||
addRangeSelections(diagnostic, textDocument, rangeFormat, text, extraSelections);
|
addRangeSelections(diagnostic, textDocument, contextFormat, text, extraSelections);
|
||||||
|
|
||||||
extraSelections.push_back(std::move(extraSelection));
|
extraSelections.push_back(std::move(extraSelection));
|
||||||
}
|
}
|
||||||
@@ -135,30 +137,25 @@ void addWarningSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diag
|
|||||||
QTextDocument *textDocument,
|
QTextDocument *textDocument,
|
||||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||||
{
|
{
|
||||||
QTextCharFormat warningFormat;
|
const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings();
|
||||||
warningFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
|
||||||
warningFormat.setUnderlineColor(QColor(180, 180, 0, 255));
|
|
||||||
|
|
||||||
QTextCharFormat warningRangeFormat;
|
QTextCharFormat warningFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING);
|
||||||
warningRangeFormat.setUnderlineStyle(QTextCharFormat::DotLine);
|
|
||||||
warningRangeFormat.setUnderlineColor(QColor(180, 180, 0, 255));
|
|
||||||
|
|
||||||
addSelections(diagnostics, textDocument, warningFormat, warningRangeFormat, extraSelections);
|
QTextCharFormat warningContextFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING_CONTEXT);
|
||||||
|
|
||||||
|
addSelections(diagnostics, textDocument, warningFormat, warningContextFormat, extraSelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addErrorSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void addErrorSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
QTextDocument *textDocument,
|
QTextDocument *textDocument,
|
||||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||||
{
|
{
|
||||||
QTextCharFormat errorFormat;
|
const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings();
|
||||||
errorFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
|
||||||
errorFormat.setUnderlineColor(QColor(255, 0, 0, 255));
|
|
||||||
|
|
||||||
QTextCharFormat errorRangeFormat;
|
QTextCharFormat errorFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR);
|
||||||
errorRangeFormat.setUnderlineStyle(QTextCharFormat::DotLine);
|
QTextCharFormat errorContextFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR_CONTEXT);
|
||||||
errorRangeFormat.setUnderlineColor(QColor(255, 0, 0, 255));
|
|
||||||
|
|
||||||
addSelections(diagnostics, textDocument, errorFormat, errorRangeFormat, extraSelections);
|
addSelections(diagnostics, textDocument, errorFormat, errorContextFormat, extraSelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous
|
} // anonymous
|
||||||
|
@@ -29,111 +29,22 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "clangeditordocumentparser.h"
|
#include "clangeditordocumentparser.h"
|
||||||
#include "clangutils.h"
|
|
||||||
#include "pchinfo.h"
|
|
||||||
#include "pchmanager.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
#include <cpptools/cppprojects.h>
|
|
||||||
#include <cpptools/cppworkingcopy.h>
|
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.clangeditordocumentparser")
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
QStringList createOptions(const QString &filePath,
|
|
||||||
const CppTools::ProjectPart::Ptr &part,
|
|
||||||
bool includeSpellCheck = false)
|
|
||||||
{
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
|
|
||||||
QStringList options;
|
|
||||||
if (part.isNull())
|
|
||||||
return options;
|
|
||||||
|
|
||||||
if (includeSpellCheck)
|
|
||||||
options += QLatin1String("-fspell-checking");
|
|
||||||
|
|
||||||
options += ClangCodeModel::Utils::createClangOptions(part, filePath);
|
|
||||||
|
|
||||||
if (Internal::PchInfo::Ptr pchInfo = Internal::PchManager::instance()->pchInfo(part))
|
|
||||||
options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString messageLine(const QStringList &options, const QString &fileName)
|
|
||||||
{
|
|
||||||
const QStringList allOptions = QStringList(options)
|
|
||||||
<< QLatin1String("-fsyntax-only") << fileName;
|
|
||||||
QStringList allOptionsQuoted;
|
|
||||||
foreach (const QString &option, allOptions)
|
|
||||||
allOptionsQuoted.append(QLatin1Char('\'') + option + QLatin1Char('\''));
|
|
||||||
return ::Utils::HostOsInfo::withExecutableSuffix(QLatin1String("clang"))
|
|
||||||
+ QLatin1Char(' ') + allOptionsQuoted.join(QLatin1Char(' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
|
ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
|
||||||
: BaseEditorDocumentParser(filePath)
|
: BaseEditorDocumentParser(filePath)
|
||||||
, m_marker(new ClangCodeModel::SemanticMarker)
|
|
||||||
{
|
{
|
||||||
BaseEditorDocumentParser::Configuration config = configuration();
|
BaseEditorDocumentParser::Configuration config = configuration();
|
||||||
config.stickToPreviousProjectPart = false;
|
config.stickToPreviousProjectPart = false;
|
||||||
setConfiguration(config);
|
setConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info)
|
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_marker, return);
|
|
||||||
|
|
||||||
// Determine project part
|
|
||||||
State state_ = state();
|
State state_ = state();
|
||||||
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
|
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
|
||||||
setState(state_);
|
setState(state_);
|
||||||
emit projectPartDetermined(state_.projectPart);
|
|
||||||
|
|
||||||
// Determine message line arguments
|
|
||||||
const QStringList options = createOptions(filePath(), state_.projectPart, true);
|
|
||||||
qCDebug(log, "Reparse options (cmd line equivalent): %s",
|
|
||||||
messageLine(options, filePath()).toUtf8().constData());
|
|
||||||
|
|
||||||
// Run
|
|
||||||
QTime t; t.start();
|
|
||||||
QMutexLocker lock(m_marker->mutex());
|
|
||||||
m_marker->setFileName(filePath());
|
|
||||||
m_marker->setCompilationOptions(options);
|
|
||||||
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(info.workingCopy,
|
|
||||||
info.modifiedFiles);
|
|
||||||
m_marker->reparse(unsavedFiles);
|
|
||||||
qCDebug(log) << "Reparse took" << t.elapsed() << "ms.";
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Diagnostic> ClangEditorDocumentParser::diagnostics() const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_marker, return QList<Diagnostic>());
|
|
||||||
QMutexLocker(m_marker->mutex());
|
|
||||||
return m_marker->diagnostics();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<SemanticMarker::Range> ClangEditorDocumentParser::ifdefedOutBlocks() const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_marker, return QList<SemanticMarker::Range>());
|
|
||||||
QMutexLocker(m_marker->mutex());
|
|
||||||
return m_marker->ifdefedOutBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
SemanticMarker::Ptr ClangEditorDocumentParser::semanticMarker() const
|
|
||||||
{
|
|
||||||
return m_marker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
@@ -31,12 +31,8 @@
|
|||||||
#ifndef CLANGEDITORDOCUMENTPARSER_H
|
#ifndef CLANGEDITORDOCUMENTPARSER_H
|
||||||
#define CLANGEDITORDOCUMENTPARSER_H
|
#define CLANGEDITORDOCUMENTPARSER_H
|
||||||
|
|
||||||
#include "semanticmarker.h"
|
|
||||||
|
|
||||||
#include <cpptools/baseeditordocumentparser.h>
|
#include <cpptools/baseeditordocumentparser.h>
|
||||||
|
|
||||||
namespace CppTools { class WorkingCopy; }
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
|
class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
|
||||||
@@ -46,17 +42,8 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
|
|||||||
public:
|
public:
|
||||||
ClangEditorDocumentParser(const QString &filePath);
|
ClangEditorDocumentParser(const QString &filePath);
|
||||||
|
|
||||||
QList<Diagnostic> diagnostics() const;
|
|
||||||
QList<SemanticMarker::Range> ifdefedOutBlocks() const;
|
|
||||||
SemanticMarker::Ptr semanticMarker() const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void projectPartDetermined(CppTools::ProjectPart::Ptr projectPart);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) override;
|
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &) override;
|
||||||
|
|
||||||
SemanticMarker::Ptr m_marker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
@@ -32,11 +32,9 @@
|
|||||||
|
|
||||||
#include "clangfixitoperation.h"
|
#include "clangfixitoperation.h"
|
||||||
#include "clangfixitoperationsextractor.h"
|
#include "clangfixitoperationsextractor.h"
|
||||||
|
#include "clanghighlightingmarksreporter.h"
|
||||||
#include "clangmodelmanagersupport.h"
|
#include "clangmodelmanagersupport.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
#include "cppcreatemarkers.h"
|
|
||||||
#include "diagnostic.h"
|
|
||||||
#include "pchinfo.h"
|
|
||||||
|
|
||||||
#include <diagnosticcontainer.h>
|
#include <diagnosticcontainer.h>
|
||||||
#include <sourcelocationcontainer.h>
|
#include <sourcelocationcontainer.h>
|
||||||
@@ -59,22 +57,6 @@
|
|||||||
|
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef CPlusPlus::Document::DiagnosticMessage CppToolsDiagnostic;
|
|
||||||
|
|
||||||
QList<TextEditor::BlockRange> toTextEditorBlocks(
|
|
||||||
const QList<ClangCodeModel::SemanticMarker::Range> &ranges)
|
|
||||||
{
|
|
||||||
QList<TextEditor::BlockRange> result;
|
|
||||||
result.reserve(ranges.size());
|
|
||||||
foreach (const ClangCodeModel::SemanticMarker::Range &range, ranges)
|
|
||||||
result.append(TextEditor::BlockRange(range.first, range.last));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -89,26 +71,12 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
|||||||
, m_semanticHighlighter(document)
|
, m_semanticHighlighter(document)
|
||||||
, m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
|
, m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
|
||||||
{
|
{
|
||||||
connect(m_parser.data(), &ClangEditorDocumentParser::projectPartDetermined,
|
|
||||||
this, &ClangEditorDocumentProcessor::onParserDeterminedProjectPart);
|
|
||||||
|
|
||||||
// Forwarding the semantic info from the builtin processor enables us to provide all
|
// Forwarding the semantic info from the builtin processor enables us to provide all
|
||||||
// editor (widget) related features that are not yet implemented by the clang plugin.
|
// editor (widget) related features that are not yet implemented by the clang plugin.
|
||||||
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::cppDocumentUpdated,
|
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::cppDocumentUpdated,
|
||||||
this, &ClangEditorDocumentProcessor::cppDocumentUpdated);
|
this, &ClangEditorDocumentProcessor::cppDocumentUpdated);
|
||||||
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
|
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
|
||||||
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
|
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
|
||||||
|
|
||||||
m_semanticHighlighter.setHighlightingRunner(
|
|
||||||
[this]() -> QFuture<TextEditor::HighlightingResult> {
|
|
||||||
const int firstLine = 1;
|
|
||||||
const int lastLine = baseTextDocument()->document()->blockCount();
|
|
||||||
|
|
||||||
CreateMarkers *createMarkers = CreateMarkers::create(m_parser->semanticMarker(),
|
|
||||||
baseTextDocument()->filePath().toString(),
|
|
||||||
firstLine, lastLine);
|
|
||||||
return createMarkers->start();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
|
ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
|
||||||
@@ -125,7 +93,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
|
|||||||
|
|
||||||
void ClangEditorDocumentProcessor::run()
|
void ClangEditorDocumentProcessor::run()
|
||||||
{
|
{
|
||||||
requestDiagnostics();
|
updateTranslationUnitIfProjectPartExists();
|
||||||
|
|
||||||
// Run clang parser
|
// Run clang parser
|
||||||
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
||||||
@@ -153,7 +121,9 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force)
|
|||||||
void ClangEditorDocumentProcessor::semanticRehighlight()
|
void ClangEditorDocumentProcessor::semanticRehighlight()
|
||||||
{
|
{
|
||||||
m_semanticHighlighter.updateFormatMapFromFontSettings();
|
m_semanticHighlighter.updateFormatMapFromFontSettings();
|
||||||
m_semanticHighlighter.run();
|
|
||||||
|
if (m_projectPart)
|
||||||
|
requestDocumentAnnotations(m_projectPart->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
|
CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
|
||||||
@@ -201,6 +171,36 @@ void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector<ClangBackEnd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QList<TextEditor::BlockRange>
|
||||||
|
toTextEditorBlocks(const QVector<ClangBackEnd::SourceRangeContainer> &ifdefedOutRanges)
|
||||||
|
{
|
||||||
|
QList<TextEditor::BlockRange> blockRanges;
|
||||||
|
blockRanges.reserve(ifdefedOutRanges.size());
|
||||||
|
|
||||||
|
for (const auto &range : ifdefedOutRanges)
|
||||||
|
blockRanges.append(TextEditor::BlockRange(range.start().offset(),range.end().offset()));
|
||||||
|
|
||||||
|
return blockRanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangEditorDocumentProcessor::updateHighlighting(
|
||||||
|
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
|
||||||
|
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||||
|
uint documentRevision)
|
||||||
|
{
|
||||||
|
if (documentRevision == revision()) {
|
||||||
|
const auto skippedPreprocessorBlocks = toTextEditorBlocks(skippedPreprocessorRanges);
|
||||||
|
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
|
||||||
|
|
||||||
|
m_semanticHighlighter.setHighlightingRunner(
|
||||||
|
[highlightingMarks]() {
|
||||||
|
auto *reporter = new HighlightingMarksReporter(highlightingMarks);
|
||||||
|
return reporter->start();
|
||||||
|
});
|
||||||
|
m_semanticHighlighter.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int currentLine(const TextEditor::AssistInterface &assistInterface)
|
static int currentLine(const TextEditor::AssistInterface &assistInterface)
|
||||||
{
|
{
|
||||||
int line, column;
|
int line, column;
|
||||||
@@ -219,9 +219,9 @@ TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOpe
|
|||||||
return extractor.extract(assistInterface.fileName(), currentLine(assistInterface));
|
return extractor.extract(assistInterface.fileName(), currentLine(assistInterface));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainer() const
|
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const
|
||||||
{
|
{
|
||||||
return fileContainer(m_projectPart.data());
|
return fileContainerWithArguments(m_projectPart.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::clearDiagnosticsWithFixIts()
|
void ClangEditorDocumentProcessor::clearDiagnosticsWithFixIts()
|
||||||
@@ -240,75 +240,58 @@ static bool isProjectPartLoadedOrIsFallback(CppTools::ProjectPart::Ptr projectPa
|
|||||||
&& (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartLoaded(projectPart));
|
&& (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartLoaded(projectPart));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor(
|
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor()
|
||||||
CppTools::ProjectPart::Ptr projectPart)
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(projectPart, return);
|
const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPart();
|
||||||
|
|
||||||
if (isProjectPartLoadedOrIsFallback(projectPart)) {
|
if (isProjectPartLoadedOrIsFallback(projectPart)) {
|
||||||
updateTranslationUnitForEditor(projectPart.data());
|
registerTranslationUnitForEditor(projectPart.data());
|
||||||
requestDiagnostics(projectPart.data());
|
|
||||||
|
|
||||||
m_projectPart = projectPart;
|
m_projectPart = projectPart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::onParserDeterminedProjectPart(
|
|
||||||
CppTools::ProjectPart::Ptr projectPart)
|
|
||||||
{
|
|
||||||
updateProjectPartAndTranslationUnitForEditor(projectPart);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::onParserFinished()
|
void ClangEditorDocumentProcessor::onParserFinished()
|
||||||
{
|
{
|
||||||
if (revision() != m_parserRevision)
|
if (revision() != m_parserRevision)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Emit ifdefed out blocks
|
updateProjectPartAndTranslationUnitForEditor();
|
||||||
const auto ifdefoutBlocks = toTextEditorBlocks(m_parser->ifdefedOutBlocks());
|
|
||||||
emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks);
|
|
||||||
|
|
||||||
// Run semantic highlighter
|
|
||||||
m_semanticHighlighter.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart)
|
void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_modelManagerSupport, return);
|
QTC_ASSERT(m_modelManagerSupport, return);
|
||||||
IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
|
IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
|
||||||
|
|
||||||
if (m_projectPart) {
|
if (m_projectPart) {
|
||||||
if (projectPart->id() != m_projectPart->id()) {
|
if (projectPart->id() != m_projectPart->id()) {
|
||||||
ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainer()});
|
ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()});
|
||||||
ipcCommunicator.registerTranslationUnitsForEditor({fileContainer(projectPart)});
|
ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ipcCommunicator.registerTranslationUnitsForEditor({{fileContainer(projectPart)}});
|
ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::requestDiagnostics(CppTools::ProjectPart *projectPart)
|
void ClangEditorDocumentProcessor::updateTranslationUnitIfProjectPartExists()
|
||||||
{
|
{
|
||||||
if (!m_projectPart || projectPart->id() != m_projectPart->id()) {
|
|
||||||
IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
|
|
||||||
|
|
||||||
ipcCommunicator.requestDiagnostics({fileContainer(projectPart)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::requestDiagnostics()
|
|
||||||
{
|
|
||||||
// Get diagnostics
|
|
||||||
if (m_projectPart) {
|
if (m_projectPart) {
|
||||||
auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
|
const ClangBackEnd::FileContainer fileContainer = fileContainerWithDocumentContent(m_projectPart->id());
|
||||||
ipcCommunicator.requestDiagnostics({filePath(),
|
|
||||||
m_projectPart->id(),
|
m_modelManagerSupport->ipcCommunicator().updateTranslationUnitWithRevisionCheck(fileContainer);
|
||||||
baseTextDocument()->plainText(),
|
|
||||||
true,
|
|
||||||
revision()});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangEditorDocumentProcessor::requestDocumentAnnotations(const QString &projectpartId)
|
||||||
|
{
|
||||||
|
const auto fileContainer = fileContainerWithDocumentContent(projectpartId);
|
||||||
|
|
||||||
|
auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
|
||||||
|
ipcCommunicator.requestDiagnostics(fileContainer);
|
||||||
|
ipcCommunicator.requestHighlighting(fileContainer);
|
||||||
|
}
|
||||||
|
|
||||||
static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart)
|
static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart)
|
||||||
{
|
{
|
||||||
if (projectPart)
|
if (projectPart)
|
||||||
@@ -332,7 +315,7 @@ static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClangBackEnd::FileContainer
|
ClangBackEnd::FileContainer
|
||||||
ClangEditorDocumentProcessor::fileContainer(CppTools::ProjectPart *projectPart) const
|
ClangEditorDocumentProcessor::fileContainerWithArguments(CppTools::ProjectPart *projectPart) const
|
||||||
{
|
{
|
||||||
const auto projectPartId = projectPart
|
const auto projectPartId = projectPart
|
||||||
? Utf8String::fromString(projectPart->id())
|
? Utf8String::fromString(projectPart->id())
|
||||||
@@ -342,5 +325,15 @@ ClangEditorDocumentProcessor::fileContainer(CppTools::ProjectPart *projectPart)
|
|||||||
return {filePath(), projectPartId, Utf8StringVector(theFileArguments), revision()};
|
return {filePath(), projectPartId, Utf8StringVector(theFileArguments), revision()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClangBackEnd::FileContainer
|
||||||
|
ClangEditorDocumentProcessor::fileContainerWithDocumentContent(const QString &projectpartId) const
|
||||||
|
{
|
||||||
|
return ClangBackEnd::FileContainer(filePath(),
|
||||||
|
projectpartId,
|
||||||
|
baseTextDocument()->plainText(),
|
||||||
|
true,
|
||||||
|
revision());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
class DiagnosticContainer;
|
class DiagnosticContainer;
|
||||||
|
class HighlightingMarkContainer;
|
||||||
class FileContainer;
|
class FileContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,11 +76,14 @@ public:
|
|||||||
|
|
||||||
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
uint documentRevision);
|
uint documentRevision);
|
||||||
|
void updateHighlighting(const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
|
||||||
|
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||||
|
uint documentRevision);
|
||||||
|
|
||||||
TextEditor::QuickFixOperations
|
TextEditor::QuickFixOperations
|
||||||
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
|
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
|
||||||
|
|
||||||
ClangBackEnd::FileContainer fileContainer() const;
|
ClangBackEnd::FileContainer fileContainerWithArguments() const;
|
||||||
|
|
||||||
void clearDiagnosticsWithFixIts();
|
void clearDiagnosticsWithFixIts();
|
||||||
|
|
||||||
@@ -87,15 +91,15 @@ public:
|
|||||||
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onParserDeterminedProjectPart(CppTools::ProjectPart::Ptr projectPart);
|
|
||||||
void onParserFinished();
|
void onParserFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateProjectPartAndTranslationUnitForEditor(CppTools::ProjectPart::Ptr projectPart);
|
void updateProjectPartAndTranslationUnitForEditor();
|
||||||
void updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart);
|
void registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart);
|
||||||
void requestDiagnostics(CppTools::ProjectPart *projectPart);
|
void updateTranslationUnitIfProjectPartExists();
|
||||||
void requestDiagnostics();
|
void requestDocumentAnnotations(const QString &projectpartId);
|
||||||
ClangBackEnd::FileContainer fileContainer(CppTools::ProjectPart *projectPart) const;
|
ClangBackEnd::FileContainer fileContainerWithArguments(CppTools::ProjectPart *projectPart) const;
|
||||||
|
ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClangDiagnosticManager m_diagnosticManager;
|
ClangDiagnosticManager m_diagnosticManager;
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "clangfunctionhintmodel.h"
|
#include "clangfunctionhintmodel.h"
|
||||||
|
|
||||||
#include "completionchunkstotextconverter.h"
|
#include "clangcompletionchunkstotextconverter.h"
|
||||||
|
|
||||||
#include <cplusplus/SimpleLexer.h>
|
#include <cplusplus/SimpleLexer.h>
|
||||||
|
|
||||||
|
155
src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp
Normal file
155
src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "clanghighlightingmarksreporter.h"
|
||||||
|
|
||||||
|
#include <cpptools/semantichighlighter.h>
|
||||||
|
|
||||||
|
#include <QFuture>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
CppTools::SemanticHighlighter::Kind toCppToolsSemanticHighlighterKind(
|
||||||
|
ClangBackEnd::HighlightingType type)
|
||||||
|
{
|
||||||
|
using ClangBackEnd::HighlightingType;
|
||||||
|
using CppTools::SemanticHighlighter;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case HighlightingType::Keyword:
|
||||||
|
return SemanticHighlighter::PseudoKeywordUse;
|
||||||
|
case HighlightingType::Function:
|
||||||
|
return SemanticHighlighter::FunctionUse;
|
||||||
|
case HighlightingType::VirtualFunction:
|
||||||
|
return SemanticHighlighter::VirtualMethodUse;
|
||||||
|
case HighlightingType::Type:
|
||||||
|
return SemanticHighlighter::TypeUse;
|
||||||
|
case HighlightingType::LocalVariable:
|
||||||
|
return SemanticHighlighter::LocalUse;
|
||||||
|
case HighlightingType::Field:
|
||||||
|
return SemanticHighlighter::FieldUse;
|
||||||
|
case HighlightingType::GlobalVariable:
|
||||||
|
return SemanticHighlighter::Unknown;
|
||||||
|
case HighlightingType::Enumeration:
|
||||||
|
return SemanticHighlighter::EnumerationUse;
|
||||||
|
case HighlightingType::Label:
|
||||||
|
return SemanticHighlighter::LabelUse;
|
||||||
|
case HighlightingType::Preprocessor:
|
||||||
|
return SemanticHighlighter::MacroUse;
|
||||||
|
default:
|
||||||
|
return SemanticHighlighter::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEditor::HighlightingResult toHighlightingResult(
|
||||||
|
const ClangBackEnd::HighlightingMarkContainer &highlightingMark)
|
||||||
|
{
|
||||||
|
const auto highlighterKind = toCppToolsSemanticHighlighterKind(highlightingMark.type());
|
||||||
|
|
||||||
|
return TextEditor::HighlightingResult(highlightingMark.line(),
|
||||||
|
highlightingMark.column(),
|
||||||
|
highlightingMark.length(),
|
||||||
|
highlighterKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous
|
||||||
|
|
||||||
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
|
HighlightingMarksReporter::HighlightingMarksReporter(
|
||||||
|
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks)
|
||||||
|
: m_highlightingMarks(highlightingMarks)
|
||||||
|
{
|
||||||
|
m_chunksToReport.reserve(m_chunkSize + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighlightingMarksReporter::reportChunkWise(
|
||||||
|
const TextEditor::HighlightingResult &highlightingResult)
|
||||||
|
{
|
||||||
|
if (m_chunksToReport.size() >= m_chunkSize) {
|
||||||
|
if (m_flushRequested && highlightingResult.line != m_flushLine) {
|
||||||
|
reportAndClearCurrentChunks();
|
||||||
|
} else if (!m_flushRequested) {
|
||||||
|
m_flushRequested = true;
|
||||||
|
m_flushLine = highlightingResult.line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_chunksToReport.append(highlightingResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighlightingMarksReporter::reportAndClearCurrentChunks()
|
||||||
|
{
|
||||||
|
m_flushRequested = false;
|
||||||
|
m_flushLine = 0;
|
||||||
|
|
||||||
|
if (!m_chunksToReport.isEmpty()) {
|
||||||
|
reportResults(m_chunksToReport);
|
||||||
|
m_chunksToReport.erase(m_chunksToReport.begin(), m_chunksToReport.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighlightingMarksReporter::setChunkSize(int chunkSize)
|
||||||
|
{
|
||||||
|
m_chunkSize = chunkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighlightingMarksReporter::run()
|
||||||
|
{
|
||||||
|
run_internal();
|
||||||
|
reportFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighlightingMarksReporter::run_internal()
|
||||||
|
{
|
||||||
|
if (isCanceled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const auto &highlightingMark : m_highlightingMarks)
|
||||||
|
reportChunkWise(toHighlightingResult(highlightingMark));
|
||||||
|
|
||||||
|
if (isCanceled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
reportAndClearCurrentChunks();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFuture<TextEditor::HighlightingResult> HighlightingMarksReporter::start()
|
||||||
|
{
|
||||||
|
this->setRunnable(this);
|
||||||
|
this->reportStarted();
|
||||||
|
QFuture<TextEditor::HighlightingResult> future = this->future();
|
||||||
|
QThreadPool::globalInstance()->start(this, QThread::LowestPriority);
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangCodeModel
|
@@ -28,56 +28,51 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef CLANG_DIAGNOSTIC_H
|
#ifndef CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H
|
||||||
#define CLANG_DIAGNOSTIC_H
|
#define CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H
|
||||||
|
|
||||||
#include "clang_global.h"
|
#include <QFutureInterface>
|
||||||
#include "sourcelocation.h"
|
#include <QObject>
|
||||||
|
#include <QRunnable>
|
||||||
|
#include <QThreadPool>
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <texteditor/semantichighlighter.h>
|
||||||
|
|
||||||
|
#include <clangbackendipc/highlightingmarkcontainer.h>
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
class CLANG_EXPORT Diagnostic
|
class HighlightingMarksReporter:
|
||||||
|
public QObject,
|
||||||
|
public QRunnable,
|
||||||
|
public QFutureInterface<TextEditor::HighlightingResult>
|
||||||
{
|
{
|
||||||
public:
|
Q_OBJECT
|
||||||
enum Severity {
|
|
||||||
Unknown = -1,
|
|
||||||
Ignored = 0,
|
|
||||||
Note = 1,
|
|
||||||
Warning = 2,
|
|
||||||
Error = 3,
|
|
||||||
Fatal = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Diagnostic();
|
HighlightingMarksReporter(const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks);
|
||||||
Diagnostic(Severity severity, const SourceLocation &location, unsigned length, const QString &spelling);
|
|
||||||
|
|
||||||
Severity severity() const
|
void setChunkSize(int chunkSize);
|
||||||
{ return m_severity; }
|
|
||||||
|
|
||||||
const QString severityAsString() const;
|
QFuture<TextEditor::HighlightingResult> start();
|
||||||
|
|
||||||
const SourceLocation &location() const
|
|
||||||
{ return m_loc; }
|
|
||||||
|
|
||||||
unsigned length() const
|
|
||||||
{ return m_length; }
|
|
||||||
|
|
||||||
const QString &spelling() const
|
|
||||||
{ return m_spelling; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Severity m_severity;
|
void run() override;
|
||||||
SourceLocation m_loc;
|
void run_internal();
|
||||||
unsigned m_length;
|
|
||||||
QString m_spelling;
|
void reportChunkWise(const TextEditor::HighlightingResult &highlightingResult);
|
||||||
|
void reportAndClearCurrentChunks();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<ClangBackEnd::HighlightingMarkContainer> m_highlightingMarks;
|
||||||
|
QVector<TextEditor::HighlightingResult> m_chunksToReport;
|
||||||
|
|
||||||
|
int m_chunkSize = 100;
|
||||||
|
|
||||||
|
bool m_flushRequested = false;
|
||||||
|
unsigned m_flushLine = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
} // namespace ClangCodeModel
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ClangCodeModel::Diagnostic)
|
#endif // CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H
|
||||||
Q_DECLARE_METATYPE(QList<ClangCodeModel::Diagnostic>)
|
|
||||||
|
|
||||||
#endif // CLANG_DIAGNOSTIC_H
|
|
@@ -1,172 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "clangindexer.h"
|
|
||||||
#include "clangutils.h"
|
|
||||||
#include "indexer.h"
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
#include <projectexplorer/session.h>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
|
|
||||||
ClangIndexingSupport::ClangIndexingSupport(ClangIndexer *indexer)
|
|
||||||
: m_indexer(indexer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ClangIndexingSupport::~ClangIndexingSupport()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<void> ClangIndexingSupport::refreshSourceFiles(
|
|
||||||
const QSet<QString> &sourceFiles,
|
|
||||||
CppTools::CppModelManager::ProgressNotificationMode mode)
|
|
||||||
{
|
|
||||||
Q_UNUSED(mode);
|
|
||||||
|
|
||||||
return m_indexer->refreshSourceFiles(sourceFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
CppTools::SymbolSearcher *ClangIndexingSupport::createSymbolSearcher(CppTools::SymbolSearcher::Parameters parameters, QSet<QString> fileNames)
|
|
||||||
{
|
|
||||||
Q_UNUSED(parameters);
|
|
||||||
Q_UNUSED(fileNames)
|
|
||||||
// return new ClangSymbolSearcher(m_indexer, parameters, fileNames);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClangIndexer::ClangIndexer()
|
|
||||||
: QObject(0)
|
|
||||||
, m_indexingSupport(new ClangIndexingSupport(this))
|
|
||||||
, m_isLoadingSession(false)
|
|
||||||
, m_clangIndexer(new Indexer(this))
|
|
||||||
{
|
|
||||||
connect(m_clangIndexer, SIGNAL(indexingStarted(QFuture<void>,Internal::ProgressNotificationMode)),
|
|
||||||
this, SLOT(onIndexingStarted(QFuture<void>,Internal::ProgressNotificationMode)));
|
|
||||||
|
|
||||||
QObject *session = ProjectExplorer::SessionManager::instance();
|
|
||||||
|
|
||||||
connect(session, SIGNAL(aboutToLoadSession(QString)),
|
|
||||||
this, SLOT(onAboutToLoadSession(QString)));
|
|
||||||
connect(session, SIGNAL(sessionLoaded(QString)),
|
|
||||||
this, SLOT(onSessionLoaded(QString)));
|
|
||||||
connect(session, SIGNAL(aboutToSaveSession()),
|
|
||||||
this, SLOT(onAboutToSaveSession()));
|
|
||||||
}
|
|
||||||
|
|
||||||
ClangIndexer::~ClangIndexer()
|
|
||||||
{
|
|
||||||
m_clangIndexer->cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
CppTools::CppIndexingSupport *ClangIndexer::indexingSupport()
|
|
||||||
{
|
|
||||||
return m_indexingSupport.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<void> ClangIndexer::refreshSourceFiles(const QSet<QString> &sourceFiles)
|
|
||||||
{
|
|
||||||
typedef CppTools::ProjectPart ProjectPart;
|
|
||||||
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
|
||||||
|
|
||||||
if (m_clangIndexer->isBusy())
|
|
||||||
m_clangIndexer->cancel(true);
|
|
||||||
|
|
||||||
foreach (const QString &file, sourceFiles) {
|
|
||||||
if (m_clangIndexer->isTracking(file))
|
|
||||||
continue; // we get notified separately about open files.
|
|
||||||
const QList<ProjectPart::Ptr> &parts = modelManager->projectPart(file);
|
|
||||||
if (!parts.isEmpty())
|
|
||||||
m_clangIndexer->addFile(file, parts.at(0));
|
|
||||||
else
|
|
||||||
m_clangIndexer->addFile(file, ProjectPart::Ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_isLoadingSession)
|
|
||||||
m_clangIndexer->regenerate();
|
|
||||||
|
|
||||||
return QFuture<void>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::match(ClangSymbolSearcher *searcher) const
|
|
||||||
{
|
|
||||||
m_clangIndexer->match(searcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::onAboutToLoadSession(const QString &sessionName)
|
|
||||||
{
|
|
||||||
m_isLoadingSession = true;
|
|
||||||
|
|
||||||
if (sessionName == QLatin1String("default"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString path = Core::ICore::instance()->userResourcePath() + QLatin1String("/codemodel/");
|
|
||||||
if (QFile::exists(path) || QDir().mkpath(path))
|
|
||||||
m_clangIndexer->initialize(path + sessionName + QLatin1String(".qci"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::onSessionLoaded(QString)
|
|
||||||
{
|
|
||||||
m_isLoadingSession = false;
|
|
||||||
m_clangIndexer->regenerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::onAboutToSaveSession()
|
|
||||||
{
|
|
||||||
m_clangIndexer->finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::indexNow(Unit::Ptr unit)
|
|
||||||
{
|
|
||||||
typedef CppTools::ProjectPart ProjectPart;
|
|
||||||
|
|
||||||
QString file = unit->fileName();
|
|
||||||
CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance();
|
|
||||||
const QList<ProjectPart::Ptr> &parts = mmi->projectPart(file);
|
|
||||||
ProjectPart::Ptr part;
|
|
||||||
if (!parts.isEmpty())
|
|
||||||
part = parts.at(0);
|
|
||||||
if (!m_isLoadingSession)
|
|
||||||
m_clangIndexer->runQuickIndexing(unit, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangIndexer::onIndexingStarted(QFuture<void> indexingFuture)
|
|
||||||
{
|
|
||||||
Core::ProgressManager::addTask(indexingFuture, QCoreApplication::translate(
|
|
||||||
"ClangCodeModel::Internal::ClangIndexer",
|
|
||||||
"Parsing C/C++/ObjC Files"),
|
|
||||||
"ClangCodeMode.Task.Indexing");
|
|
||||||
}
|
|
@@ -1,99 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CLANGINDEXER_H
|
|
||||||
#define CLANGINDEXER_H
|
|
||||||
|
|
||||||
#include "fastindexer.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppindexingsupport.h>
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
class Indexer;
|
|
||||||
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
typedef CppTools::CppModelManager::ProgressNotificationMode ProgressNotificationMode;
|
|
||||||
class ClangIndexer;
|
|
||||||
class ClangSymbolSearcher;
|
|
||||||
|
|
||||||
class ClangIndexingSupport: public CppTools::CppIndexingSupport
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClangIndexingSupport(ClangIndexer *indexer);
|
|
||||||
virtual ~ClangIndexingSupport();
|
|
||||||
|
|
||||||
virtual QFuture<void> refreshSourceFiles(
|
|
||||||
const QSet<QString> &sourceFiles,
|
|
||||||
ProgressNotificationMode mode);
|
|
||||||
virtual CppTools::SymbolSearcher *createSymbolSearcher(
|
|
||||||
CppTools::SymbolSearcher::Parameters parameters, QSet<QString> fileNames);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ClangIndexer *m_indexer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClangIndexer: public QObject, public FastIndexer
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClangIndexer();
|
|
||||||
~ClangIndexer();
|
|
||||||
|
|
||||||
CppTools::CppIndexingSupport *indexingSupport();
|
|
||||||
|
|
||||||
QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles);
|
|
||||||
|
|
||||||
void match(ClangSymbolSearcher *searcher) const;
|
|
||||||
|
|
||||||
void indexNow(Unit::Ptr unit);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onAboutToLoadSession(const QString &sessionName);
|
|
||||||
void onSessionLoaded(QString);
|
|
||||||
void onAboutToSaveSession();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onIndexingStarted(QFuture<void> indexingFuture);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QScopedPointer<ClangIndexingSupport> m_indexingSupport;
|
|
||||||
bool m_isLoadingSession;
|
|
||||||
Indexer *m_clangIndexer;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
#endif // CLANGINDEXER_H
|
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "clangmodelmanagersupport.h"
|
#include "clangmodelmanagersupport.h"
|
||||||
|
|
||||||
#include "constants.h"
|
#include "clangconstants.h"
|
||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
|
|
||||||
@@ -66,9 +66,14 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
|||||||
|
|
||||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
connect(editorManager, &Core::EditorManager::currentEditorChanged,
|
connect(editorManager, &Core::EditorManager::currentEditorChanged,
|
||||||
this, &ModelManagerSupportClang::onCurrentEditorChanged);
|
this, &ModelManagerSupportClang::onCurrentEditorChanged,
|
||||||
|
Qt::QueuedConnection);
|
||||||
connect(editorManager, &Core::EditorManager::editorOpened,
|
connect(editorManager, &Core::EditorManager::editorOpened,
|
||||||
this, &ModelManagerSupportClang::onEditorOpened);
|
this, &ModelManagerSupportClang::onEditorOpened,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(editorManager, &Core::EditorManager::editorsClosed,
|
||||||
|
this, &ModelManagerSupportClang::onEditorClosed,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
CppTools::CppModelManager *modelManager = cppModelManager();
|
CppTools::CppModelManager *modelManager = cppModelManager();
|
||||||
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
||||||
@@ -97,20 +102,9 @@ CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentP
|
|||||||
return new ClangEditorDocumentProcessor(this, baseTextDocument);
|
return new ClangEditorDocumentProcessor(this, baseTextDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent)
|
void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *)
|
||||||
{
|
{
|
||||||
// If we switch away from a cpp editor, update the backend about
|
m_ipcCommunicator.updateTranslationUnitVisiblity();
|
||||||
// the document's unsaved content.
|
|
||||||
if (m_previousCppEditor && m_previousCppEditor->document()->isModified()) {
|
|
||||||
m_ipcCommunicator.updateTranslationUnitFromCppEditorDocument(
|
|
||||||
m_previousCppEditor->document()->filePath().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember previous editor
|
|
||||||
if (newCurrent && cppModelManager()->isCppEditor(newCurrent))
|
|
||||||
m_previousCppEditor = newCurrent;
|
|
||||||
else
|
|
||||||
m_previousCppEditor.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument)
|
void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument)
|
||||||
@@ -181,6 +175,11 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelManagerSupportClang::onEditorClosed(const QList<Core::IEditor *> &)
|
||||||
|
{
|
||||||
|
m_ipcCommunicator.updateTranslationUnitVisiblity();
|
||||||
|
}
|
||||||
|
|
||||||
void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit()
|
void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit()
|
||||||
{
|
{
|
||||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||||
@@ -193,7 +192,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool
|
|||||||
if (success) {
|
if (success) {
|
||||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||||
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
|
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
|
||||||
m_ipcCommunicator.requestDiagnostics(textDocument);
|
m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(textDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +341,7 @@ void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
|
|||||||
{
|
{
|
||||||
const auto processors = clangProcessorsWithProjectParts(projectPartIds);
|
const auto processors = clangProcessorsWithProjectParts(projectPartIds);
|
||||||
foreach (ClangEditorDocumentProcessor *processor, processors) {
|
foreach (ClangEditorDocumentProcessor *processor, processors) {
|
||||||
m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainer()});
|
m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()});
|
||||||
processor->clearProjectPart();
|
processor->clearProjectPart();
|
||||||
processor->run();
|
processor->run();
|
||||||
}
|
}
|
||||||
|
@@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void onEditorOpened(Core::IEditor *editor);
|
void onEditorOpened(Core::IEditor *editor);
|
||||||
|
void onEditorClosed(const QList<Core::IEditor *> &editors);
|
||||||
void onCurrentEditorChanged(Core::IEditor *newCurrent);
|
void onCurrentEditorChanged(Core::IEditor *newCurrent);
|
||||||
void onCppDocumentAboutToReloadOnTranslationUnit();
|
void onCppDocumentAboutToReloadOnTranslationUnit();
|
||||||
void onCppDocumentReloadFinishedOnTranslationUnit(bool success);
|
void onCppDocumentReloadFinishedOnTranslationUnit(bool success);
|
||||||
@@ -103,7 +104,6 @@ private:
|
|||||||
private:
|
private:
|
||||||
IpcCommunicator m_ipcCommunicator;
|
IpcCommunicator m_ipcCommunicator;
|
||||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||||
QPointer<Core::IEditor> m_previousCppEditor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
||||||
|
@@ -31,8 +31,6 @@
|
|||||||
#ifndef CLANGPROJECTSETTINGS_H
|
#ifndef CLANGPROJECTSETTINGS_H
|
||||||
#define CLANGPROJECTSETTINGS_H
|
#define CLANGPROJECTSETTINGS_H
|
||||||
|
|
||||||
#include "clang_global.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -40,7 +38,7 @@
|
|||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
class CLANG_EXPORT ClangProjectSettings: public QObject
|
class ClangProjectSettings: public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@@ -30,11 +30,6 @@
|
|||||||
|
|
||||||
#include "clangprojectsettings.h"
|
#include "clangprojectsettings.h"
|
||||||
#include "clangprojectsettingspropertiespage.h"
|
#include "clangprojectsettingspropertiespage.h"
|
||||||
#include "pchmanager.h"
|
|
||||||
|
|
||||||
#include <QButtonGroup>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QFileDialog>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace ClangCodeModel::Internal;
|
using namespace ClangCodeModel::Internal;
|
||||||
@@ -43,88 +38,4 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(Project *project)
|
|||||||
: m_project(project)
|
: m_project(project)
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(project);
|
|
||||||
Q_ASSERT(cps);
|
|
||||||
|
|
||||||
QButtonGroup *pchGroup = new QButtonGroup(this);
|
|
||||||
pchGroup->addButton(m_ui.noneButton, ClangProjectSettings::PchUse_None);
|
|
||||||
pchGroup->addButton(m_ui.exactButton, ClangProjectSettings::PchUse_BuildSystem_Exact);
|
|
||||||
pchGroup->addButton(m_ui.fuzzyButton, ClangProjectSettings::PchUse_BuildSystem_Fuzzy);
|
|
||||||
pchGroup->addButton(m_ui.customButton, ClangProjectSettings::PchUse_Custom);
|
|
||||||
switch (cps->pchUsage()) {
|
|
||||||
case ClangProjectSettings::PchUse_None:
|
|
||||||
case ClangProjectSettings::PchUse_BuildSystem_Exact:
|
|
||||||
case ClangProjectSettings::PchUse_BuildSystem_Fuzzy:
|
|
||||||
case ClangProjectSettings::PchUse_Custom:
|
|
||||||
pchGroup->button(cps->pchUsage())->setChecked(true);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
pchUsageChanged(cps->pchUsage());
|
|
||||||
connect(pchGroup, SIGNAL(buttonClicked(int)),
|
|
||||||
this, SLOT(pchUsageChanged(int)));
|
|
||||||
|
|
||||||
m_ui.customField->setText(cps->customPchFile());
|
|
||||||
connect(m_ui.customField, SIGNAL(editingFinished()),
|
|
||||||
this, SLOT(customPchFileChanged()));
|
|
||||||
connect(m_ui.customButton, SIGNAL(clicked()),
|
|
||||||
this, SLOT(customPchButtonClicked()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::pchUsageChanged(int id)
|
|
||||||
{
|
|
||||||
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
|
|
||||||
Q_ASSERT(cps);
|
|
||||||
cps->setPchUsage(static_cast<ClangProjectSettings::PchUsage>(id));
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case ClangProjectSettings::PchUse_None:
|
|
||||||
case ClangProjectSettings::PchUse_BuildSystem_Fuzzy:
|
|
||||||
case ClangProjectSettings::PchUse_BuildSystem_Exact:
|
|
||||||
m_ui.customField->setEnabled(false);
|
|
||||||
m_ui.chooseButton->setEnabled(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ClangProjectSettings::PchUse_Custom:
|
|
||||||
m_ui.customField->setEnabled(true);
|
|
||||||
m_ui.chooseButton->setEnabled(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::customPchFileChanged()
|
|
||||||
{
|
|
||||||
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
|
|
||||||
Q_ASSERT(cps);
|
|
||||||
if (cps->pchUsage() != ClangProjectSettings::PchUse_Custom)
|
|
||||||
return;
|
|
||||||
QString fileName = m_ui.customField->text();
|
|
||||||
if (!QFile(fileName).exists())
|
|
||||||
return;
|
|
||||||
|
|
||||||
cps->setCustomPchFile(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangProjectSettingsWidget::customPchButtonClicked()
|
|
||||||
{
|
|
||||||
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
|
|
||||||
Q_ASSERT(cps);
|
|
||||||
|
|
||||||
QFileDialog d(this);
|
|
||||||
d.setNameFilters(QStringList() << tr("Header Files (*.h)")
|
|
||||||
<< tr("All Files (*)"));
|
|
||||||
d.setFileMode(QFileDialog::ExistingFile);
|
|
||||||
d.setDirectory(m_project->projectDirectory().toString());
|
|
||||||
if (!d.exec())
|
|
||||||
return;
|
|
||||||
const QStringList fileNames = d.selectedFiles();
|
|
||||||
if (fileNames.isEmpty() || fileNames.first().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_ui.customField->setText(fileNames.first());
|
|
||||||
cps->setCustomPchFile(fileNames.first());
|
|
||||||
}
|
}
|
||||||
|
@@ -33,8 +33,6 @@
|
|||||||
|
|
||||||
#include "ui_clangprojectsettingspropertiespage.h"
|
#include "ui_clangprojectsettingspropertiespage.h"
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class Project;
|
class Project;
|
||||||
}
|
}
|
||||||
@@ -49,11 +47,6 @@ class ClangProjectSettingsWidget: public QWidget
|
|||||||
public:
|
public:
|
||||||
ClangProjectSettingsWidget(ProjectExplorer::Project *project);
|
ClangProjectSettingsWidget(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void pchUsageChanged(int id);
|
|
||||||
void customPchFileChanged();
|
|
||||||
void customPchButtonClicked();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ClangProjectSettingsPropertiesPage m_ui;
|
Ui::ClangProjectSettingsPropertiesPage m_ui;
|
||||||
ProjectExplorer::Project *m_project;
|
ProjectExplorer::Project *m_project;
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage</class>
|
<class>ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage</class>
|
||||||
<widget class="QWidget" name="ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage">
|
<widget class="QWidget" name="ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "clangtextmark.h"
|
#include "clangtextmark.h"
|
||||||
|
|
||||||
#include "constants.h"
|
#include "clangconstants.h"
|
||||||
|
|
||||||
#include <coreplugin/coreicons.h>
|
#include <coreplugin/coreicons.h>
|
||||||
|
|
||||||
|
@@ -32,25 +32,18 @@
|
|||||||
|
|
||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
|
|
||||||
#include <cpptools/baseeditordocumentparser.h>
|
#include <cpptools/baseeditordocumentparser.h>
|
||||||
#include <cpptools/cppprojects.h>
|
#include <cpptools/cppprojects.h>
|
||||||
#include <cpptools/cppworkingcopy.h>
|
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSet>
|
#include <QStringList>
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
using namespace ClangCodeModel;
|
||||||
using namespace ClangCodeModel::Internal;
|
using namespace ClangCodeModel::Internal;
|
||||||
@@ -62,21 +55,6 @@ namespace Utils {
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
|
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
|
||||||
|
|
||||||
UnsavedFiles createUnsavedFiles(const WorkingCopy &workingCopy,
|
|
||||||
const ::Utils::FileNameList &modifiedFiles)
|
|
||||||
{
|
|
||||||
UnsavedFiles result;
|
|
||||||
QHashIterator< ::Utils::FileName, QPair<QByteArray, unsigned> > wcIter = workingCopy.iterator();
|
|
||||||
while (wcIter.hasNext()) {
|
|
||||||
wcIter.next();
|
|
||||||
const ::Utils::FileName &fileName = wcIter.key();
|
|
||||||
if (modifiedFiles.contains(fileName) && QFile(fileName.toString()).exists())
|
|
||||||
result.insert(fileName.toString(), wcIter.value().first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates list of message-line arguments required for correct parsing
|
* @brief Creates list of message-line arguments required for correct parsing
|
||||||
* @param pPart Null if file isn't part of any project
|
* @param pPart Null if file isn't part of any project
|
||||||
|
@@ -31,10 +31,7 @@
|
|||||||
#ifndef CPPTOOLS_CLANGUTILS_H
|
#ifndef CPPTOOLS_CLANGUTILS_H
|
||||||
#define CPPTOOLS_CLANGUTILS_H
|
#define CPPTOOLS_CLANGUTILS_H
|
||||||
|
|
||||||
#include "clang_global.h"
|
#include <cpptools/cppprojects.h>
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
@@ -43,10 +40,6 @@ namespace Utils {
|
|||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
||||||
|
|
||||||
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(
|
|
||||||
const CppTools::WorkingCopy &workingCopy,
|
|
||||||
const ::Utils::FileNameList &modifiedFiles);
|
|
||||||
|
|
||||||
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||||
CppTools::ProjectFile::Kind fileKind);
|
CppTools::ProjectFile::Kind fileKind);
|
||||||
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||||
|
@@ -1,65 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CONSTANTS_H
|
|
||||||
#define CONSTANTS_H
|
|
||||||
|
|
||||||
#include <QtCore/QLatin1Char>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Constants {
|
|
||||||
|
|
||||||
static const QLatin1Char kLParen('(');
|
|
||||||
static const QLatin1Char kRParen(')');
|
|
||||||
static const QLatin1Char kLBrace('{');
|
|
||||||
static const QLatin1Char kRBrace('}');
|
|
||||||
static const QLatin1Char kLBracket('[');
|
|
||||||
static const QLatin1Char kRBracket(']');
|
|
||||||
static const QLatin1Char kLABracket('<');
|
|
||||||
static const QLatin1Char kRABracket('>');
|
|
||||||
static const QLatin1Char kSemiColon(';');
|
|
||||||
static const QLatin1Char kPound('#');
|
|
||||||
static const QLatin1Char kColon(':');
|
|
||||||
static const QLatin1Char kExclamation('!');
|
|
||||||
static const QLatin1Char kSpace(' ');
|
|
||||||
static const QLatin1Char kSlash('/');
|
|
||||||
static const QLatin1Char kStar('*');
|
|
||||||
static const QLatin1Char kDoubleQuote('"');
|
|
||||||
static const QLatin1Char kNewLine('\n');
|
|
||||||
static const QLatin1Char kHorizontalTab('\t');
|
|
||||||
|
|
||||||
const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeModel.ClangCodeModel";
|
|
||||||
const char CLANG_ERROR[] = "Clang.Error";
|
|
||||||
const char CLANG_WARNING[] = "Clang.Warning";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CONSTANTS_H
|
|
@@ -1,135 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "clangutils.h"
|
|
||||||
#include "cppcreatemarkers.h"
|
|
||||||
|
|
||||||
#include <cplusplus/CppDocument.h>
|
|
||||||
#include <utils/executeondestruction.h>
|
|
||||||
#include <utils/runextensions.h>
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QThreadPool>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
using namespace CppTools;
|
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.createmarkers")
|
|
||||||
|
|
||||||
CreateMarkers *CreateMarkers::create(SemanticMarker::Ptr semanticMarker,
|
|
||||||
const QString &fileName,
|
|
||||||
unsigned firstLine, unsigned lastLine)
|
|
||||||
{
|
|
||||||
if (semanticMarker.isNull())
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return new CreateMarkers(semanticMarker, fileName, firstLine, lastLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateMarkers::CreateMarkers(SemanticMarker::Ptr semanticMarker,
|
|
||||||
const QString &fileName,
|
|
||||||
unsigned firstLine, unsigned lastLine)
|
|
||||||
: m_marker(semanticMarker)
|
|
||||||
, m_fileName(fileName)
|
|
||||||
, m_firstLine(firstLine)
|
|
||||||
, m_lastLine(lastLine)
|
|
||||||
{
|
|
||||||
Q_ASSERT(!semanticMarker.isNull());
|
|
||||||
|
|
||||||
m_flushRequested = false;
|
|
||||||
m_flushLine = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateMarkers::~CreateMarkers()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void CreateMarkers::run()
|
|
||||||
{
|
|
||||||
QMutexLocker lock(m_marker->mutex());
|
|
||||||
|
|
||||||
::Utils::ExecuteOnDestruction reportFinishedOnDestruction([this]() { reportFinished(); });
|
|
||||||
|
|
||||||
if (isCanceled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
qCDebug(log) << "Creating markers from" << m_firstLine << "to" << m_lastLine
|
|
||||||
<< "of" << m_fileName;
|
|
||||||
QTime t; t.start();
|
|
||||||
|
|
||||||
m_usages.clear();
|
|
||||||
|
|
||||||
if (isCanceled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const QList<ClangCodeModel::SourceMarker> markers
|
|
||||||
= m_marker->sourceMarkersInRange(m_firstLine, m_lastLine);
|
|
||||||
foreach (const ClangCodeModel::SourceMarker &m, markers)
|
|
||||||
addUse(SourceMarker(m.location().line(), m.location().column(), m.length(), m.kind()));
|
|
||||||
|
|
||||||
if (isCanceled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
flush();
|
|
||||||
|
|
||||||
qCDebug(log) << "Creating markers took" << t.elapsed() << "ms in total.";
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateMarkers::addUse(const SourceMarker &marker)
|
|
||||||
{
|
|
||||||
// if (! enclosingFunctionDefinition()) {
|
|
||||||
if (m_usages.size() >= 100) {
|
|
||||||
if (m_flushRequested && marker.line != m_flushLine)
|
|
||||||
flush();
|
|
||||||
else if (! m_flushRequested) {
|
|
||||||
m_flushRequested = true;
|
|
||||||
m_flushLine = marker.line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
|
|
||||||
m_usages.append(marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateMarkers::flush()
|
|
||||||
{
|
|
||||||
m_flushRequested = false;
|
|
||||||
m_flushLine = 0;
|
|
||||||
|
|
||||||
if (m_usages.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
reportResults(m_usages);
|
|
||||||
m_usages.clear();
|
|
||||||
}
|
|
@@ -1,94 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CPPCREATEMARKERS_H
|
|
||||||
#define CPPCREATEMARKERS_H
|
|
||||||
|
|
||||||
#include "fastindexer.h"
|
|
||||||
#include "sourcemarker.h"
|
|
||||||
#include "semanticmarker.h"
|
|
||||||
#include "pchinfo.h"
|
|
||||||
|
|
||||||
#include <texteditor/semantichighlighter.h>
|
|
||||||
|
|
||||||
#include <QFuture>
|
|
||||||
#include <QtConcurrentRun>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
class CreateMarkers:
|
|
||||||
public QObject,
|
|
||||||
public QRunnable,
|
|
||||||
public QFutureInterface<TextEditor::HighlightingResult>
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_DISABLE_COPY(CreateMarkers)
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~CreateMarkers();
|
|
||||||
|
|
||||||
virtual void run();
|
|
||||||
|
|
||||||
typedef TextEditor::HighlightingResult SourceMarker;
|
|
||||||
|
|
||||||
typedef QFuture<SourceMarker> Future;
|
|
||||||
|
|
||||||
Future start()
|
|
||||||
{
|
|
||||||
this->setRunnable(this);
|
|
||||||
this->reportStarted();
|
|
||||||
Future future = this->future();
|
|
||||||
QThreadPool::globalInstance()->start(this, QThread::LowestPriority);
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CreateMarkers *create(ClangCodeModel::SemanticMarker::Ptr semanticMarker,
|
|
||||||
const QString &fileName, unsigned firstLine, unsigned lastLine);
|
|
||||||
|
|
||||||
void addUse(const SourceMarker &marker);
|
|
||||||
void flush();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CreateMarkers(ClangCodeModel::SemanticMarker::Ptr semanticMarker,
|
|
||||||
const QString &fileName, unsigned firstLine, unsigned lastLine);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ClangCodeModel::SemanticMarker::Ptr m_marker;
|
|
||||||
QString m_fileName;
|
|
||||||
unsigned m_firstLine;
|
|
||||||
unsigned m_lastLine;
|
|
||||||
QVector<SourceMarker> m_usages;
|
|
||||||
bool m_flushRequested;
|
|
||||||
unsigned m_flushLine;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
#endif // CPPCREATEMARKERS_H
|
|
@@ -1,551 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "cxprettyprinter.h"
|
|
||||||
#include "utils_p.h"
|
|
||||||
#include "cxraii.h"
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
|
|
||||||
CXPrettyPrinter::CXPrettyPrinter()
|
|
||||||
: m_indent(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::toString(CXCompletionChunkKind kind) const
|
|
||||||
{
|
|
||||||
switch (kind) {
|
|
||||||
case CXCompletionChunk_Optional:
|
|
||||||
return QLatin1String("Optional");
|
|
||||||
case CXCompletionChunk_TypedText:
|
|
||||||
return QLatin1String("TypedText");
|
|
||||||
case CXCompletionChunk_Text:
|
|
||||||
return QLatin1String("Text");
|
|
||||||
case CXCompletionChunk_Placeholder:
|
|
||||||
return QLatin1String("Placeholder");
|
|
||||||
case CXCompletionChunk_Informative:
|
|
||||||
return QLatin1String("Informative");
|
|
||||||
case CXCompletionChunk_CurrentParameter:
|
|
||||||
return QLatin1String("CurrentParameter");
|
|
||||||
case CXCompletionChunk_LeftParen:
|
|
||||||
return QLatin1String("LeftParen");
|
|
||||||
case CXCompletionChunk_RightParen:
|
|
||||||
return QLatin1String("RightParen");
|
|
||||||
case CXCompletionChunk_LeftBracket:
|
|
||||||
return QLatin1String("LeftBracket");
|
|
||||||
case CXCompletionChunk_RightBracket:
|
|
||||||
return QLatin1String("RightBracket");
|
|
||||||
case CXCompletionChunk_LeftBrace:
|
|
||||||
return QLatin1String("LeftBrace");
|
|
||||||
case CXCompletionChunk_RightBrace:
|
|
||||||
return QLatin1String("RightBrace");
|
|
||||||
case CXCompletionChunk_LeftAngle:
|
|
||||||
return QLatin1String("LeftAngle");
|
|
||||||
case CXCompletionChunk_RightAngle:
|
|
||||||
return QLatin1String("RightAngle");
|
|
||||||
case CXCompletionChunk_Comma:
|
|
||||||
return QLatin1String("Comma");
|
|
||||||
case CXCompletionChunk_ResultType:
|
|
||||||
return QLatin1String("ResultType");
|
|
||||||
case CXCompletionChunk_Colon:
|
|
||||||
return QLatin1String("Colon");
|
|
||||||
case CXCompletionChunk_SemiColon:
|
|
||||||
return QLatin1String("SemiColon");
|
|
||||||
case CXCompletionChunk_Equal:
|
|
||||||
return QLatin1String("Equal");
|
|
||||||
case CXCompletionChunk_HorizontalSpace:
|
|
||||||
return QLatin1String("HorizontalSpace");
|
|
||||||
case CXCompletionChunk_VerticalSpace:
|
|
||||||
return QLatin1String("VerticalSpace");
|
|
||||||
default:
|
|
||||||
return QLatin1String("<UNKNOWN>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::toString(CXAvailabilityKind kind) const
|
|
||||||
{
|
|
||||||
switch (kind) {
|
|
||||||
case CXAvailability_Available:
|
|
||||||
return QLatin1String("Available");
|
|
||||||
case CXAvailability_Deprecated:
|
|
||||||
return QLatin1String("Deprecated");
|
|
||||||
case CXAvailability_NotAccessible:
|
|
||||||
return QLatin1String("NotAccessible");
|
|
||||||
case CXAvailability_NotAvailable:
|
|
||||||
return QLatin1String("NotAvailable");
|
|
||||||
default:
|
|
||||||
return QLatin1String("<UNKNOWN>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::toString(CXCursorKind kind) const
|
|
||||||
{
|
|
||||||
return getQString(clang_getCursorKindSpelling(kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::toString(CXDiagnosticSeverity severity) const
|
|
||||||
{
|
|
||||||
switch (severity)
|
|
||||||
{
|
|
||||||
case CXDiagnostic_Ignored:
|
|
||||||
return QLatin1String("Ignored");
|
|
||||||
case CXDiagnostic_Note:
|
|
||||||
return QLatin1String("Note");
|
|
||||||
case CXDiagnostic_Warning:
|
|
||||||
return QLatin1String("Warning");
|
|
||||||
case CXDiagnostic_Error:
|
|
||||||
return QLatin1String("Error");
|
|
||||||
case CXDiagnostic_Fatal:
|
|
||||||
return QLatin1String("Fatal");
|
|
||||||
default:
|
|
||||||
return QLatin1String("<UNKNOWN>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::jsonForCompletionMeta(CXCodeCompleteResults *results)
|
|
||||||
{
|
|
||||||
QString json;
|
|
||||||
m_printed.swap(json);
|
|
||||||
m_indent = 0;
|
|
||||||
|
|
||||||
m_printed += QLatin1String("CXCodeCompleteResults {");
|
|
||||||
m_indent += 4;
|
|
||||||
|
|
||||||
CXCursorKind containerKind = clang_codeCompleteGetContainerKind(results, NULL);
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("'container CursorKind': ");
|
|
||||||
m_printed += toString(containerKind);
|
|
||||||
m_printed += QLatin1Char(',');
|
|
||||||
|
|
||||||
QString containerUSR(Internal::getQString(clang_codeCompleteGetContainerUSR(results)));
|
|
||||||
if (!containerUSR.isEmpty()) {
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("'container USR': ");
|
|
||||||
m_printed += containerUSR;
|
|
||||||
m_printed += QLatin1Char(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
QString objCSelector(Internal::getQString(clang_codeCompleteGetObjCSelector(results)));
|
|
||||||
if (!objCSelector.isEmpty()) {
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("'Objective-C selector': ");
|
|
||||||
m_printed += objCSelector;
|
|
||||||
m_printed += QLatin1Char(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("'contexts': [");
|
|
||||||
m_indent += 4;
|
|
||||||
writeCompletionContexts(results);
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
|
|
||||||
m_printed.swap(json);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::jsonForCompletionString(const CXCompletionString &string)
|
|
||||||
{
|
|
||||||
QString json;
|
|
||||||
m_printed.swap(json);
|
|
||||||
m_indent = 0;
|
|
||||||
|
|
||||||
m_printed += QLatin1String("CXCompletionString: ");
|
|
||||||
writeCompletionStringJson(string);
|
|
||||||
|
|
||||||
m_printed.swap(json);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CXPrettyPrinter::jsonForCompletion(const CXCompletionResult &result)
|
|
||||||
{
|
|
||||||
QString json;
|
|
||||||
m_printed.swap(json);
|
|
||||||
m_indent = 4;
|
|
||||||
|
|
||||||
m_printed += QLatin1String("CXCompletionResult: {\n"
|
|
||||||
" CompletionString: ");
|
|
||||||
writeCompletionStringJson(result.CompletionString);
|
|
||||||
m_printed += QLatin1Char('\n');
|
|
||||||
|
|
||||||
m_printed += QLatin1String(" CursorKind: ");
|
|
||||||
m_printed += toString(result.CursorKind);
|
|
||||||
m_printed += QLatin1String(";\n}");
|
|
||||||
|
|
||||||
m_printed.swap(json);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief CXPrettyPrinter::jsonForDiagnsotic
|
|
||||||
* @param diagnostic
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* List of used clang-c API calls:
|
|
||||||
* CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);
|
|
||||||
* CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
|
|
||||||
* CXString clang_getDiagnosticOption(CXDiagnostic Diag,
|
|
||||||
* CXString *Disable);
|
|
||||||
* unsigned clang_getDiagnosticCategory(CXDiagnostic);
|
|
||||||
* CXString clang_getDiagnosticCategoryText(CXDiagnostic);
|
|
||||||
* unsigned clang_getDiagnosticNumRanges(CXDiagnostic);
|
|
||||||
* CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
|
|
||||||
* unsigned Range);
|
|
||||||
* unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
|
|
||||||
* CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
|
|
||||||
* unsigned FixIt,
|
|
||||||
* CXSourceRange *ReplacementRange);
|
|
||||||
*/
|
|
||||||
QString CXPrettyPrinter::jsonForDiagnsotic(const CXDiagnostic &diagnostic)
|
|
||||||
{
|
|
||||||
QString json;
|
|
||||||
m_printed.swap(json);
|
|
||||||
m_indent = 0;
|
|
||||||
|
|
||||||
m_printed += QLatin1String("CXDiagnostic: ");
|
|
||||||
writeDiagnosticJson(diagnostic);
|
|
||||||
|
|
||||||
m_printed.swap(json);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeCompletionContexts(CXCodeCompleteResults *results)
|
|
||||||
{
|
|
||||||
quint64 contexts = clang_codeCompleteGetContexts(results);
|
|
||||||
QStringList lines;
|
|
||||||
|
|
||||||
if (contexts & CXCompletionContext_AnyType)
|
|
||||||
lines << QLatin1String("'any type'");
|
|
||||||
if (contexts & CXCompletionContext_AnyValue)
|
|
||||||
lines << QLatin1String("'any value'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCObjectValue)
|
|
||||||
lines << QLatin1String("'Objective-C object'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCSelectorValue)
|
|
||||||
lines << QLatin1String("'Objective-C selector'");
|
|
||||||
if (contexts & CXCompletionContext_CXXClassTypeValue)
|
|
||||||
lines << QLatin1String("'C++ class'");
|
|
||||||
if (contexts & CXCompletionContext_DotMemberAccess)
|
|
||||||
lines << QLatin1String("'. member access'");
|
|
||||||
if (contexts & CXCompletionContext_ArrowMemberAccess)
|
|
||||||
lines << QLatin1String("'-> member access'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCPropertyAccess)
|
|
||||||
lines << QLatin1String("'. Objective-C property access'");
|
|
||||||
if (contexts & CXCompletionContext_EnumTag)
|
|
||||||
lines << QLatin1String("'enum tag'");
|
|
||||||
if (contexts & CXCompletionContext_UnionTag)
|
|
||||||
lines << QLatin1String("'union tag'");
|
|
||||||
if (contexts & CXCompletionContext_StructTag)
|
|
||||||
lines << QLatin1String("'struct tag'");
|
|
||||||
if (contexts & CXCompletionContext_ClassTag)
|
|
||||||
lines << QLatin1String("'C++ class tag'");
|
|
||||||
if (contexts & CXCompletionContext_Namespace)
|
|
||||||
lines << QLatin1String("'namespace tag'");
|
|
||||||
if (contexts & CXCompletionContext_NestedNameSpecifier)
|
|
||||||
lines << QLatin1String("'C++ nested name specifier'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCInterface)
|
|
||||||
lines << QLatin1String("'Objective-C interface'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCProtocol)
|
|
||||||
lines << QLatin1String("'Objective-C protocol'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCCategory)
|
|
||||||
lines << QLatin1String("'Objective-C category'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCInstanceMessage)
|
|
||||||
lines << QLatin1String("'Objective-C instance message'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCClassMessage)
|
|
||||||
lines << QLatin1String("'Objective-C class message'");
|
|
||||||
if (contexts & CXCompletionContext_ObjCSelectorName)
|
|
||||||
lines << QLatin1String("'Objective-C selector name'");
|
|
||||||
if (contexts & CXCompletionContext_MacroName)
|
|
||||||
lines << QLatin1String("'macro name'");
|
|
||||||
if (contexts & CXCompletionContext_NaturalLanguage)
|
|
||||||
lines << QLatin1String("'natural language'");
|
|
||||||
|
|
||||||
foreach (const QString &line, lines) {
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += line + QLatin1Char(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeCompletionStringJson(const CXCompletionString &string)
|
|
||||||
{
|
|
||||||
m_printed += QLatin1Char('{');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// availability
|
|
||||||
m_printed += QLatin1String("availability: ");
|
|
||||||
m_printed += toString(clang_getCompletionAvailability(string));
|
|
||||||
m_printed += QLatin1Char(';');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// priority
|
|
||||||
m_printed += QLatin1String("priority: ");
|
|
||||||
m_printed += QString::number(clang_getCompletionPriority(string));
|
|
||||||
m_printed += QLatin1Char(';');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// parent
|
|
||||||
m_printed += QLatin1String("parent: \'");
|
|
||||||
m_printed += getQString(clang_getCompletionParent(string, NULL));
|
|
||||||
m_printed += QLatin1String("\';");
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// chunks
|
|
||||||
m_printed += QLatin1String("chunks: [");
|
|
||||||
m_indent += 4;
|
|
||||||
unsigned numChunks = clang_getNumCompletionChunks(string);
|
|
||||||
for (unsigned i = 0; i < numChunks; ++i) {
|
|
||||||
writeLineEnd();
|
|
||||||
writeCompletionChunkJson(string, i);
|
|
||||||
}
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// annotation
|
|
||||||
m_printed += QLatin1String("annotations: [");
|
|
||||||
m_indent += 4;
|
|
||||||
unsigned numAnns = clang_getCompletionNumAnnotations(string);
|
|
||||||
for (unsigned i = 0; i < numAnns; ++i) {
|
|
||||||
writeLineEnd();
|
|
||||||
writeCompletionAnnotationJson(string, i);
|
|
||||||
}
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeCompletionChunkJson(const CXCompletionString &string, unsigned i)
|
|
||||||
{
|
|
||||||
QString text = getQString(clang_getCompletionChunkText(string, i));
|
|
||||||
QString kind = toString(clang_getCompletionChunkKind(string, i));
|
|
||||||
CXCompletionString optional = clang_getCompletionChunkCompletionString(string, i);
|
|
||||||
|
|
||||||
m_printed += kind;
|
|
||||||
m_printed += QLatin1String(": ");
|
|
||||||
if (!text.isEmpty()) {
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
m_printed += text;
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
}
|
|
||||||
if (optional != NULL) {
|
|
||||||
if (!text.isEmpty())
|
|
||||||
m_printed += QLatin1String(", ");
|
|
||||||
m_indent += 4;
|
|
||||||
writeCompletionStringJson(optional);
|
|
||||||
m_indent -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeCompletionAnnotationJson(const CXCompletionString &string, unsigned i)
|
|
||||||
{
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
m_printed += getQString(clang_getCompletionAnnotation(string, i));
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeDiagnosticJson(const CXDiagnostic &diag)
|
|
||||||
{
|
|
||||||
m_printed += QLatin1Char('{');
|
|
||||||
m_indent += 4;
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// message
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
m_printed += getQString(clang_formatDiagnostic(diag, /*options*/ 0));
|
|
||||||
m_printed += QLatin1Char('\'');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// severity
|
|
||||||
m_printed += QLatin1String("severity: ");
|
|
||||||
m_printed += toString(clang_getDiagnosticSeverity(diag));
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// location
|
|
||||||
m_printed += QLatin1String("location: ");
|
|
||||||
writeLocationJson(clang_getDiagnosticLocation(diag));
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
// fix-its
|
|
||||||
unsigned numFixIts = clang_getDiagnosticNumFixIts(diag);
|
|
||||||
if (numFixIts > 0) {
|
|
||||||
m_printed += QLatin1String("FixIts: [");
|
|
||||||
writeLineEnd();
|
|
||||||
for (unsigned i = 0; i < numFixIts; ++i) {
|
|
||||||
writeFixItJson(diag, i);
|
|
||||||
writeLineEnd();
|
|
||||||
}
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
writeLineEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clang CLI options
|
|
||||||
CXString cxDisabler;
|
|
||||||
QString enabler = getQString(clang_getDiagnosticOption(diag, &cxDisabler));
|
|
||||||
QString disabler = getQString(cxDisabler);
|
|
||||||
if (!enabler.isEmpty()) {
|
|
||||||
m_printed += QLatin1String("enabledBy: \'");
|
|
||||||
m_printed += enabler;
|
|
||||||
m_printed += QLatin1String("';");
|
|
||||||
writeLineEnd();
|
|
||||||
}
|
|
||||||
if (!disabler.isEmpty()) {
|
|
||||||
m_printed += QLatin1String("disabledBy: \'");
|
|
||||||
m_printed += disabler;
|
|
||||||
m_printed += QLatin1String("';");
|
|
||||||
writeLineEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
// diagnostic category
|
|
||||||
m_printed += QLatin1String("category: \'");
|
|
||||||
m_printed += getQString(clang_getDiagnosticCategoryText(diag));
|
|
||||||
m_printed += QLatin1String("';");
|
|
||||||
|
|
||||||
// ranges
|
|
||||||
unsigned numRanges = clang_getDiagnosticNumRanges(diag);
|
|
||||||
if (numRanges > 0) {
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("ranges: [");
|
|
||||||
m_indent += 4;
|
|
||||||
for (unsigned i = 0; i < numRanges; ++i) {
|
|
||||||
writeLineEnd();
|
|
||||||
writeRangeJson(clang_getDiagnosticRange(diag, i));
|
|
||||||
}
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
}
|
|
||||||
|
|
||||||
// children
|
|
||||||
CXDiagnosticSet set(clang_getChildDiagnostics(diag));
|
|
||||||
unsigned numChildren = clang_getNumDiagnosticsInSet(set);
|
|
||||||
if (numChildren > 0) {
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1String("children: [");
|
|
||||||
m_indent += 4;
|
|
||||||
for (unsigned i = 0; i < numChildren; ++i) {
|
|
||||||
writeLineEnd();
|
|
||||||
ScopedCXDiagnostic child(clang_getDiagnosticInSet(set, i));
|
|
||||||
writeDiagnosticJson(child);
|
|
||||||
}
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char(']');
|
|
||||||
}
|
|
||||||
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeFixItJson(const CXDiagnostic &diag, unsigned i)
|
|
||||||
{
|
|
||||||
CXSourceRange range; // half-open range [a, b)
|
|
||||||
QString text = getQString(clang_getDiagnosticFixIt(diag, i, &range));
|
|
||||||
|
|
||||||
m_printed += QLatin1String("{ newText: ");
|
|
||||||
m_printed += QLatin1String("\'");
|
|
||||||
m_printed += text;
|
|
||||||
m_printed += QLatin1String("\', range: ");
|
|
||||||
writeRangeJson(range);
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeRangeJson(const CXSourceRange &range)
|
|
||||||
{
|
|
||||||
SourceLocation start = getSpellingLocation(clang_getRangeStart(range));
|
|
||||||
SourceLocation end = getSpellingLocation(clang_getRangeEnd(range));
|
|
||||||
|
|
||||||
m_printed += QLatin1Char('{');
|
|
||||||
m_indent += 4;
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1String("file: \'");
|
|
||||||
m_printed += start.fileName();
|
|
||||||
m_printed += QLatin1String("\',");
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1String("from: {");
|
|
||||||
m_printed += QString::number(start.line());
|
|
||||||
m_printed += QLatin1String(", ");
|
|
||||||
m_printed += QString::number(start.column());
|
|
||||||
m_printed += QLatin1String("},");
|
|
||||||
|
|
||||||
m_printed += QLatin1String("to: {");
|
|
||||||
m_printed += QString::number(end.line());
|
|
||||||
m_printed += QLatin1String(", ");
|
|
||||||
m_printed += QString::number(end.column());
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeLocationJson(const CXSourceLocation &location)
|
|
||||||
{
|
|
||||||
SourceLocation loc = getSpellingLocation(location);
|
|
||||||
m_printed += QLatin1Char('{');
|
|
||||||
m_indent += 4;
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1String("file: \'");
|
|
||||||
m_printed += loc.fileName();
|
|
||||||
m_printed += QLatin1String("\',");
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1String("line: ");
|
|
||||||
m_printed += QString::number(loc.line());
|
|
||||||
m_printed += QLatin1Char(',');
|
|
||||||
writeLineEnd();
|
|
||||||
|
|
||||||
m_printed += QLatin1String("column: ");
|
|
||||||
m_printed += QString::number(loc.column());
|
|
||||||
|
|
||||||
m_indent -= 4;
|
|
||||||
writeLineEnd();
|
|
||||||
m_printed += QLatin1Char('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXPrettyPrinter::writeLineEnd()
|
|
||||||
{
|
|
||||||
m_printed += QLatin1Char('\n');
|
|
||||||
for (int i = 0; i < m_indent; ++i)
|
|
||||||
m_printed += QLatin1Char(' ');
|
|
||||||
}
|
|
@@ -1,76 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CXPRETTYPRINTER_H
|
|
||||||
#define CXPRETTYPRINTER_H
|
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class CXPrettyPrinter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CXPrettyPrinter();
|
|
||||||
|
|
||||||
QString toString(CXCompletionChunkKind kind) const;
|
|
||||||
QString toString(CXAvailabilityKind kind) const;
|
|
||||||
QString toString(CXCursorKind kind) const;
|
|
||||||
QString toString(CXDiagnosticSeverity severity) const;
|
|
||||||
|
|
||||||
QString jsonForCompletionMeta(CXCodeCompleteResults *results);
|
|
||||||
QString jsonForCompletionString(const CXCompletionString &string);
|
|
||||||
QString jsonForCompletion(const CXCompletionResult &result);
|
|
||||||
QString jsonForDiagnsotic(const CXDiagnostic &diagnostic);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_indent;
|
|
||||||
QString m_printed;
|
|
||||||
|
|
||||||
void writeCompletionContexts(CXCodeCompleteResults *results);
|
|
||||||
void writeCompletionStringJson(const CXCompletionString &string);
|
|
||||||
void writeCompletionChunkJson(const CXCompletionString &string, unsigned i);
|
|
||||||
void writeCompletionAnnotationJson(const CXCompletionString &string, unsigned i);
|
|
||||||
|
|
||||||
void writeDiagnosticJson(const CXDiagnostic &diag);
|
|
||||||
void writeFixItJson(const CXDiagnostic &diag, unsigned i);
|
|
||||||
|
|
||||||
void writeRangeJson(const CXSourceRange &range);
|
|
||||||
void writeLocationJson(const CXSourceLocation &location);
|
|
||||||
|
|
||||||
void writeLineEnd();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
#endif // CXPRETTYPRINTER_H
|
|
@@ -1,146 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CXRAII_H
|
|
||||||
#define CXRAII_H
|
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
|
|
||||||
// Simple RAII types for their CX correspondings
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
template <class CXType_T>
|
|
||||||
struct ScopedCXType
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef void (*DisposeFunction)(CXType_T);
|
|
||||||
|
|
||||||
ScopedCXType(DisposeFunction f)
|
|
||||||
: m_cx(0), m_disposeFunction(f)
|
|
||||||
{}
|
|
||||||
ScopedCXType(const CXType_T &cx, DisposeFunction f)
|
|
||||||
: m_cx(cx) , m_disposeFunction(f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
~ScopedCXType()
|
|
||||||
{
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator CXType_T() const { return m_cx; }
|
|
||||||
bool operator!() const { return !m_cx; }
|
|
||||||
bool isNull() const { return !m_cx; }
|
|
||||||
void reset(const CXType_T &cx)
|
|
||||||
{
|
|
||||||
dispose();
|
|
||||||
m_cx = cx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ScopedCXType(const ScopedCXType &);
|
|
||||||
const ScopedCXType &operator=(const ScopedCXType &);
|
|
||||||
|
|
||||||
void dispose()
|
|
||||||
{
|
|
||||||
if (m_cx)
|
|
||||||
m_disposeFunction(m_cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXType_T m_cx;
|
|
||||||
DisposeFunction m_disposeFunction;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedCXIndex : ScopedCXType<CXIndex>
|
|
||||||
{
|
|
||||||
ScopedCXIndex()
|
|
||||||
: ScopedCXType<CXIndex>(&clang_disposeIndex)
|
|
||||||
{}
|
|
||||||
ScopedCXIndex(const CXIndex &index)
|
|
||||||
: ScopedCXType<CXIndex>(index, &clang_disposeIndex)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedCXTranslationUnit : ScopedCXType<CXTranslationUnit>
|
|
||||||
{
|
|
||||||
ScopedCXTranslationUnit()
|
|
||||||
: ScopedCXType<CXTranslationUnit>(&clang_disposeTranslationUnit)
|
|
||||||
{}
|
|
||||||
ScopedCXTranslationUnit(const CXTranslationUnit &unit)
|
|
||||||
: ScopedCXType<CXTranslationUnit>(unit, &clang_disposeTranslationUnit)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedCXDiagnostic : ScopedCXType<CXDiagnostic>
|
|
||||||
{
|
|
||||||
ScopedCXDiagnostic()
|
|
||||||
: ScopedCXType<CXDiagnostic>(&clang_disposeDiagnostic)
|
|
||||||
{}
|
|
||||||
ScopedCXDiagnostic(const CXDiagnostic &diagnostic)
|
|
||||||
: ScopedCXType<CXDiagnostic>(diagnostic, &clang_disposeDiagnostic)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedCXDiagnosticSet : ScopedCXType<CXDiagnostic>
|
|
||||||
{
|
|
||||||
ScopedCXDiagnosticSet()
|
|
||||||
: ScopedCXType<CXDiagnosticSet>(&clang_disposeDiagnosticSet)
|
|
||||||
{}
|
|
||||||
ScopedCXDiagnosticSet(const CXDiagnostic &diagnostic)
|
|
||||||
: ScopedCXType<CXDiagnosticSet>(diagnostic, &clang_disposeDiagnosticSet)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScopedCXCodeCompleteResults : ScopedCXType<CXCodeCompleteResults*>
|
|
||||||
{
|
|
||||||
ScopedCXCodeCompleteResults()
|
|
||||||
: ScopedCXType<CXCodeCompleteResults*>(&clang_disposeCodeCompleteResults)
|
|
||||||
{}
|
|
||||||
ScopedCXCodeCompleteResults(CXCodeCompleteResults *results)
|
|
||||||
: ScopedCXType<CXCodeCompleteResults*>(results, &clang_disposeCodeCompleteResults)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unsigned size() const
|
|
||||||
{
|
|
||||||
return static_cast<CXCodeCompleteResults *>(*this)->NumResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CXCompletionResult &completionAt(unsigned i)
|
|
||||||
{
|
|
||||||
return static_cast<CXCodeCompleteResults *>(*this)->Results[i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Internal
|
|
||||||
} // ClangCodeModel
|
|
||||||
|
|
||||||
#endif // CXRAII_H
|
|
@@ -1,209 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "dependencygraph.h"
|
|
||||||
|
|
||||||
#include <QtCore/QtConcurrentRun>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
DependencyGraph::DependencyGraph()
|
|
||||||
{
|
|
||||||
m_includeTracker.setResolutionMode(IncludeTracker::EveryMatchResolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyGraph::~DependencyGraph()
|
|
||||||
{
|
|
||||||
discard();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::cancel()
|
|
||||||
{
|
|
||||||
if (m_computeWatcher.isRunning()) {
|
|
||||||
m_computeWatcher.cancel();
|
|
||||||
m_computeWatcher.waitForFinished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::addFile(const QString &fileName, const QStringList &compilationOptions)
|
|
||||||
{
|
|
||||||
cancel();
|
|
||||||
|
|
||||||
m_files.append(qMakePair(fileName, compilationOptions));
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<void> DependencyGraph::compute()
|
|
||||||
{
|
|
||||||
QFuture<void> future = QtConcurrent::run(this, &DependencyGraph::computeCore);
|
|
||||||
m_computeWatcher.setFuture(future);
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::computeCore()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_files.size(); ++i) {
|
|
||||||
if (m_computeWatcher.isCanceled())
|
|
||||||
break;
|
|
||||||
|
|
||||||
const QPair<QString, QStringList> &p = m_files.at(i);
|
|
||||||
const QString ¤tFile = p.first;
|
|
||||||
const QStringList &options = p.second;
|
|
||||||
const QPair<bool, NodeRefSetIt> &v = findVertex(currentFile);
|
|
||||||
if (!v.first)
|
|
||||||
processIncludes(insertVertex(currentFile), options);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit dependencyGraphAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::processIncludes(NodeRefSetIt currentIt,
|
|
||||||
const QStringList &compilationOptions)
|
|
||||||
{
|
|
||||||
const QString ¤tFile = currentIt.key();
|
|
||||||
const QStringList &includes = m_includeTracker.directIncludes(currentFile, compilationOptions);
|
|
||||||
foreach (const QString &include, includes) {
|
|
||||||
if (m_computeWatcher.isCanceled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPair<bool, NodeRefSetIt> v = findVertex(include);
|
|
||||||
if (!v.first) {
|
|
||||||
v.second = insertVertex(include);
|
|
||||||
processIncludes(v.second, compilationOptions);
|
|
||||||
}
|
|
||||||
insertEdge(currentIt, v.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct SimpleVisitor
|
|
||||||
{
|
|
||||||
bool acceptFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
m_allFiles.append(fileName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList m_allFiles;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList DependencyGraph::collectDependencies(const QString &referenceFile,
|
|
||||||
DependencyRole role) const
|
|
||||||
{
|
|
||||||
SimpleVisitor visitor;
|
|
||||||
collectDependencies(referenceFile, role, &visitor);
|
|
||||||
|
|
||||||
return visitor.m_allFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DependencyGraph::hasDependency(const QString &referenceFile, DependencyRole role) const
|
|
||||||
{
|
|
||||||
QPair<bool, NodeRefSetIt> v = findVertex(referenceFile);
|
|
||||||
if (!v.first)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
NodeListIt nodeIt = v.second.value();
|
|
||||||
|
|
||||||
if (role == FilesDirectlyIncludedBy || role == FilesIncludedBy)
|
|
||||||
return nodeIt->m_out != 0;
|
|
||||||
|
|
||||||
return nodeIt->m_in != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::discard()
|
|
||||||
{
|
|
||||||
cancel();
|
|
||||||
|
|
||||||
for (NodeListIt it = m_nodes.begin(); it != m_nodes.end(); ++it) {
|
|
||||||
deleteAdjacencies(it->m_out);
|
|
||||||
deleteAdjacencies(it->m_in);
|
|
||||||
}
|
|
||||||
m_nodes.clear();
|
|
||||||
m_nodesRefs.clear();
|
|
||||||
m_files.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DependencyGraph::Node::Node(const QString &fileName)
|
|
||||||
: m_fileName(fileName)
|
|
||||||
, m_out(0)
|
|
||||||
, m_in(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
DependencyGraph::AdjacencyNode::AdjacencyNode(NodeListIt it)
|
|
||||||
: m_next(0)
|
|
||||||
, m_nodeIt(it)
|
|
||||||
{}
|
|
||||||
|
|
||||||
QPair<bool, DependencyGraph::NodeRefSetIt> DependencyGraph::findVertex(const QString &s) const
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
NodeRefSetIt it = const_cast<NodeRefSet &>(m_nodesRefs).find(s);
|
|
||||||
if (it != m_nodesRefs.end())
|
|
||||||
found = true;
|
|
||||||
return qMakePair(found, it);
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyGraph::NodeRefSetIt DependencyGraph::insertVertex(const QString &s)
|
|
||||||
{
|
|
||||||
Q_ASSERT(m_nodesRefs.find(s) == m_nodesRefs.end());
|
|
||||||
|
|
||||||
m_nodes.append(Node(s));
|
|
||||||
return m_nodesRefs.insert(s, m_nodes.end() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::insertEdge(DependencyGraph::NodeRefSetIt fromIt,
|
|
||||||
DependencyGraph::NodeRefSetIt toIt)
|
|
||||||
{
|
|
||||||
NodeListIt nodeFromIt = fromIt.value();
|
|
||||||
NodeListIt nodeToIt = toIt.value();
|
|
||||||
|
|
||||||
createAdjacency(&nodeFromIt->m_out, new AdjacencyNode(nodeToIt));
|
|
||||||
createAdjacency(&nodeToIt->m_in, new AdjacencyNode(nodeFromIt));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::deleteAdjacencies(AdjacencyNode *node)
|
|
||||||
{
|
|
||||||
while (node) {
|
|
||||||
AdjacencyNode *next = node->m_next;
|
|
||||||
delete node;
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DependencyGraph::createAdjacency(AdjacencyNode **node, AdjacencyNode *newNode)
|
|
||||||
{
|
|
||||||
if (*node)
|
|
||||||
newNode->m_next = *node;
|
|
||||||
*node = newNode;
|
|
||||||
}
|
|
@@ -1,236 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef DEPENDENCYGRAPH_H
|
|
||||||
#define DEPENDENCYGRAPH_H
|
|
||||||
|
|
||||||
#include "includetracker.h"
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <QtCore/QLinkedList>
|
|
||||||
#include <QtCore/QHash>
|
|
||||||
#include <QtCore/QPair>
|
|
||||||
#include <QtCore/QQueue>
|
|
||||||
#include <QtCore/QFuture>
|
|
||||||
#include <QtCore/QFutureWatcher>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class DependencyGraph : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_DISABLE_COPY(DependencyGraph)
|
|
||||||
|
|
||||||
public:
|
|
||||||
DependencyGraph();
|
|
||||||
~DependencyGraph();
|
|
||||||
|
|
||||||
void addFile(const QString &fileName, const QStringList &compilationOptions);
|
|
||||||
|
|
||||||
QFuture<void> compute();
|
|
||||||
|
|
||||||
enum DependencyRole
|
|
||||||
{
|
|
||||||
FilesDirectlyIncludedBy, // Only direct inclusions
|
|
||||||
FilesIncludedBy, // Both direct and indirect inclusions
|
|
||||||
FilesWhichDirectlyInclude, // This one is directly included from...
|
|
||||||
FilesWhichInclude // This one is directly or indirectly included from...
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* You should use this version if you simply want all the dependencies, no matter what.
|
|
||||||
*/
|
|
||||||
QStringList collectDependencies(const QString &referenceFile, DependencyRole role) const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* You should use this version if you might be interested on a particular dependency
|
|
||||||
* and don't want to continue the search once you have found it. In this case you need
|
|
||||||
* supply a visitor. Currently the visitor concept simply requires that a type Visitor_T
|
|
||||||
* models a function that will receive a file string s and indicate whether or not to
|
|
||||||
* continue:
|
|
||||||
*
|
|
||||||
* Visitor_T().acceptFile(s) must be a valid expression.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template <class Visitor_T>
|
|
||||||
void collectDependencies(const QString &referenceFile,
|
|
||||||
DependencyRole role,
|
|
||||||
Visitor_T *visitor) const;
|
|
||||||
|
|
||||||
bool hasDependency(const QString &referenceFile, DependencyRole role) const;
|
|
||||||
|
|
||||||
void discard();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void dependencyGraphAvailable();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<QPair<QString, QStringList> > m_files;
|
|
||||||
IncludeTracker m_includeTracker;
|
|
||||||
QFutureWatcher<void> m_computeWatcher;
|
|
||||||
|
|
||||||
void cancel();
|
|
||||||
void computeCore();
|
|
||||||
|
|
||||||
// The dependency graph is represent as an adjacency list. The vertices contains
|
|
||||||
// a list of *out* edges and a list of *in* edges. Each vertex corresponds to a file.
|
|
||||||
// Its out edges correspond to the files which get directly included by this one, while
|
|
||||||
// its in edges correspond to files that directly include this one.
|
|
||||||
//
|
|
||||||
// For better space efficiency, the adjacency nodes doen't explicitly store the file
|
|
||||||
// names themselves, but rather an iterator to the corresponding vertex. In addition,
|
|
||||||
// for speed efficiency we keep track of a hash table that contains iterators to the
|
|
||||||
// actual vertex storage container, which actually contains the strings for the file
|
|
||||||
// names. The vertex container itself is a linked list, it has the semantics we need,
|
|
||||||
// in particular regarding iterator invalidation.
|
|
||||||
|
|
||||||
struct AdjacencyNode;
|
|
||||||
struct Node
|
|
||||||
{
|
|
||||||
Node(const QString &fileName);
|
|
||||||
|
|
||||||
QString m_fileName;
|
|
||||||
AdjacencyNode *m_out;
|
|
||||||
AdjacencyNode *m_in;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef QLinkedList<Node> NodeList;
|
|
||||||
typedef NodeList::iterator NodeListIt;
|
|
||||||
typedef QHash<QString, NodeListIt> NodeRefSet;
|
|
||||||
typedef NodeRefSet::iterator NodeRefSetIt;
|
|
||||||
|
|
||||||
struct AdjacencyNode
|
|
||||||
{
|
|
||||||
AdjacencyNode(NodeListIt it);
|
|
||||||
|
|
||||||
AdjacencyNode *m_next;
|
|
||||||
NodeListIt m_nodeIt;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void processIncludes(NodeRefSetIt currentFileIt,
|
|
||||||
const QStringList &compilationOptions);
|
|
||||||
|
|
||||||
template <class Visitor_T>
|
|
||||||
void collectFilesBFS(NodeListIt nodeIt, DependencyRole role, Visitor_T *visitor) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Core graph operations and data
|
|
||||||
|
|
||||||
QPair<bool, NodeRefSetIt> findVertex(const QString &s) const;
|
|
||||||
NodeRefSetIt insertVertex(const QString &s);
|
|
||||||
void insertEdge(NodeRefSetIt fromIt, NodeRefSetIt toIt);
|
|
||||||
|
|
||||||
void deleteAdjacencies(AdjacencyNode *node);
|
|
||||||
void createAdjacency(AdjacencyNode **node, AdjacencyNode *newNode);
|
|
||||||
|
|
||||||
NodeList m_nodes;
|
|
||||||
NodeRefSet m_nodesRefs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Visitor_T>
|
|
||||||
void DependencyGraph::collectDependencies(const QString &referenceFile,
|
|
||||||
DependencyRole role,
|
|
||||||
Visitor_T *visitor) const
|
|
||||||
{
|
|
||||||
if (m_computeWatcher.isRunning())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPair<bool, NodeRefSetIt> v = findVertex(referenceFile);
|
|
||||||
if (!v.first)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NodeListIt nodeIt = v.second.value();
|
|
||||||
|
|
||||||
if (role == FilesDirectlyIncludedBy || role == FilesWhichDirectlyInclude) {
|
|
||||||
AdjacencyNode *adj;
|
|
||||||
if (role == FilesDirectlyIncludedBy)
|
|
||||||
adj = nodeIt->m_out;
|
|
||||||
else
|
|
||||||
adj = nodeIt->m_in;
|
|
||||||
|
|
||||||
for (; adj; adj = adj->m_next) {
|
|
||||||
NodeListIt dependentIt = adj->m_nodeIt;
|
|
||||||
if (visitor->acceptFile(dependentIt->m_fileName))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
collectFilesBFS(nodeIt, role, visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Visitor_T>
|
|
||||||
void DependencyGraph::collectFilesBFS(NodeListIt nodeIt,
|
|
||||||
DependencyRole role,
|
|
||||||
Visitor_T *visitor) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(role == FilesIncludedBy || role == FilesWhichInclude);
|
|
||||||
|
|
||||||
if (m_computeWatcher.isRunning())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QQueue<NodeListIt> q;
|
|
||||||
q.enqueue(nodeIt);
|
|
||||||
|
|
||||||
QSet<QString> visited;
|
|
||||||
visited.insert(nodeIt->m_fileName);
|
|
||||||
|
|
||||||
while (!q.isEmpty()) {
|
|
||||||
NodeListIt currentIt = q.dequeue();
|
|
||||||
AdjacencyNode *adj;
|
|
||||||
if (role == FilesIncludedBy)
|
|
||||||
adj = currentIt->m_out;
|
|
||||||
else
|
|
||||||
adj = currentIt->m_in;
|
|
||||||
while (adj) {
|
|
||||||
NodeListIt adjNodeIt = adj->m_nodeIt;
|
|
||||||
adj = adj->m_next;
|
|
||||||
|
|
||||||
const QString &adjFileName = adjNodeIt->m_fileName;
|
|
||||||
if (visited.contains(adjFileName))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (visitor->acceptFile(adjFileName))
|
|
||||||
return;
|
|
||||||
|
|
||||||
visited.insert(adjFileName);
|
|
||||||
q.enqueue(adjNodeIt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // Internal
|
|
||||||
} // ClangCodeModel
|
|
||||||
|
|
||||||
#endif // DEPENDENCYGRAPH_H
|
|
@@ -1,64 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "diagnostic.h"
|
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
|
|
||||||
Diagnostic::Diagnostic()
|
|
||||||
: m_severity(Unknown)
|
|
||||||
, m_length(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Diagnostic::Diagnostic(Severity severity, const SourceLocation &location, unsigned length, const QString &spelling)
|
|
||||||
: m_severity(severity)
|
|
||||||
, m_loc(location)
|
|
||||||
, m_length(length)
|
|
||||||
, m_spelling(spelling)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const QString Diagnostic::severityAsString() const
|
|
||||||
{
|
|
||||||
if (m_severity == Unknown)
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
static QStringList strs = QStringList()
|
|
||||||
<< QCoreApplication::translate("ClangCodeModel::Diagnostic", "ignored")
|
|
||||||
<< QCoreApplication::translate("ClangCodeModel::Diagnostic", "note")
|
|
||||||
<< QCoreApplication::translate("ClangCodeModel::Diagnostic", "warning")
|
|
||||||
<< QCoreApplication::translate("ClangCodeModel::Diagnostic", "error")
|
|
||||||
<< QCoreApplication::translate("ClangCodeModel::Diagnostic", "fatal")
|
|
||||||
;
|
|
||||||
|
|
||||||
return strs.at(m_severity);
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "fastindexer.h"
|
|
||||||
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
|
|
||||||
FastIndexer::~FastIndexer()
|
|
||||||
{
|
|
||||||
}
|
|
@@ -1,491 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "index.h"
|
|
||||||
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QLinkedList>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QDataStream>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class ClangSymbolSearcher;
|
|
||||||
|
|
||||||
class IndexPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IndexPrivate();
|
|
||||||
|
|
||||||
void insertSymbol(const Symbol &symbol, const QDateTime &timeStamp);
|
|
||||||
QList<Symbol> symbols(const QString &fileName) const;
|
|
||||||
QList<Symbol> symbols(const QString &fileName, Symbol::Kind kind) const;
|
|
||||||
QList<Symbol> symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const;
|
|
||||||
QList<Symbol> symbols(const QString &fileName, const QString &uqName) const;
|
|
||||||
QList<Symbol> symbols(Symbol::Kind kind) const;
|
|
||||||
|
|
||||||
void match(ClangSymbolSearcher *searcher) const;
|
|
||||||
|
|
||||||
void insertFile(const QString &fileName, const QDateTime &timeStamp);
|
|
||||||
void removeFile(const QString &fileName);
|
|
||||||
void removeFiles(const QStringList &fileNames);
|
|
||||||
bool containsFile(const QString &fileName) const;
|
|
||||||
QStringList files() const;
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
bool isEmpty() const;
|
|
||||||
|
|
||||||
void trackTimeStamp(const Symbol &symbol, const QDateTime &timeStamp);
|
|
||||||
void trackTimeStamp(const QString &fileName, const QDateTime &timeStamp);
|
|
||||||
|
|
||||||
bool validate(const QString &fileName) const;
|
|
||||||
|
|
||||||
QByteArray serialize() const;
|
|
||||||
void deserialize(const QByteArray &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef QLinkedList<Symbol> SymbolCont;
|
|
||||||
typedef SymbolCont::iterator SymbolIt;
|
|
||||||
|
|
||||||
typedef QHash<QString, QList<SymbolIt> > NameIndex;
|
|
||||||
typedef QHash<Symbol::Kind, NameIndex> KindIndex;
|
|
||||||
typedef QHash<QString, KindIndex> FileIndex;
|
|
||||||
|
|
||||||
typedef QList<SymbolIt>::iterator SymbolIndexIt;
|
|
||||||
typedef NameIndex::iterator NameIndexIt;
|
|
||||||
typedef KindIndex::iterator KindIndexIt;
|
|
||||||
typedef FileIndex::iterator FileIndexIt;
|
|
||||||
typedef FileIndex::const_iterator FileIndexCIt;
|
|
||||||
|
|
||||||
void insertSymbol(const Symbol &symbol);
|
|
||||||
void removeSymbol(SymbolIndexIt it);
|
|
||||||
|
|
||||||
QPair<bool, SymbolIndexIt> findEquivalentSymbol(const Symbol &symbol);
|
|
||||||
void updateEquivalentSymbol(SymbolIndexIt it, const Symbol &symbol);
|
|
||||||
|
|
||||||
void createIndexes(SymbolIt it);
|
|
||||||
QList<SymbolIt> removeIndexes(const QString &fileName);
|
|
||||||
|
|
||||||
static QList<Symbol> symbolsFromIterators(const QList<SymbolIt> &symbolList);
|
|
||||||
|
|
||||||
// @TODO: Sharing of compilation options...
|
|
||||||
|
|
||||||
mutable QMutex m_mutex;
|
|
||||||
SymbolCont m_container;
|
|
||||||
FileIndex m_files;
|
|
||||||
QHash<QString, QDateTime> m_timeStamps;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
IndexPrivate::IndexPrivate()
|
|
||||||
: m_mutex(QMutex::Recursive)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::createIndexes(SymbolIt it)
|
|
||||||
{
|
|
||||||
m_files[it->m_location.fileName()][it->m_kind][it->m_name].append(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QLinkedList<Symbol>::iterator> IndexPrivate::removeIndexes(const QString &fileName)
|
|
||||||
{
|
|
||||||
QList<SymbolIt> iterators;
|
|
||||||
KindIndex kindIndex = m_files.take(fileName);
|
|
||||||
KindIndexIt it = kindIndex.begin();
|
|
||||||
KindIndexIt eit = kindIndex.end();
|
|
||||||
for (; it != eit; ++it) {
|
|
||||||
NameIndex nameIndex = *it;
|
|
||||||
NameIndexIt nit = nameIndex.begin();
|
|
||||||
NameIndexIt neit = nameIndex.end();
|
|
||||||
for (; nit != neit; ++nit)
|
|
||||||
iterators.append(*nit);
|
|
||||||
}
|
|
||||||
return iterators;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::insertSymbol(const Symbol &symbol)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
SymbolIt it = m_container.insert(m_container.begin(), symbol);
|
|
||||||
createIndexes(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::insertSymbol(const Symbol &symbol, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
const QPair<bool, SymbolIndexIt> &find = findEquivalentSymbol(symbol);
|
|
||||||
if (find.first)
|
|
||||||
updateEquivalentSymbol(find.second, symbol);
|
|
||||||
else
|
|
||||||
insertSymbol(symbol);
|
|
||||||
|
|
||||||
trackTimeStamp(symbol, timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<bool, IndexPrivate::SymbolIndexIt> IndexPrivate::findEquivalentSymbol(const Symbol &symbol)
|
|
||||||
{
|
|
||||||
// Despite the loop below finding a symbol should be efficient, since we already filter
|
|
||||||
// the file name, the kind, and the qualified name through the indexing mechanism. In many
|
|
||||||
// cases it will iterate only once.
|
|
||||||
QList<SymbolIt> &byName = m_files[symbol.m_location.fileName()][symbol.m_kind][symbol.m_name];
|
|
||||||
for (SymbolIndexIt it = byName.begin(); it != byName.end(); ++it) {
|
|
||||||
const Symbol &candidateSymbol = *(*it);
|
|
||||||
// @TODO: Overloads, template specializations
|
|
||||||
if (candidateSymbol.m_qualification == symbol.m_qualification)
|
|
||||||
return qMakePair(true, it);
|
|
||||||
}
|
|
||||||
|
|
||||||
return qMakePair(false, QList<SymbolIt>::iterator());
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::updateEquivalentSymbol(SymbolIndexIt it, const Symbol &symbol)
|
|
||||||
{
|
|
||||||
SymbolIt symbolIt = *it;
|
|
||||||
|
|
||||||
Q_ASSERT(symbolIt->m_kind == symbol.m_kind);
|
|
||||||
Q_ASSERT(symbolIt->m_qualification == symbol.m_qualification);
|
|
||||||
Q_ASSERT(symbolIt->m_name == symbol.m_name);
|
|
||||||
Q_ASSERT(symbolIt->m_location.fileName() == symbol.m_location.fileName());
|
|
||||||
|
|
||||||
symbolIt->m_location = symbol.m_location;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::removeSymbol(SymbolIndexIt it)
|
|
||||||
{
|
|
||||||
SymbolIt symbolIt = *it;
|
|
||||||
|
|
||||||
m_container.erase(symbolIt);
|
|
||||||
|
|
||||||
KindIndex &kindIndex = m_files[symbolIt->m_location.fileName()];
|
|
||||||
NameIndex &nameIndex = kindIndex[symbolIt->m_kind];
|
|
||||||
QList<SymbolIt> &byName = nameIndex[symbolIt->m_name];
|
|
||||||
byName.erase(it);
|
|
||||||
if (byName.isEmpty()) {
|
|
||||||
nameIndex.remove(symbolIt->m_name);
|
|
||||||
if (nameIndex.isEmpty()) {
|
|
||||||
kindIndex.remove(symbolIt->m_kind);
|
|
||||||
if (kindIndex.isEmpty())
|
|
||||||
m_files.remove(symbolIt->m_location.fileName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> IndexPrivate::symbols(const QString &fileName) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
QList<Symbol> all;
|
|
||||||
const QList<NameIndex> &byKind = m_files.value(fileName).values();
|
|
||||||
foreach (const NameIndex &nameIndex, byKind) {
|
|
||||||
const QList<QList<SymbolIt> > &byName = nameIndex.values();
|
|
||||||
foreach (const QList<SymbolIt> &symbols, byName)
|
|
||||||
all.append(symbolsFromIterators(symbols));
|
|
||||||
}
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> IndexPrivate::symbols(const QString &fileName, Symbol::Kind kind) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
QList<Symbol> all;
|
|
||||||
const QList<QList<SymbolIt> > &byName = m_files.value(fileName).value(kind).values();
|
|
||||||
foreach (const QList<SymbolIt> &symbols, byName)
|
|
||||||
all.append(symbolsFromIterators(symbols));
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> IndexPrivate::symbols(const QString &fileName,
|
|
||||||
Symbol::Kind kind,
|
|
||||||
const QString &uqName) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
return symbolsFromIterators(m_files.value(fileName).value(kind).value(uqName));
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> IndexPrivate::symbols(Symbol::Kind kind) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
QList<Symbol> all;
|
|
||||||
FileIndexCIt it = m_files.begin();
|
|
||||||
FileIndexCIt eit = m_files.end();
|
|
||||||
for (; it != eit; ++it)
|
|
||||||
all.append(symbols(it.key(), kind));
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::match(ClangSymbolSearcher *searcher) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
Q_UNUSED(searcher);
|
|
||||||
// searcher->search(m_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> IndexPrivate::symbolsFromIterators(const QList<SymbolIt> &symbolList)
|
|
||||||
{
|
|
||||||
QList<Symbol> all;
|
|
||||||
foreach (SymbolIt symbolIt, symbolList)
|
|
||||||
all.append(*symbolIt);
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::trackTimeStamp(const Symbol &symbol, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
trackTimeStamp(symbol.m_location.fileName(), timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::trackTimeStamp(const QString &fileName, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
// We keep track of time stamps on a per file basis (most recent one).
|
|
||||||
m_timeStamps[fileName] = timeStamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IndexPrivate::validate(const QString &fileName) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
const QDateTime &timeStamp = m_timeStamps.value(fileName);
|
|
||||||
if (!timeStamp.isValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QFileInfo fileInfo(fileName);
|
|
||||||
if (fileInfo.lastModified() > timeStamp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::insertFile(const QString &fileName, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
trackTimeStamp(fileName, timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList IndexPrivate::files() const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
return m_timeStamps.keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IndexPrivate::containsFile(const QString &fileName) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
return m_timeStamps.contains(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::removeFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
const QList<SymbolIt> &iterators = removeIndexes(fileName);
|
|
||||||
foreach (SymbolIt it, iterators)
|
|
||||||
m_container.erase(it);
|
|
||||||
|
|
||||||
m_timeStamps.remove(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::removeFiles(const QStringList &fileNames)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
foreach (const QString &fileName, fileNames)
|
|
||||||
removeFile(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::clear()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
m_container.clear();
|
|
||||||
m_files.clear();
|
|
||||||
m_timeStamps.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IndexPrivate::isEmpty() const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
return m_timeStamps.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray IndexPrivate::serialize() const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
|
|
||||||
stream << (quint32)0x0A0BFFEE;
|
|
||||||
stream << (quint16)1;
|
|
||||||
stream.setVersion(QDataStream::Qt_4_7);
|
|
||||||
stream << m_container;
|
|
||||||
stream << m_timeStamps;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexPrivate::deserialize(const QByteArray &data)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
// @TODO: Version compatibility handling.
|
|
||||||
|
|
||||||
QDataStream stream(data);
|
|
||||||
|
|
||||||
quint32 header;
|
|
||||||
stream >> header;
|
|
||||||
if (header != 0x0A0BFFEE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
quint16 indexVersion;
|
|
||||||
stream >> indexVersion;
|
|
||||||
if (indexVersion != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stream.setVersion(QDataStream::Qt_4_7);
|
|
||||||
|
|
||||||
SymbolCont symbols;
|
|
||||||
stream >> symbols;
|
|
||||||
stream >> m_timeStamps;
|
|
||||||
|
|
||||||
// @TODO: Overload the related functions with batch versions.
|
|
||||||
foreach (const Symbol &symbol, symbols)
|
|
||||||
insertSymbol(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Index::Index()
|
|
||||||
: d(new IndexPrivate)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Index::~Index()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void Index::insertSymbol(const Symbol &symbol, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
d->insertSymbol(symbol, timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> Index::symbols(const QString &fileName) const
|
|
||||||
{
|
|
||||||
return d->symbols(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> Index::symbols(const QString &fileName, Symbol::Kind kind) const
|
|
||||||
{
|
|
||||||
return d->symbols(fileName, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> Index::symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const
|
|
||||||
{
|
|
||||||
return d->symbols(fileName, kind, uqName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol> Index::symbols(Symbol::Kind kind) const
|
|
||||||
{
|
|
||||||
return d->symbols(kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::match(ClangSymbolSearcher *searcher) const
|
|
||||||
{
|
|
||||||
d->match(searcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::insertFile(const QString &fileName, const QDateTime &timeStamp)
|
|
||||||
{
|
|
||||||
d->insertFile(fileName, timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Index::files() const
|
|
||||||
{
|
|
||||||
return d->files();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Index::containsFile(const QString &fileName) const
|
|
||||||
{
|
|
||||||
return d->containsFile(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::removeFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
d->removeFile(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::removeFiles(const QStringList &fileNames)
|
|
||||||
{
|
|
||||||
d->removeFiles(fileNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::clear()
|
|
||||||
{
|
|
||||||
d->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Index::isEmpty() const
|
|
||||||
{
|
|
||||||
return d->isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Index::validate(const QString &fileName) const
|
|
||||||
{
|
|
||||||
return d->validate(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray Index::serialize() const
|
|
||||||
{
|
|
||||||
return d->serialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Index::deserialize(const QByteArray &data)
|
|
||||||
{
|
|
||||||
d->deserialize(data);
|
|
||||||
}
|
|
@@ -1,88 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef INDEX_H
|
|
||||||
#define INDEX_H
|
|
||||||
|
|
||||||
#include "symbol.h"
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QScopedPointer>
|
|
||||||
#include <QtCore/QDateTime>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
class Symbol;
|
|
||||||
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class ClangSymbolSearcher;
|
|
||||||
class IndexPrivate;
|
|
||||||
|
|
||||||
class Index
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Index();
|
|
||||||
~Index();
|
|
||||||
|
|
||||||
void insertSymbol(const Symbol &symbol, const QDateTime &timeStamp);
|
|
||||||
QList<Symbol> symbols(const QString &fileName) const;
|
|
||||||
QList<Symbol> symbols(const QString &fileName, Symbol::Kind kind) const;
|
|
||||||
QList<Symbol> symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const;
|
|
||||||
QList<Symbol> symbols(Symbol::Kind kind) const;
|
|
||||||
|
|
||||||
void match(ClangSymbolSearcher *searcher) const;
|
|
||||||
|
|
||||||
void insertFile(const QString &fileName, const QDateTime &timeStamp);
|
|
||||||
void removeFile(const QString &fileName);
|
|
||||||
void removeFiles(const QStringList &fileNames);
|
|
||||||
bool containsFile(const QString &fileName) const;
|
|
||||||
QStringList files() const;
|
|
||||||
|
|
||||||
bool validate(const QString &fileName) const;
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
bool isEmpty() const;
|
|
||||||
|
|
||||||
QByteArray serialize() const;
|
|
||||||
void deserialize(const QByteArray &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QScopedPointer<IndexPrivate> d;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Internal
|
|
||||||
} // ClangCodeModel
|
|
||||||
|
|
||||||
#endif // INDEX_H
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,104 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef INDEXER_H
|
|
||||||
#define INDEXER_H
|
|
||||||
|
|
||||||
#include "clang_global.h"
|
|
||||||
#include "symbol.h"
|
|
||||||
#include "unit.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <QtCore/QScopedPointer>
|
|
||||||
#include <QtCore/QFuture>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
namespace Internal { class ClangSymbolSearcher; }
|
|
||||||
|
|
||||||
class IndexerPrivate;
|
|
||||||
|
|
||||||
class CLANG_EXPORT Indexer : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef CppTools::ProjectPart ProjectPart;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Indexer(QObject *parent = 0);
|
|
||||||
~Indexer();
|
|
||||||
|
|
||||||
void initialize(const QString &storagePath);
|
|
||||||
void finalize();
|
|
||||||
|
|
||||||
void regenerate();
|
|
||||||
void evaluateFile(const QString &fileName);
|
|
||||||
bool isBusy() const;
|
|
||||||
void cancel(bool waitForFinished);
|
|
||||||
|
|
||||||
bool addFile(const QString &fileName, ProjectPart::Ptr projectPart);
|
|
||||||
QStringList allFiles() const;
|
|
||||||
QStringList compilationOptions(const QString &fileName) const;
|
|
||||||
|
|
||||||
QList<Symbol> allFunctions() const;
|
|
||||||
QList<Symbol> allClasses() const;
|
|
||||||
QList<Symbol> allMethods() const;
|
|
||||||
QList<Symbol> allConstructors() const;
|
|
||||||
QList<Symbol> allDestructors() const;
|
|
||||||
QList<Symbol> functionsFromFile(const QString &fileName) const;
|
|
||||||
QList<Symbol> classesFromFile(const QString &fileName) const;
|
|
||||||
QList<Symbol> methodsFromFile(const QString &fileName) const;
|
|
||||||
QList<Symbol> constructorsFromFile(const QString &fileName) const;
|
|
||||||
QList<Symbol> destructorsFromFile(const QString &fileName) const;
|
|
||||||
QList<Symbol> allFromFile(const QString &fileName) const;
|
|
||||||
|
|
||||||
void match(Internal::ClangSymbolSearcher *searcher) const;
|
|
||||||
|
|
||||||
void runQuickIndexing(Internal::Unit::Ptr unit, const ProjectPart::Ptr &part);
|
|
||||||
|
|
||||||
bool isTracking(const QString &fileName) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void indexingStarted(QFuture<void> future);
|
|
||||||
void indexingFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class IndexerPrivate;
|
|
||||||
QScopedPointer<IndexerPrivate> m_d;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // ClangCodeModel
|
|
||||||
|
|
||||||
#endif // INDEXER_H
|
|
@@ -1,81 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PCHINFO_H
|
|
||||||
#define PCHINFO_H
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QTemporaryFile>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class PchInfo
|
|
||||||
{
|
|
||||||
PchInfo();
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef QSharedPointer<PchInfo> Ptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
~PchInfo();
|
|
||||||
|
|
||||||
static Ptr createEmpty();
|
|
||||||
static Ptr createWithFileName(const QString &inputFileName,
|
|
||||||
const QStringList &options, bool objcEnabled);
|
|
||||||
|
|
||||||
/// \return the (temporary) file name for the PCH file.
|
|
||||||
QString fileName() const
|
|
||||||
{ return m_file.fileName(); }
|
|
||||||
|
|
||||||
/// \return the input file for the PCH compilation.
|
|
||||||
QString inputFileName() const
|
|
||||||
{ return m_inputFileName; }
|
|
||||||
|
|
||||||
/// \return the options used to generate this PCH file.
|
|
||||||
QStringList options() const
|
|
||||||
{ return m_options; }
|
|
||||||
|
|
||||||
bool objcWasEnabled() const
|
|
||||||
{ return m_objcEnabled; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_inputFileName;
|
|
||||||
QStringList m_options;
|
|
||||||
bool m_objcEnabled;
|
|
||||||
QTemporaryFile m_file;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Internal namespace
|
|
||||||
} // ClangCodeModel namespace
|
|
||||||
|
|
||||||
#endif // PCHINFO_H
|
|
@@ -1,448 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "pchmanager.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "clangutils.h"
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <utils/runextensions.h>
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
using namespace CPlusPlus;
|
|
||||||
|
|
||||||
PchManager *PchManager::m_instance = 0;
|
|
||||||
|
|
||||||
PchManager::PchManager(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
Q_ASSERT(!m_instance);
|
|
||||||
m_instance = this;
|
|
||||||
|
|
||||||
QObject *msgMgr = Core::MessageManager::instance();
|
|
||||||
connect(this, SIGNAL(pchMessage(QString,Core::MessageManager::PrintToOutputPaneFlags)),
|
|
||||||
msgMgr, SLOT(write(QString,Core::MessageManager::PrintToOutputPaneFlags)));
|
|
||||||
|
|
||||||
connect(&m_pchGenerationWatcher, SIGNAL(finished()),
|
|
||||||
this, SLOT(updateActivePchFiles()));
|
|
||||||
}
|
|
||||||
|
|
||||||
PchManager::~PchManager()
|
|
||||||
{
|
|
||||||
Q_ASSERT(m_instance);
|
|
||||||
m_instance = 0;
|
|
||||||
qDeleteAll(m_projectSettings.values());
|
|
||||||
m_projectSettings.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
PchManager *PchManager::instance()
|
|
||||||
{
|
|
||||||
return m_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
PchInfo::Ptr PchManager::pchInfo(const ProjectPart::Ptr &projectPart) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
return m_activePchFiles[projectPart];
|
|
||||||
}
|
|
||||||
|
|
||||||
ClangProjectSettings *PchManager::settingsForProject(ProjectExplorer::Project *project)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
ClangProjectSettings *cps = m_projectSettings.value(project);
|
|
||||||
if (!cps) {
|
|
||||||
cps = new ClangProjectSettings(project);
|
|
||||||
m_projectSettings.insert(project, cps);
|
|
||||||
cps->pullSettings();
|
|
||||||
connect(cps, SIGNAL(pchSettingsChanged()),
|
|
||||||
this, SLOT(clangProjectSettingsChanged()));
|
|
||||||
}
|
|
||||||
return cps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::setPCHInfo(const QList<ProjectPart::Ptr> &projectParts,
|
|
||||||
const PchInfo::Ptr &pchInfo,
|
|
||||||
const QPair<bool, QStringList> &msgs)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
foreach (ProjectPart::Ptr pPart, projectParts)
|
|
||||||
m_activePchFiles[pPart] = pchInfo;
|
|
||||||
|
|
||||||
if (pchInfo) {
|
|
||||||
if (msgs.first) {
|
|
||||||
if (!pchInfo->fileName().isEmpty())
|
|
||||||
emit pchMessage(tr("Successfully generated PCH file \"%1\".").arg(
|
|
||||||
pchInfo->fileName()), Core::MessageManager::Silent);
|
|
||||||
} else {
|
|
||||||
emit pchMessage(tr("Failed to generate PCH file \"%1\".").arg(
|
|
||||||
pchInfo->fileName()), Core::MessageManager::Silent);
|
|
||||||
}
|
|
||||||
if (!msgs.second.isEmpty())
|
|
||||||
emit pchMessage(msgs.second.join(QLatin1Char('\n')), Core::MessageManager::Flash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::clangProjectSettingsChanged()
|
|
||||||
{
|
|
||||||
ClangProjectSettings *cps = qobject_cast<ClangProjectSettings *>(sender());
|
|
||||||
if (!cps)
|
|
||||||
return;
|
|
||||||
|
|
||||||
onProjectPartsUpdated(cps->project());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
|
|
||||||
{
|
|
||||||
Q_UNUSED(project);
|
|
||||||
|
|
||||||
// we cannot ask the ModelManager for the parts, because, depending on
|
|
||||||
// the order of signal delivery, it might already have wiped any information
|
|
||||||
// about the project.
|
|
||||||
|
|
||||||
updateActivePchFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::onProjectPartsUpdated(ProjectExplorer::Project *project)
|
|
||||||
{
|
|
||||||
ClangProjectSettings *cps = settingsForProject(project);
|
|
||||||
Q_ASSERT(cps);
|
|
||||||
|
|
||||||
CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance();
|
|
||||||
const QList<ProjectPart::Ptr> projectParts = mmi->projectInfo(
|
|
||||||
cps->project()).projectParts();
|
|
||||||
updatePchInfo(cps, projectParts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::updatePchInfo(ClangProjectSettings *cps,
|
|
||||||
const QList<ProjectPart::Ptr> &projectParts)
|
|
||||||
{
|
|
||||||
if (m_pchGenerationWatcher.isRunning()) {
|
|
||||||
m_pchGenerationWatcher.waitForFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString customPchFile = cps->customPchFile();
|
|
||||||
const ClangProjectSettings::PchUsage pchUsage = cps->pchUsage();
|
|
||||||
|
|
||||||
void (*updateFunction)(QFutureInterface<void> &future,
|
|
||||||
const PchManager::UpdateParams params) = 0;
|
|
||||||
QString message;
|
|
||||||
if (pchUsage == ClangProjectSettings::PchUse_None
|
|
||||||
|| (pchUsage == ClangProjectSettings::PchUse_Custom && customPchFile.isEmpty())) {
|
|
||||||
updateFunction = &PchManager::doPchInfoUpdateNone;
|
|
||||||
message = QLatin1String("updatePchInfo: switching to none");
|
|
||||||
} else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Fuzzy) {
|
|
||||||
updateFunction = &PchManager::doPchInfoUpdateFuzzy;
|
|
||||||
message = QLatin1String("updatePchInfo: switching to build system (fuzzy)");
|
|
||||||
} else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Exact) {
|
|
||||||
updateFunction = &PchManager::doPchInfoUpdateExact;
|
|
||||||
message = QLatin1String("updatePchInfo: switching to build system (exact)");
|
|
||||||
} else if (pchUsage == ClangProjectSettings::PchUse_Custom) {
|
|
||||||
updateFunction = &PchManager::doPchInfoUpdateCustom;
|
|
||||||
message = QLatin1String("updatePchInfo: switching to custom") + customPchFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(updateFunction && !message.isEmpty(), return);
|
|
||||||
|
|
||||||
Core::MessageManager::write(message, Core::MessageManager::Silent);
|
|
||||||
QFuture<void> future = QtConcurrent::run(updateFunction,
|
|
||||||
UpdateParams(customPchFile, projectParts));
|
|
||||||
m_pchGenerationWatcher.setFuture(future);
|
|
||||||
Core::ProgressManager::addTask(future, tr("Precompiling"), "Key.Tmp.Precompiling");
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
bool hasObjCFiles(const CppTools::ProjectPart::Ptr &projectPart)
|
|
||||||
{
|
|
||||||
foreach (const CppTools::ProjectFile &file, projectPart->files) {
|
|
||||||
switch (file.kind) {
|
|
||||||
case CppTools::ProjectFile::ObjCHeader:
|
|
||||||
case CppTools::ProjectFile::ObjCSource:
|
|
||||||
case CppTools::ProjectFile::ObjCXXHeader:
|
|
||||||
case CppTools::ProjectFile::ObjCXXSource:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasCppFiles(const CppTools::ProjectPart::Ptr &projectPart)
|
|
||||||
{
|
|
||||||
foreach (const CppTools::ProjectFile &file, projectPart->files) {
|
|
||||||
switch (file.kind) {
|
|
||||||
case CppTools::ProjectFile::CudaSource:
|
|
||||||
case CppTools::ProjectFile::CXXHeader:
|
|
||||||
case CppTools::ProjectFile::CXXSource:
|
|
||||||
case CppTools::ProjectFile::OpenCLSource:
|
|
||||||
case CppTools::ProjectFile::ObjCXXHeader:
|
|
||||||
case CppTools::ProjectFile::ObjCXXSource:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CppTools::ProjectFile::Kind getPrefixFileKind(bool hasObjectiveC, bool hasCPlusPlus)
|
|
||||||
{
|
|
||||||
if (hasObjectiveC && hasCPlusPlus)
|
|
||||||
return CppTools::ProjectFile::ObjCXXHeader;
|
|
||||||
else if (hasObjectiveC)
|
|
||||||
return CppTools::ProjectFile::ObjCHeader;
|
|
||||||
else if (hasCPlusPlus)
|
|
||||||
return CppTools::ProjectFile::CXXHeader;
|
|
||||||
return CppTools::ProjectFile::CHeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::doPchInfoUpdateNone(QFutureInterface<void> &future,
|
|
||||||
const PchManager::UpdateParams params)
|
|
||||||
{
|
|
||||||
future.setProgressRange(0, 1);
|
|
||||||
PchInfo::Ptr emptyPch = PchInfo::createEmpty();
|
|
||||||
PchManager::instance()->setPCHInfo(params.projectParts, emptyPch,
|
|
||||||
qMakePair(true, QStringList()));
|
|
||||||
future.setProgressValue(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
|
|
||||||
const PchManager::UpdateParams params)
|
|
||||||
{
|
|
||||||
typedef ProjectPart::HeaderPath HeaderPath;
|
|
||||||
QHash<QString, QSet<HeaderPath>> headers;
|
|
||||||
QHash<QString, QSet<QByteArray> > definesPerPCH;
|
|
||||||
QHash<QString, bool> objc;
|
|
||||||
QHash<QString, bool> cplusplus;
|
|
||||||
QHash<QString, ProjectPart::QtVersion> qtVersions;
|
|
||||||
QHash<QString, ProjectPart::LanguageVersion> languageVersions;
|
|
||||||
QHash<QString, ProjectPart::LanguageExtensions> languageExtensionsMap;
|
|
||||||
QHash<QString, QList<ProjectPart::Ptr> > inputToParts;
|
|
||||||
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
|
|
||||||
if (projectPart->precompiledHeaders.isEmpty())
|
|
||||||
continue;
|
|
||||||
const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file.
|
|
||||||
if (!QFile(pch).exists())
|
|
||||||
continue;
|
|
||||||
inputToParts[pch].append(projectPart);
|
|
||||||
|
|
||||||
headers[pch].unite(QSet<HeaderPath>::fromList(projectPart->headerPaths));
|
|
||||||
languageVersions[pch] = std::max(languageVersions.value(pch, ProjectPart::C89),
|
|
||||||
projectPart->languageVersion);
|
|
||||||
languageExtensionsMap[pch] = languageExtensionsMap[pch] | projectPart->languageExtensions;
|
|
||||||
|
|
||||||
if (hasObjCFiles(projectPart))
|
|
||||||
objc[pch] = true;
|
|
||||||
if (hasCppFiles(projectPart))
|
|
||||||
cplusplus[pch] = true;
|
|
||||||
|
|
||||||
QSet<QByteArray> projectDefines = QSet<QByteArray>::fromList(projectPart->toolchainDefines.split('\n'));
|
|
||||||
QMutableSetIterator<QByteArray> iter(projectDefines);
|
|
||||||
while (iter.hasNext()){
|
|
||||||
QByteArray v = iter.next();
|
|
||||||
if (v.startsWith("#define _") || v.isEmpty()) // TODO: see ProjectPart::createClangOptions
|
|
||||||
iter.remove();
|
|
||||||
}
|
|
||||||
projectDefines.unite(QSet<QByteArray>::fromList(projectPart->projectDefines.split('\n')));
|
|
||||||
|
|
||||||
if (definesPerPCH.contains(pch)) {
|
|
||||||
definesPerPCH[pch].intersect(projectDefines);
|
|
||||||
} else {
|
|
||||||
definesPerPCH[pch] = projectDefines;
|
|
||||||
}
|
|
||||||
|
|
||||||
qtVersions[pch] = projectPart->qtVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
future.setProgressRange(0, definesPerPCH.size() + 1);
|
|
||||||
future.setProgressValue(0);
|
|
||||||
|
|
||||||
foreach (const QString &pch, inputToParts.keys()) {
|
|
||||||
if (future.isCanceled())
|
|
||||||
return;
|
|
||||||
ProjectPart::Ptr projectPart(new ProjectPart);
|
|
||||||
projectPart->qtVersion = qtVersions[pch];
|
|
||||||
projectPart->languageVersion = languageVersions[pch];
|
|
||||||
projectPart->languageExtensions = languageExtensionsMap[pch];
|
|
||||||
projectPart->headerPaths = headers[pch].toList();
|
|
||||||
projectPart->updateLanguageFeatures();
|
|
||||||
|
|
||||||
QList<QByteArray> defines = definesPerPCH[pch].toList();
|
|
||||||
if (!defines.isEmpty()) {
|
|
||||||
projectPart->projectDefines = defines[0];
|
|
||||||
for (int i = 1; i < defines.size(); ++i) {
|
|
||||||
projectPart->projectDefines += '\n';
|
|
||||||
projectPart->projectDefines += defines[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CppTools::ProjectFile::Kind prefixFileKind =
|
|
||||||
getPrefixFileKind(objc.value(pch, false), cplusplus.value(pch, false));
|
|
||||||
|
|
||||||
QStringList options = Utils::createClangOptions(projectPart, prefixFileKind);
|
|
||||||
projectPart.clear();
|
|
||||||
|
|
||||||
PchManager *pchManager = PchManager::instance();
|
|
||||||
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, true);
|
|
||||||
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());
|
|
||||||
if (pchInfo.isNull()) {
|
|
||||||
|
|
||||||
pchInfo = PchInfo::createWithFileName(pch, options, objc[pch]);
|
|
||||||
msgs = precompile(pchInfo);
|
|
||||||
}
|
|
||||||
pchManager->setPCHInfo(inputToParts[pch], pchInfo, msgs);
|
|
||||||
future.setProgressValue(future.progressValue() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
future.setProgressValue(future.progressValue() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::doPchInfoUpdateExact(QFutureInterface<void> &future,
|
|
||||||
const PchManager::UpdateParams params)
|
|
||||||
{
|
|
||||||
future.setProgressRange(0, params.projectParts.size() + 1);
|
|
||||||
future.setProgressValue(0);
|
|
||||||
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
|
|
||||||
if (future.isCanceled())
|
|
||||||
return;
|
|
||||||
if (projectPart->precompiledHeaders.isEmpty())
|
|
||||||
continue;
|
|
||||||
const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file.
|
|
||||||
if (!QFile(pch).exists())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const bool hasObjC = hasObjCFiles(projectPart);
|
|
||||||
QStringList options = Utils::createClangOptions(
|
|
||||||
projectPart, getPrefixFileKind(hasObjC, hasCppFiles(projectPart)));
|
|
||||||
|
|
||||||
PchManager *pchManager = PchManager::instance();
|
|
||||||
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, false);
|
|
||||||
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());
|
|
||||||
if (pchInfo.isNull()) {
|
|
||||||
pchInfo = PchInfo::createWithFileName(pch, options, hasObjC);
|
|
||||||
msgs = precompile(pchInfo);
|
|
||||||
}
|
|
||||||
pchManager->setPCHInfo(QList<ProjectPart::Ptr>() << projectPart,
|
|
||||||
pchInfo, msgs);
|
|
||||||
future.setProgressValue(future.progressValue() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
future.setProgressValue(future.progressValue() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::doPchInfoUpdateCustom(QFutureInterface<void> &future,
|
|
||||||
const PchManager::UpdateParams params)
|
|
||||||
{
|
|
||||||
future.setProgressRange(0, 1);
|
|
||||||
future.setProgressValue(0);
|
|
||||||
|
|
||||||
ProjectPart::HeaderPaths headers;
|
|
||||||
bool objc = false;
|
|
||||||
bool cplusplus = false;
|
|
||||||
ProjectPart::Ptr united(new ProjectPart());
|
|
||||||
united->languageVersion = ProjectPart::C89;
|
|
||||||
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
|
|
||||||
headers += projectPart->headerPaths;
|
|
||||||
united->languageVersion = std::max(united->languageVersion, projectPart->languageVersion);
|
|
||||||
united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion);
|
|
||||||
objc |= hasObjCFiles(projectPart);
|
|
||||||
cplusplus |= hasCppFiles(projectPart);
|
|
||||||
}
|
|
||||||
united->updateLanguageFeatures();
|
|
||||||
united->headerPaths = headers;
|
|
||||||
QStringList opts = Utils::createClangOptions(
|
|
||||||
united, getPrefixFileKind(objc, cplusplus));
|
|
||||||
united.clear();
|
|
||||||
|
|
||||||
PchManager *pchManager = PchManager::instance();
|
|
||||||
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(params.customPchFile, opts, true);
|
|
||||||
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());;
|
|
||||||
if (future.isCanceled())
|
|
||||||
return;
|
|
||||||
if (pchInfo.isNull()) {
|
|
||||||
pchInfo = PchInfo::createWithFileName(params.customPchFile, opts, objc);
|
|
||||||
msgs = precompile(pchInfo);
|
|
||||||
}
|
|
||||||
pchManager->setPCHInfo(params.projectParts, pchInfo, msgs);
|
|
||||||
future.setProgressValue(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
PchInfo::Ptr PchManager::findMatchingPCH(const QString &inputFileName,
|
|
||||||
const QStringList &options,
|
|
||||||
bool fuzzyMatching) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
if (fuzzyMatching) {
|
|
||||||
QStringList opts = options;
|
|
||||||
opts.sort();
|
|
||||||
foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values()) {
|
|
||||||
if (pchInfo->inputFileName() != inputFileName)
|
|
||||||
continue;
|
|
||||||
QStringList pchOpts = pchInfo->options();
|
|
||||||
pchOpts.sort();
|
|
||||||
if (pchOpts == opts)
|
|
||||||
return pchInfo;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values())
|
|
||||||
if (pchInfo->inputFileName() == inputFileName
|
|
||||||
&& pchInfo->options() == options)
|
|
||||||
return pchInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PchInfo::Ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PchManager::updateActivePchFiles()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
|
|
||||||
QSet<ProjectPart::Ptr> activeParts;
|
|
||||||
CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance();
|
|
||||||
foreach (const CppTools::ProjectInfo &pi, mmi->projectInfos())
|
|
||||||
activeParts.unite(QSet<ProjectPart::Ptr>::fromList(pi.projectParts()));
|
|
||||||
QList<ProjectPart::Ptr> partsWithPCHFiles = m_activePchFiles.keys();
|
|
||||||
foreach (ProjectPart::Ptr pPart, partsWithPCHFiles)
|
|
||||||
if (!activeParts.contains(pPart))
|
|
||||||
m_activePchFiles.remove(pPart);
|
|
||||||
}
|
|
@@ -1,109 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PCHMANAGER_H
|
|
||||||
#define PCHMANAGER_H
|
|
||||||
|
|
||||||
#include "clangprojectsettings.h"
|
|
||||||
#include "pchinfo.h"
|
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
|
||||||
#include <projectexplorer/project.h>
|
|
||||||
#include <coreplugin/messagemanager.h>
|
|
||||||
|
|
||||||
#include <QFutureWatcher>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class PchManager : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
typedef CppTools::ProjectPart ProjectPart;
|
|
||||||
|
|
||||||
static PchManager *m_instance;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PchManager(QObject *parent = 0);
|
|
||||||
virtual ~PchManager();
|
|
||||||
|
|
||||||
static PchManager *instance();
|
|
||||||
|
|
||||||
PchInfo::Ptr pchInfo(const ProjectPart::Ptr &projectPart) const;
|
|
||||||
ClangProjectSettings *settingsForProject(ProjectExplorer::Project *project);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void pchMessage(const QString &message, Core::MessageManager::PrintToOutputPaneFlags flags);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void clangProjectSettingsChanged();
|
|
||||||
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
|
||||||
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateActivePchFiles();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct UpdateParams {
|
|
||||||
UpdateParams(const QString &customPchFile, const QList<ProjectPart::Ptr> &projectParts)
|
|
||||||
: customPchFile(customPchFile) , projectParts(projectParts) {}
|
|
||||||
const QString customPchFile;
|
|
||||||
const QList<ProjectPart::Ptr> projectParts;
|
|
||||||
};
|
|
||||||
|
|
||||||
void updatePchInfo(ClangProjectSettings *cps,
|
|
||||||
const QList<ProjectPart::Ptr> &projectParts);
|
|
||||||
|
|
||||||
static void doPchInfoUpdateNone(QFutureInterface<void> &future, const UpdateParams params);
|
|
||||||
static void doPchInfoUpdateFuzzy(QFutureInterface<void> &future, const UpdateParams params);
|
|
||||||
static void doPchInfoUpdateExact(QFutureInterface<void> &future, const UpdateParams params);
|
|
||||||
static void doPchInfoUpdateCustom(QFutureInterface<void> &future, const UpdateParams params);
|
|
||||||
|
|
||||||
void setPCHInfo(const QList<ProjectPart::Ptr> &projectParts,
|
|
||||||
const PchInfo::Ptr &pchInfo,
|
|
||||||
const QPair<bool, QStringList> &msgs);
|
|
||||||
PchInfo::Ptr findMatchingPCH(const QString &inputFileName, const QStringList &options,
|
|
||||||
bool fuzzyMatching) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable QMutex m_mutex;
|
|
||||||
QHash<ProjectPart::Ptr, PchInfo::Ptr> m_activePchFiles;
|
|
||||||
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;
|
|
||||||
QFutureWatcher<void> m_pchGenerationWatcher;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
#endif // PCHMANAGER_H
|
|
@@ -1,104 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "scopedclangoptions.h"
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class ClangCodeModel::ScopedClangOptions
|
|
||||||
* @brief Converts QStringList to raw options, acceptable by clang-c parsing and indexing API
|
|
||||||
*/
|
|
||||||
|
|
||||||
ScopedClangOptions::ScopedClangOptions(const QStringList &options)
|
|
||||||
: m_size(options.size())
|
|
||||||
, m_rawOptions(new const char*[options.size()])
|
|
||||||
{
|
|
||||||
for (int i = 0 ; i < m_size; ++i)
|
|
||||||
m_rawOptions[i] = qstrdup(options[i].toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedClangOptions::~ScopedClangOptions()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_size; ++i)
|
|
||||||
delete[] m_rawOptions[i];
|
|
||||||
delete[] m_rawOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char **ScopedClangOptions::data() const
|
|
||||||
{
|
|
||||||
return m_rawOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScopedClangOptions::size() const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class ClangCodeModel::SharedClangOptions
|
|
||||||
* @brief Shared wrapper around \a {ClangCodeModel::ScopedClangOptions} ScopedClangOptions
|
|
||||||
*/
|
|
||||||
|
|
||||||
SharedClangOptions::SharedClangOptions()
|
|
||||||
: d(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedClangOptions::SharedClangOptions(const QStringList &options)
|
|
||||||
: d(new ScopedClangOptions(options))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Replaces options with new options list
|
|
||||||
*/
|
|
||||||
void SharedClangOptions::reloadOptions(const QStringList &options)
|
|
||||||
{
|
|
||||||
d = QSharedPointer<ScopedClangOptions>(new ScopedClangOptions(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pointer to clang raw options or NULL if uninitialized
|
|
||||||
*/
|
|
||||||
const char **SharedClangOptions::data() const
|
|
||||||
{
|
|
||||||
return d ? d->data() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Options count or 0 if uninitialized
|
|
||||||
*/
|
|
||||||
int SharedClangOptions::size() const
|
|
||||||
{
|
|
||||||
return d ? d->size() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
|
@@ -1,531 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "semanticmarker.h"
|
|
||||||
#include "unit.h"
|
|
||||||
#include "utils_p.h"
|
|
||||||
#include "cxraii.h"
|
|
||||||
|
|
||||||
#include <utils/mimetypes/mimedatabase.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
using namespace ClangCodeModel::Internal;
|
|
||||||
|
|
||||||
static const unsigned ATTACHED_NOTES_LIMIT = 10;
|
|
||||||
|
|
||||||
SemanticMarker::SemanticMarker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SemanticMarker::~SemanticMarker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SemanticMarker::fileName() const
|
|
||||||
{
|
|
||||||
if (!m_unit)
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
return m_unit->fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SemanticMarker::setFileName(const QString &fileName)
|
|
||||||
{
|
|
||||||
if (this->fileName() == fileName)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QStringList oldOptions;
|
|
||||||
if (m_unit)
|
|
||||||
oldOptions = m_unit->compilationOptions();
|
|
||||||
m_unit = Unit::create(fileName);
|
|
||||||
if (!oldOptions.isEmpty())
|
|
||||||
m_unit->setCompilationOptions(oldOptions);
|
|
||||||
|
|
||||||
unsigned clangOpts = clang_defaultEditingTranslationUnitOptions();
|
|
||||||
clangOpts |= CXTranslationUnit_DetailedPreprocessingRecord;
|
|
||||||
clangOpts |= CXTranslationUnit_Incomplete;
|
|
||||||
clangOpts &= ~CXTranslationUnit_CacheCompletionResults;
|
|
||||||
m_unit->setManagementOptions(clangOpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SemanticMarker::setCompilationOptions(const QStringList &options)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_unit, return);
|
|
||||||
|
|
||||||
if (m_unit->compilationOptions() == options)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_unit->setCompilationOptions(options);
|
|
||||||
m_unit->unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SemanticMarker::reparse(const UnsavedFiles &unsavedFiles)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_unit, return);
|
|
||||||
|
|
||||||
m_unit->setUnsavedFiles(unsavedFiles);
|
|
||||||
if (m_unit->isLoaded())
|
|
||||||
m_unit->reparse();
|
|
||||||
else
|
|
||||||
m_unit->parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Calculate one or several ranges and append diagnostic for each range
|
|
||||||
* Extracted from SemanticMarker::diagnostics() to reuse code
|
|
||||||
*/
|
|
||||||
static void appendDiagnostic(const CXDiagnostic &diag,
|
|
||||||
const CXSourceLocation &cxLocation,
|
|
||||||
Diagnostic::Severity severity,
|
|
||||||
const QString &spelling,
|
|
||||||
QList<Diagnostic> &diagnostics)
|
|
||||||
{
|
|
||||||
const unsigned rangeCount = clang_getDiagnosticNumRanges(diag);
|
|
||||||
bool expandLocation = true;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < rangeCount; ++i) {
|
|
||||||
CXSourceRange r = clang_getDiagnosticRange(diag, i);
|
|
||||||
const SourceLocation &spellBegin = Internal::getSpellingLocation(clang_getRangeStart(r));
|
|
||||||
const SourceLocation &spellEnd = Internal::getSpellingLocation(clang_getRangeEnd(r));
|
|
||||||
unsigned length = spellEnd.offset() - spellBegin.offset();
|
|
||||||
|
|
||||||
// File name can be empty due clang bug
|
|
||||||
if (!spellBegin.fileName().isEmpty()) {
|
|
||||||
Diagnostic d(severity, spellBegin, length, spelling);
|
|
||||||
diagnostics.append(d);
|
|
||||||
expandLocation = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expandLocation) {
|
|
||||||
const SourceLocation &location = Internal::getExpansionLocation(cxLocation);
|
|
||||||
Diagnostic d(severity, location, 0, spelling);
|
|
||||||
diagnostics.append(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isBlackListedDiagnostic(const Utils::MimeType &mimeType, const QString &diagnostic)
|
|
||||||
{
|
|
||||||
static const QStringList blackList {
|
|
||||||
QLatin1String("#pragma once in main file"),
|
|
||||||
QLatin1String("#include_next in primary source file")
|
|
||||||
};
|
|
||||||
|
|
||||||
return mimeType.inherits(QLatin1String("text/x-chdr")) && blackList.contains(diagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Diagnostic> SemanticMarker::diagnostics() const
|
|
||||||
{
|
|
||||||
QList<Diagnostic> diagnostics;
|
|
||||||
if (!m_unit || !m_unit->isLoaded())
|
|
||||||
return diagnostics;
|
|
||||||
|
|
||||||
Utils::MimeDatabase mimeDatabase;
|
|
||||||
const Utils::MimeType mimeType = mimeDatabase.mimeTypeForFile(fileName());
|
|
||||||
|
|
||||||
const unsigned diagCount = m_unit->getNumDiagnostics();
|
|
||||||
for (unsigned i = 0; i < diagCount; ++i) {
|
|
||||||
ScopedCXDiagnostic diag(m_unit->getDiagnostic(i));
|
|
||||||
|
|
||||||
Diagnostic::Severity severity = static_cast<Diagnostic::Severity>(clang_getDiagnosticSeverity(diag));
|
|
||||||
if (severity == Diagnostic::Ignored || severity == Diagnostic::Note)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CXSourceLocation cxLocation = clang_getDiagnosticLocation(diag);
|
|
||||||
QString spelling = Internal::getQString(clang_getDiagnosticSpelling(diag));
|
|
||||||
|
|
||||||
if (isBlackListedDiagnostic(mimeType, spelling))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Attach messages with Diagnostic::Note severity
|
|
||||||
ScopedCXDiagnosticSet cxChildren(clang_getChildDiagnostics(diag));
|
|
||||||
const unsigned numChildren = clang_getNumDiagnosticsInSet(cxChildren);
|
|
||||||
const unsigned size = qMin(ATTACHED_NOTES_LIMIT, numChildren);
|
|
||||||
for (unsigned di = 0; di < size; ++di) {
|
|
||||||
ScopedCXDiagnostic child(clang_getDiagnosticInSet(cxChildren, di));
|
|
||||||
|
|
||||||
const Diagnostic::Severity severity
|
|
||||||
= static_cast<Diagnostic::Severity>(clang_getDiagnosticSeverity(child));
|
|
||||||
if (severity == Diagnostic::Ignored || severity == Diagnostic::Note)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
spelling.append(QLatin1String("\n "));
|
|
||||||
spelling.append(Internal::getQString(clang_getDiagnosticSpelling(child)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatal error may occur in another file, but it breaks whole parsing
|
|
||||||
// Typical fatal error is unresolved #include
|
|
||||||
if (severity == Diagnostic::Fatal) {
|
|
||||||
for (unsigned di = 0; di < numChildren; ++di) {
|
|
||||||
ScopedCXDiagnostic child(clang_getDiagnosticInSet(cxChildren, di));
|
|
||||||
appendDiagnostic(child, clang_getDiagnosticLocation(child), Diagnostic::Warning, spelling, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appendDiagnostic(diag, cxLocation, severity, spelling, diagnostics);
|
|
||||||
}
|
|
||||||
|
|
||||||
return diagnostics;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<SemanticMarker::Range> SemanticMarker::ifdefedOutBlocks() const
|
|
||||||
{
|
|
||||||
QList<Range> blocks;
|
|
||||||
|
|
||||||
if (!m_unit || !m_unit->isLoaded())
|
|
||||||
return blocks;
|
|
||||||
|
|
||||||
#if CINDEX_VERSION_MINOR >= 21
|
|
||||||
CXSourceRangeList *skippedRanges = clang_getSkippedRanges(m_unit->clangTranslationUnit(),
|
|
||||||
m_unit->getFile());
|
|
||||||
blocks.reserve(skippedRanges->count);
|
|
||||||
for (unsigned i = 0; i < skippedRanges->count; ++i) {
|
|
||||||
const CXSourceRange &r = skippedRanges->ranges[i];
|
|
||||||
const SourceLocation &spellBegin = Internal::getSpellingLocation(clang_getRangeStart(r));
|
|
||||||
if (spellBegin.fileName() != fileName())
|
|
||||||
continue;
|
|
||||||
const SourceLocation &spellEnd = Internal::getSpellingLocation(clang_getRangeEnd(r));
|
|
||||||
const int begin = spellBegin.offset() + 1;
|
|
||||||
const int end = spellEnd.offset() - spellEnd.column();
|
|
||||||
blocks.append(Range(begin, end));
|
|
||||||
}
|
|
||||||
clang_disposeSourceRangeList(skippedRanges);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
static void add(QList<SourceMarker> &markers,
|
|
||||||
const CXSourceRange &extent,
|
|
||||||
SourceMarker::Kind kind)
|
|
||||||
{
|
|
||||||
CXSourceLocation start = clang_getRangeStart(extent);
|
|
||||||
CXSourceLocation end = clang_getRangeEnd(extent);
|
|
||||||
const SourceLocation &location = Internal::getExpansionLocation(start);
|
|
||||||
const SourceLocation &locationEnd = Internal::getExpansionLocation(end);
|
|
||||||
|
|
||||||
if (location.offset() < locationEnd.offset()) {
|
|
||||||
const unsigned length = locationEnd.offset() - location.offset();
|
|
||||||
markers.append(SourceMarker(location, length, kind));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Selects correct highlighting for cursor that is reference
|
|
||||||
* @return SourceMarker::Unknown if cannot select highlighting
|
|
||||||
*/
|
|
||||||
static SourceMarker::Kind getKindByReferencedCursor(const CXCursor &cursor)
|
|
||||||
{
|
|
||||||
const CXCursor referenced = clang_getCursorReferenced(cursor);
|
|
||||||
switch (clang_getCursorKind(referenced)) {
|
|
||||||
case CXCursor_EnumConstantDecl:
|
|
||||||
return SourceMarker::Enumeration;
|
|
||||||
|
|
||||||
case CXCursor_FieldDecl:
|
|
||||||
case CXCursor_ObjCIvarDecl:
|
|
||||||
case CXCursor_ObjCPropertyDecl:
|
|
||||||
return SourceMarker::Field;
|
|
||||||
|
|
||||||
case CXCursor_FunctionDecl:
|
|
||||||
case CXCursor_FunctionTemplate:
|
|
||||||
case CXCursor_Constructor:
|
|
||||||
return SourceMarker::Function;
|
|
||||||
|
|
||||||
case CXCursor_VarDecl:
|
|
||||||
case CXCursor_ParmDecl:
|
|
||||||
case CXCursor_NonTypeTemplateParameter:
|
|
||||||
return SourceMarker::Local;
|
|
||||||
|
|
||||||
case CXCursor_CXXMethod:
|
|
||||||
if (clang_CXXMethod_isVirtual(referenced))
|
|
||||||
return SourceMarker::VirtualMethod;
|
|
||||||
else
|
|
||||||
return SourceMarker::Function;
|
|
||||||
|
|
||||||
case CXCursor_ObjCClassMethodDecl:
|
|
||||||
case CXCursor_ObjCInstanceMethodDecl:
|
|
||||||
// calling method as property, e.h. "layer.shouldRasterize = YES"
|
|
||||||
return SourceMarker::Field;
|
|
||||||
|
|
||||||
case CXCursor_UnexposedDecl:
|
|
||||||
// NSObject "self" method which is a pseudo keyword
|
|
||||||
if (clang_getCursorLanguage(referenced) == CXLanguage_ObjC)
|
|
||||||
return SourceMarker::PseudoKeyword;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return SourceMarker::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const QSet<QString> ObjcPseudoKeywords = QSet<QString>()
|
|
||||||
<< QLatin1String("end")
|
|
||||||
<< QLatin1String("try")
|
|
||||||
<< QLatin1String("defs")
|
|
||||||
<< QLatin1String("throw")
|
|
||||||
<< QLatin1String("class")
|
|
||||||
<< QLatin1String("catch")
|
|
||||||
<< QLatin1String("encode")
|
|
||||||
<< QLatin1String("public")
|
|
||||||
<< QLatin1String("dynamic")
|
|
||||||
<< QLatin1String("finally")
|
|
||||||
<< QLatin1String("package")
|
|
||||||
<< QLatin1String("private")
|
|
||||||
<< QLatin1String("optional")
|
|
||||||
<< QLatin1String("property")
|
|
||||||
<< QLatin1String("protocol")
|
|
||||||
<< QLatin1String("required")
|
|
||||||
<< QLatin1String("selector")
|
|
||||||
<< QLatin1String("interface")
|
|
||||||
<< QLatin1String("protected")
|
|
||||||
<< QLatin1String("synthesize")
|
|
||||||
<< QLatin1String("not_keyword")
|
|
||||||
<< QLatin1String("synchronized")
|
|
||||||
<< QLatin1String("implementation")
|
|
||||||
<< QLatin1String("compatibility_alias")
|
|
||||||
;
|
|
||||||
|
|
||||||
} // Anonymous namespace
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief SemanticMarker::sourceMarkersInRange
|
|
||||||
* @param firstLine - first line where to generate highlighting markers
|
|
||||||
* @param lastLine - last line where to generate highlighting markers
|
|
||||||
*
|
|
||||||
* There still two kinds of problems:
|
|
||||||
* - clang_annotateTokens() can return wrong cursor, and it's normal behavior
|
|
||||||
* - some cases no handled
|
|
||||||
*
|
|
||||||
* Problems caused by wrong cursors:
|
|
||||||
* - range-based for from C++ 2011
|
|
||||||
* - identifiers in some compound statements have type DeclStmt
|
|
||||||
* or CompoundStmt which refers to top-level construction.
|
|
||||||
* - CXCursor_ObjCIvarDecl mapped to field, but instance variable have
|
|
||||||
* incorrect cursor kind if it declared in private interface
|
|
||||||
* @interface MyApplication() {
|
|
||||||
* NSArray* _items;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Missed cases:
|
|
||||||
* - global variables highlighted as locals
|
|
||||||
* - appropriate marker had not been selected for listed cursors:
|
|
||||||
* CXCursor_ObjCProtocolExpr, CXCursor_ObjCEncodeExpr,
|
|
||||||
* CXCursor_ObjCDynamicDecl, CXCursor_ObjCBridgedCastExpr,
|
|
||||||
* CXCursor_ObjCSuperClassRef
|
|
||||||
* - template members of template classes&functions always highlighted
|
|
||||||
* as members, even if they are functions - no way to differ found.
|
|
||||||
* - @1, @{}, @[]
|
|
||||||
*/
|
|
||||||
QList<SourceMarker> SemanticMarker::sourceMarkersInRange(unsigned firstLine,
|
|
||||||
unsigned lastLine)
|
|
||||||
{
|
|
||||||
QList<SourceMarker> result;
|
|
||||||
|
|
||||||
if (!m_unit || !m_unit->isLoaded())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Highlighting called asynchronously, and a few lines at the end can be deleted for this time.
|
|
||||||
CXSourceRange unitRange = clang_getCursorExtent(m_unit->getTranslationUnitCursor());
|
|
||||||
SourceLocation unitEnd = getExpansionLocation(clang_getRangeEnd(unitRange));
|
|
||||||
if (lastLine > unitEnd.line())
|
|
||||||
lastLine = unitEnd.line();
|
|
||||||
|
|
||||||
if (firstLine > lastLine)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
IdentifierTokens idTokens(*m_unit, firstLine, lastLine);
|
|
||||||
|
|
||||||
const CXSourceRange *atTokenExtent = 0;
|
|
||||||
for (unsigned i = 0; i < idTokens.count(); ++i) {
|
|
||||||
const CXToken &tok = idTokens.token(i);
|
|
||||||
CXTokenKind kind = clang_getTokenKind(tok);
|
|
||||||
if (atTokenExtent) {
|
|
||||||
if (CXToken_Literal == kind) {
|
|
||||||
if (m_unit->getTokenSpelling(tok).startsWith(QLatin1Char('"')))
|
|
||||||
add(result, *atTokenExtent, SourceMarker::ObjCString);
|
|
||||||
atTokenExtent = 0;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
add(result, *atTokenExtent, SourceMarker::PseudoKeyword);
|
|
||||||
atTokenExtent = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CXSourceRange &tokenExtent = idTokens.extent(i);
|
|
||||||
|
|
||||||
if (CXToken_Keyword == kind) {
|
|
||||||
QString spell = m_unit->getTokenSpelling(tok);
|
|
||||||
if (ObjcPseudoKeywords.contains(spell))
|
|
||||||
add(result, tokenExtent, SourceMarker::PseudoKeyword);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CXToken_Punctuation == kind) {
|
|
||||||
static const QLatin1String at("@");
|
|
||||||
if (m_unit->getTokenSpelling(tok) == at)
|
|
||||||
atTokenExtent = &tokenExtent;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CXToken_Identifier != kind)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const CXCursor &cursor = idTokens.cursor(i);
|
|
||||||
const CXCursorKind cursorKind = clang_getCursorKind(cursor);
|
|
||||||
if (clang_isInvalid(cursorKind))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (cursorKind) {
|
|
||||||
case CXCursor_EnumConstantDecl:
|
|
||||||
add(result, tokenExtent, SourceMarker::Enumeration);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_ClassDecl:
|
|
||||||
case CXCursor_UnionDecl:
|
|
||||||
case CXCursor_ClassTemplate:
|
|
||||||
case CXCursor_ClassTemplatePartialSpecialization:
|
|
||||||
case CXCursor_EnumDecl:
|
|
||||||
case CXCursor_Namespace:
|
|
||||||
case CXCursor_NamespaceRef:
|
|
||||||
case CXCursor_NamespaceAlias:
|
|
||||||
case CXCursor_StructDecl:
|
|
||||||
case CXCursor_TemplateRef:
|
|
||||||
case CXCursor_TypeRef:
|
|
||||||
case CXCursor_TypedefDecl:
|
|
||||||
case CXCursor_Constructor:
|
|
||||||
case CXCursor_TemplateTypeParameter:
|
|
||||||
case CXCursor_TemplateTemplateParameter:
|
|
||||||
case CXCursor_UnexposedDecl: /* friend class MyClass; */
|
|
||||||
add(result, tokenExtent, SourceMarker::Type);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_ParmDecl:
|
|
||||||
case CXCursor_VariableRef:
|
|
||||||
case CXCursor_VarDecl:
|
|
||||||
case CXCursor_NonTypeTemplateParameter:
|
|
||||||
add(result, tokenExtent, SourceMarker::Local);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_MemberRefExpr:
|
|
||||||
case CXCursor_MemberRef:
|
|
||||||
case CXCursor_DeclRefExpr:
|
|
||||||
case CXCursor_CallExpr: {
|
|
||||||
SourceMarker::Kind kind = getKindByReferencedCursor(cursor);
|
|
||||||
if (kind == SourceMarker::Unknown && cursorKind == CXCursor_MemberRefExpr) {
|
|
||||||
/* template class member in template function */
|
|
||||||
kind = SourceMarker::Field;
|
|
||||||
}
|
|
||||||
if (kind != SourceMarker::Unknown)
|
|
||||||
add(result, tokenExtent, kind);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case CXCursor_FieldDecl:
|
|
||||||
add(result, tokenExtent, SourceMarker::Field);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_Destructor:
|
|
||||||
case CXCursor_CXXMethod: {
|
|
||||||
if (clang_CXXMethod_isVirtual(cursor))
|
|
||||||
add(result, tokenExtent, SourceMarker::VirtualMethod);
|
|
||||||
else
|
|
||||||
add(result, tokenExtent, SourceMarker::Function);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case CXCursor_CXXOverrideAttr:
|
|
||||||
case CXCursor_CXXFinalAttr:
|
|
||||||
case CXCursor_AnnotateAttr: // 'annotate' in '__attribute__((annotate("AnyComment")))'
|
|
||||||
case CXCursor_UnexposedAttr: // 'align' in '__declspec(align(8))'
|
|
||||||
add(result, tokenExtent, SourceMarker::PseudoKeyword);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_FunctionDecl:
|
|
||||||
case CXCursor_FunctionTemplate:
|
|
||||||
case CXCursor_OverloadedDeclRef:
|
|
||||||
add(result, tokenExtent, SourceMarker::Function);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_ObjCInstanceMethodDecl:
|
|
||||||
case CXCursor_ObjCClassMethodDecl:
|
|
||||||
case CXCursor_ObjCSelectorExpr:
|
|
||||||
add(result, tokenExtent, SourceMarker::ObjectiveCMessage);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_ObjCMessageExpr: {
|
|
||||||
static const QLatin1String super("super");
|
|
||||||
if (m_unit->getTokenSpelling(tok) == super)
|
|
||||||
add(result, tokenExtent, SourceMarker::PseudoKeyword);
|
|
||||||
else
|
|
||||||
add(result, tokenExtent, SourceMarker::ObjectiveCMessage);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case CXCursor_ObjCCategoryDecl:
|
|
||||||
case CXCursor_ObjCCategoryImplDecl:
|
|
||||||
case CXCursor_ObjCImplementationDecl:
|
|
||||||
case CXCursor_ObjCInterfaceDecl:
|
|
||||||
case CXCursor_ObjCProtocolDecl:
|
|
||||||
case CXCursor_ObjCProtocolRef:
|
|
||||||
case CXCursor_ObjCClassRef:
|
|
||||||
case CXCursor_ObjCSuperClassRef:
|
|
||||||
case CXCursor_TypeAliasDecl: // C++11 type alias: 'using value_t = T'
|
|
||||||
add(result, tokenExtent, SourceMarker::Type);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_ObjCSynthesizeDecl:
|
|
||||||
case CXCursor_ObjCDynamicDecl:
|
|
||||||
case CXCursor_ObjCPropertyDecl:
|
|
||||||
case CXCursor_ObjCIvarDecl:
|
|
||||||
add(result, tokenExtent, SourceMarker::Field);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_MacroDefinition:
|
|
||||||
case CXCursor_MacroExpansion:
|
|
||||||
add(result, tokenExtent, SourceMarker::Macro);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CXCursor_LabelRef:
|
|
||||||
case CXCursor_LabelStmt:
|
|
||||||
add(result, tokenExtent, SourceMarker::Label);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Unit::Ptr SemanticMarker::unit() const
|
|
||||||
{
|
|
||||||
return m_unit;
|
|
||||||
}
|
|
@@ -1,95 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CLANG_SEMANTICMARKER_H
|
|
||||||
#define CLANG_SEMANTICMARKER_H
|
|
||||||
|
|
||||||
#include "clang_global.h"
|
|
||||||
#include "diagnostic.h"
|
|
||||||
#include "fastindexer.h"
|
|
||||||
#include "sourcemarker.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QScopedPointer>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
class CLANG_EXPORT SemanticMarker
|
|
||||||
{
|
|
||||||
Q_DISABLE_COPY(SemanticMarker)
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef QSharedPointer<SemanticMarker> Ptr;
|
|
||||||
|
|
||||||
class Range
|
|
||||||
{
|
|
||||||
Range();
|
|
||||||
public:
|
|
||||||
Range(int first, int last) : first(first), last(last) {}
|
|
||||||
|
|
||||||
int first;
|
|
||||||
int last;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
SemanticMarker();
|
|
||||||
~SemanticMarker();
|
|
||||||
|
|
||||||
QMutex *mutex() const
|
|
||||||
{ return &m_mutex; }
|
|
||||||
|
|
||||||
QString fileName() const;
|
|
||||||
void setFileName(const QString &fileName);
|
|
||||||
|
|
||||||
void setCompilationOptions(const QStringList &options);
|
|
||||||
|
|
||||||
void reparse(const Internal::UnsavedFiles &unsavedFiles);
|
|
||||||
|
|
||||||
QList<Diagnostic> diagnostics() const;
|
|
||||||
|
|
||||||
QList<Range> ifdefedOutBlocks() const;
|
|
||||||
|
|
||||||
QList<SourceMarker> sourceMarkersInRange(unsigned firstLine,
|
|
||||||
unsigned lastLine);
|
|
||||||
|
|
||||||
Internal::Unit::Ptr unit() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable QMutex m_mutex;
|
|
||||||
Internal::Unit::Ptr m_unit;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ClangCodeModel
|
|
||||||
|
|
||||||
#endif // CLANG_SEMANTICMARKER_H
|
|
@@ -1,80 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "sourcelocation.h"
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
|
|
||||||
SourceLocation::SourceLocation()
|
|
||||||
: m_line(0)
|
|
||||||
, m_column(0)
|
|
||||||
, m_offset(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SourceLocation::SourceLocation(const QString &fileName,
|
|
||||||
unsigned line,
|
|
||||||
unsigned column,
|
|
||||||
unsigned offset)
|
|
||||||
: m_fileName(fileName)
|
|
||||||
, m_line(line)
|
|
||||||
, m_column(column)
|
|
||||||
, m_offset(offset)
|
|
||||||
{}
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
bool operator==(const SourceLocation &a, const SourceLocation &b)
|
|
||||||
{
|
|
||||||
return a.line() == b.line()
|
|
||||||
&& a.column() == b.column()
|
|
||||||
&& a.offset() == b.offset()
|
|
||||||
&& a.fileName() == b.fileName()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const SourceLocation &a, const SourceLocation &b)
|
|
||||||
{
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const SourceLocation &location)
|
|
||||||
{
|
|
||||||
dbg.nospace() << location.fileName()
|
|
||||||
<< " ["
|
|
||||||
<< location.line()
|
|
||||||
<< ":"
|
|
||||||
<< location.column()
|
|
||||||
<< "("
|
|
||||||
<< location.offset()
|
|
||||||
<< ")]";
|
|
||||||
return dbg.space();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // ClangCodeModel
|
|
@@ -1,70 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SOURCELOCATION_H
|
|
||||||
#define SOURCELOCATION_H
|
|
||||||
|
|
||||||
#include "clang_global.h"
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
|
||||||
|
|
||||||
class CLANG_EXPORT SourceLocation
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SourceLocation();
|
|
||||||
SourceLocation(const QString &fileName,
|
|
||||||
unsigned line = 0,
|
|
||||||
unsigned column = 0,
|
|
||||||
unsigned offset = 0);
|
|
||||||
|
|
||||||
bool isNull() const { return m_fileName.isEmpty(); }
|
|
||||||
const QString &fileName() const { return m_fileName; }
|
|
||||||
unsigned line() const { return m_line; }
|
|
||||||
unsigned column() const { return m_column; }
|
|
||||||
unsigned offset() const { return m_offset; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_fileName;
|
|
||||||
unsigned m_line;
|
|
||||||
unsigned m_column;
|
|
||||||
unsigned m_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const SourceLocation &a, const SourceLocation &b);
|
|
||||||
bool operator!=(const SourceLocation &a, const SourceLocation &b);
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const SourceLocation &location);
|
|
||||||
|
|
||||||
} // ClangCodeModel
|
|
||||||
|
|
||||||
#endif // SOURCELOCATION_H
|
|
@@ -1,42 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "sourcemarker.h"
|
|
||||||
|
|
||||||
using namespace ClangCodeModel;
|
|
||||||
|
|
||||||
SourceMarker::SourceMarker()
|
|
||||||
: m_length(0), m_kind(Unknown)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SourceMarker::SourceMarker(const SourceLocation &location, unsigned length, Kind kind)
|
|
||||||
: m_loc(location), m_length(length), m_kind(kind)
|
|
||||||
{
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user