Commit 3b8b6e89 authored by Christian Kamm's avatar Christian Kamm
Browse files

QmlJS: Autocomplete dot and colon for properties.

Reviewed-by: Roberto Raggi
parent d0d61182
......@@ -217,15 +217,6 @@
<property name="heightRatio" type="qreal"/>
<signal name="pageChanged"/>
</type>
<type name="QDeclarativeGraphicsWidget" defaultProperty="children" extends="Qt.QGraphicsWidget">
<property name="anchors" type="QDeclarativeAnchors"/>
<property name="left" type="QDeclarativeAnchorLine"/>
<property name="right" type="QDeclarativeAnchorLine"/>
<property name="horizontalCenter" type="QDeclarativeAnchorLine"/>
<property name="top" type="QDeclarativeAnchorLine"/>
<property name="bottom" type="QDeclarativeAnchorLine"/>
<property name="verticalCenter" type="QDeclarativeAnchorLine"/>
</type>
<type name="QDeclarativeImageBase" defaultProperty="data" extends="Qt.Item">
<enum name="Status">
<enumerator name="Null" value="0"/>
......@@ -1456,12 +1447,12 @@
<type name="Qt.AnchorAnimation" version="4.7" extends="Qt.Animation">
<property name="targets" type="Qt.Item" isList="true"/>
<property name="duration" type="int"/>
<property name="easing" type="Qt.Easing"/>
<property name="easing" type="QEasingCurve"/>
<signal name="durationChanged">
<param type="int"/>
</signal>
<signal name="easingChanged">
<param type="Qt.Easing"/>
<param type="QEasingCurve"/>
</signal>
</type>
<type name="Qt.AnchorChanges" version="4.7" extends="QDeclarativeStateOperation">
......@@ -2405,7 +2396,7 @@
<property name="duration" type="int"/>
<property name="from" type="QVariant"/>
<property name="to" type="QVariant"/>
<property name="easing" type="Qt.Easing"/>
<property name="easing" type="QEasingCurve"/>
<property name="target" type="Qt.QtObject"/>
<property name="property" type="string"/>
<property name="properties" type="string"/>
......@@ -2421,7 +2412,7 @@
<param type="QVariant"/>
</signal>
<signal name="easingChanged">
<param type="Qt.Easing"/>
<param type="QEasingCurve"/>
</signal>
<signal name="propertiesChanged">
<param type="string"/>
......@@ -2436,24 +2427,14 @@
<property name="restoreEntryValues" type="bool"/>
<property name="explicit" type="bool"/>
</type>
<type name="Qt.QGraphicsWidget" version="4.7" defaultProperty="children" extends="QGraphicsObject">
<property name="palette" type="QPalette"/>
<property name="font" type="QFont"/>
<property name="layoutDirection" type="Qt.LayoutDirection"/>
<property name="size" type="QSizeF"/>
<property name="minimumSize" type="QSizeF"/>
<property name="preferredSize" type="QSizeF"/>
<property name="maximumSize" type="QSizeF"/>
<property name="sizePolicy" type="QSizePolicy"/>
<property name="focusPolicy" type="Qt.FocusPolicy"/>
<property name="windowFlags" type="Qt.WindowFlags"/>
<property name="windowTitle" type="string"/>
<property name="geometry" type="QRectF"/>
<property name="autoFillBackground" type="bool"/>
<property name="layout" type="QGraphicsLayout"/>
<signal name="geometryChanged"/>
<signal name="layoutChanged"/>
<method name="close" type="bool"/>
<type name="Qt.QGraphicsWidget" version="4.7" defaultProperty="children" extends="__extended__.Qt.QGraphicsWidget">
<property name="anchors" type="QDeclarativeAnchors"/>
<property name="left" type="QDeclarativeAnchorLine"/>
<property name="right" type="QDeclarativeAnchorLine"/>
<property name="horizontalCenter" type="QDeclarativeAnchorLine"/>
<property name="top" type="QDeclarativeAnchorLine"/>
<property name="bottom" type="QDeclarativeAnchorLine"/>
<property name="verticalCenter" type="QDeclarativeAnchorLine"/>
</type>
<type name="Qt.QtObject" version="4.7">
<property name="objectName" type="string"/>
......@@ -3092,6 +3073,25 @@
<param name="count" type="int"/>
</method>
</type>
<type name="__extended__.Qt.QGraphicsWidget" version="4.7" defaultProperty="children" extends="QGraphicsObject">
<property name="palette" type="QPalette"/>
<property name="font" type="QFont"/>
<property name="layoutDirection" type="Qt.LayoutDirection"/>
<property name="size" type="QSizeF"/>
<property name="minimumSize" type="QSizeF"/>
<property name="preferredSize" type="QSizeF"/>
<property name="maximumSize" type="QSizeF"/>
<property name="sizePolicy" type="QSizePolicy"/>
<property name="focusPolicy" type="Qt.FocusPolicy"/>
<property name="windowFlags" type="Qt.WindowFlags"/>
<property name="windowTitle" type="string"/>
<property name="geometry" type="QRectF"/>
<property name="autoFillBackground" type="bool"/>
<property name="layout" type="QGraphicsLayout"/>
<signal name="geometryChanged"/>
<signal name="layoutChanged"/>
<method name="close" type="bool"/>
</type>
<type name="org.webkit.WebView" version="1.0" defaultProperty="data" extends="Qt.Item">
<enum name="Status">
<enumerator name="Null" value="0"/>
......@@ -3167,8 +3167,5 @@
<param name="maxzoom" type="qreal"/>
</method>
</type>
<type name="Script">
<property name="script" type="string"/>
<property name="source" type="QUrl"/>
</type>
<type name="QEasingCurve" extends="Qt.Easing"/>
</module>
......@@ -911,6 +911,23 @@ bool QmlObjectValue::enumContainsKey(const QString &enumName, const QString &enu
return false;
}
// Returns true if this object is in a package or if there is an object that
// has this one in its prototype chain and is itself in a package.
bool QmlObjectValue::hasChildInPackage() const
{
if (!packageName().isEmpty())
return true;
foreach (const FakeMetaObject *other, MetaTypeSystem::_metaObjects) {
if (other->packageName().isEmpty())
continue;
for (const FakeMetaObject *iter = other; iter; iter = iter->superClass()) {
if (iter == _metaObject) // this object is a parent of other
return true;
}
}
return false;
}
bool QmlObjectValue::isDerivedFrom(const FakeMetaObject *base) const
{
for (const FakeMetaObject *iter = _metaObject; iter; iter = iter->superClass()) {
......
......@@ -404,6 +404,7 @@ public:
bool isListProperty(const QString &name) const;
bool isEnum(const QString &typeName) const;
bool enumContainsKey(const QString &enumName, const QString &enumKeyName) const;
bool hasChildInPackage() const;
protected:
const Value *findOrCreateSignature(int index, const FakeMetaMethod &method, QString *methodName) const;
......@@ -531,6 +532,8 @@ public:
private:
QHash<QString, QList<QmlObjectValue *> > _importedTypes;
friend class QmlObjectValue;
};
class ConvertToNumber: protected ValueVisitor // ECMAScript ToInt()
......
......@@ -622,6 +622,31 @@ void CodeCompletion::addCompletions(const QStringList &newCompletions,
}
}
void CodeCompletion::addCompletionsPropertyLhs(
const QHash<QString, const Interpreter::Value *> &newCompletions,
const QIcon &icon)
{
QHashIterator<QString, const Interpreter::Value *> it(newCompletions);
while (it.hasNext()) {
it.next();
TextEditor::CompletionItem item(this);
item.text = it.key();
if (const Interpreter::QmlObjectValue *qmlValue = dynamic_cast<const Interpreter::QmlObjectValue *>(it.value())) {
// to distinguish "anchors." from "gradient:" we check if the right hand side
// type is instantiatable or is the prototype of an instantiatable object
if (qmlValue->hasChildInPackage())
item.text.append(QLatin1String(": "));
else
item.text.append(QLatin1Char('.'));
} else {
item.text.append(QLatin1String(": "));
}
item.icon = icon;
m_completions.append(item);
}
}
int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
{
m_editor = editor;
......@@ -665,6 +690,14 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
if (m_startPosition > 0)
completionOperator = editor->characterAt(m_startPosition - 1);
QTextCursor startPositionCursor(edit->document());
startPositionCursor.setPosition(m_startPosition);
CompletionContextFinder contextFinder(startPositionCursor);
const Interpreter::ObjectValue *qmlScopeType = 0;
if (contextFinder.isInQmlContext())
qmlScopeType = context.lookupType(document.data(), contextFinder.qmlObjectTypeName());
if (completionOperator.isSpace() || completionOperator.isNull() || isDelimiter(completionOperator) ||
(completionOperator == QLatin1Char('(') && m_startPosition != editor->position())) {
......@@ -672,14 +705,6 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
bool doQmlKeywordCompletion = true;
bool doJsKeywordCompletion = true;
QTextCursor startPositionCursor(edit->document());
startPositionCursor.setPosition(m_startPosition);
CompletionContextFinder contextFinder(startPositionCursor);
const Interpreter::ObjectValue *qmlScopeType = 0;
if (contextFinder.isInQmlContext())
qmlScopeType = context.lookupType(document.data(), contextFinder.qmlObjectTypeName());
if (contextFinder.isInLhsOfBinding() && qmlScopeType) {
doGlobalCompletion = false;
doJsKeywordCompletion = false;
......@@ -688,7 +713,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
enumerateProperties.setGlobalCompletion(true);
enumerateProperties.setEnumerateGeneratedSlots(true);
addCompletions(enumerateProperties(qmlScopeType), symbolIcon);
addCompletionsPropertyLhs(enumerateProperties(qmlScopeType), symbolIcon);
addCompletions(enumerateProperties(context.scopeChain().qmlTypes), symbolIcon);
if (ScopeBuilder::isPropertyChangesObject(&context, qmlScopeType)
......@@ -776,7 +801,10 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
if (value && completionOperator == QLatin1Char('.')) { // member completion
EnumerateProperties enumerateProperties(&context);
addCompletions(enumerateProperties(value), symbolIcon);
if (contextFinder.isInLhsOfBinding() && qmlScopeType)
addCompletionsPropertyLhs(enumerateProperties(value), symbolIcon);
else
addCompletions(enumerateProperties(value), symbolIcon);
} else if (value && completionOperator == QLatin1Char('(') && m_startPosition == editor->position()) {
// function completion
if (const Interpreter::FunctionValue *f = value->asFunctionValue()) {
......
......@@ -84,6 +84,9 @@ private:
const QIcon &icon);
void addCompletions(const QStringList &newCompletions,
const QIcon &icon);
void addCompletionsPropertyLhs(
const QHash<QString, const QmlJS::Interpreter::Value *> &newCompletions,
const QIcon &icon);
ModelManagerInterface *m_modelManager;
TextEditor::ITextEditable *m_editor;
......
......@@ -217,33 +217,16 @@ void dump(const QMetaObject *meta, QXmlStreamWriter *xml)
xml->writeEndElement();
}
void writeScriptElement(QXmlStreamWriter *xml)
void writeEasingCurve(QXmlStreamWriter *xml)
{
xml->writeStartElement("type");
{
QXmlStreamAttributes attributes;
attributes.append(QXmlStreamAttribute("name", "Script"));
attributes.append(QXmlStreamAttribute("name", "QEasingCurve"));
attributes.append(QXmlStreamAttribute("extends", "Qt.Easing"));
xml->writeAttributes(attributes);
}
xml->writeStartElement("property");
{
QXmlStreamAttributes attributes;
attributes.append(QXmlStreamAttribute("name", "script"));
attributes.append(QXmlStreamAttribute("type", "string"));
xml->writeAttributes(attributes);
}
xml->writeEndElement();
xml->writeStartElement("property");
{
QXmlStreamAttributes attributes;
attributes.append(QXmlStreamAttribute("name", "source"));
attributes.append(QXmlStreamAttribute("type", "QUrl"));
xml->writeAttributes(attributes);
}
xml->writeEndElement();
xml->writeEndElement();
}
......@@ -268,7 +251,6 @@ int main(int argc, char *argv[])
}
cppToQml.insert("QString", "string");
cppToQml.insert("QEasingCurve", "Qt.Easing");
cppToQml.insert("QDeclarativeEasingValueType::Type", "Type");
QSet<const QMetaObject *> metas;
......@@ -340,7 +322,8 @@ int main(int argc, char *argv[])
dump(meta, &xml);
}
writeScriptElement(&xml);
// define QEasingCurve as an extension of Qt.Easing
writeEasingCurve(&xml);
xml.writeEndElement();
xml.writeEndDocument();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment