OSDN Git Service

QmlJS: Improve completion of signals.
authorChristian Kamm <christian.d.kamm@nokia.com>
Tue, 13 Sep 2011 12:29:47 +0000 (14:29 +0200)
committerChristian Kamm <christian.d.kamm@nokia.com>
Wed, 14 Sep 2011 11:00:29 +0000 (13:00 +0200)
* Change from Reference to FunctionValue: There was no reason for them
  being References as the argument types never need lookup.
* Enumerate in global completion: When you define 'signal foo(int a)'
  you now get completion for 'foo' and will get the function argument
  hint popup.

Change-Id: Ic348db477a34ba468dfdb690499a9cd8fd605cd2
Reviewed-on: http://codereview.qt-project.org/4774
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
src/libs/qmljs/qmljsinterpreter.cpp
src/libs/qmljs/qmljsinterpreter.h
src/libs/qmljs/qmljsvalueowner.cpp
src/libs/qmljs/qmljsvalueowner.h
src/plugins/qmljseditor/qmljscompletionassist.cpp

index 34ae127..0a44669 100644 (file)
@@ -269,21 +269,22 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
         return objectValue;
     }
 
+    // try qml builtin type names
+    if (const Value *v = valueOwner()->defaultValueForBuiltinType(typeName)) {
+        if (!v->asUndefinedValue())
+            return v;
+    }
+
+    // map other C++ types
     if (typeName == QLatin1String("QByteArray")
-            || typeName == QLatin1String("string")
             || typeName == QLatin1String("QString")) {
         return valueOwner()->stringValue();
     } else if (typeName == QLatin1String("QUrl")) {
         return valueOwner()->urlValue();
-    } else if (typeName == QLatin1String("bool")) {
-        return valueOwner()->booleanValue();
-    } else if (typeName == QLatin1String("int")
-               || typeName == QLatin1String("long")) {
+    } else if (typeName == QLatin1String("long")) {
         return valueOwner()->intValue();
     }  else if (typeName == QLatin1String("float")
-                || typeName == QLatin1String("double")
                 || typeName == QLatin1String("qreal")) {
-        // ### Review: more types here?
         return valueOwner()->realValue();
     } else if (typeName == QLatin1String("QFont")) {
         return valueOwner()->qmlFontObject();
@@ -1673,7 +1674,7 @@ ASTObjectValue::ASTObjectValue(UiQualifiedId *typeName,
                     if (def->defaultToken.isValid())
                         _defaultPropertyRef = ref;
                 } else if (def->type == UiPublicMember::Signal && !def->name.isEmpty()) {
-                    ASTSignalReference *ref = new ASTSignalReference(def, _doc, valueOwner);
+                    ASTSignal *ref = new ASTSignal(def, _doc, valueOwner);
                     _signals.append(ref);
                 }
             }
@@ -1700,7 +1701,7 @@ void ASTObjectValue::processMembers(MemberProcessor *processor) const
         // ### Should get a different value?
         processor->processGeneratedSlot(ref->onChangedSlotName(), ref);
     }
-    foreach (ASTSignalReference *ref, _signals) {
+    foreach (ASTSignal *ref, _signals) {
         processor->processSignal(ref->ast()->name.toString(), ref);
         // ### Should get a different value?
         processor->processGeneratedSlot(ref->slotName(), ref);
@@ -1894,8 +1895,8 @@ const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) con
     return valueOwner()->undefinedValue();
 }
 
