Commit 5b1a24ab authored by Christian Kamm's avatar Christian Kamm

QmlJS: Improve completion of signals.

* 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/4774Reviewed-by: default avatarThomas Hartmann <Thomas.Hartmann@nokia.com>
parent fa281be8
......@@ -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)
......
......@@ -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:
......
......@@ -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();
}
......@@ -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
......
......@@ -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;
}
......
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