Editor: move ownership of assist interface to processor

This way the base class can manage the lifetime of the interface object
and it doesn't need to be done in each implementation of perform.

Change-Id: Ie1ce742e31b688a337533ee6c57d376146e25ace
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-11-15 14:19:06 +01:00
parent aa6633ca21
commit 0e4b0a26d3
43 changed files with 325 additions and 321 deletions

View File

@@ -46,7 +46,7 @@ public:
unsigned completionOperator, CustomAssistMode mode);
private:
IAssistProposal *perform(AssistInterface *interface) override;
IAssistProposal *perform() override;
AssistProposalItemInterface *createItem(const QString &text, const QIcon &icon) const;
@@ -85,7 +85,7 @@ public:
~ClangdCompletionAssistProcessor();
private:
IAssistProposal *perform(AssistInterface *interface) override;
IAssistProposal *perform() override;
QList<AssistProposalItemInterface *> generateCompletionItems(
const QList<LanguageServerProtocol::CompletionItem> &items) const override;
@@ -99,7 +99,7 @@ public:
ClangdFunctionHintProcessor(ClangdClient *client);
private:
IAssistProposal *perform(AssistInterface *interface) override;
IAssistProposal *perform() override;
ClangdClient * const m_client;
};
@@ -152,11 +152,7 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
if (contextAnalyzer.completionAction()
!= ClangCompletionContextAnalyzer::CompleteIncludePath) {
class NoOpProcessor : public IAssistProcessor {
IAssistProposal *perform(AssistInterface *interface) override
{
delete interface;
return nullptr;
}
IAssistProposal *perform() override { return nullptr; }
};
return new NoOpProcessor;
}
@@ -406,7 +402,7 @@ CustomAssistProcessor::CustomAssistProcessor(ClangdClient *client, int position,
, m_mode(mode)
{}
IAssistProposal *CustomAssistProcessor::perform(AssistInterface *interface)
IAssistProposal *CustomAssistProcessor::perform()
{
QList<AssistProposalItemInterface *> completions;
switch (m_mode) {
@@ -422,21 +418,20 @@ IAssistProposal *CustomAssistProcessor::perform(AssistInterface *interface)
: CppCompletionAssistProcessor::preprocessorCompletions()) {
completions << createItem(completion, macroIcon);
}
if (ProjectFile::isObjC(interface->filePath().toString()))
if (ProjectFile::isObjC(interface()->filePath().toString()))
completions << createItem("import", macroIcon);
break;
}
case CustomAssistMode::IncludePath: {
HeaderPaths headerPaths;
const ProjectPart::ConstPtr projectPart
= projectPartForFile(interface->filePath().toString());
= projectPartForFile(interface()->filePath().toString());
if (projectPart)
headerPaths = projectPart->headerPaths;
completions = completeInclude(m_endPos, m_completionOperator, interface, headerPaths);
completions = completeInclude(m_endPos, m_completionOperator, interface(), headerPaths);
break;
}
}
delete interface;
GenericProposalModelPtr model(new GenericProposalModel);
model->loadContent(completions);
const auto proposal = new GenericProposal(m_position, model);
@@ -572,14 +567,14 @@ ClangdCompletionAssistProcessor::~ClangdCompletionAssistProcessor()
<< "ClangdCompletionAssistProcessor took: " << m_timer.elapsed() << " ms";
}
IAssistProposal *ClangdCompletionAssistProcessor::perform(AssistInterface *interface)
IAssistProposal *ClangdCompletionAssistProcessor::perform()
{
if (m_client->testingEnabled()) {
setAsyncCompletionAvailableHandler([this](IAssistProposal *proposal) {
emit m_client->proposalReady(proposal);
});
}
return LanguageClientCompletionAssistProcessor::perform(interface);
return LanguageClientCompletionAssistProcessor::perform();
}
QList<AssistProposalItemInterface *> ClangdCompletionAssistProcessor::generateCompletionItems(
@@ -618,14 +613,14 @@ ClangdFunctionHintProcessor::ClangdFunctionHintProcessor(ClangdClient *client)
, m_client(client)
{}
IAssistProposal *ClangdFunctionHintProcessor::perform(AssistInterface *interface)
IAssistProposal *ClangdFunctionHintProcessor::perform()
{
if (m_client->testingEnabled()) {
setAsyncCompletionAvailableHandler([this](IAssistProposal *proposal) {
emit m_client->proposalReady(proposal);
});
}
return FunctionHintProcessor::perform(interface);
return FunctionHintProcessor::perform();
}
ClangdCompletionCapabilities::ClangdCompletionCapabilities(const JsonObject &object)

View File

@@ -42,9 +42,8 @@ public:
void resetData(bool resetFollowSymbolData);
private:
IAssistProposal *perform(AssistInterface *interface) override
IAssistProposal *perform() override
{
delete interface;
return createProposal(false);
}
@@ -61,7 +60,7 @@ public:
: m_followSymbol(followSymbol) {}
private:
IAssistProcessor *createProcessor(const AssistInterface *) const override;
IAssistProcessor *createProcessor(const AssistInterface *interface) const override;
const QPointer<ClangdFollowSymbol> m_followSymbol;
};

View File

@@ -47,15 +47,13 @@ public:
}
private:
IAssistProposal *perform(AssistInterface *interface) override
IAssistProposal *perform() override
{
m_interface = interface;
// Step 1: Collect clangd code actions asynchronously
LanguageClientQuickFixAssistProcessor::perform(interface);
LanguageClientQuickFixAssistProcessor::perform();
// Step 2: Collect built-in quickfixes synchronously
m_builtinOps = CppEditor::quickFixOperations(interface);
m_builtinOps = CppEditor::quickFixOperations(interface());
return nullptr;
}
@@ -82,13 +80,12 @@ private:
ops << op;
}
}
return GenericProposal::createProposal(m_interface, ops + m_builtinOps);
return GenericProposal::createProposal(interface(), ops + m_builtinOps);
}
return nullptr;
}
QuickFixOperations m_builtinOps;
const AssistInterface *m_interface = nullptr;
};
ClangdQuickFixProvider::ClangdQuickFixProvider(ClangdClient *client)

View File

