int colonCount = 0;
bool delimiterFound = false;
bool firstToken = true;
+ bool identifierExpected = false;
+ bool dotExpected = false;
while (!delimiterFound) {
if (i < 0) {
if (!readLine())
case Token::Colon:
++colonCount;
+ identifierExpected = true;
+ dotExpected = false;
+ m_bindingPropertyName.clear();
break;
- case Token::Identifier:
- if (firstToken && yyLine->midRef(token.begin(), token.length) == QLatin1String("on"))
+ case Token::Identifier: {
+ QStringRef tokenString = yyLine->midRef(token.begin(), token.length);
+ if (firstToken && tokenString == QLatin1String("on")) {
m_behaviorBinding = true;
+ } else if (identifierExpected) {
+ m_bindingPropertyName.prepend(tokenString.toString());
+ identifierExpected = false;
+ dotExpected = true;
+ } else {
+ dotExpected = false;
+ }
+ } break;
+
+ case Token::Dot:
+ if (dotExpected) {
+ dotExpected = false;
+ identifierExpected = true;
+ } else {
+ identifierExpected = false;
+ }
break;
default:
+ dotExpected = false;
+ identifierExpected = false;
break;
}
bool CompletionContextFinder::isInRhsOfBinding() const
{
- return isInQmlContext() && m_colonCount == 1;
+ return isInQmlContext() && m_colonCount >= 1;
+}
+
+QStringList CompletionContextFinder::bindingPropertyName() const
+{
+ return m_bindingPropertyName;
}
/*!
QSet<const Interpreter::ObjectValue *> _processed;
QHash<QString, const Interpreter::Value *> _properties;
bool _globalCompletion;
+ bool _enumerateGeneratedSlots;
Interpreter::Context *_context;
const Interpreter::ObjectValue *_currentObject;
public:
EnumerateProperties(Interpreter::Context *context)
: _globalCompletion(false),
+ _enumerateGeneratedSlots(false),
_context(context),
_currentObject(0)
{
_globalCompletion = globalCompletion;
}
+ void setEnumerateGeneratedSlots(bool enumerate)
+ {
+ _enumerateGeneratedSlots = enumerate;
+ }
+
QHash<QString, const Interpreter::Value *> operator ()(const Interpreter::Value *value)
{
_processed.clear();
virtual bool processGeneratedSlot(const QString &name, const Interpreter::Value *value)
{
- if (_globalCompletion || (_currentObject && _currentObject->className().endsWith(QLatin1String("Keys")))) {
+ if (_enumerateGeneratedSlots || (_currentObject && _currentObject->className().endsWith(QLatin1String("Keys")))) {
// ### FIXME: add support for attached properties.
insertProperty(name, value);
}
if (completionOperator.isSpace() || completionOperator.isNull() || isDelimiter(completionOperator) ||
(completionOperator == QLatin1Char('(') && m_startPosition != editor->position())) {
+ bool doGlobalCompletion = true;
+ bool doQmlKeywordCompletion = true;
+ bool doJsKeywordCompletion = true;
+
QTextCursor startPositionCursor(edit->document());
startPositionCursor.setPosition(m_startPosition);
CompletionContextFinder contextFinder(startPositionCursor);
if (contextFinder.isInQmlContext())
qmlScopeType = context.lookupType(document.data(), contextFinder.qmlObjectTypeName());
- bool doGlobalCompletion = true;
if (contextFinder.isInLhsOfBinding() && qmlScopeType) {
doGlobalCompletion = false;
+ doJsKeywordCompletion = false;
+
EnumerateProperties enumerateProperties(&context);
enumerateProperties.setGlobalCompletion(true);
+ enumerateProperties.setEnumerateGeneratedSlots(true);
QHashIterator<QString, const Interpreter::Value *> it(enumerateProperties(qmlScopeType));
while (it.hasNext()) {
TextEditor::CompletionItem item(this);
item.text = it.key();
- item.data = it.key();
- if (!contextFinder.isAfterOnInLhsOfBinding())
- item.data = QString(item.data.toString() + QLatin1String(": "));
item.icon = symbolIcon;
m_completions.append(item);
}
}
}
+ if (contextFinder.isInRhsOfBinding() && qmlScopeType) {
+ doQmlKeywordCompletion = false;
+ qDebug() << "property name: " << contextFinder.bindingPropertyName();
+
+ if (!contextFinder.bindingPropertyName().isEmpty()) {
+ const Interpreter::Value *value = qmlScopeType;
+ foreach (const QString &name, contextFinder.bindingPropertyName()) {
+ if (const Interpreter::ObjectValue *objectValue = value->asObjectValue()) {
+ value = objectValue->property(name, &context);
+ if (!value)
+ break;
+ } else {
+ value = 0;
+ break;
+ }
+ }
+
+ if (const Interpreter::QmlEnumValue *enumValue = dynamic_cast<const Interpreter::QmlEnumValue *>(value)) {
+ foreach (const QString &key, enumValue->keys()) {
+ TextEditor::CompletionItem item(this);
+ item.text = key;
+ item.data = QString("\"%1\"").arg(key);
+ item.icon = symbolIcon;
+ m_completions.append(item);
+ }
+ }
+ }
+ }
+
if (doGlobalCompletion) {
// It's a global completion.
EnumerateProperties enumerateProperties(&context);
item.icon = symbolIcon;
m_completions.append(item);
}
+ }
+ if (doJsKeywordCompletion) {
// add js keywords
foreach (const QString &word, Scanner::keywords()) {
TextEditor::CompletionItem item(this);
}
// add qml extra words
- if (isQmlFile) {
+ if (doQmlKeywordCompletion && isQmlFile) {
static QStringList qmlWords;
if (qmlWords.isEmpty()) {
item.icon = keywordIcon;
m_completions.append(item);
}
+
+ if (!doJsKeywordCompletion) {
+ {
+ TextEditor::CompletionItem item(this);
+ item.text = QLatin1String("default");
+ item.icon = keywordIcon;
+ m_completions.append(item);
+ }
+
+ {
+ TextEditor::CompletionItem item(this);
+ item.text = QLatin1String("function");
+ item.icon = keywordIcon;
+ m_completions.append(item);
+ }
+ }
}
}