summaryrefslogtreecommitdiff
path: root/src/plugins/qmljseditor
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2011-10-12 13:11:20 +0200
committerChristian Kamm <christian.d.kamm@nokia.com>2011-10-12 14:07:57 +0200
commit1b036eb9e7f243077c1f7ba7edd533f62f538cf0 (patch)
tree546eb742abd30656f16ea97c7d996c6e31c011db /src/plugins/qmljseditor
parent2ecde07ca127a64be8c8305a1cfb30f0aa81f7d2 (diff)
downloadqt-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.cpp126
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;
}