forked from qt-creator/qt-creator
ClangCodeModel: Forward to the built-in code model
... if the user tries to complete inside a comment or string. Fixes: QTCREATORBUG-20828 Change-Id: I245e1bd16acaf696601cabe33f27210da21cc12a Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <cppeditor/cppcompletionassistprocessor.h>
|
#include <cppeditor/cppcompletionassistprocessor.h>
|
||||||
#include <cppeditor/cppcompletionassistprovider.h>
|
#include <cppeditor/cppcompletionassistprovider.h>
|
||||||
#include <cppeditor/cppdoxygen.h>
|
|
||||||
#include <cppeditor/cppeditorconstants.h>
|
#include <cppeditor/cppeditorconstants.h>
|
||||||
#include <cppeditor/cppmodelmanager.h>
|
#include <cppeditor/cppmodelmanager.h>
|
||||||
#include <cppeditor/cppprojectfile.h>
|
#include <cppeditor/cppprojectfile.h>
|
||||||
@@ -44,7 +43,7 @@ namespace ClangCodeModel::Internal {
|
|||||||
static Q_LOGGING_CATEGORY(clangdLogCompletion, "qtc.clangcodemodel.clangd.completion",
|
static Q_LOGGING_CATEGORY(clangdLogCompletion, "qtc.clangcodemodel.clangd.completion",
|
||||||
QtWarningMsg);
|
QtWarningMsg);
|
||||||
|
|
||||||
enum class CustomAssistMode { Doxygen, Preprocessor, IncludePath };
|
enum class CustomAssistMode { Preprocessor, IncludePath };
|
||||||
|
|
||||||
class CustomAssistProcessor : public IAssistProcessor
|
class CustomAssistProcessor : public IAssistProcessor
|
||||||
{
|
{
|
||||||
@@ -126,6 +125,12 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
|
|||||||
<< interface->textAt(interface->position(), -10);
|
<< interface->textAt(interface->position(), -10);
|
||||||
qCDebug(clangdLogCompletion) << "text after cursor is"
|
qCDebug(clangdLogCompletion) << "text after cursor is"
|
||||||
<< interface->textAt(interface->position(), 10);
|
<< interface->textAt(interface->position(), 10);
|
||||||
|
|
||||||
|
if (!interface->isBaseObject()) {
|
||||||
|
qCDebug(clangdLogCompletion) << "encountered assist interface for built-in code model";
|
||||||
|
return CppEditor::getCppCompletionAssistProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(),
|
ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(),
|
||||||
interface->position(), false, {});
|
interface->position(), false, {});
|
||||||
contextAnalyzer.analyze();
|
contextAnalyzer.analyze();
|
||||||
@@ -133,13 +138,6 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
|
|||||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
|
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
|
||||||
qCDebug(clangdLogCompletion) << "creating function hint processor";
|
qCDebug(clangdLogCompletion) << "creating function hint processor";
|
||||||
return new ClangdFunctionHintProcessor(m_client);
|
return new ClangdFunctionHintProcessor(m_client);
|
||||||
case ClangCompletionContextAnalyzer::CompleteDoxygenKeyword:
|
|
||||||
qCDebug(clangdLogCompletion) << "creating doxygen processor";
|
|
||||||
return new CustomAssistProcessor(m_client,
|
|
||||||
contextAnalyzer.positionForProposal(),
|
|
||||||
contextAnalyzer.positionEndOfExpression(),
|
|
||||||
contextAnalyzer.completionOperator(),
|
|
||||||
CustomAssistMode::Doxygen);
|
|
||||||
case ClangCompletionContextAnalyzer::CompletePreprocessorDirective:
|
case ClangCompletionContextAnalyzer::CompletePreprocessorDirective:
|
||||||
qCDebug(clangdLogCompletion) << "creating macro processor";
|
qCDebug(clangdLogCompletion) << "creating macro processor";
|
||||||
return new CustomAssistProcessor(m_client,
|
return new CustomAssistProcessor(m_client,
|
||||||
@@ -147,10 +145,6 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
|
|||||||
contextAnalyzer.positionEndOfExpression(),
|
contextAnalyzer.positionEndOfExpression(),
|
||||||
contextAnalyzer.completionOperator(),
|
contextAnalyzer.completionOperator(),
|
||||||
CustomAssistMode::Preprocessor);
|
CustomAssistMode::Preprocessor);
|
||||||
case ClangCompletionContextAnalyzer::CompleteSignal:
|
|
||||||
case ClangCompletionContextAnalyzer::CompleteSlot:
|
|
||||||
if (!interface->isBaseObject())
|
|
||||||
return CppEditor::getCppCompletionAssistProcessor();
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -415,12 +409,6 @@ IAssistProposal *CustomAssistProcessor::perform()
|
|||||||
{
|
{
|
||||||
QList<AssistProposalItemInterface *> completions;
|
QList<AssistProposalItemInterface *> completions;
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case CustomAssistMode::Doxygen:
|
|
||||||
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
|
|
||||||
completions << createItem(QLatin1String(doxygenTagSpell(i)),
|
|
||||||
CPlusPlus::Icons::keywordIcon());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CustomAssistMode::Preprocessor: {
|
case CustomAssistMode::Preprocessor: {
|
||||||
static QIcon macroIcon = Utils::CodeModelIcon::iconForType(CodeModelIcon::Macro);
|
static QIcon macroIcon = Utils::CodeModelIcon::iconForType(CodeModelIcon::Macro);
|
||||||
for (const QString &completion
|
for (const QString &completion
|
||||||
|
|||||||
@@ -1500,7 +1500,7 @@ ClangdTestCompletion::ClangdTestCompletion()
|
|||||||
setProjectFileName("completion.pro");
|
setProjectFileName("completion.pro");
|
||||||
setSourceFileNames({"completionWithProject.cpp", "constructorCompletion.cpp",
|
setSourceFileNames({"completionWithProject.cpp", "constructorCompletion.cpp",
|
||||||
"classAndConstructorCompletion.cpp", "dotToArrowCorrection.cpp",
|
"classAndConstructorCompletion.cpp", "dotToArrowCorrection.cpp",
|
||||||
"doxygenKeywordsCompletion.cpp", "functionAddress.cpp",
|
"functionAddress.cpp",
|
||||||
"functionCompletion.cpp", "functionCompletionFiltered2.cpp",
|
"functionCompletion.cpp", "functionCompletionFiltered2.cpp",
|
||||||
"functionCompletionFiltered.cpp", "globalCompletion.cpp",
|
"functionCompletionFiltered.cpp", "globalCompletion.cpp",
|
||||||
"includeDirectiveCompletion.cpp", "mainwindow.cpp",
|
"includeDirectiveCompletion.cpp", "mainwindow.cpp",
|
||||||
@@ -1518,18 +1518,6 @@ void ClangdTestCompletion::initTestCase()
|
|||||||
startCollectingHighlightingInfo();
|
startCollectingHighlightingInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdTestCompletion::testCompleteDoxygenKeywords()
|
|
||||||
{
|
|
||||||
ProposalModelPtr proposal;
|
|
||||||
getProposal("doxygenKeywordsCompletion.cpp", proposal);
|
|
||||||
|
|
||||||
QVERIFY(proposal);
|
|
||||||
QVERIFY(hasItem(proposal, "brief"));
|
|
||||||
QVERIFY(hasItem(proposal, "param"));
|
|
||||||
QVERIFY(hasItem(proposal, "return"));
|
|
||||||
QVERIFY(!hasSnippet(proposal, "class "));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangdTestCompletion::testCompletePreprocessorKeywords()
|
void ClangdTestCompletion::testCompletePreprocessorKeywords()
|
||||||
{
|
{
|
||||||
ProposalModelPtr proposal;
|
ProposalModelPtr proposal;
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void initTestCase() override;
|
void initTestCase() override;
|
||||||
|
|
||||||
void testCompleteDoxygenKeywords();
|
|
||||||
void testCompletePreprocessorKeywords();
|
void testCompletePreprocessorKeywords();
|
||||||
void testCompleteIncludeDirective();
|
void testCompleteIncludeDirective();
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
<file>completion/classAndConstructorCompletion.cpp</file>
|
<file>completion/classAndConstructorCompletion.cpp</file>
|
||||||
<file>completion/completionWithProject.cpp</file>
|
<file>completion/completionWithProject.cpp</file>
|
||||||
<file>completion/constructorCompletion.cpp</file>
|
<file>completion/constructorCompletion.cpp</file>
|
||||||
<file>completion/doxygenKeywordsCompletion.cpp</file>
|
|
||||||
<file>completion/functionCompletion.cpp</file>
|
<file>completion/functionCompletion.cpp</file>
|
||||||
<file>completion/functionCompletionFiltered.cpp</file>
|
<file>completion/functionCompletionFiltered.cpp</file>
|
||||||
<file>completion/functionCompletionFiltered2.cpp</file>
|
<file>completion/functionCompletionFiltered2.cpp</file>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
//! \ /* COMPLETE HERE */
|
|
||||||
@@ -1268,7 +1268,8 @@ std::unique_ptr<AssistInterface> CppEditorWidget::createAssistInterface(AssistKi
|
|||||||
if (cap)
|
if (cap)
|
||||||
return cap->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason);
|
return cap->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason);
|
||||||
|
|
||||||
if (isOldStyleSignalOrSlot()) {
|
if (isOldStyleSignalOrSlot()
|
||||||
|
|| isInCommentOrString(textCursor(), LanguageFeatures::defaultFeatures())) {
|
||||||
return CppModelManager::completionAssistProvider()
|
return CppModelManager::completionAssistProvider()
|
||||||
->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason);
|
->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,29 +293,33 @@ bool isInCommentOrString(const TextEditor::AssistInterface *interface,
|
|||||||
{
|
{
|
||||||
QTextCursor tc(interface->textDocument());
|
QTextCursor tc(interface->textDocument());
|
||||||
tc.setPosition(interface->position());
|
tc.setPosition(interface->position());
|
||||||
|
return isInCommentOrString(tc, features);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInCommentOrString(const QTextCursor &cursor, CPlusPlus::LanguageFeatures features)
|
||||||
|
{
|
||||||
SimpleLexer tokenize;
|
SimpleLexer tokenize;
|
||||||
features.qtMocRunEnabled = true;
|
features.qtMocRunEnabled = true;
|
||||||
tokenize.setLanguageFeatures(features);
|
tokenize.setLanguageFeatures(features);
|
||||||
tokenize.setSkipComments(false);
|
tokenize.setSkipComments(false);
|
||||||
const Tokens &tokens = tokenize(tc.block().text(),
|
const Tokens &tokens = tokenize(cursor.block().text(),
|
||||||
BackwardsScanner::previousBlockState(tc.block()));
|
BackwardsScanner::previousBlockState(cursor.block()));
|
||||||
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, cursor.positionInBlock() - 1));
|
||||||
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
||||||
|
|
||||||
if (tk.isComment())
|
if (tk.isComment())
|
||||||
return true;
|
return true;
|
||||||
if (!tk.isLiteral())
|
if (!tk.isStringLiteral())
|
||||||
return false;
|
return false;
|
||||||
if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
|
if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
|
||||||
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
||||||
const QString &line = tc.block().text();
|
const QString &line = cursor.block().text();
|
||||||
const Token &idToken = tokens.at(1);
|
const Token &idToken = tokens.at(1);
|
||||||
QStringView identifier = QStringView(line).mid(idToken.utf16charsBegin(),
|
QStringView identifier = QStringView(line).mid(idToken.utf16charsBegin(),
|
||||||
idToken.utf16chars());
|
idToken.utf16chars());
|
||||||
if (identifier == QLatin1String("include")
|
if (identifier == QLatin1String("include")
|
||||||
|| identifier == QLatin1String("include_next")
|
|| identifier == QLatin1String("include_next")
|
||||||
|| (features.objCEnabled && identifier == QLatin1String("import"))) {
|
|| (features.objCEnabled && identifier == QLatin1String("import"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ const CPlusPlus::Macro CPPEDITOR_EXPORT *findCanonicalMacro(const QTextCursor &c
|
|||||||
|
|
||||||
bool CPPEDITOR_EXPORT isInCommentOrString(const TextEditor::AssistInterface *interface,
|
bool CPPEDITOR_EXPORT isInCommentOrString(const TextEditor::AssistInterface *interface,
|
||||||
CPlusPlus::LanguageFeatures features);
|
CPlusPlus::LanguageFeatures features);
|
||||||
|
bool CPPEDITOR_EXPORT isInCommentOrString(const QTextCursor &cursor,
|
||||||
|
CPlusPlus::LanguageFeatures features);
|
||||||
TextEditor::QuickFixOperations CPPEDITOR_EXPORT
|
TextEditor::QuickFixOperations CPPEDITOR_EXPORT
|
||||||
quickFixOperations(const TextEditor::AssistInterface *interface);
|
quickFixOperations(const TextEditor::AssistInterface *interface);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user