forked from qt-creator/qt-creator
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:
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user