-ASTSignalReference::ASTSignalReference(UiPublicMember *ast, const Document *doc, ValueOwner *valueOwner)
-    : Reference(valueOwner), _ast(ast), _doc(doc)
+ASTSignal::ASTSignal(UiPublicMember *ast, const Document *doc, ValueOwner *valueOwner)
+    : FunctionValue(valueOwner), _ast(ast), _doc(doc)
 {
     const QString &signalName = ast->name.toString();
     _slotName = QLatin1String("on");
@@ -1903,11 +1904,39 @@ ASTSignalReference::ASTSignalReference(UiPublicMember *ast, const Document *doc,
     _slotName += signalName.midRef(1);
 }
 
-ASTSignalReference::~ASTSignalReference()
+ASTSignal::~ASTSignal()
 {
 }
 
-bool ASTSignalReference::getSourceLocation(QString *fileName, int *line, int *column) const
+int ASTSignal::argumentCount() const
+{
+    int count = 0;
+    for (UiParameterList *it = _ast->parameters; it; it = it->next)
+        ++count;
+    return count;
+}
+
+const Value *ASTSignal::argument(int index) const
+{
+    UiParameterList *param = _ast->parameters;
+    for (int i = 0; param && i < index; ++i)
+        param = param->next;
+    if (!param || param->type.isEmpty())
+        return valueOwner()->undefinedValue();
+    return valueOwner()->defaultValueForBuiltinType(param->type.toString());
+}
+
+QString ASTSignal::argumentName(int index) const
+{
+    UiParameterList *param = _ast->parameters;
+    for (int i = 0; param && i < index; ++i)
+        param = param->next;
+    if (!param || param->name.isEmpty())
+        return FunctionValue::argumentName(index);
+    return param->name.toString();
+}
+
+bool ASTSignal::getSourceLocation(QString *fileName, int *line, int *column) const
 {
     *fileName = _doc->fileName();
     *line = _ast->identifierToken.startLine;
@@ -1915,10 +1944,6 @@ bool ASTSignalReference::getSourceLocation(QString *fileName, int *line, int *co
     return true;
 }
 
-const Value *ASTSignalReference::value(ReferenceContext *) const
-{
-    return valueOwner()->undefinedValue();
-}
 
 ImportInfo::ImportInfo()
     : _type(InvalidImport)
index 7b1116d..899d1be 100644 (file)
@@ -759,23 +759,26 @@ private:
     virtual const Value *value(ReferenceContext *referenceContext) const;
 };
 
-class QMLJS_EXPORT ASTSignalReference: public Reference
+class QMLJS_EXPORT ASTSignal: public FunctionValue
 {
     AST::UiPublicMember *_ast;
     const Document *_doc;
     QString _slotName;
 
 public:
-    ASTSignalReference(AST::UiPublicMember *ast, const Document *doc, ValueOwner *valueOwner);
-    virtual ~ASTSignalReference();
+    ASTSignal(AST::UiPublicMember *ast, const Document *doc, ValueOwner *valueOwner);
+    virtual ~ASTSignal();
 
     AST::UiPublicMember *ast() const { return _ast; }
     QString slotName() const { return _slotName; }
 
-    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
+    // FunctionValue interface
+    virtual int argumentCount() const;
+    virtual const Value *argument(int index) const;
+    virtual QString argumentName(int index) const;
 
-private:
-    virtual const Value *value(ReferenceContext *referenceContext) const;
+    // Value interface
+    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
 };
 
 class QMLJS_EXPORT ASTObjectValue: public ObjectValue
@@ -784,7 +787,7 @@ class QMLJS_EXPORT ASTObjectValue: public ObjectValue
     AST::UiObjectInitializer *_initializer;
     const Document *_doc;
     QList<ASTPropertyReference *> _properties;
-    QList<ASTSignalReference *> _signals;
+    QList<ASTSignal *> _signals;
     ASTPropertyReference *_defaultPropertyRef;
 
 public:
index 8a5b5ce..2f0764c 100644 (file)
@@ -928,21 +928,24 @@ const ObjectValue *ValueOwner::qmlVector3DObject()
     return _qmlVector3DObject;
 }
 
-const Value *ValueOwner::defaultValueForBuiltinType(const QString &typeName) const
+const Value *ValueOwner::defaultValueForBuiltinType(const QString &name) const
 {
-    if (typeName == QLatin1String("string"))
-        return stringValue();
-    else if (typeName == QLatin1String("url"))
-        return urlValue();
-    else if (typeName == QLatin1String("bool"))
+    if (name == QLatin1String("int")) {
+            return intValue();
+    } else if (name == QLatin1String("bool")) {
         return booleanValue();
-    else if (typeName == QLatin1String("int"))
-        return intValue();
-    else if (typeName == QLatin1String("real"))
+    }  else if (name == QLatin1String("double")
+                || name == QLatin1String("real")) {
         return realValue();
-    else if (typeName == QLatin1String("color"))
+    } else if (name == QLatin1String("string")) {
+        return stringValue();
+    } else if (name == QLatin1String("url")) {
+        return urlValue();
+    } else if (name == QLatin1String("color")) {
         return colorValue();
-    // ### more types...
-
+    } else if (name == QLatin1String("date")) {
+        return datePrototype();
+    }
+    // ### variant
     return undefinedValue();
 }
index 148e434..7e69057 100644 (file)
@@ -94,6 +94,7 @@ public:
     const ObjectValue *qmlRectObject();
     const ObjectValue *qmlVector3DObject();
 
+    // converts builtin types, such as int, string to a Value
     const Value *defaultValueForBuiltinType(const QString &typeName) const;
 
     // global object
index e14e0ce..da7426f 100644 (file)
@@ -156,8 +156,10 @@ private:
         return true;
     }
 
-    virtual bool processSignal(const QString &, const Value *)
+    virtual bool processSignal(const QString &name, const Value *value)
     {
+        if (_globalCompletion)
+            insertProperty(name, value);
         return true;
     }