forked from qt-creator/qt-creator
ClangCodeModel: Support setting additional preprocessor directives
... for a document. This was only ever implemented for the built-in code model. Fixes: QTCREATORBUG-20423 Change-Id: Ia99d0136e9995a5626058ad06173ea077be024d8 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -335,7 +335,7 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
|
|||||||
= CppEditor::ClangdSettings(d->settings).clangdIncludePath();
|
= CppEditor::ClangdSettings(d->settings).clangdIncludePath();
|
||||||
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
||||||
*CppEditor::CppModelManager::instance()->fallbackProjectPart(),
|
*CppEditor::CppModelManager::instance()->fallbackProjectPart(),
|
||||||
warningsConfigForProject(nullptr), includeDir);
|
warningsConfigForProject(nullptr), includeDir, {});
|
||||||
const CppEditor::UsePrecompiledHeaders usePch = CppEditor::getPchUsage();
|
const CppEditor::UsePrecompiledHeaders usePch = CppEditor::getPchUsage();
|
||||||
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
||||||
optionsBuilder, globalClangOptions());
|
optionsBuilder, globalClangOptions());
|
||||||
@@ -714,23 +714,26 @@ void ClangdClient::handleUiHeaderChange(const QString &fileName)
|
|||||||
void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
||||||
const CppEditor::BaseEditorDocumentParser::Configuration &config)
|
const CppEditor::BaseEditorDocumentParser::Configuration &config)
|
||||||
{
|
{
|
||||||
if (config.preferredProjectPartId.isEmpty())
|
// TODO: Also handle usePrecompiledHeaders?
|
||||||
return;
|
const auto projectPart = !config.preferredProjectPartId.isEmpty()
|
||||||
|
? CppEditor::CppModelManager::instance()->projectPartForId(
|
||||||
CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
|
config.preferredProjectPartId)
|
||||||
if (cachedConfig == config)
|
: projectPartForFile(filePath.toString());
|
||||||
return;
|
|
||||||
cachedConfig = config;
|
|
||||||
|
|
||||||
// TODO: Also handle editorDefines (and usePrecompiledHeaders?)
|
|
||||||
const auto projectPart = CppEditor::CppModelManager::instance()
|
|
||||||
->projectPartForId(config.preferredProjectPartId);
|
|
||||||
if (!projectPart)
|
if (!projectPart)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CppEditor::BaseEditorDocumentParser::Configuration fullConfig = config;
|
||||||
|
fullConfig.preferredProjectPartId = projectPart->id();
|
||||||
|
CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
|
||||||
|
if (cachedConfig == fullConfig)
|
||||||
|
return;
|
||||||
|
cachedConfig = fullConfig;
|
||||||
|
|
||||||
QJsonObject cdbChanges;
|
QJsonObject cdbChanges;
|
||||||
const Utils::FilePath includeDir = CppEditor::ClangdSettings(d->settings).clangdIncludePath();
|
const Utils::FilePath includeDir = CppEditor::ClangdSettings(d->settings).clangdIncludePath();
|
||||||
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
||||||
*projectPart, warningsConfigForProject(project()), includeDir);
|
*projectPart, warningsConfigForProject(project()), includeDir,
|
||||||
|
ProjectExplorer::Macro::toMacros(config.editorDefines));
|
||||||
const CppEditor::ProjectFile file(filePath.toString(),
|
const CppEditor::ProjectFile file(filePath.toString(),
|
||||||
CppEditor::ProjectFile::classify(filePath.toString()));
|
CppEditor::ProjectFile::classify(filePath.toString()));
|
||||||
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
||||||
@@ -742,6 +745,7 @@ void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
|||||||
DidChangeConfigurationParams configChangeParams;
|
DidChangeConfigurationParams configChangeParams;
|
||||||
configChangeParams.setSettings(settings);
|
configChangeParams.setSettings(settings);
|
||||||
sendMessage(DidChangeConfigurationNotification(configChangeParams));
|
sendMessage(DidChangeConfigurationNotification(configChangeParams));
|
||||||
|
emit configChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::switchIssuePaneEntries(const Utils::FilePath &filePath)
|
void ClangdClient::switchIssuePaneEntries(const Utils::FilePath &filePath)
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ signals:
|
|||||||
const Utils::FilePath &file);
|
const Utils::FilePath &file);
|
||||||
void proposalReady(TextEditor::IAssistProposal *proposal);
|
void proposalReady(TextEditor::IAssistProposal *proposal);
|
||||||
void textMarkCreated(const Utils::FilePath &file);
|
void textMarkCreated(const Utils::FilePath &file);
|
||||||
|
void configChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms) override;
|
void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms) override;
|
||||||
|
|||||||
@@ -3,12 +3,10 @@
|
|||||||
|
|
||||||
#include "clangeditordocumentprocessor.h"
|
#include "clangeditordocumentprocessor.h"
|
||||||
|
|
||||||
#include "clangdiagnostictooltipwidget.h"
|
|
||||||
#include "clangfixitoperation.h"
|
|
||||||
#include "clangmodelmanagersupport.h"
|
#include "clangmodelmanagersupport.h"
|
||||||
#include "clangutils.h"
|
|
||||||
|
|
||||||
#include <cppeditor/builtincursorinfo.h>
|
#include <cppeditor/builtincursorinfo.h>
|
||||||
|
#include <cppeditor/builtineditordocumentparser.h>
|
||||||
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
||||||
#include <cppeditor/compileroptionsbuilder.h>
|
#include <cppeditor/compileroptionsbuilder.h>
|
||||||
#include <cppeditor/cppcodemodelsettings.h>
|
#include <cppeditor/cppcodemodelsettings.h>
|
||||||
@@ -41,6 +39,11 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(TextEditor::TextDocum
|
|||||||
{
|
{
|
||||||
connect(parser().data(), &CppEditor::BaseEditorDocumentParser::projectPartInfoUpdated,
|
connect(parser().data(), &CppEditor::BaseEditorDocumentParser::projectPartInfoUpdated,
|
||||||
this, &BaseEditorDocumentProcessor::projectPartInfoUpdated);
|
this, &BaseEditorDocumentProcessor::projectPartInfoUpdated);
|
||||||
|
connect(static_cast<CppEditor::BuiltinEditorDocumentParser *>(parser().data()),
|
||||||
|
&CppEditor::BuiltinEditorDocumentParser::finished,
|
||||||
|
this, [this] {
|
||||||
|
emit parserConfigChanged(Utils::FilePath::fromString(filePath()), parserConfig());
|
||||||
|
});
|
||||||
setSemanticHighlightingChecker([this] {
|
setSemanticHighlightingChecker([this] {
|
||||||
return !ClangModelManagerSupport::clientForFile(m_document.filePath());
|
return !ClangModelManagerSupport::clientForFile(m_document.filePath());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> p
|
|||||||
QTC_ASSERT(projectInfo, continue);
|
QTC_ASSERT(projectInfo, continue);
|
||||||
QStringList args;
|
QStringList args;
|
||||||
const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
|
||||||
*projectPart, warningsConfig, clangIncludeDir);
|
*projectPart, warningsConfig, clangIncludeDir, {});
|
||||||
QJsonArray ppOptions;
|
QJsonArray ppOptions;
|
||||||
if (purpose == CompilationDbPurpose::Project) {
|
if (purpose == CompilationDbPurpose::Project) {
|
||||||
args = projectPartArguments(*projectPart);
|
args = projectPartArguments(*projectPart);
|
||||||
@@ -328,7 +328,8 @@ QString textUntilPreviousStatement(TextEditor::TextDocumentManipulatorInterface
|
|||||||
|
|
||||||
CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
|
CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
|
||||||
const ClangDiagnosticConfig &warningsConfig,
|
const ClangDiagnosticConfig &warningsConfig,
|
||||||
const Utils::FilePath &clangIncludeDir)
|
const FilePath &clangIncludeDir,
|
||||||
|
const Macros &extraMacros)
|
||||||
{
|
{
|
||||||
const auto useBuildSystemWarnings = warningsConfig.useBuildSystemWarnings()
|
const auto useBuildSystemWarnings = warningsConfig.useBuildSystemWarnings()
|
||||||
? UseBuildSystemWarnings::Yes
|
? UseBuildSystemWarnings::Yes
|
||||||
@@ -336,7 +337,9 @@ CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
|
|||||||
CompilerOptionsBuilder optionsBuilder(projectPart, UseSystemHeader::No,
|
CompilerOptionsBuilder optionsBuilder(projectPart, UseSystemHeader::No,
|
||||||
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No,
|
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No,
|
||||||
useBuildSystemWarnings, clangIncludeDir);
|
useBuildSystemWarnings, clangIncludeDir);
|
||||||
optionsBuilder.provideAdditionalMacros({ProjectExplorer::Macro("Q_CREATOR_RUN", "1")});
|
Macros fullMacroList = extraMacros;
|
||||||
|
fullMacroList += Macro("Q_CREATOR_RUN", "1");
|
||||||
|
optionsBuilder.provideAdditionalMacros(fullMacroList);
|
||||||
optionsBuilder.build(ProjectFile::Unclassified, UsePrecompiledHeaders::No);
|
optionsBuilder.build(ProjectFile::Unclassified, UsePrecompiledHeaders::No);
|
||||||
optionsBuilder.add("-fmessage-length=0", /*gccOnlyOption=*/true);
|
optionsBuilder.add("-fmessage-length=0", /*gccOnlyOption=*/true);
|
||||||
optionsBuilder.add("-fdiagnostics-show-note-include-stack", /*gccOnlyOption=*/true);
|
optionsBuilder.add("-fdiagnostics-show-note-include-stack", /*gccOnlyOption=*/true);
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ const QStringList globalClangOptions();
|
|||||||
CppEditor::CompilerOptionsBuilder clangOptionsBuilder(
|
CppEditor::CompilerOptionsBuilder clangOptionsBuilder(
|
||||||
const CppEditor::ProjectPart &projectPart,
|
const CppEditor::ProjectPart &projectPart,
|
||||||
const CppEditor::ClangDiagnosticConfig &warningsConfig,
|
const CppEditor::ClangDiagnosticConfig &warningsConfig,
|
||||||
const Utils::FilePath &clangIncludeDir);
|
const Utils::FilePath &clangIncludeDir,
|
||||||
|
const ProjectExplorer::Macros &extraMacros);
|
||||||
QJsonArray projectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder);
|
QJsonArray projectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder);
|
||||||
QJsonArray fullProjectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
QJsonArray fullProjectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
||||||
const QStringList &projectOptions);
|
const QStringList &projectOptions);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <texteditor/codeassist/assistproposaliteminterface.h>
|
#include <texteditor/codeassist/assistproposaliteminterface.h>
|
||||||
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
|
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
|
||||||
|
#include <texteditor/textmark.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
@@ -2001,6 +2002,15 @@ ClangdTestExternalChanges::ClangdTestExternalChanges()
|
|||||||
|
|
||||||
void ClangdTestExternalChanges::test()
|
void ClangdTestExternalChanges::test()
|
||||||
{
|
{
|
||||||
|
ClangdClient * const oldClient = client();
|
||||||
|
QVERIFY(oldClient);
|
||||||
|
|
||||||
|
// Wait until things have settled.
|
||||||
|
while (true) {
|
||||||
|
if (!waitForSignalOrTimeout(oldClient, &ClangdClient::configChanged, timeOutInMs()))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Break a header file that is used, but not open in Creator.
|
// Break a header file that is used, but not open in Creator.
|
||||||
// Neither we nor the server should notice, and no diagnostics should be shown for the
|
// Neither we nor the server should notice, and no diagnostics should be shown for the
|
||||||
// source file that includes the now-broken header.
|
// source file that includes the now-broken header.
|
||||||
@@ -2008,14 +2018,15 @@ void ClangdTestExternalChanges::test()
|
|||||||
QVERIFY(header.open(QIODevice::WriteOnly));
|
QVERIFY(header.open(QIODevice::WriteOnly));
|
||||||
header.write("blubb");
|
header.write("blubb");
|
||||||
header.close();
|
header.close();
|
||||||
ClangdClient * const oldClient = client();
|
|
||||||
QVERIFY(oldClient);
|
|
||||||
waitForSignalOrTimeout(LanguageClientManager::instance(),
|
waitForSignalOrTimeout(LanguageClientManager::instance(),
|
||||||
&LanguageClientManager::clientAdded, timeOutInMs());
|
&LanguageClientManager::clientAdded, timeOutInMs());
|
||||||
QCOMPARE(client(), oldClient);
|
QCOMPARE(client(), oldClient);
|
||||||
QCOMPARE(client(), ClangModelManagerSupport::clientForProject(project()));
|
QCOMPARE(client(), ClangModelManagerSupport::clientForProject(project()));
|
||||||
const TextDocument * const curDoc = document("main.cpp");
|
const TextDocument * const curDoc = document("main.cpp");
|
||||||
QVERIFY(curDoc);
|
QVERIFY(curDoc);
|
||||||
|
if (!curDoc->marks().isEmpty())
|
||||||
|
for (const auto &m : curDoc->marks())
|
||||||
|
qDebug() << m->lineAnnotation();
|
||||||
QVERIFY(curDoc->marks().isEmpty());
|
QVERIFY(curDoc->marks().isEmpty());
|
||||||
|
|
||||||
// Now trigger an external change in an open, but not currently visible file and
|
// Now trigger an external change in an open, but not currently visible file and
|
||||||
|
|||||||
@@ -507,19 +507,15 @@ void CppEditorWidget::finalizeInitialization()
|
|||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// Toolbar: '#' Button
|
// Toolbar: '#' Button
|
||||||
// TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
|
d->m_preprocessorButton = new QToolButton(this);
|
||||||
if (!d->m_modelManager->isClangCodeModelActive()) {
|
d->m_preprocessorButton->setText(QLatin1String("#"));
|
||||||
d->m_preprocessorButton = new QToolButton(this);
|
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
||||||
d->m_preprocessorButton->setText(QLatin1String("#"));
|
connect(cmd, &Command::keySequenceChanged,
|
||||||
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
this, &CppEditorWidget::updatePreprocessorButtonTooltip);
|
||||||
connect(cmd, &Command::keySequenceChanged,
|
updatePreprocessorButtonTooltip();
|
||||||
this, &CppEditorWidget::updatePreprocessorButtonTooltip);
|
connect(d->m_preprocessorButton, &QAbstractButton::clicked,
|
||||||
updatePreprocessorButtonTooltip();
|
this, &CppEditorWidget::showPreProcessorWidget);
|
||||||
connect(d->m_preprocessorButton, &QAbstractButton::clicked,
|
insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
|
||||||
this, &CppEditorWidget::showPreProcessorWidget);
|
|
||||||
|
|
||||||
insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(this, &TextEditor::TextEditorWidget::toolbarOutlineChanged,
|
connect(this, &TextEditor::TextEditorWidget::toolbarOutlineChanged,
|
||||||
this, &CppEditorWidget::handleOutlineChanged);
|
this, &CppEditorWidget::handleOutlineChanged);
|
||||||
|
|||||||
Reference in New Issue
Block a user