@@ -24,7 +24,7 @@ class CMakeFileCompletionAssist : public KeywordsCompletionAssistProcessor
public:
CMakeFileCompletionAssist();
IAssistProposal *performAsync(AssistInterface *interface) final;
IAssistProposal *performAsync() final;
};
CMakeFileCompletionAssist::CMakeFileCompletionAssist() :
@@ -34,10 +34,10 @@ CMakeFileCompletionAssist::CMakeFileCompletionAssist() :
setDynamicCompletionFunction(&TextEditor::pathComplete);
}
IAssistProposal *CMakeFileCompletionAssist::performAsync(AssistInterface *interface)
IAssistProposal *CMakeFileCompletionAssist::performAsync()
{
Keywords kw;
const Utils::FilePath &filePath = interface->filePath();
const Utils::FilePath &filePath = interface()->filePath();
if (!filePath.isEmpty() && filePath.toFileInfo().isFile()) {
Project *p = SessionManager::projectForFile(filePath);
if (p && p->activeTarget()) {
@@ -48,7 +48,7 @@ IAssistProposal *CMakeFileCompletionAssist::performAsync(AssistInterface *interf
}
setKeywords(kw);
return KeywordsCompletionAssistProcessor::performAsync(interface);
return KeywordsCompletionAssistProcessor::performAsync();
}
IAssistProcessor *CMakeFileCompletionAssistProvider::createProcessor(const AssistInterface *) const

View File

@@ -86,17 +86,19 @@ public:
QTextCursor textCursor = m_editorWidget->textCursor();
textCursor.setPosition(m_position);
m_editorWidget->setTextCursor(textCursor);
CppCompletionAssistInterface *ai
= new CppCompletionAssistInterface(m_editorWidget->textDocument()->filePath(),
m_editorWidget,
ExplicitlyInvoked, m_snapshot,
ProjectExplorer::HeaderPaths(),
languageFeatures);
std::unique_ptr<CppCompletionAssistInterface> ai(
new CppCompletionAssistInterface(m_editorWidget->textDocument()->filePath(),
m_editorWidget,
ExplicitlyInvoked,
m_snapshot,
ProjectExplorer::HeaderPaths(),
languageFeatures));
ai->prepareForAsyncUse();
ai->recreateTextDocument();
InternalCppCompletionAssistProcessor processor;
processor.setupAssistInterface(std::move(ai));
const QScopedPointer<IAssistProposal> proposal(processor.performAsync(ai));
const QScopedPointer<IAssistProposal> proposal(processor.performAsync());
if (!proposal)
return completions;
ProposalModelPtr model = proposal->model();

View File

@@ -400,7 +400,7 @@ IAssistProcessor *InternalCompletionAssistProvider::createProcessor(const Assist
return new InternalCppCompletionAssistProcessor;
}
AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
std::unique_ptr<AssistInterface> InternalCompletionAssistProvider::createAssistInterface(
const Utils::FilePath &filePath,
const TextEditorWidget *textEditorWidget,
const LanguageFeatures &languageFeatures,
@@ -408,12 +408,13 @@ AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
{
QTC_ASSERT(textEditorWidget, return nullptr);
return new CppCompletionAssistInterface(filePath,
textEditorWidget,
BuiltinEditorDocumentParser::get(filePath.toString()),
languageFeatures,
reason,
CppModelManager::instance()->workingCopy());
return std::make_unique<CppCompletionAssistInterface>(
filePath,
textEditorWidget,
BuiltinEditorDocumentParser::get(filePath.toString()),
languageFeatures,
reason,
CppModelManager::instance()->workingCopy());
}
// -----------------
@@ -794,11 +795,9 @@ InternalCppCompletionAssistProcessor::InternalCppCompletionAssistProcessor()
InternalCppCompletionAssistProcessor::~InternalCppCompletionAssistProcessor() = default;
IAssistProposal * InternalCppCompletionAssistProcessor::performAsync(AssistInterface *interface)
IAssistProposal * InternalCppCompletionAssistProcessor::performAsync()
{
m_interface.reset(static_cast<const CppCompletionAssistInterface *>(interface));
if (interface->reason() != ExplicitlyInvoked && !accepts())
if (interface()->reason() != ExplicitlyInvoked && !accepts())
return nullptr;
int index = startCompletionHelper();
@@ -814,13 +813,13 @@ IAssistProposal * InternalCppCompletionAssistProcessor::performAsync(AssistInter
bool InternalCppCompletionAssistProcessor::accepts() const
{
const int pos = m_interface->position();
const int pos = interface()->position();
unsigned token = T_EOF_SYMBOL;
const int start = startOfOperator(pos, &token, /*want function call=*/ true);
if (start != pos) {
if (token == T_POUND) {
const int column = pos - m_interface->textDocument()->findBlock(start).position();
const int column = pos - interface()->textDocument()->findBlock(start).position();
if (column != 1)
return false;
}
@@ -828,15 +827,15 @@ bool InternalCppCompletionAssistProcessor::accepts() const
return true;
} else {
// Trigger completion after n characters of a name have been typed, when not editing an existing name
QChar characterUnderCursor = m_interface->characterAt(pos);
QChar characterUnderCursor = interface()->characterAt(pos);
if (!isValidIdentifierChar(characterUnderCursor)) {
const int startOfName = findStartOfName(pos);
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
const QChar firstCharacter = m_interface->characterAt(startOfName);
const QChar firstCharacter = interface()->characterAt(startOfName);
if (isValidFirstIdentifierChar(firstCharacter)) {
return !isInCommentOrString(m_interface.data(),
m_interface->languageFeatures());
return !isInCommentOrString(interface(),
cppInterface()->languageFeatures());
}
}
}
@@ -887,9 +886,9 @@ int InternalCppCompletionAssistProcessor::startOfOperator(int positionInDocument
unsigned *kind,
bool wantFunctionCall) const
{
const QChar ch = m_interface->characterAt(positionInDocument - 1);
const QChar ch2 = m_interface->characterAt(positionInDocument - 2);
const QChar ch3 = m_interface->characterAt(positionInDocument - 3);
const QChar ch = interface()->characterAt(positionInDocument - 1);
const QChar ch2 = interface()->characterAt(positionInDocument - 2);
const QChar ch3 = interface()->characterAt(positionInDocument - 3);
int start = positionInDocument
- CppCompletionAssistProvider::activationSequenceChar(ch, ch2, ch3, kind,
@@ -898,18 +897,18 @@ int InternalCppCompletionAssistProcessor::startOfOperator(int positionInDocument
const auto dotAtIncludeCompletionHandler = [this](int &start, unsigned *kind) {
start = findStartOfName(start);
const QChar ch4 = m_interface->characterAt(start - 1);
const QChar ch5 = m_interface->characterAt(start - 2);
const QChar ch6 = m_interface->characterAt(start - 3);
const QChar ch4 = interface()->characterAt(start - 1);
const QChar ch5 = interface()->characterAt(start - 2);
const QChar ch6 = interface()->characterAt(start - 3);
start = start - CppCompletionAssistProvider::activationSequenceChar(
ch4, ch5, ch6, kind, false, false);
};
CppCompletionAssistProcessor::startOfOperator(m_interface->textDocument(),
CppCompletionAssistProcessor::startOfOperator(cppInterface()->textDocument(),
positionInDocument,
kind,
start,
m_interface->languageFeatures(),
cppInterface()->languageFeatures(),
/*adjustForQt5SignalSlotCompletion=*/ true,
dotAtIncludeCompletionHandler);
return start;
@@ -918,12 +917,12 @@ int InternalCppCompletionAssistProcessor::startOfOperator(int positionInDocument
int InternalCppCompletionAssistProcessor::findStartOfName(int pos) const
{
if (pos == -1)
pos = m_interface->position();
pos = interface()->position();
QChar chr;
// Skip to the start of a name
do {
chr = m_interface->characterAt(--pos);
chr = interface()->characterAt(--pos);
} while (isValidIdentifierChar(chr));
return pos + 1;
@@ -931,7 +930,7 @@ int InternalCppCompletionAssistProcessor::findStartOfName(int pos) const
int InternalCppCompletionAssistProcessor::startCompletionHelper()
{
if (m_interface->languageFeatures().objCEnabled) {
if (cppInterface()->languageFeatures().objCEnabled) {
if (tryObjCCompletion())
return m_positionForProposal;
}
@@ -943,7 +942,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
int endOfOperator = m_positionForProposal;
// Skip whitespace preceding this position
while (m_interface->characterAt(endOfOperator - 1).isSpace())
while (interface()->characterAt(endOfOperator - 1).isSpace())
--endOfOperator;
int endOfExpression = startOfOperator(endOfOperator,
@@ -968,15 +967,15 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
|| m_model->m_completionOperator == T_ANGLE_STRING_LITERAL
|| m_model->m_completionOperator == T_SLASH) {
QTextCursor c(m_interface->textDocument());
QTextCursor c(interface()->textDocument());
c.setPosition(endOfExpression);
if (completeInclude(c))
m_positionForProposal = endOfExpression + 1;
return m_positionForProposal;
}
ExpressionUnderCursor expressionUnderCursor(m_interface->languageFeatures());
QTextCursor tc(m_interface->textDocument());
ExpressionUnderCursor expressionUnderCursor(cppInterface()->languageFeatures());
QTextCursor tc(interface()->textDocument());
if (m_model->m_completionOperator == T_COMMA) {
tc.setPosition(endOfExpression);
@@ -992,7 +991,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
}
QString expression;
int startOfExpression = m_interface->position();
int startOfExpression = interface()->position();
tc.setPosition(endOfExpression);
if (m_model->m_completionOperator) {
@@ -1004,7 +1003,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
// "connect(sender, &" or
// "connect(otherSender, &Foo::signal1, receiver, &"
const int beforeExpression = startOfExpression - 1;
if (canCompleteClassNameAt2ndOr4thConnectArgument(m_interface.data(),
if (canCompleteClassNameAt2ndOr4thConnectArgument(cppInterface(),
beforeExpression)) {
m_model->m_completionOperator = CompleteQt5SignalOrSlotClassNameTrigger;
} else { // Ensure global completion
@@ -1017,45 +1016,45 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
// "connect(sender, &Foo::" or
// "connect(sender, &Bar::signal1, receiver, &Foo::"
const int beforeExpression = startOfExpression - 1;
if (canCompleteConnectSignalAt2ndArgument(m_interface.data(), beforeExpression))
if (canCompleteConnectSignalAt2ndArgument(cppInterface(), beforeExpression))
m_model->m_completionOperator = CompleteQt5SignalTrigger;
else if (canCompleteConnectSignalAt4thArgument(m_interface.data(), beforeExpression))
else if (canCompleteConnectSignalAt4thArgument(cppInterface(), beforeExpression))
m_model->m_completionOperator = CompleteQt5SlotTrigger;
} else if (m_model->m_completionOperator == T_LPAREN) {
if (expression.endsWith(QLatin1String("SIGNAL"))) {
m_model->m_completionOperator = T_SIGNAL;
} else if (expression.endsWith(QLatin1String("SLOT"))) {
m_model->m_completionOperator = T_SLOT;
} else if (m_interface->position() != endOfOperator) {
} else if (interface()->position() != endOfOperator) {
// We don't want a function completion when the cursor isn't at the opening brace
expression.clear();
m_model->m_completionOperator = T_EOF_SYMBOL;
m_positionForProposal = startOfName;
startOfExpression = m_interface->position();
startOfExpression = interface()->position();
}
}
} else if (expression.isEmpty()) {
while (startOfExpression > 0 && m_interface->characterAt(startOfExpression).isSpace())
while (startOfExpression > 0 && interface()->characterAt(startOfExpression).isSpace())
--startOfExpression;
}
int line = 0, column = 0;
Utils::Text::convertPosition(m_interface->textDocument(), startOfExpression, &line, &column);
const QString fileName = m_interface->filePath().toString();
Utils::Text::convertPosition(interface()->textDocument(), startOfExpression, &line, &column);
const QString fileName = interface()->filePath().toString();
return startCompletionInternal(fileName, line, column - 1, expression, endOfExpression);
}
bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
{
int end = m_interface->position();
while (m_interface->characterAt(end).isSpace())
int end = interface()->position();
while (interface()->characterAt(end).isSpace())
++end;
if (m_interface->characterAt(end) != QLatin1Char(']'))
if (interface()->characterAt(end) != QLatin1Char(']'))
return false;
QTextCursor tc(m_interface->textDocument());
QTextCursor tc(interface()->textDocument());
tc.setPosition(end);
BackwardsScanner tokens(tc, m_interface->languageFeatures());
BackwardsScanner tokens(tc, cppInterface()->languageFeatures());
if (tokens[tokens.startToken() - 1].isNot(T_RBRACKET))
return false;
@@ -1064,23 +1063,23 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
return false;
const int startPos = tokens[start].bytesBegin() + tokens.startPosition();
const QString expr = m_interface->textAt(startPos, m_interface->position() - startPos);
const QString expr = interface()->textAt(startPos, interface()->position() - startPos);
Document::Ptr thisDocument = m_interface->snapshot().document(m_interface->filePath());
Document::Ptr thisDocument = cppInterface()->snapshot().document(interface()->filePath());
if (!thisDocument)
return false;
m_model->m_typeOfExpression->init(thisDocument, m_interface->snapshot());
m_model->m_typeOfExpression->init(thisDocument, cppInterface()->snapshot());
int line = 0, column = 0;
Utils::Text::convertPosition(m_interface->textDocument(), m_interface->position(), &line,
Utils::Text::convertPosition(interface()->textDocument(), interface()->position(), &line,
&column);
Scope *scope = thisDocument->scopeAt(line, column - 1);
if (!scope)
return false;
const QList<LookupItem> items = (*m_model->m_typeOfExpression)(expr.toUtf8(), scope);
LookupContext lookupContext(thisDocument, m_interface->snapshot());
LookupContext lookupContext(thisDocument, cppInterface()->snapshot());
for (const LookupItem &item : items) {
FullySpecifiedType ty = item.type().simplified();
@@ -1102,7 +1101,7 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
if (m_completions.isEmpty())
return false;
m_positionForProposal = m_interface->position();
m_positionForProposal = interface()->position();
return true;
}
@@ -1210,9 +1209,9 @@ bool InternalCppCompletionAssistProcessor::completeInclude(const QTextCursor &cu
}
// Make completion for all relevant includes
ProjectExplorer::HeaderPaths headerPaths = m_interface->headerPaths();
ProjectExplorer::HeaderPaths headerPaths = cppInterface()->headerPaths();
const auto currentFilePath = ProjectExplorer::HeaderPath::makeUser(
m_interface->filePath().toFileInfo().path());
interface()->filePath().toFileInfo().path());
if (!headerPaths.contains(currentFilePath))
headerPaths.append(currentFilePath);
@@ -1261,10 +1260,10 @@ void InternalCppCompletionAssistProcessor::completePreprocessor()
bool InternalCppCompletionAssistProcessor::objcKeywordsWanted() const
{
if (!m_interface->languageFeatures().objCEnabled)
if (!cppInterface()->languageFeatures().objCEnabled)
return false;
const Utils::MimeType mt = Utils::mimeTypeForFile(m_interface->filePath());
const Utils::MimeType mt = Utils::mimeTypeForFile(interface()->filePath());
return mt.matchesName(QLatin1String(CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE))
|| mt.matchesName(QLatin1String(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE));
}
@@ -1277,11 +1276,11 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
{
QString expression = expr.trimmed();
Document::Ptr thisDocument = m_interface->snapshot().document(fileName);
Document::Ptr thisDocument = cppInterface()->snapshot().document(fileName);
if (!thisDocument)
return -1;
m_model->m_typeOfExpression->init(thisDocument, m_interface->snapshot());
m_model->m_typeOfExpression->init(thisDocument, cppInterface()->snapshot());
Scope *scope = thisDocument->scopeAt(line, positionInBlock);
QTC_ASSERT(scope, return -1);
@@ -1315,14 +1314,14 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
} else if (m_model->m_completionOperator == T_LPAREN) {
// Find the expression that precedes the current name
int index = endOfExpression;
while (m_interface->characterAt(index - 1).isSpace())
while (interface()->characterAt(index - 1).isSpace())
--index;
index = findStartOfName(index);
QTextCursor tc(m_interface->textDocument());
QTextCursor tc(interface()->textDocument());
tc.setPosition(index);
ExpressionUnderCursor expressionUnderCursor(m_interface->languageFeatures());
ExpressionUnderCursor expressionUnderCursor(cppInterface()->languageFeatures());
const QString baseExpression = expressionUnderCursor(tc);
// Resolve the type of this expression
@@ -1506,7 +1505,7 @@ bool InternalCppCompletionAssistProcessor::completeMember(const QList<LookupItem
ResolveExpression resolveExpression(context);
bool *replaceDotForArrow = nullptr;
if (!m_interface->languageFeatures().objCEnabled)
if (!cppInterface()->languageFeatures().objCEnabled)
replaceDotForArrow = &m_model->m_replaceDotForArrow;
if (ClassOrNamespace *binding =
@@ -1836,7 +1835,7 @@ void InternalCppCompletionAssistProcessor::addKeywords()
addKeywordCompletionItem(QLatin1String(Token::name(i)));
// "Identifiers with special meaning"
if (m_interface->languageFeatures().cxx11Enabled) {
if (cppInterface()->languageFeatures().cxx11Enabled) {
addKeywordCompletionItem(QLatin1String("override"));
addKeywordCompletionItem(QLatin1String("final"));
}
@@ -1879,6 +1878,11 @@ void InternalCppCompletionAssistProcessor::addMacros_helper(const Snapshot &snap
}
}
const CppCompletionAssistInterface *InternalCppCompletionAssistProcessor::cppInterface() const
{
return static_cast<const CppCompletionAssistInterface *>(interface());
}
bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const QList<LookupItem> &results,
int endOfExpression,
bool toolTipOnly)
@@ -1983,7 +1987,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
// get current line and column
int lineSigned = 0, columnSigned = 0;
Utils::Text::convertPosition(m_interface->textDocument(), m_interface->position(),
Utils::Text::convertPosition(interface()->textDocument(), interface()->position(),
&lineSigned, &columnSigned);
unsigned line = lineSigned, column = columnSigned - 1;
@@ -1997,9 +2001,9 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
// declaration, we should be certain that it isn't.
bool autocompleteSignature = false;
QTextCursor tc(m_interface->textDocument());
QTextCursor tc(interface()->textDocument());
tc.setPosition(endOfExpression);
BackwardsScanner bs(tc, m_interface->languageFeatures());
BackwardsScanner bs(tc, cppInterface()->languageFeatures());
const int startToken = bs.startToken();
int lineStartToken = bs.startOfLine(startToken);
// make sure the required tokens are actually available

View File

@@ -61,7 +61,7 @@ class InternalCompletionAssistProvider : public CppCompletionAssistProvider
public:
TextEditor::IAssistProcessor *createProcessor(const TextEditor::AssistInterface *) const override;
TextEditor::AssistInterface *createAssistInterface(
std::unique_ptr<TextEditor::AssistInterface> createAssistInterface(
const Utils::FilePath &filePath,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
@@ -74,7 +74,7 @@ public:
InternalCppCompletionAssistProcessor();
~InternalCppCompletionAssistProcessor() override;
TextEditor::IAssistProposal *performAsync(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *performAsync() override;
private:
TextEditor::IAssistProposal *createContentProposal();
@@ -135,6 +135,7 @@ private:
};
QScopedPointer<const CppCompletionAssistInterface> m_interface;
const CppCompletionAssistInterface *cppInterface() const;
CppAssistProposalModelPtr m_model;
};

View File

@@ -33,7 +33,7 @@ public:
bool isActivationCharSequence(const QString &sequence) const override;
bool isContinuationChar(const QChar &c) const override;
virtual TextEditor::AssistInterface *createAssistInterface(
virtual std::unique_ptr<TextEditor::AssistInterface> createAssistInterface(
const Utils::FilePath &filePath,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,

View File

@@ -981,7 +981,7 @@ void CppEditorWidget::processKeyNormally(QKeyEvent *e)
TextEditorWidget::keyPressEvent(e);
}
static void addRefactoringActions(QMenu *menu, AssistInterface *iface)
static void addRefactoringActions(QMenu *menu, std::unique_ptr<AssistInterface> iface)
{
if (!iface || !menu)
return;
@@ -990,8 +990,8 @@ static void addRefactoringActions(QMenu *menu, AssistInterface *iface)
using Proposal = QScopedPointer<IAssistProposal>;
const Processor processor(
CppEditorPlugin::instance()->quickFixProvider()->createProcessor(iface));
const Proposal proposal(processor->perform(iface)); // OK, perform() takes ownership of iface.
CppEditorPlugin::instance()->quickFixProvider()->createProcessor(iface.get()));
const Proposal proposal(processor->start(std::move(iface)));
if (proposal) {
auto model = proposal->model().staticCast<GenericProposalModel>();
for (int index = 0; index < model->size(); ++index) {
@@ -1174,7 +1174,8 @@ bool CppEditorWidget::isOldStyleSignalOrSlot() const
== CppEditor::SignalSlotType::OldStyleSignal;
}
AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistReason reason) const
std::unique_ptr<AssistInterface> CppEditorWidget::createAssistInterface(AssistKind kind,
AssistReason reason) const
{
if (kind == Completion || kind == FunctionHint) {
CppCompletionAssistProvider * const cap = kind == Completion
@@ -1190,10 +1191,7 @@ AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistR
};
if (cap)
return cap->createAssistInterface(textDocument()->filePath(),
this,
getFeatures(),
reason);
return cap->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason);
else {
if (isOldStyleSignalOrSlot())
return CppModelManager::instance()
@@ -1203,7 +1201,7 @@ AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistR
}
} else if (kind == QuickFix) {
if (isSemanticInfoValid())
return new CppQuickFixInterface(const_cast<CppEditorWidget *>(this), reason);
return std::make_unique<CppQuickFixInterface>(const_cast<CppEditorWidget *>(this), reason);
} else {
return TextEditorWidget::createAssistInterface(kind, reason);
}

View File

@@ -43,7 +43,7 @@ public:
QSharedPointer<Internal::FunctionDeclDefLink> declDefLink() const;
void applyDeclDefLinkChanges(bool jumpToMatch);
TextEditor::AssistInterface *createAssistInterface(
std::unique_ptr<TextEditor::AssistInterface> createAssistInterface(
TextEditor::AssistKind kind,
TextEditor::AssistReason reason) const override;

View File

@@ -29,10 +29,9 @@ namespace Internal {
// -------------------------
class CppQuickFixAssistProcessor : public IAssistProcessor
{
IAssistProposal *perform(AssistInterface *interface) override
IAssistProposal *perform() override
{
QSharedPointer<const AssistInterface> dummy(interface); // FIXME: Surely this cannot be our way of doing memory management???
return GenericProposal::createProposal(interface, quickFixOperations(interface));
return GenericProposal::createProposal(interface(), quickFixOperations(interface()));
}
};

View File

@@ -87,7 +87,7 @@ public:
: m_params(params)
{}
IAssistProposal *immediateProposal(AssistInterface *) override
IAssistProposal *immediateProposal() override
{
QTC_ASSERT(m_params.function, return nullptr);
@@ -102,10 +102,8 @@ public:
return new VirtualFunctionProposal(m_params.cursorPosition, items, m_params.openInNextSplit);
}
IAssistProposal *performAsync(AssistInterface *assistInterface) override
IAssistProposal *performAsync() override
{
delete assistInterface;
QTC_ASSERT(m_params.function, return nullptr);
QTC_ASSERT(m_params.staticClass, return nullptr);
QTC_ASSERT(!m_params.snapshot.isEmpty(), return nullptr);

View File

@@ -17,6 +17,7 @@
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <texteditor/codeassist/assistinterface.h>
#include <texteditor/codeassist/asyncprocessor.h>
#include <texteditor/codeassist/genericproposalmodel.h>
#include <texteditor/codeassist/iassistprocessor.h>
@@ -119,14 +120,13 @@ public:
{
VirtualFunctionAssistProvider::configure(params);
AssistInterface *assistInterface
std::unique_ptr<AssistInterface> assistInterface
= m_editorWidget->createAssistInterface(FollowSymbol, ExplicitlyInvoked);
const QScopedPointer<AsyncProcessor> processor(
dynamic_cast<AsyncProcessor *>(createProcessor(assistInterface)));
const QScopedPointer<IAssistProposal> immediateProposal(
processor->immediateProposal(assistInterface));
const QScopedPointer<IAssistProposal> finalProposal(
processor->performAsync(assistInterface));
dynamic_cast<AsyncProcessor *>(createProcessor(assistInterface.get())));
processor->setupAssistInterface(std::move(assistInterface));
const QScopedPointer<IAssistProposal> immediateProposal(processor->immediateProposal());
const QScopedPointer<IAssistProposal> finalProposal(processor->performAsync());
VirtualFunctionAssistProvider::clearParams();

View File

@@ -1045,14 +1045,14 @@ public:
: m_provider(static_cast<const FakeVimCompletionAssistProvider *>(provider))
{}
IAssistProposal *performAsync(AssistInterface *interface) override
IAssistProposal *performAsync() override
{
const QString &needle = m_provider->needle();
const int basePosition = interface->position() - needle.size();
const int basePosition = interface()->position() - needle.size();
QTextCursor tc(interface->textDocument());
tc.setPosition(interface->position());
QTextCursor tc(interface()->textDocument());
tc.setPosition(interface()->position());
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
QList<AssistProposalItemInterface *> items;
@@ -1078,7 +1078,6 @@ public:
}
//qDebug() << "COMPLETIONS" << completions->size();
delete interface;
return new GenericProposal(basePosition,
GenericProposalModelPtr(new FakeVimAssistProposalModel(items)));
}

View File

@@ -290,17 +290,17 @@ static AssistProposalItem *createCompletionItem(const QString &text, const QIcon
return item;
}
IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *interface)
IAssistProposal *GlslCompletionAssistProcessor::performAsync()
{
m_interface.reset(static_cast<const GlslCompletionAssistInterface *>(interface));
auto interface = static_cast<const GlslCompletionAssistInterface *>(this->interface());
if (interface->reason() == IdleEditor && !acceptsIdleEditor())
return nullptr;
int pos = m_interface->position() - 1;
QChar ch = m_interface->characterAt(pos);
int pos = interface->position() - 1;
QChar ch = interface->characterAt(pos);
while (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
ch = m_interface->characterAt(--pos);
ch = interface->characterAt(--pos);
CPlusPlus::ExpressionUnderCursor expressionUnderCursor(
CPlusPlus::LanguageFeatures::defaultFeatures());
@@ -310,16 +310,16 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
QStringList specialMembers;
QList<AssistProposalItemInterface *> m_completions;
bool functionCall = (ch == QLatin1Char('(') && pos == m_interface->position() - 1);
bool functionCall = (ch == QLatin1Char('(') && pos == interface->position() - 1);
if (ch == QLatin1Char(',')) {
QTextCursor tc(m_interface->textDocument());
QTextCursor tc(interface->textDocument());
tc.setPosition(pos);
const int start = expressionUnderCursor.startOfFunctionCall(tc);
if (start == -1)
return nullptr;
if (m_interface->characterAt(start) == QLatin1Char('(')) {
if (interface->characterAt(start) == QLatin1Char('(')) {
pos = start;
ch = QLatin1Char('(');
functionCall = true;
@@ -328,7 +328,7 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
if (ch == QLatin1Char('.') || functionCall) {
const bool memberCompletion = ! functionCall;
QTextCursor tc(m_interface->textDocument());
QTextCursor tc(interface->textDocument());
tc.setPosition(pos);
// get the expression under cursor
@@ -337,7 +337,7 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
// parse the expression
GLSL::Engine engine;
GLSL::Parser parser(&engine, code, code.size(), languageVariant(m_interface->mimeType()));
GLSL::Parser parser(&engine, code, code.size(), languageVariant(interface->mimeType()));
GLSL::ExpressionAST *expr = parser.parseExpression();
#if 0
@@ -347,7 +347,7 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
dump(expr);
#endif
if (Document::Ptr doc = m_interface->glslDocument()) {
if (Document::Ptr doc = interface->glslDocument()) {
GLSL::Scope *currentScope = doc->scopeAt(pos);
GLSL::Semantic sem;
@@ -396,7 +396,7 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
} else {
// it's a global completion
if (Document::Ptr doc = m_interface->glslDocument()) {
if (Document::Ptr doc = interface->glslDocument()) {
GLSL::Scope *currentScope = doc->scopeAt(pos);
bool isGlobal = !currentScope || !currentScope->scope();
@@ -435,12 +435,12 @@ IAssistProposal *GlslCompletionAssistProcessor::performAsync(AssistInterface *in
}
}
// if (m_keywordVariant != languageVariant(m_interface->mimeType())) {
QStringList keywords = GLSL::Lexer::keywords(languageVariant(m_interface->mimeType()));
// if (m_keywordVariant != languageVariant(interface->mimeType())) {
QStringList keywords = GLSL::Lexer::keywords(languageVariant(interface->mimeType()));
// m_keywordCompletions.clear();
for (int index = 0; index < keywords.size(); ++index)
m_completions << createCompletionItem(keywords.at(index), glslIcon(IconTypeKeyword));
// m_keywordVariant = languageVariant(m_interface->mimeType());
// m_keywordVariant = languageVariant(interface->mimeType());
// }
// m_completions += m_keywordCompletions;
@@ -491,22 +491,22 @@ IAssistProposal *GlslCompletionAssistProcessor::createHintProposal(
bool GlslCompletionAssistProcessor::acceptsIdleEditor() const
{
const int cursorPosition = m_interface->position();
const QChar ch = m_interface->characterAt(cursorPosition - 1);
const int cursorPosition = interface()->position();
const QChar ch = interface()->characterAt(cursorPosition - 1);
const QChar characterUnderCursor = m_interface->characterAt(cursorPosition);
const QChar characterUnderCursor = interface()->characterAt(cursorPosition);
if (isIdentifierChar(ch) && (characterUnderCursor.isSpace() ||
characterUnderCursor.isNull() ||
isDelimiter(characterUnderCursor))) {
int pos = m_interface->position() - 1;
int pos = interface()->position() - 1;
for (; pos != -1; --pos) {
if (! isIdentifierChar(m_interface->characterAt(pos)))
if (! isIdentifierChar(interface()->characterAt(pos)))
break;
}
++pos;
const QString word = m_interface->textAt(pos, cursorPosition - pos);
const QString word = interface()->textAt(pos, cursorPosition - pos);
if (word.length() >= TextEditorSettings::completionSettings().m_characterThreshold
&& checkStartOfIdentifier(word)) {
for (auto character : word) {

View File

@@ -72,14 +72,13 @@ class GlslCompletionAssistProcessor : public TextEditor::AsyncProcessor
public:
~GlslCompletionAssistProcessor() override;
TextEditor::IAssistProposal *performAsync(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *performAsync() override;
private:
TextEditor::IAssistProposal *createHintProposal(const QVector<GLSL::Function *> &symbols);
bool acceptsIdleEditor() const;
int m_startPosition = 0;
QScopedPointer<const GlslCompletionAssistInterface> m_interface;
};
class GlslCompletionAssistInterface : public TextEditor::AssistInterface

View File

@@ -143,7 +143,8 @@ public:
QSet<QString> identifiers() const;
AssistInterface *createAssistInterface(AssistKind assistKind, AssistReason reason) const override;
std::unique_ptr<AssistInterface> createAssistInterface(AssistKind assistKind,
AssistReason reason) const override;
private:
void updateDocumentNow();
@@ -343,16 +344,17 @@ int languageVariant(const QString &type)
return variant;
}
AssistInterface *GlslEditorWidget::createAssistInterface(
std::unique_ptr<AssistInterface> GlslEditorWidget::createAssistInterface(
AssistKind kind, AssistReason reason) const
{
if (kind == Completion)
return new GlslCompletionAssistInterface(textCursor(),
textDocument()->filePath(),
reason,
textDocument()->mimeType(),
m_glslDocument);
return TextEditorWidget::createAssistInterface(kind, reason);
if (kind != Completion)
return TextEditorWidget::createAssistInterface(kind, reason);
return std::make_unique<GlslCompletionAssistInterface>(textCursor(),
textDocument()->filePath(),
reason,
textDocument()->mimeType(),
m_glslDocument);
}

View File

@@ -293,8 +293,7 @@ LanguageClientCompletionAssistProcessor::~LanguageClientCompletionAssistProcesso
QTextDocument *LanguageClientCompletionAssistProcessor::document() const
{
QTC_ASSERT(m_assistInterface, return nullptr);
return m_assistInterface->textDocument();
return interface()->textDocument();
}
QList<AssistProposalItemInterface *> LanguageClientCompletionAssistProcessor::generateCompletionItems(
@@ -314,26 +313,25 @@ static QString assistReasonString(AssistReason reason)
return QString("unknown reason");
}
IAssistProposal *LanguageClientCompletionAssistProcessor::perform(AssistInterface *interface)
IAssistProposal *LanguageClientCompletionAssistProcessor::perform()
{
m_assistInterface.reset(interface);
QTC_ASSERT(m_client, return nullptr);
m_pos = interface->position();
m_pos = interface()->position();
m_basePos = m_pos;
auto isIdentifierChar = [](const QChar &c) { return c.isLetterOrNumber() || c == '_'; };
while (m_basePos > 0 && isIdentifierChar(interface->characterAt(m_basePos - 1)))
while (m_basePos > 0 && isIdentifierChar(interface()->characterAt(m_basePos - 1)))
--m_basePos;
if (interface->reason() == IdleEditor) {
if (interface()->reason() == IdleEditor) {
// Trigger an automatic completion request only when we are on a word with at least n "identifier" characters
if (m_pos - m_basePos < TextEditorSettings::completionSettings().m_characterThreshold)
return nullptr;
if (m_client->documentUpdatePostponed(interface->filePath())) {
if (m_client->documentUpdatePostponed(interface()->filePath())) {
m_postponedUpdateConnection
= QObject::connect(m_client,
&Client::documentUpdated,
[this, interface](TextEditor::TextDocument *document) {
if (document->filePath() == interface->filePath())
perform(interface);
[this](TextEditor::TextDocument *document) {
if (document->filePath() == interface()->filePath())
perform();
});
return nullptr;
}
@@ -341,9 +339,9 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(AssistInterfac
if (m_postponedUpdateConnection)
QObject::disconnect(m_postponedUpdateConnection);
CompletionParams::CompletionContext context;
if (interface->reason() == ActivationCharacter) {
if (interface()->reason() == ActivationCharacter) {
context.setTriggerKind(CompletionParams::TriggerCharacter);
QChar triggerCharacter = interface->characterAt(interface->position() - 1);
QChar triggerCharacter = interface()->characterAt(interface()->position() - 1);
if (!triggerCharacter.isNull())
context.setTriggerCharacter(triggerCharacter);
} else {
@@ -352,13 +350,14 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(AssistInterfac
CompletionParams params;
int line;
int column;
if (!Utils::Text::convertPosition(interface->textDocument(), m_pos, &line, &column))
if (!Utils::Text::convertPosition(interface()->textDocument(), m_pos, &line, &column))
return nullptr;
--line; // line is 0 based in the protocol
--column; // column is 0 based in the protocol
params.setPosition({line, column});
params.setContext(context);
params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(interface->filePath())));
params.setTextDocument(
TextDocumentIdentifier(DocumentUri::fromFilePath(interface()->filePath())));
if (const int limit = m_client->completionResultsLimit(); limit >= 0)
params.setLimit(limit);
CompletionRequest completionRequest(params);
@@ -368,10 +367,10 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(AssistInterfac
m_client->sendMessage(completionRequest);
m_client->addAssistProcessor(this);
m_currentRequest = completionRequest.id();
m_filePath = interface->filePath();
m_filePath = interface()->filePath();
qCDebug(LOGLSPCOMPLETION) << QTime::currentTime()
<< " : request completions at " << m_pos
<< " by " << assistReasonString(interface->reason());
<< " by " << assistReasonString(interface()->reason());
return nullptr;
}

View File

@@ -59,7 +59,7 @@ class LANGUAGECLIENT_EXPORT LanguageClientCompletionAssistProcessor
public:
LanguageClientCompletionAssistProcessor(Client *client, const QString &snippetsGroup);
~LanguageClientCompletionAssistProcessor() override;
TextEditor::IAssistProposal *perform(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *perform() override;
bool running() override;
bool needsRestart() const override { return true; }
void cancel() override;
@@ -74,7 +74,6 @@ protected:
private:
void handleCompletionResponse(const LanguageServerProtocol::CompletionRequest::Response &response);
QScopedPointer<const TextEditor::AssistInterface> m_assistInterface;
Utils::FilePath m_filePath;
QPointer<Client> m_client;
std::optional<LanguageServerProtocol::MessageId> m_currentRequest;

View File

@@ -66,14 +66,13 @@ FunctionHintProcessor::FunctionHintProcessor(Client *client)
: m_client(client)
{}
IAssistProposal *FunctionHintProcessor::perform(AssistInterface *interface)
IAssistProposal *FunctionHintProcessor::perform()
{
const QScopedPointer<const AssistInterface> deleter(interface);
QTC_ASSERT(m_client, return nullptr);
m_pos = interface->position();
QTextCursor cursor(interface->textDocument());
m_pos = interface()->position();
QTextCursor cursor(interface()->textDocument());
cursor.setPosition(m_pos);
auto uri = DocumentUri::fromFilePath(interface->filePath());
auto uri = DocumentUri::fromFilePath(interface()->filePath());
SignatureHelpRequest request((TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(cursor))));
request.setResponseCallback([this](auto response) { this->handleSignatureResponse(response); });
m_client->addAssistProcessor(this);
@@ -118,7 +117,7 @@ FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client)
, m_client(client)
{}
TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor(
IAssistProcessor *FunctionHintAssistProvider::createProcessor(
const AssistInterface *) const
{
return new FunctionHintProcessor(m_client);

View File

@@ -44,7 +44,7 @@ class LANGUAGECLIENT_EXPORT FunctionHintProcessor : public TextEditor::IAssistPr
{
public:
explicit FunctionHintProcessor(Client *client);
TextEditor::IAssistProposal *perform(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *perform() override;
bool running() override { return m_currentRequest.has_value(); }
bool needsRestart() const override { return true; }
void cancel() override;

View File

@@ -45,13 +45,11 @@ void CommandQuickFixOperation::perform()
m_client->executeCommand(m_command);
}
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(AssistInterface *interface)
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform()
{
m_assistInterface = QSharedPointer<const AssistInterface>(interface);
CodeActionParams params;
params.setContext({});
QTextCursor cursor = interface->cursor();
QTextCursor cursor = interface()->cursor();
if (!cursor.hasSelection()) {
if (cursor.atBlockEnd() || cursor.atBlockStart())
cursor.select(QTextCursor::LineUnderCursor);
@@ -62,7 +60,7 @@ IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(AssistInterface
cursor.select(QTextCursor::LineUnderCursor);
Range range(cursor);
params.setRange(range);
auto uri = DocumentUri::fromFilePath(interface->filePath());
auto uri = DocumentUri::fromFilePath(interface()->filePath());
params.setTextDocument(TextDocumentIdentifier(uri));
CodeActionParams::CodeActionContext context;
context.setDiagnostics(m_client->diagnosticsAt(uri, cursor));
@@ -110,7 +108,7 @@ GenericProposal *LanguageClientQuickFixAssistProcessor::handleCodeActionResult(c
else if (auto command = std::get_if<Command>(&item))
ops << new CommandQuickFixOperation(*command, m_client);
}
return GenericProposal::createProposal(m_assistInterface.data(), ops);
return GenericProposal::createProposal(interface(), ops);
}
return nullptr;
}

View File

@@ -63,7 +63,7 @@ class LANGUAGECLIENT_EXPORT LanguageClientQuickFixAssistProcessor
public:
explicit LanguageClientQuickFixAssistProcessor(Client *client) : m_client(client) {}
bool running() override { return m_currentRequest.has_value(); }
TextEditor::IAssistProposal *perform(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *perform() override;
void cancel() override;
protected:
@@ -76,7 +76,6 @@ private:
virtual TextEditor::GenericProposal *handleCodeActionResult(
const LanguageServerProtocol::CodeActionResult &result);
QSharedPointer<const TextEditor::AssistInterface> m_assistInterface;
Client *m_client = nullptr; // not owned
std::optional<LanguageServerProtocol::MessageId> m_currentRequest;
};

View File

@@ -43,25 +43,24 @@ class NimCompletionAssistProcessor : public QObject, public TextEditor::IAssistP
Q_OBJECT
public:
TextEditor::IAssistProposal *perform(TextEditor::AssistInterface *interface) final
TextEditor::IAssistProposal *perform() final
{
QTC_ASSERT(this->thread() == qApp->thread(), return nullptr);
if (interface->reason() == IdleEditor && !acceptsIdleEditor(interface))
if (interface()->reason() == IdleEditor && !acceptsIdleEditor(interface()))
return nullptr;
Suggest::NimSuggest *suggest = nimSuggestInstance(interface);
Suggest::NimSuggest *suggest = nimSuggestInstance(interface());
QTC_ASSERT(suggest, return nullptr);
if (suggest->executablePath().isEmpty() || suggest->projectFile().isEmpty())
return nullptr;
if (!suggest->isReady()) {
m_interface = interface;
QObject::connect(suggest, &Suggest::NimSuggest::readyChanged, this,
[this, suggest](bool ready) { onNimSuggestReady(suggest, ready); });
} else {
doPerform(interface, suggest);
doPerform(interface(), suggest);
}
m_running = true;
@@ -76,13 +75,13 @@ public:
private:
void onNimSuggestReady(Suggest::NimSuggest *suggest, bool ready)
{
QTC_ASSERT(m_interface, return);
QTC_ASSERT(interface(), return);
if (!ready) {
m_running = false;
setAsyncProposalAvailable(nullptr);
} else {
doPerform(m_interface, suggest);
doPerform(interface(), suggest);
}
}
@@ -231,7 +230,6 @@ private:
std::weak_ptr<Suggest::NimSuggest> m_suggest;
std::shared_ptr<Suggest::NimSuggestClientRequest> m_request;
std::unique_ptr<QTemporaryFile> m_dirtyFile;
const TextEditor::AssistInterface *m_interface = nullptr;
};

View File

@@ -76,10 +76,10 @@ bool BindingEditorWidget::event(QEvent *event)
return QmlJSEditor::QmlJSEditorWidget::event(event);
}
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
std::unique_ptr<TextEditor::AssistInterface> BindingEditorWidget::createAssistInterface(
[[maybe_unused]] TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
{
return new QmlJSEditor::QmlJSCompletionAssistInterface(
return std::make_unique<QmlJSEditor::QmlJSCompletionAssistInterface>(
textCursor(), Utils::FilePath(),
assistReason, qmljsdocument->semanticInfo());
}

View File

@@ -29,8 +29,8 @@ public:
bool event(QEvent *event) override;
TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind,
TextEditor::AssistReason assistReason) const override;
std::unique_ptr<TextEditor::AssistInterface> createAssistInterface(
TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const override;
signals:
void returnKeyClicked();

View File

@@ -315,14 +315,9 @@ QStringList qmlJSAutoComplete(QTextDocument *textDocument,
QmlJSCompletionAssistProcessor processor;
QTextCursor cursor(textDocument);
cursor.setPosition(position);
QScopedPointer<IAssistProposal> proposal(processor.perform( /* The processor takes ownership. */
new QmlJSCompletionAssistInterface(
cursor,
fileName,
reason,
info)));
if (proposal) {
std::unique_ptr<QmlJSCompletionAssistInterface>
interface = std::make_unique<QmlJSCompletionAssistInterface>(cursor, fileName, reason, info);
if (QScopedPointer<IAssistProposal> proposal{processor.start(std::move(interface))}) {
GenericProposalModelPtr model = proposal->model().staticCast<GenericProposalModel>();
int basePosition = proposal->basePosition();
@@ -525,21 +520,19 @@ IAssistProposal *QmlJSCompletionAssistProcessor::createHintProposal(
return new FunctionHintProposal(m_startPosition, model);
}
IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *assistInterface)
IAssistProposal *QmlJSCompletionAssistProcessor::performAsync()
{
m_interface.reset(static_cast<const QmlJSCompletionAssistInterface *>(assistInterface));
if (assistInterface->reason() == IdleEditor && !acceptsIdleEditor())
if (interface()->reason() == IdleEditor && !acceptsIdleEditor())
return nullptr;
m_startPosition = assistInterface->position();
while (isIdentifierChar(m_interface->textDocument()->characterAt(m_startPosition - 1), false, false))
m_startPosition = interface()->position();
while (isIdentifierChar(interface()->textDocument()->characterAt(m_startPosition - 1), false, false))
--m_startPosition;
const bool onIdentifier = m_startPosition != assistInterface->position();
const bool onIdentifier = m_startPosition != interface()->position();
m_completions.clear();
auto qmlInterface = static_cast<const QmlJSCompletionAssistInterface *>(assistInterface);
auto qmlInterface = static_cast<const QmlJSCompletionAssistInterface *>(interface());
const SemanticInfo &semanticInfo = qmlInterface->semanticInfo();
if (!semanticInfo.isValid())
return nullptr;
@@ -547,10 +540,10 @@ IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *a
const Document::Ptr document = semanticInfo.document;
bool isQmlFile = false;
if (m_interface->filePath().endsWith(".qml"))
if (interface()->filePath().endsWith(".qml"))
isQmlFile = true;
const QList<AST::Node *> path = semanticInfo.rangePath(m_interface->position());
const QList<AST::Node *> path = semanticInfo.rangePath(interface()->position());
const ContextPtr &context = semanticInfo.context;
const ScopeChain &scopeChain = semanticInfo.scopeChain(path);
@@ -561,7 +554,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *a
// a +b<complete> -> '+'
QChar completionOperator;
if (m_startPosition > 0)
completionOperator = m_interface->textDocument()->characterAt(m_startPosition - 1);
completionOperator = interface()->textDocument()->characterAt(m_startPosition - 1);
QTextCursor startPositionCursor(qmlInterface->textDocument());
startPositionCursor.setPosition(m_startPosition);
@@ -709,7 +702,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *a
}
} else if (value
&& completionOperator == QLatin1Char('(')
&& m_startPosition == m_interface->position()) {
&& m_startPosition == interface()->position()) {
// function completion
if (const FunctionValue *f = value->asFunctionValue()) {
QString functionName = expressionUnderCursor.text();
@@ -733,7 +726,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *a
}
// global completion
if (onIdentifier || assistInterface->reason() == ExplicitlyInvoked) {
if (onIdentifier || interface()->reason() == ExplicitlyInvoked) {
bool doGlobalCompletion = true;
bool doQmlKeywordCompletion = true;
@@ -845,14 +838,14 @@ IAssistProposal *QmlJSCompletionAssistProcessor::performAsync(AssistInterface *a
bool QmlJSCompletionAssistProcessor::acceptsIdleEditor() const
{
const int cursorPos = m_interface->position();
const int cursorPos = interface()->position();
bool maybeAccept = false;
const QChar &charBeforeCursor = m_interface->textDocument()->characterAt(cursorPos - 1);
const QChar &charBeforeCursor = interface()->textDocument()->characterAt(cursorPos - 1);
if (isActivationChar(charBeforeCursor)) {
maybeAccept = true;
} else {
const QChar &charUnderCursor = m_interface->textDocument()->characterAt(cursorPos);
const QChar &charUnderCursor = interface()->textDocument()->characterAt(cursorPos);
if (isValidIdentifierChar(charUnderCursor))
return false;
if (isIdentifierChar(charBeforeCursor)
@@ -863,12 +856,12 @@ bool QmlJSCompletionAssistProcessor::acceptsIdleEditor() const
int startPos = cursorPos - 1;
for (; startPos != -1; --startPos) {
if (!isIdentifierChar(m_interface->textDocument()->characterAt(startPos)))
if (!isIdentifierChar(interface()->textDocument()->characterAt(startPos)))
break;
}
++startPos;
const QString &word = m_interface->textAt(startPos, cursorPos - startPos);
const QString &word = interface()->textAt(startPos, cursorPos - startPos);
if (word.length() >= TextEditorSettings::completionSettings().m_characterThreshold
&& isIdentifierChar(word.at(0), true)) {
for (int i = 1; i < word.length(); ++i) {
@@ -881,15 +874,15 @@ bool QmlJSCompletionAssistProcessor::acceptsIdleEditor() const
}
if (maybeAccept) {
QTextCursor tc(m_interface->textDocument());
tc.setPosition(m_interface->position());
QTextCursor tc(interface()->textDocument());
tc.setPosition(interface()->position());
const QTextBlock &block = tc.block();
const QString &blockText = block.text();
const int blockState = qMax(0, block.previous().userState()) & 0xff;
Scanner scanner;
const QList<Token> tokens = scanner(blockText, blockState);
const int column = block.position() - m_interface->position();
const int column = block.position() - interface()->position();
for (const Token &tk : tokens) {
if (column >= tk.begin() && column <= tk.end()) {
if (charBeforeCursor == QLatin1Char('/') && tk.is(Token::String))

View File

@@ -57,7 +57,7 @@ public:
QmlJSCompletionAssistProcessor();
~QmlJSCompletionAssistProcessor() override;
TextEditor::IAssistProposal *performAsync(TextEditor::AssistInterface *interface) override;
TextEditor::IAssistProposal *performAsync() override;
private:
TextEditor::IAssistProposal *createContentProposal() const;
@@ -73,7 +73,6 @@ private:
const QStringList &patterns = QStringList());
int m_startPosition;
QScopedPointer<const QmlJSCompletionAssistInterface> m_interface;
QList<TextEditor::AssistProposalItemInterface *> m_completions;
TextEditor::SnippetAssistCollector m_snippetCollector;
};

View File

@@ -857,11 +857,11 @@ void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e)
QMenu *refactoringMenu = new QMenu(Tr::tr("Refactoring"), menu);
if (!m_qmlJsEditorDocument->isSemanticInfoOutdated()) {
AssistInterface *interface = createAssistInterface(QuickFix, ExplicitlyInvoked);
std::unique_ptr<AssistInterface> interface = createAssistInterface(QuickFix, ExplicitlyInvoked);
if (interface) {
QScopedPointer<IAssistProcessor> processor(
Internal::QmlJSEditorPlugin::quickFixAssistProvider()->createProcessor(interface));
QScopedPointer<IAssistProposal> proposal(processor->perform(interface));
Internal::QmlJSEditorPlugin::quickFixAssistProvider()->createProcessor(interface.get()));
QScopedPointer<IAssistProposal> proposal(processor->start(std::move(interface)));
if (!proposal.isNull()) {
GenericProposalModelPtr model = proposal->model().staticCast<GenericProposalModel>();
for (int index = 0; index < model->size(); ++index) {
@@ -999,15 +999,16 @@ bool QmlJSEditorWidget::hideContextPane()
return b;
}
AssistInterface *QmlJSEditorWidget::createAssistInterface(
std::unique_ptr<AssistInterface> QmlJSEditorWidget::createAssistInterface(
AssistKind assistKind,
AssistReason reason) const
{
if (assistKind == Completion) {
return new QmlJSCompletionAssistInterface(textCursor(), textDocument()->filePath(),
reason, m_qmlJsEditorDocument->semanticInfo());
return std::make_unique<QmlJSCompletionAssistInterface>(
textCursor(), textDocument()->filePath(), reason, m_qmlJsEditorDocument->semanticInfo());
} else if (assistKind == QuickFix) {
return new Internal::QmlJSQuickFixAssistInterface(const_cast<QmlJSEditorWidget *>(this), reason);
return std::make_unique<Internal::QmlJSQuickFixAssistInterface>(
const_cast<QmlJSEditorWidget *>(this), reason);
}
return nullptr;
}

View File

@@ -44,8 +44,8 @@ public:
void updateOutlineIndexNow();
bool isOutlineCursorChangesBlocked();
TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind,
TextEditor::AssistReason reason) const override;
std::unique_ptr<TextEditor::AssistInterface> createAssistInterface(
TextEditor::AssistKind assistKind, TextEditor::AssistReason reason) const override;
void inspectElementUnderCursor() const;

View File

@@ -48,9 +48,9 @@ QmlJSRefactoringFilePtr QmlJSQuickFixAssistInterface::currentFile() const
// ---------------------------
class QmlJSQuickFixAssistProcessor : public IAssistProcessor
{
IAssistProposal *perform(AssistInterface *interface) override
IAssistProposal *perform() override
{
return GenericProposal::createProposal(interface, findQmlJSQuickFixes(interface));
return GenericProposal::createProposal(interface(), findQmlJSQuickFixes(interface()));
}
};

View File

@@ -63,12 +63,8 @@ private:
class ClipboardAssistProcessor: public IAssistProcessor
{
public:
IAssistProposal *perform(AssistInterface *interface) override
IAssistProposal *perform() override
{
if (!interface)
return nullptr;
const QScopedPointer<const AssistInterface> AssistInterface(interface);
QIcon icon = QIcon::fromTheme(QLatin1String("edit-paste"), Utils::Icons::PASTE.icon()).pixmap(16);
CircularClipboard * clipboard = CircularClipboard::instance();
QList<AssistProposalItemInterface *> items;
@@ -82,7 +78,7 @@ public:
items.append(item);
}
return new GenericProposal(interface->position(), items);
return new GenericProposal(interface()->position(), items);
}
};

View File

@@ -17,14 +17,13 @@ AsyncProcessor::AsyncProcessor()
});
}
IAssistProposal *AsyncProcessor::perform(AssistInterface *interface)
IAssistProposal *AsyncProcessor::perform()
{
IAssistProposal *result = immediateProposal(interface);
m_interface = interface;
m_interface->prepareForAsyncUse();
IAssistProposal *result = immediateProposal();
interface()->prepareForAsyncUse();
m_watcher.setFuture(Utils::runAsync([this]() {
m_interface->recreateTextDocument();
return performAsync(m_interface);
interface()->recreateTextDocument();
return performAsync();
}));
return result;
}
@@ -44,9 +43,8 @@ void AsyncProcessor::cancel()
});
}
IAssistProposal *AsyncProcessor::immediateProposal(AssistInterface *interface)
IAssistProposal *AsyncProcessor::immediateProposal()
{
Q_UNUSED(interface)
return nullptr;
}

View File

@@ -14,18 +14,17 @@ class TEXTEDITOR_EXPORT AsyncProcessor : public TextEditor::IAssistProcessor
public:
AsyncProcessor();
IAssistProposal *perform(AssistInterface *interface) final;
IAssistProposal *perform() final;
bool running() override;
void cancel() override;
virtual IAssistProposal *performAsync(AssistInterface *interface) = 0;
virtual IAssistProposal *immediateProposal(AssistInterface *interface);
virtual IAssistProposal *performAsync() = 0;
virtual IAssistProposal *immediateProposal();
protected:
bool isCanceled() const;
private:
AssistInterface *m_interface = nullptr;
QFutureWatcher<IAssistProposal *> m_watcher;
};

View File

@@ -176,7 +176,8 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
return;
}
AssistInterface *assistInterface = m_editorWidget->createAssistInterface(kind, reason);
std::unique_ptr<AssistInterface> assistInterface =
m_editorWidget->createAssistInterface(kind, reason);
if (!assistInterface)
return;
@@ -185,8 +186,7 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
m_assistKind = kind;
m_requestProvider = provider;
IAssistProcessor *processor = provider->createProcessor(assistInterface);
IAssistProcessor *processor = provider->createProcessor(assistInterface.get());
processor->setAsyncCompletionAvailableHandler([this, reason, processor](
IAssistProposal *newProposal) {
if (!processor->running()) {
@@ -211,7 +211,7 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
}
});
if (IAssistProposal *newProposal = processor->perform(assistInterface))
if (IAssistProposal *newProposal = processor->start(std::move(assistInterface)))
displayProposal(newProposal, reason);
if (!processor->running()) {
if (isUpdate)

View File

@@ -29,7 +29,7 @@ public:
DocumentContentCompletionProcessor(const QString &snippetGroupId);
~DocumentContentCompletionProcessor() final;
IAssistProposal *performAsync(AssistInterface *interface) override;
IAssistProposal *performAsync() override;
private:
QString m_snippetGroup;
@@ -53,23 +53,21 @@ DocumentContentCompletionProcessor::~DocumentContentCompletionProcessor()
cancel();
}
IAssistProposal *DocumentContentCompletionProcessor::performAsync(AssistInterface *interface)
IAssistProposal *DocumentContentCompletionProcessor::performAsync()
{
QScopedPointer<AssistInterface> interfaceDeleter(interface);
int pos = interface->position();
int pos = interface()->position();
QChar chr;
// Skip to the start of a name
do {
chr = interface->characterAt(--pos);
chr = interface()->characterAt(--pos);
} while (chr.isLetterOrNumber() || chr == '_');
++pos;
int length = interface->position() - pos;
int length = interface()->position() - pos;
if (interface->reason() == IdleEditor) {
QChar characterUnderCursor = interface->characterAt(interface->position());
if (interface()->reason() == IdleEditor) {
QChar characterUnderCursor = interface()->characterAt(interface()->position());
if (characterUnderCursor.isLetterOrNumber()
|| length < TextEditorSettings::completionSettings().m_characterThreshold) {
return nullptr;
@@ -80,8 +78,8 @@ IAssistProposal *DocumentContentCompletionProcessor::performAsync(AssistInterfac
m_snippetGroup, QIcon(":/texteditor/images/snippet.png"));
QList<AssistProposalItemInterface *> items = snippetCollector.collect();
const QString wordUnderCursor = interface->textAt(pos, length);
const QString text = interface->textDocument()->toPlainText();
const QString wordUnderCursor = interface()->textAt(pos, length);
const QString text = interface()->textDocument()->toPlainText();
const QRegularExpression wordRE("([\\p{L}_][\\p{L}0-9_]{2,})");
QSet<QString> words;

View File

@@ -17,7 +17,7 @@ public:
DocumentContentCompletionProvider(
const QString &snippetGroup = QString(Constants::TEXT_SNIPPET_GROUP_ID));
IAssistProcessor *createProcessor(const AssistInterface *) const override;
IAssistProcessor *createProcessor(const AssistInterface *interface) const override;
private:
QString m_snippetGroup;

View File

@@ -3,6 +3,10 @@
#include "iassistprocessor.h"
#include "assistinterface.h"
#include <utils/qtcassert.h>
using namespace TextEditor;
/*!
@@ -18,6 +22,14 @@ IAssistProcessor::IAssistProcessor() = default;
IAssistProcessor::~IAssistProcessor() = default;
IAssistProposal *IAssistProcessor::start(std::unique_ptr<AssistInterface> &&interface)
{
QTC_ASSERT(!running(), return nullptr);
m_interface = std::move(interface);
QTC_ASSERT(m_interface, return nullptr);
return perform();
}
void IAssistProcessor::setAsyncProposalAvailable(IAssistProposal *proposal)
{
if (m_asyncCompletionsAvailableHandler)
@@ -30,15 +42,27 @@ void IAssistProcessor::setAsyncCompletionAvailableHandler(
m_asyncCompletionsAvailableHandler = handler;
}
bool IAssistProcessor::running() { return false; }
bool IAssistProcessor::needsRestart() const { return false; }
void IAssistProcessor::cancel() {}
AssistInterface *IAssistProcessor::interface() { return m_interface.get(); }
const AssistInterface *IAssistProcessor::interface() const { return m_interface.get(); }
#ifdef WITH_TESTS
void IAssistProcessor::setupAssistInterface(std::unique_ptr<AssistInterface> &&interface)
{
m_interface = std::move(interface);
}
#endif
/*!
\fn IAssistProposal *TextEditor::IAssistProcessor::perform(const AssistInterface *interface)
\fn IAssistProposal *TextEditor::IAssistProcessor::start()
Computes a proposal and returns it. Access to the document is made through the \a interface.
If this is an asynchronous processor the \a interface will be detached.
The processor takes ownership of the interface. Also, one should be careful in the case of
sharing data across asynchronous processors since there might be more than one instance of
them computing a proposal at a particular time.
\sa AssistInterface::detach()
*/
them computing a proposal at a particular time.*/

View File

@@ -6,6 +6,7 @@
#include <texteditor/texteditor_global.h>
#include <functional>
#include <memory>
namespace TextEditor {
@@ -18,21 +19,30 @@ public:
IAssistProcessor();
virtual ~IAssistProcessor();
virtual IAssistProposal *perform(AssistInterface *interface) = 0; // takes ownership
void setAsyncProposalAvailable(IAssistProposal *proposal);
IAssistProposal *start(std::unique_ptr<AssistInterface> &&interface);
// Internal, used by CodeAssist
using AsyncCompletionsAvailableHandler
= std::function<void (IAssistProposal *proposal)>;
void setAsyncCompletionAvailableHandler(const AsyncCompletionsAvailableHandler &handler);
void setAsyncProposalAvailable(IAssistProposal *proposal);
virtual bool running() { return false; }
virtual bool needsRestart() const { return false; }
virtual void cancel() {}
virtual bool running();
virtual bool needsRestart() const;
virtual void cancel();
#ifdef WITH_TESTS
void setupAssistInterface(std::unique_ptr<AssistInterface> &&interface);
#endif
protected:
virtual IAssistProposal *perform() = 0;
AssistInterface *interface();
const AssistInterface *interface() const;
private:
AsyncCompletionsAvailableHandler m_asyncCompletionsAvailableHandler;
std::unique_ptr<AssistInterface> m_interface;
};
} // TextEditor

View File

@@ -150,34 +150,33 @@ KeywordsCompletionAssistProcessor::KeywordsCompletionAssistProcessor(const Keywo
, m_keywords(keywords)
{}
IAssistProposal *KeywordsCompletionAssistProcessor::performAsync(AssistInterface *interface)
IAssistProposal *KeywordsCompletionAssistProcessor::performAsync()
{
QScopedPointer<const AssistInterface> assistInterface(interface);
if (isInComment(interface))
if (isInComment(interface()))
return nullptr;
int pos = interface->position();
int pos = interface()->position();
// Find start position
QChar chr = interface->characterAt(pos - 1);
QChar chr = interface()->characterAt(pos - 1);
if (chr == '(')
--pos;
// Skip to the start of a name
do {
chr = interface->characterAt(--pos);
chr = interface()->characterAt(--pos);
} while (chr.isLetterOrNumber() || chr == '_');
++pos;
int startPosition = pos;
if (interface->reason() == IdleEditor) {
QChar characterUnderCursor = interface->characterAt(interface->position());
if (characterUnderCursor.isLetterOrNumber() || interface->position() - startPosition
if (interface()->reason() == IdleEditor) {
QChar characterUnderCursor = interface()->characterAt(interface()->position());
if (characterUnderCursor.isLetterOrNumber() || interface()->position() - startPosition
< TextEditorSettings::completionSettings().m_characterThreshold) {
QList<AssistProposalItemInterface *> items;
if (m_dynamicCompletionFunction)
m_dynamicCompletionFunction(interface, &items, startPosition);
m_dynamicCompletionFunction(interface(), &items, startPosition);
if (items.isEmpty())
return nullptr;
return new GenericProposal(startPosition, items);
@@ -187,11 +186,11 @@ IAssistProposal *KeywordsCompletionAssistProcessor::performAsync(AssistInterface
// extract word
QString word;
do {
word += interface->characterAt(pos);
chr = interface->characterAt(++pos);
word += interface()->characterAt(pos);
chr = interface()->characterAt(++pos);
} while ((chr.isLetterOrNumber() || chr == '_') && chr != '(');
if (m_keywords.isFunction(word) && interface->characterAt(pos) == '(') {
if (m_keywords.isFunction(word) && interface()->characterAt(pos) == '(') {
QStringList functionSymbols = m_keywords.argsForFunction(word);
if (functionSymbols.size() == 0)
return nullptr;
@@ -201,7 +200,7 @@ IAssistProposal *KeywordsCompletionAssistProcessor::performAsync(AssistInterface
const int originalStartPos = startPosition;
QList<AssistProposalItemInterface *> items;
if (m_dynamicCompletionFunction)
m_dynamicCompletionFunction(interface, &items, startPosition);
m_dynamicCompletionFunction(interface(), &items, startPosition);
if (startPosition == originalStartPos) {
items.append(m_snippetCollector.collect());
items.append(generateProposalList(m_keywords.variables(), m_variableIcon));

View File

@@ -85,7 +85,7 @@ public:
KeywordsCompletionAssistProcessor(const Keywords &keywords);
~KeywordsCompletionAssistProcessor() override = default;
IAssistProposal *performAsync(AssistInterface *interface) override;
IAssistProposal *performAsync() override;
void setSnippetGroup(const QString &id);

View File

@@ -8534,11 +8534,11 @@ void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider)
setOverwriteMode(previousMode);
}
AssistInterface *TextEditorWidget::createAssistInterface(AssistKind kind,
AssistReason reason) const
std::unique_ptr<AssistInterface> TextEditorWidget::createAssistInterface(AssistKind kind,
AssistReason reason) const
{
Q_UNUSED(kind)
return new AssistInterface(textCursor(), d->m_document->filePath(), reason);
return std::make_unique<AssistInterface>(textCursor(), d->m_document->filePath(), reason);
}
QString TextEditorWidget::foldReplacementText(const QTextBlock &) const

View File

@@ -23,7 +23,9 @@
#include <QPlainTextEdit>
#include <QSharedPointer>
#include <functional>
#include <memory>
QT_BEGIN_NAMESPACE
class QToolBar;
@@ -259,8 +261,8 @@ public:
void invokeAssist(AssistKind assistKind, IAssistProvider *provider = nullptr);
virtual TextEditor::AssistInterface *createAssistInterface(AssistKind assistKind,
AssistReason assistReason) const;
virtual std::unique_ptr<AssistInterface> createAssistInterface(AssistKind assistKind,
AssistReason assistReason) const;
static QMimeData *duplicateMimeData(const QMimeData *source);
static QString msgTextTooLarge(quint64 size);