diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2011-10-12 13:11:20 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2011-10-12 14:07:57 +0200 |
commit | 1b036eb9e7f243077c1f7ba7edd533f62f538cf0 (patch) | |
tree | 546eb742abd30656f16ea97c7d996c6e31c011db /src/plugins/qmljseditor | |
parent | 2ecde07ca127a64be8c8305a1cfb30f0aa81f7d2 (diff) | |
download | qt-creator-1b036eb9e7f243077c1f7ba7edd533f62f538cf0.tar.gz |
QmlJS: Clean up completion logic.
To avoid '/' triggering a global completion and improve code
readability.
Change-Id: I0cdb8efb159199156a766982db8979ee987f414b
Reviewed-by: Leandro T. C. Melo <leandro.melo@nokia.com>
Diffstat (limited to 'src/plugins/qmljseditor')
-rw-r--r-- | src/plugins/qmljseditor/qmljscompletionassist.cpp | 126 |
1 files changed, 62 insertions, 64 deletions
diff --git a/src/plugins/qmljseditor/qmljscompletionassist.cpp b/src/plugins/qmljseditor/qmljscompletionassist.cpp index eae0794e78..cec78a97ed 100644 --- a/src/plugins/qmljseditor/qmljscompletionassist.cpp +++ b/src/plugins/qmljseditor/qmljscompletionassist.cpp @@ -492,6 +492,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface m_startPosition = assistInterface->position(); while (isIdentifierChar(m_interface->document()->characterAt(m_startPosition - 1), false, false)) --m_startPosition; + const bool onIdentifier = m_startPosition != assistInterface->position(); m_completions.clear(); @@ -512,7 +513,11 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface const ContextPtr &context = semanticInfo.context; const ScopeChain &scopeChain = semanticInfo.scopeChain(path); - // Search for the operator that triggered the completion. + // The completionOperator is the character under the cursor or directly before the + // identifier under cursor. Use in conjunction with onIdentifier. Examples: + // a + b<complete> -> ' ' + // a +<complete> -> '+' + // a +b<complete> -> '+' QChar completionOperator; if (m_startPosition > 0) completionOperator = m_interface->document()->characterAt(m_startPosition - 1); @@ -590,15 +595,62 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface // ### enum completion? - // completion gets triggered for / in string literals, if we don't - // return here, this will mean the snippet completion pops up for - // each / in a string literal that is not triggering file completion return 0; - } else if (completionOperator.isSpace() - || completionOperator.isNull() - || isDelimiterChar(completionOperator) - || (completionOperator == QLatin1Char('(') - && m_startPosition != m_interface->position())) { + } + // member "a.bc<complete>" or function "foo(<complete>" completion + else if (completionOperator == QLatin1Char('.') + || (completionOperator == QLatin1Char('(') && !onIdentifier)) { + // Look at the expression under cursor. + //QTextCursor tc = textWidget->textCursor(); + QTextCursor tc(qmlInterface->document()); + tc.setPosition(m_startPosition - 1); + + QmlExpressionUnderCursor expressionUnderCursor; + QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc); + + if (expression != 0 && ! isLiteral(expression)) { + // Evaluate the expression under cursor. + ValueOwner *interp = context->valueOwner(); + const Value *value = + interp->convertToObject(scopeChain.evaluate(expression)); + //qDebug() << "type:" << interp->typeId(value); + + if (value && completionOperator == QLatin1Char('.')) { // member completion + ProcessProperties processProperties(&scopeChain); + if (contextFinder.isInLhsOfBinding() && qmlScopeType) { + LhsCompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), + PropertyOrder, contextFinder.isAfterOnInLhsOfBinding()); + processProperties.setEnumerateGeneratedSlots(true); + processProperties(value, &completionAdder); + } else { + CompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), SymbolOrder); + processProperties(value, &completionAdder); + } + } else if (value + && completionOperator == QLatin1Char('(') + && m_startPosition == m_interface->position()) { + // function completion + if (const FunctionValue *f = value->asFunctionValue()) { + QString functionName = expressionUnderCursor.text(); + int indexOfDot = functionName.lastIndexOf(QLatin1Char('.')); + if (indexOfDot != -1) + functionName = functionName.mid(indexOfDot + 1); + + QStringList signature; + for (int i = 0; i < f->argumentCount(); ++i) + signature.append(f->argumentName(i)); + + return createHintProposal(functionName.trimmed(), signature); + } + } + } + + if (! m_completions.isEmpty()) + return createContentProposal(); + return 0; + } + // global completion + else if (onIdentifier || assistInterface->reason() == ExplicitlyInvoked) { bool doGlobalCompletion = true; bool doQmlKeywordCompletion = true; @@ -698,68 +750,14 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface if (!doJsKeywordCompletion) addCompletions(&m_completions, qmlWordsAlsoInJs, m_interface->keywordIcon(), KeywordOrder); } - } - else if (completionOperator == QLatin1Char('.') || completionOperator == QLatin1Char('(')) { - // Look at the expression under cursor. - //QTextCursor tc = textWidget->textCursor(); - QTextCursor tc(qmlInterface->document()); - tc.setPosition(m_startPosition - 1); - - QmlExpressionUnderCursor expressionUnderCursor; - QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc); - - if (expression != 0 && ! isLiteral(expression)) { - // Evaluate the expression under cursor. - ValueOwner *interp = context->valueOwner(); - const Value *value = - interp->convertToObject(scopeChain.evaluate(expression)); - //qDebug() << "type:" << interp->typeId(value); - - if (value && completionOperator == QLatin1Char('.')) { // member completion - ProcessProperties processProperties(&scopeChain); - if (contextFinder.isInLhsOfBinding() && qmlScopeType) { - LhsCompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), - PropertyOrder, contextFinder.isAfterOnInLhsOfBinding()); - processProperties.setEnumerateGeneratedSlots(true); - processProperties(value, &completionAdder); - } else { - CompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), SymbolOrder); - processProperties(value, &completionAdder); - } - } else if (value - && completionOperator == QLatin1Char('(') - && m_startPosition == m_interface->position()) { - // function completion - if (const FunctionValue *f = value->asFunctionValue()) { - QString functionName = expressionUnderCursor.text(); - int indexOfDot = functionName.lastIndexOf(QLatin1Char('.')); - if (indexOfDot != -1) - functionName = functionName.mid(indexOfDot + 1); - - QStringList signature; - for (int i = 0; i < f->argumentCount(); ++i) - signature.append(f->argumentName(i)); - - return createHintProposal(functionName.trimmed(), signature); - } - } - } + m_completions.append(m_snippetCollector.collect()); if (! m_completions.isEmpty()) return createContentProposal(); return 0; } - if (isQmlFile - && (completionOperator.isNull() - || completionOperator.isSpace() - || isDelimiterChar(completionOperator))) { - m_completions.append(m_snippetCollector.collect()); - } - - if (! m_completions.isEmpty()) - return createContentProposal(); return 0; } |