forked from qt-creator/qt-creator
Clang: Remove dead code
Change-Id: Ia36e96424580d9b34000cf4a9b38eab98f9c449c Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
@@ -5,7 +5,7 @@ LIBS += $$LLVM_LIBS
|
||||
INCLUDEPATH += $$LLVM_INCLUDEPATH
|
||||
DEFINES += CLANGCODEMODEL_LIBRARY
|
||||
|
||||
# The following defines are used to determine the clang include path for intrinsics
|
||||
# The following defines are used to determine the clang include path for intrinsics.
|
||||
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
|
||||
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\""
|
||||
|
||||
@@ -33,26 +33,15 @@ SOURCES += \
|
||||
clangmodelmanagersupport.cpp \
|
||||
clangprojectsettings.cpp \
|
||||
clangprojectsettingspropertiespage.cpp \
|
||||
clangsymbol.cpp \
|
||||
clangtextmark.cpp \
|
||||
clangutils.cpp \
|
||||
completionchunkstotextconverter.cpp \
|
||||
cppcreatemarkers.cpp \
|
||||
cxprettyprinter.cpp \
|
||||
diagnostic.cpp \
|
||||
fastindexer.cpp \
|
||||
highlightingmarksreporter.cpp \
|
||||
pchinfo.cpp \
|
||||
pchmanager.cpp \
|
||||
raii/scopedclangoptions.cpp \
|
||||
semanticmarker.cpp \
|
||||
sourcelocation.cpp \
|
||||
sourcemarker.cpp \
|
||||
unit.cpp \
|
||||
unsavedfiledata.cpp \
|
||||
utils.cpp \
|
||||
utils_p.cpp
|
||||
|
||||
unsavedfiledata.cpp
|
||||
|
||||
HEADERS += \
|
||||
activationsequencecontextprocessor.h \
|
||||
@@ -77,42 +66,16 @@ HEADERS += \
|
||||
clangmodelmanagersupport.h \
|
||||
clangprojectsettings.h \
|
||||
clangprojectsettingspropertiespage.h \
|
||||
clangsymbol.h \
|
||||
clangtextmark.h \
|
||||
clangutils.h \
|
||||
completionchunkstotextconverter.h \
|
||||
constants.h \
|
||||
cppcreatemarkers.h \
|
||||
cxprettyprinter.h \
|
||||
cxraii.h \
|
||||
diagnostic.h \
|
||||
fastindexer.h \
|
||||
highlightingmarksreporter.h \
|
||||
pchinfo.h \
|
||||
pchmanager.h \
|
||||
raii/scopedclangoptions.h \
|
||||
semanticmarker.h \
|
||||
sourcelocation.h \
|
||||
sourcemarker.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 \
|
||||
}
|
||||
unsavedfiledata.h
|
||||
|
||||
FORMS += clangprojectsettingspropertiespage.ui
|
||||
|
||||
|
@@ -20,10 +20,6 @@ QtcPlugin {
|
||||
"QmakeProjectManager",
|
||||
]
|
||||
|
||||
property bool clangCompletion: true
|
||||
property bool clangHighlighting: true
|
||||
property bool clangIndexing: false
|
||||
|
||||
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader)
|
||||
property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
|
||||
property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
|
||||
@@ -39,67 +35,77 @@ QtcPlugin {
|
||||
|
||||
cpp.defines: {
|
||||
var defines = base;
|
||||
// The following defines are used to determine the clang include path for intrinsics.
|
||||
defines.push('CLANG_VERSION="' + llvmVersion + '"');
|
||||
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;
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Completion support"
|
||||
condition: product.clangCompletion
|
||||
files: [
|
||||
"activationsequencecontextprocessor.cpp",
|
||||
"activationsequencecontextprocessor.h",
|
||||
"activationsequenceprocessor.cpp",
|
||||
"activationsequenceprocessor.h",
|
||||
"clangassistproposal.cpp",
|
||||
"clangassistproposal.h",
|
||||
"clangassistproposalitem.cpp",
|
||||
"clangassistproposalitem.h",
|
||||
"clangassistproposalmodel.cpp",
|
||||
"clangassistproposalmodel.h",
|
||||
"clangcompletionassistinterface.cpp",
|
||||
"clangcompletionassistinterface.h",
|
||||
"clangcompletionassistprocessor.cpp",
|
||||
"clangcompletionassistprocessor.h",
|
||||
"clangcompletionassistprovider.cpp",
|
||||
"clangcompletionassistprovider.h",
|
||||
"clangfunctionhintmodel.cpp",
|
||||
"clangfunctionhintmodel.h",
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Highlighting support"
|
||||
condition: product.clangHighlighting
|
||||
files: [
|
||||
"cppcreatemarkers.cpp",
|
||||
"cppcreatemarkers.h",
|
||||
"highlightingmarksreporter.cpp",
|
||||
"highlightingmarksreporter.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"
|
||||
]
|
||||
}
|
||||
files: [
|
||||
"activationsequencecontextprocessor.cpp",
|
||||
"activationsequencecontextprocessor.h",
|
||||
"activationsequenceprocessor.cpp",
|
||||
"activationsequenceprocessor.h",
|
||||
"clangassistproposal.cpp",
|
||||
"clangassistproposal.h",
|
||||
"clangassistproposalitem.cpp",
|
||||
"clangassistproposalitem.h",
|
||||
"clangassistproposalmodel.cpp",
|
||||
"clangassistproposalmodel.h",
|
||||
"clangbackendipcintegration.cpp",
|
||||
"clangbackendipcintegration.h",
|
||||
"clangcodemodelplugin.cpp",
|
||||
"clangcodemodelplugin.h",
|
||||
"clangcompletionassistinterface.cpp",
|
||||
"clangcompletionassistinterface.h",
|
||||
"clangcompletionassistprocessor.cpp",
|
||||
"clangcompletionassistprocessor.h",
|
||||
"clangcompletionassistprovider.cpp",
|
||||
"clangcompletionassistprovider.h",
|
||||
"clangcompletioncontextanalyzer.cpp",
|
||||
"clangcompletioncontextanalyzer.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.h",
|
||||
"clang_global.h",
|
||||
"clangmodelmanagersupport.cpp",
|
||||
"clangmodelmanagersupport.h",
|
||||
"clangprojectsettings.cpp",
|
||||
"clangprojectsettings.h",
|
||||
"clangprojectsettingspropertiespage.cpp",
|
||||
"clangprojectsettingspropertiespage.h",
|
||||
"clangprojectsettingspropertiespage.ui",
|
||||
"clangtextmark.cpp",
|
||||
"clangtextmark.h",
|
||||
"clangutils.cpp",
|
||||
"clangutils.h",
|
||||
"completionchunkstotextconverter.cpp",
|
||||
"completionchunkstotextconverter.h",
|
||||
"constants.h",
|
||||
"highlightingmarksreporter.cpp",
|
||||
"highlightingmarksreporter.h",
|
||||
"pchinfo.cpp",
|
||||
"pchinfo.h",
|
||||
"pchmanager.cpp",
|
||||
"pchmanager.h",
|
||||
"raii/scopedclangoptions.cpp",
|
||||
"raii/scopedclangoptions.h",
|
||||
"unit.cpp",
|
||||
"unit.h",
|
||||
"unsavedfiledata.cpp",
|
||||
"unsavedfiledata.h",
|
||||
]
|
||||
|
||||
Group {
|
||||
name: "Tests"
|
||||
@@ -119,69 +125,4 @@ QtcPlugin {
|
||||
files: [ "*" ]
|
||||
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",
|
||||
"clangsymbol.cpp",
|
||||
"clangsymbol.h",
|
||||
"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",
|
||||
"unit.cpp",
|
||||
"unit.h",
|
||||
"unsavedfiledata.cpp",
|
||||
"unsavedfiledata.h",
|
||||
"utils.cpp",
|
||||
"utils.h",
|
||||
"utils_p.cpp",
|
||||
"utils_p.h",
|
||||
"raii/scopedclangoptions.cpp",
|
||||
"raii/scopedclangoptions.h",
|
||||
]
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include "clangprojectsettingspropertiespage.h"
|
||||
#include "constants.h"
|
||||
#include "pchmanager.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
# include "test/clangcodecompletion_test.h"
|
||||
@@ -47,10 +46,14 @@
|
||||
|
||||
#include <texteditor/textmark.h>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static void initializeTextMarks()
|
||||
namespace {
|
||||
|
||||
void initializeTextMarks()
|
||||
{
|
||||
TextEditor::TextMark::setCategoryColor(Core::Id(Constants::CLANG_WARNING),
|
||||
Utils::Theme::ClangCodeModel_Warning_TextMarkColor);
|
||||
@@ -58,6 +61,25 @@ static void initializeTextMarks()
|
||||
Utils::Theme::ClangCodeModel_Error_TextMarkColor);
|
||||
}
|
||||
|
||||
static bool clangInitialised = false;
|
||||
static QMutex initialisationMutex;
|
||||
|
||||
void initializeClang()
|
||||
{
|
||||
if (clangInitialised)
|
||||
return;
|
||||
|
||||
QMutexLocker locker(&initialisationMutex);
|
||||
if (clangInitialised)
|
||||
return;
|
||||
|
||||
clang_toggleCrashRecovery(1);
|
||||
clang_enableStackTraces();
|
||||
clangInitialised = true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
{
|
||||
Q_UNUSED(arguments)
|
||||
@@ -73,18 +95,12 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
|
||||
// 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);
|
||||
auto cppModelManager = CppTools::CppModelManager::instance();
|
||||
connect(cppModelManager, &CppTools::CppModelManager::projectPartsUpdated,
|
||||
pchManager, &PchManager::onProjectPartsUpdated);
|
||||
|
||||
|
@@ -33,14 +33,8 @@
|
||||
|
||||
#include "clangmodelmanagersupport.h"
|
||||
|
||||
#ifdef CLANG_INDEXING
|
||||
# include "clangindexer.h"
|
||||
#endif // CLANG_INDEXING
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
@@ -55,9 +49,6 @@ public:
|
||||
|
||||
private:
|
||||
ModelManagerSupportProviderClang m_modelManagerSupportProvider;
|
||||
#ifdef CLANG_INDEXING
|
||||
QScopedPointer<ClangIndexer> m_indexer;
|
||||
#endif // CLANG_INDEXING
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
QList<QObject *> createTestObjects() const;
|
||||
|
@@ -94,7 +94,7 @@ IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const
|
||||
return m_ipcCommunicator;
|
||||
}
|
||||
|
||||
const UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const
|
||||
const Utils::UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const
|
||||
{
|
||||
return m_unsavedFiles;
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "clangbackendipcintegration.h"
|
||||
#include "pchinfo.h"
|
||||
#include "utils.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <cpptools/cppcompletionassistprovider.h>
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
const CPlusPlus::LanguageFeatures &features);
|
||||
|
||||
IpcCommunicator &ipcCommunicator() const;
|
||||
const UnsavedFiles &unsavedFiles() const;
|
||||
const Utils::UnsavedFiles &unsavedFiles() const;
|
||||
bool objcEnabled() const;
|
||||
const CppTools::ProjectPart::HeaderPaths &headerPaths() const;
|
||||
CPlusPlus::LanguageFeatures languageFeatures() const;
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
private:
|
||||
IpcCommunicator &m_ipcCommunicator;
|
||||
UnsavedFiles m_unsavedFiles;
|
||||
Utils::UnsavedFiles m_unsavedFiles;
|
||||
QStringList m_options;
|
||||
CppTools::ProjectPart::HeaderPaths m_headerPaths;
|
||||
Internal::PchInfo::Ptr m_savedPchPointer;
|
||||
|
@@ -34,8 +34,6 @@
|
||||
#include "clangfixitoperationsextractor.h"
|
||||
#include "clangmodelmanagersupport.h"
|
||||
#include "clangutils.h"
|
||||
#include "cppcreatemarkers.h"
|
||||
#include "diagnostic.h"
|
||||
#include "highlightingmarksreporter.h"
|
||||
#include "pchinfo.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
|
@@ -1,118 +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 "clangsymbol.h"
|
||||
|
||||
#include <cplusplus/Icons.h>
|
||||
|
||||
using namespace ClangCodeModel;
|
||||
|
||||
Symbol::Symbol()
|
||||
: m_kind(Unknown)
|
||||
{}
|
||||
|
||||
Symbol::Symbol(const QString &name,
|
||||
const QString &qualification,
|
||||
Kind type,
|
||||
const SourceLocation &location)
|
||||
: m_name(name)
|
||||
, m_qualification(qualification)
|
||||
, m_location(location)
|
||||
, m_kind(type)
|
||||
{}
|
||||
|
||||
QIcon Symbol::iconForSymbol() const
|
||||
{
|
||||
CPlusPlus::Icons icons;
|
||||
switch (m_kind) {
|
||||
case Enum:
|
||||
return icons.iconForType(CPlusPlus::Icons::EnumIconType);
|
||||
case Class:
|
||||
return icons.iconForType(CPlusPlus::Icons::ClassIconType);
|
||||
case Method:
|
||||
case Function:
|
||||
case Declaration:
|
||||
case Constructor:
|
||||
case Destructor:
|
||||
return icons.iconForType(CPlusPlus::Icons::FuncPublicIconType);
|
||||
default:
|
||||
return icons.iconForType(CPlusPlus::Icons::UnknownIconType);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ClangCodeModel {
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const Symbol &symbol)
|
||||
{
|
||||
stream << symbol.m_name
|
||||
<< symbol.m_qualification
|
||||
<< symbol.m_location.fileName()
|
||||
<< (quint32)symbol.m_location.line()
|
||||
<< (quint16)symbol.m_location.column()
|
||||
<< (quint32)symbol.m_location.offset()
|
||||
<< (qint8)symbol.m_kind;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &stream, Symbol &symbol)
|
||||
{
|
||||
QString fileName;
|
||||
quint32 line;
|
||||
quint16 column;
|
||||
quint32 offset;
|
||||
quint8 kind;
|
||||
stream >> symbol.m_name
|
||||
>> symbol.m_qualification
|
||||
>> fileName
|
||||
>> line
|
||||
>> column
|
||||
>> offset
|
||||
>> kind;
|
||||
symbol.m_location = SourceLocation(fileName, line, column, offset);
|
||||
symbol.m_kind = Symbol::Kind(kind);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool operator==(const Symbol &a, const Symbol &b)
|
||||
{
|
||||
return a.m_name == b.m_name
|
||||
&& a.m_qualification == b.m_qualification
|
||||
&& a.m_location == b.m_location
|
||||
&& a.m_kind == b.m_kind;
|
||||
}
|
||||
|
||||
bool operator!=(const Symbol &a, const Symbol &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
} // ClangCodeModel
|
@@ -1,78 +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 INDEXEDSYMBOLINFO_H
|
||||
#define INDEXEDSYMBOLINFO_H
|
||||
|
||||
#include "sourcelocation.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDataStream>
|
||||
#include <QIcon>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
|
||||
class Symbol
|
||||
{
|
||||
public:
|
||||
enum Kind {
|
||||
Enum,
|
||||
Class,
|
||||
Method, // A member-function.
|
||||
Function, // A free-function (global or within a namespace).
|
||||
Declaration,
|
||||
Constructor,
|
||||
Destructor,
|
||||
Unknown
|
||||
};
|
||||
|
||||
Symbol();
|
||||
Symbol(const QString &name,
|
||||
const QString &qualification,
|
||||
Kind type,
|
||||
const SourceLocation &location);
|
||||
|
||||
QString m_name;
|
||||
QString m_qualification;
|
||||
SourceLocation m_location;
|
||||
Kind m_kind;
|
||||
|
||||
QIcon iconForSymbol() const;
|
||||
};
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const Symbol &symbol);
|
||||
QDataStream &operator>>(QDataStream &stream, Symbol &symbol);
|
||||
|
||||
bool operator==(const Symbol &a, const Symbol &b);
|
||||
bool operator!=(const Symbol &a, const Symbol &b);
|
||||
|
||||
} // Clang
|
||||
|
||||
#endif // INDEXEDSYMBOLINFO_H
|
@@ -32,7 +32,6 @@
|
||||
#define CPPTOOLS_CLANGUTILS_H
|
||||
|
||||
#include "clang_global.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
|
||||
@@ -41,11 +40,12 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Utils {
|
||||
|
||||
typedef QMap<QString, QByteArray> UnsavedFiles;
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
||||
|
||||
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(
|
||||
const CppTools::WorkingCopy &workingCopy,
|
||||
const ::Utils::FileNameList &modifiedFiles);
|
||||
UnsavedFiles createUnsavedFiles(const CppTools::WorkingCopy &workingCopy,
|
||||
const ::Utils::FileNameList &modifiedFiles);
|
||||
|
||||
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||
CppTools::ProjectFile::Kind fileKind);
|
||||
|
@@ -31,35 +31,14 @@
|
||||
#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";
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Constants
|
||||
} // namespace ClangCodeModel
|
||||
|
||||
#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,83 +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_DIAGNOSTIC_H
|
||||
#define CLANG_DIAGNOSTIC_H
|
||||
|
||||
#include "clang_global.h"
|
||||
#include "sourcelocation.h"
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
|
||||
class CLANG_EXPORT Diagnostic
|
||||
{
|
||||
public:
|
||||
enum Severity {
|
||||
Unknown = -1,
|
||||
Ignored = 0,
|
||||
Note = 1,
|
||||
Warning = 2,
|
||||
Error = 3,
|
||||
Fatal = 4
|
||||
};
|
||||
|
||||
public:
|
||||
Diagnostic();
|
||||
Diagnostic(Severity severity, const SourceLocation &location, unsigned length, const QString &spelling);
|
||||
|
||||
Severity severity() const
|
||||
{ return m_severity; }
|
||||
|
||||
const QString severityAsString() const;
|
||||
|
||||
const SourceLocation &location() const
|
||||
{ return m_loc; }
|
||||
|
||||
unsigned length() const
|
||||
{ return m_length; }
|
||||
|
||||
const QString &spelling() const
|
||||
{ return m_spelling; }
|
||||
|
||||
private:
|
||||
Severity m_severity;
|
||||
SourceLocation m_loc;
|
||||
unsigned m_length;
|
||||
QString m_spelling;
|
||||
};
|
||||
|
||||
} // namespace ClangCodeModel
|
||||
|
||||
Q_DECLARE_METATYPE(ClangCodeModel::Diagnostic)
|
||||
Q_DECLARE_METATYPE(QList<ClangCodeModel::Diagnostic>)
|
||||
|
||||
#endif // CLANG_DIAGNOSTIC_H
|
@@ -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,50 +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 FASTINDEXER_H
|
||||
#define FASTINDEXER_H
|
||||
|
||||
#include "unit.h"
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
class FastIndexer
|
||||
{
|
||||
public:
|
||||
virtual ~FastIndexer() = 0;
|
||||
|
||||
virtual void indexNow(Unit::Ptr unit) = 0;
|
||||
};
|
||||
|
||||
} // Internal namespace
|
||||
} // ClangCodeModel namespace
|
||||
|
||||
#endif // FASTINDEXER_H
|
@@ -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 "clangsymbol.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 "clangsymbol.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
|
@@ -29,7 +29,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "pchmanager.h"
|
||||
#include "utils.h"
|
||||
#include "unit.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -44,6 +44,70 @@ using namespace ClangCodeModel;
|
||||
using namespace ClangCodeModel::Internal;
|
||||
using namespace CPlusPlus;
|
||||
|
||||
namespace {
|
||||
|
||||
QString getQString(const CXString &cxString, bool disposeCXString = true)
|
||||
{
|
||||
QString s = QString::fromUtf8(clang_getCString(cxString));
|
||||
if (disposeCXString)
|
||||
clang_disposeString(cxString);
|
||||
return s;
|
||||
}
|
||||
|
||||
QStringList formattedDiagnostics(const Unit::Ptr &unit)
|
||||
{
|
||||
QStringList diags;
|
||||
if (!unit->isLoaded())
|
||||
return diags;
|
||||
|
||||
const unsigned count = unit->getNumDiagnostics();
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
CXDiagnostic diag = unit->getDiagnostic(i);
|
||||
|
||||
unsigned opt = CXDiagnostic_DisplaySourceLocation
|
||||
| CXDiagnostic_DisplayColumn
|
||||
| CXDiagnostic_DisplaySourceRanges
|
||||
| CXDiagnostic_DisplayOption
|
||||
| CXDiagnostic_DisplayCategoryId
|
||||
| CXDiagnostic_DisplayCategoryName
|
||||
;
|
||||
diags << getQString(clang_formatDiagnostic(diag, opt));
|
||||
clang_disposeDiagnostic(diag);
|
||||
}
|
||||
|
||||
return diags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to create a PCH file from a header file.
|
||||
*
|
||||
* \returns a boolean indicating success (true) or failure (false), and a
|
||||
* list of diagnostic messages.
|
||||
*/
|
||||
QPair<bool, QStringList> precompile(const PchInfo::Ptr &pchInfo)
|
||||
{
|
||||
// qDebug() << "*** Precompiling" << pchInfo->inputFileName()
|
||||
// << "into" << pchInfo->fileName()
|
||||
// << "with options" << pchInfo->options();
|
||||
|
||||
bool ok = false;
|
||||
|
||||
Unit::Ptr unit = Unit::create(pchInfo->inputFileName());
|
||||
unit->setCompilationOptions(pchInfo->options());
|
||||
|
||||
unsigned parseOpts = CXTranslationUnit_ForSerialization
|
||||
| CXTranslationUnit_Incomplete;
|
||||
unit->setManagementOptions(parseOpts);
|
||||
|
||||
unit->parse();
|
||||
if (unit->isLoaded())
|
||||
ok = CXSaveError_None == unit->save(pchInfo->fileName());
|
||||
|
||||
return qMakePair(ok, formattedDiagnostics(unit));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
PchManager *PchManager::m_instance = 0;
|
||||
|
||||
PchManager::PchManager(QObject *parent)
|
||||
|
@@ -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)
|
||||
{
|
||||
}
|
@@ -1,98 +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_SOURCEMARKER_H
|
||||
#define CLANG_SOURCEMARKER_H
|
||||
|
||||
#include "clang_global.h"
|
||||
#include "sourcelocation.h"
|
||||
|
||||
namespace ClangCodeModel {
|
||||
|
||||
class CLANG_EXPORT SourceMarker
|
||||
{
|
||||
public: // TODO: remove this, it's about the same as the TextEditor::SemanticHighlighter::Result
|
||||
enum Kind {
|
||||
Unknown = 0,
|
||||
Type = 1,
|
||||
Local,
|
||||
Field,
|
||||
Enumeration,
|
||||
VirtualMethod,
|
||||
Label,
|
||||
Macro,
|
||||
Function,
|
||||
PseudoKeyword,
|
||||
ObjCString,
|
||||
|
||||
ObjectiveCMessage = VirtualMethod
|
||||
};
|
||||
|
||||
SourceMarker();
|
||||
SourceMarker(const SourceLocation &location,
|
||||
unsigned length,
|
||||
Kind kind);
|
||||
|
||||
bool isValid() const
|
||||
{ return m_loc.line() != 0; }
|
||||
|
||||
bool isInvalid() const
|
||||
{ return m_loc.line() == 0; }
|
||||
|
||||
const SourceLocation &location() const
|
||||
{ return m_loc; }
|
||||
|
||||
unsigned length() const
|
||||
{ return m_length; }
|
||||
|
||||
Kind kind() const
|
||||
{ return m_kind; }
|
||||
|
||||
bool lessThan(const SourceMarker &other) const
|
||||
{
|
||||
if (m_loc.line() != other.m_loc.line())
|
||||
return m_loc.line() < other.m_loc.line();
|
||||
if (m_loc.column() != other.m_loc.column())
|
||||
return m_loc.column() < other.m_loc.column();
|
||||
return m_length < other.m_length;
|
||||
}
|
||||
|
||||
private:
|
||||
SourceLocation m_loc;
|
||||
unsigned m_length;
|
||||
Kind m_kind;
|
||||
};
|
||||
|
||||
CLANG_EXPORT inline bool operator<(const SourceMarker &one, const SourceMarker &two)
|
||||
{ return one.lessThan(two); }
|
||||
|
||||
} // namespace Clang
|
||||
|
||||
#endif // CLANG_SOURCEMARKER_H
|
@@ -179,7 +179,7 @@ bool writeFile(const QString &filePath, const QByteArray &contents)
|
||||
void insertTextAtTopOfEditor(TextEditor::BaseTextEditor *editor, const QByteArray &text)
|
||||
{
|
||||
QTC_ASSERT(editor, return);
|
||||
Utils::ChangeSet cs;
|
||||
::Utils::ChangeSet cs;
|
||||
cs.insert(0, QString::fromUtf8(text));
|
||||
QTextCursor textCursor = editor->textCursor();
|
||||
cs.apply(&textCursor);
|
||||
@@ -1099,7 +1099,7 @@ void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderByRefactor
|
||||
|
||||
// Modify header document without switching to its editor.
|
||||
// This simulates e.g. changes from refactoring actions.
|
||||
Utils::ChangeSet cs;
|
||||
::Utils::ChangeSet cs;
|
||||
cs.insert(0, QLatin1String("int globalFromHeaderUnsaved;\n"));
|
||||
QTextCursor textCursor = openHeader.editor()->textCursor();
|
||||
cs.apply(&textCursor);
|
||||
|
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "clangutils.h"
|
||||
#include "unsavedfiledata.h"
|
||||
#include "utils_p.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
@@ -105,12 +104,12 @@ void Unit::setCompilationOptions(const QStringList &compOptions)
|
||||
m_sharedCompOptions.reloadOptions(compOptions);
|
||||
}
|
||||
|
||||
UnsavedFiles Unit::unsavedFiles() const
|
||||
ClangCodeModel::Utils::UnsavedFiles Unit::unsavedFiles() const
|
||||
{
|
||||
return m_unsaved;
|
||||
}
|
||||
|
||||
void Unit::setUnsavedFiles(const UnsavedFiles &unsavedFiles)
|
||||
void Unit::setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles)
|
||||
{
|
||||
m_unsaved = unsavedFiles;
|
||||
}
|
||||
@@ -189,20 +188,6 @@ CXSourceLocation Unit::getLocation(const CXFile &file, unsigned line, unsigned c
|
||||
return clang_getLocation(m_tu, file, line, column);
|
||||
}
|
||||
|
||||
void Unit::codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results)
|
||||
{
|
||||
unsigned flags = clang_defaultCodeCompleteOptions();
|
||||
#if defined(CINDEX_VERSION) && (CINDEX_VERSION > 5)
|
||||
flags |= CXCodeComplete_IncludeBriefComments;
|
||||
#endif
|
||||
|
||||
UnsavedFileData unsaved(m_unsaved);
|
||||
results.reset(clang_codeCompleteAt(m_tu, m_fileName.constData(),
|
||||
line, column,
|
||||
unsaved.files(), unsaved.count(),
|
||||
flags));
|
||||
}
|
||||
|
||||
void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const
|
||||
{
|
||||
Q_ASSERT(isLoaded());
|
||||
@@ -250,13 +235,6 @@ CXIndex Unit::clangIndex() const
|
||||
return m_index;
|
||||
}
|
||||
|
||||
QString Unit::getTokenSpelling(const CXToken &tok) const
|
||||
{
|
||||
Q_ASSERT(isLoaded());
|
||||
|
||||
return getQString(clang_getTokenSpelling(m_tu, tok));
|
||||
}
|
||||
|
||||
CXCursor Unit::getTranslationUnitCursor() const
|
||||
{
|
||||
Q_ASSERT(isLoaded());
|
||||
|
@@ -31,9 +31,10 @@
|
||||
#ifndef UNIT_H
|
||||
#define UNIT_H
|
||||
|
||||
#include "utils.h"
|
||||
#include "clangutils.h"
|
||||
#include "raii/scopedclangoptions.h"
|
||||
#include "cxraii.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QSharedPointer>
|
||||
@@ -95,8 +96,8 @@ public:
|
||||
QStringList compilationOptions() const;
|
||||
void setCompilationOptions(const QStringList &compOptions);
|
||||
|
||||
UnsavedFiles unsavedFiles() const;
|
||||
void setUnsavedFiles(const UnsavedFiles &unsavedFiles);
|
||||
Utils::UnsavedFiles unsavedFiles() const;
|
||||
void setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles);
|
||||
|
||||
unsigned managementOptions() const;
|
||||
void setManagementOptions(unsigned managementOptions);
|
||||
@@ -135,8 +136,6 @@ public:
|
||||
// - Physical source locations
|
||||
CXSourceLocation getLocation(const CXFile &file, unsigned line, unsigned column) const;
|
||||
|
||||
void codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results);
|
||||
|
||||
void tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const;
|
||||
void disposeTokens(CXToken *tokens, unsigned tokenCount) const;
|
||||
CXSourceRange getTokenExtent(const CXToken &token) const;
|
||||
@@ -145,8 +144,6 @@ public:
|
||||
CXTranslationUnit clangTranslationUnit() const;
|
||||
CXIndex clangIndex() const;
|
||||
|
||||
QString getTokenSpelling(const CXToken &tok) const;
|
||||
|
||||
private:
|
||||
void updateTimeStamp();
|
||||
|
||||
@@ -156,7 +153,7 @@ private:
|
||||
QStringList m_compOptions;
|
||||
SharedClangOptions m_sharedCompOptions;
|
||||
unsigned m_managementOptions;
|
||||
UnsavedFiles m_unsaved;
|
||||
Utils::UnsavedFiles m_unsaved;
|
||||
QDateTime m_timeStamp;
|
||||
};
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#ifndef CLANG_INTERNAL_UNSAVEDFILEDATA_H
|
||||
#define CLANG_INTERNAL_UNSAVEDFILEDATA_H
|
||||
|
||||
#include "utils.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
@@ -43,7 +43,7 @@ class UnsavedFileData
|
||||
UnsavedFileData(const UnsavedFileData &);
|
||||
UnsavedFileData &operator=(const UnsavedFileData &);
|
||||
|
||||
typedef ClangCodeModel::Internal::UnsavedFiles UnsavedFiles;
|
||||
typedef ClangCodeModel::Utils::UnsavedFiles UnsavedFiles;
|
||||
|
||||
public:
|
||||
UnsavedFileData(const UnsavedFiles &unsavedFiles);
|
||||
|
@@ -1,90 +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 "unit.h"
|
||||
#include "utils.h"
|
||||
#include "utils_p.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
QPair<bool, QStringList> precompile(const PchInfo::Ptr &pchInfo)
|
||||
{
|
||||
// qDebug() << "*** Precompiling" << pchInfo->inputFileName()
|
||||
// << "into" << pchInfo->fileName()
|
||||
// << "with options" << pchInfo->options();
|
||||
|
||||
bool ok = false;
|
||||
|
||||
Internal::Unit::Ptr unit = Internal::Unit::create(pchInfo->inputFileName());
|
||||
unit->setCompilationOptions(pchInfo->options());
|
||||
|
||||
unsigned parseOpts = CXTranslationUnit_ForSerialization
|
||||
| CXTranslationUnit_Incomplete;
|
||||
unit->setManagementOptions(parseOpts);
|
||||
|
||||
unit->parse();
|
||||
if (unit->isLoaded())
|
||||
ok = CXSaveError_None == unit->save(pchInfo->fileName());
|
||||
|
||||
return qMakePair(ok, Internal::formattedDiagnostics(unit));
|
||||
}
|
||||
|
||||
namespace {
|
||||
static bool clangInitialised = false;
|
||||
static QMutex initialisationMutex;
|
||||
} // anonymous namespace
|
||||
|
||||
void initializeClang()
|
||||
{
|
||||
if (clangInitialised)
|
||||
return;
|
||||
|
||||
QMutexLocker locker(&initialisationMutex);
|
||||
if (clangInitialised)
|
||||
return;
|
||||
|
||||
clang_toggleCrashRecovery(1);
|
||||
clang_enableStackTraces();
|
||||
clangInitialised = true;
|
||||
|
||||
qRegisterMetaType<ClangCodeModel::Diagnostic>();
|
||||
qRegisterMetaType<QList<ClangCodeModel::Diagnostic> >();
|
||||
}
|
||||
|
||||
} // Internal namespace
|
||||
} // ClangCodeModel namespace
|
||||
|
@@ -1,66 +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 UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include "pchinfo.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QByteArray>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
/*
|
||||
* A header for globally visible typedefs. This is particularly useful
|
||||
* so we don't have to #include files simply because of a typedef. Still,
|
||||
* not every typedef should go in here, only the minimal subset of the
|
||||
* ones which are needed quite often.
|
||||
*/
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
typedef QMap<QString, QByteArray> UnsavedFiles;
|
||||
|
||||
/**
|
||||
* Utility method to create a PCH file from a header file.
|
||||
*
|
||||
* \returns a boolean indicating success (true) or failure (false), and a
|
||||
* list of diagnostic messages.
|
||||
*/
|
||||
QPair<bool, QStringList> precompile(const PchInfo::Ptr &pchInfo);
|
||||
|
||||
void initializeClang();
|
||||
|
||||
} // Internal namespace
|
||||
} // ClangCodeModel namespace
|
||||
|
||||
#endif // UTILS_H
|
@@ -1,125 +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 "unit.h"
|
||||
#include "utils_p.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
QString getQString(const CXString &cxString, bool disposeCXString)
|
||||
{
|
||||
QString s = QString::fromUtf8(clang_getCString(cxString));
|
||||
if (disposeCXString)
|
||||
clang_disposeString(cxString);
|
||||
return s;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
SourceLocation getLocation(const CXSourceLocation &loc,
|
||||
void (*clangFunction)(CXSourceLocation,
|
||||
CXFile *,
|
||||
unsigned *,
|
||||
unsigned *,
|
||||
unsigned *))
|
||||
{
|
||||
CXFile file;
|
||||
unsigned line, column, offset;
|
||||
(*clangFunction)(loc, &file, &line, &column, &offset);
|
||||
return SourceLocation(normalizeFileName(getQString(clang_getFileName(file))),
|
||||
line,
|
||||
column,
|
||||
offset);
|
||||
}
|
||||
|
||||
} // Anonymous
|
||||
|
||||
SourceLocation getInstantiationLocation(const CXSourceLocation &loc)
|
||||
{
|
||||
return getLocation(loc, &clang_getInstantiationLocation);
|
||||
}
|
||||
|
||||
SourceLocation getSpellingLocation(const CXSourceLocation &loc)
|
||||
{
|
||||
return getLocation(loc, &clang_getSpellingLocation);
|
||||
}
|
||||
|
||||
SourceLocation getExpansionLocation(const CXSourceLocation &loc)
|
||||
{
|
||||
// return getLocation(loc, &clang_getExpansionLocation);
|
||||
return getLocation(loc, &clang_getInstantiationLocation);
|
||||
}
|
||||
|
||||
QString normalizeFileName(const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return fileName;
|
||||
|
||||
return normalizeFileName(QFileInfo(fileName));
|
||||
}
|
||||
|
||||
QString normalizeFileName(const QFileInfo &fileInfo)
|
||||
{
|
||||
if (!fileInfo.isFile())
|
||||
return QString();
|
||||
|
||||
return QDir::cleanPath(fileInfo.absoluteFilePath());
|
||||
}
|
||||
|
||||
QStringList formattedDiagnostics(const Unit::Ptr &unit)
|
||||
{
|
||||
QStringList diags;
|
||||
if (!unit->isLoaded())
|
||||
return diags;
|
||||
|
||||
const unsigned count = unit->getNumDiagnostics();
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
CXDiagnostic diag = unit->getDiagnostic(i);
|
||||
|
||||
unsigned opt = CXDiagnostic_DisplaySourceLocation
|
||||
| CXDiagnostic_DisplayColumn
|
||||
| CXDiagnostic_DisplaySourceRanges
|
||||
| CXDiagnostic_DisplayOption
|
||||
| CXDiagnostic_DisplayCategoryId
|
||||
| CXDiagnostic_DisplayCategoryName
|
||||
;
|
||||
diags << getQString(clang_formatDiagnostic(diag, opt));
|
||||
clang_disposeDiagnostic(diag);
|
||||
}
|
||||
|
||||
return diags;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // ClangCodeModel
|
@@ -1,66 +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_REUSE_H
|
||||
#define CLANG_REUSE_H
|
||||
|
||||
#include "sourcelocation.h"
|
||||
#include "unit.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFileInfo;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
QString getQString(const CXString &cxString, bool disposeCXString = true);
|
||||
|
||||
SourceLocation getInstantiatonLocation(const CXSourceLocation &loc); // Deprecated
|
||||
SourceLocation getSpellingLocation(const CXSourceLocation &loc);
|
||||
SourceLocation getExpansionLocation(const CXSourceLocation &loc);
|
||||
|
||||
// There are slight differences of behavior from apparently similar Qt file processing functions.
|
||||
// For instance, QFileInfo::absoluteFilePath will uppercase driver letters, while the corresponding
|
||||
// QDir function will not do so. Besides, we need to keep paths clean. So in order to avoid
|
||||
// inconsistencies the functions below should be used for any indexing related task.
|
||||
QString normalizeFileName(const QString &fileName);
|
||||
QString normalizeFileName(const QFileInfo &fileInfo);
|
||||
|
||||
QStringList formattedDiagnostics(const Unit::Ptr &unit);
|
||||
|
||||
} // Internal
|
||||
} // ClangCodeModel
|
||||
|
||||
#endif // CLANG_REUSE_H
|
Reference in New Issue
Block a user