forked from qt-creator/qt-creator
Show the argument names from the method's signature.
This commit is contained in:
@@ -47,11 +47,58 @@ namespace {
|
|||||||
|
|
||||||
#ifndef NO_DECLARATIVE_BACKEND
|
#ifndef NO_DECLARATIVE_BACKEND
|
||||||
|
|
||||||
|
class MetaFunction: public FunctionValue
|
||||||
|
{
|
||||||
|
QMetaMethod _method;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MetaFunction(const QMetaMethod &method, Engine *engine)
|
||||||
|
: FunctionValue(engine), _method(method)
|
||||||
|
{
|
||||||
|
engine->registerObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const Value *returnValue() const
|
||||||
|
{
|
||||||
|
return engine()->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int argumentCount() const
|
||||||
|
{
|
||||||
|
return _method.parameterNames().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const Value *argument(int) const
|
||||||
|
{
|
||||||
|
return engine()->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual QString argumentName(int index) const
|
||||||
|
{
|
||||||
|
if (index < _method.parameterNames().size())
|
||||||
|
return _method.parameterNames().at(index);
|
||||||
|
|
||||||
|
return FunctionValue::argumentName(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isVariadic() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const Value *invoke(const Activation *) const
|
||||||
|
{
|
||||||
|
return engine()->undefinedValue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class QmlObjectValue: public ObjectValue
|
class QmlObjectValue: public ObjectValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlObjectValue(const QMetaObject *metaObject, Engine *engine)
|
QmlObjectValue(const QMetaObject *metaObject, Engine *engine)
|
||||||
: ObjectValue(engine), _metaObject(metaObject) {}
|
: ObjectValue(engine), _metaObject(metaObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~QmlObjectValue() {}
|
virtual ~QmlObjectValue() {}
|
||||||
|
|
||||||
@@ -64,6 +111,28 @@ public:
|
|||||||
return propertyValue(prop);
|
return propertyValue(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int index = 0; index < _metaObject->methodCount(); ++index) {
|
||||||
|
QMetaMethod method = _metaObject->method(index);
|
||||||
|
|
||||||
|
const QString signature = QString::fromUtf8(method.signature());
|
||||||
|
|
||||||
|
const int indexOfParen = signature.indexOf(QLatin1Char('('));
|
||||||
|
if (indexOfParen == -1)
|
||||||
|
continue; // skip it, invalid signature.
|
||||||
|
|
||||||
|
const QString methodName = signature.left(indexOfParen);
|
||||||
|
|
||||||
|
if (methodName != name) {
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
|
||||||
|
return new MetaFunction(method, engine());
|
||||||
|
|
||||||
|
} else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
|
||||||
|
return new MetaFunction(method, engine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ObjectValue::lookupMember(name);
|
return ObjectValue::lookupMember(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,9 +145,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < _metaObject->methodCount(); ++index) {
|
for (int index = 0; index < _metaObject->methodCount(); ++index) {
|
||||||
QMetaMethod meth = _metaObject->method(index);
|
QMetaMethod method = _metaObject->method(index);
|
||||||
|
|
||||||
const QString signature = QString::fromUtf8(meth.signature());
|
const QString signature = QString::fromUtf8(method.signature());
|
||||||
|
|
||||||
const int indexOfParen = signature.indexOf(QLatin1Char('('));
|
const int indexOfParen = signature.indexOf(QLatin1Char('('));
|
||||||
if (indexOfParen == -1)
|
if (indexOfParen == -1)
|
||||||
@@ -86,12 +155,12 @@ public:
|
|||||||
|
|
||||||
const QString methodName = signature.left(indexOfParen);
|
const QString methodName = signature.left(indexOfParen);
|
||||||
|
|
||||||
if (meth.methodType() == QMetaMethod::Slot && meth.access() == QMetaMethod::Public) {
|
if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public) {
|
||||||
processor->processSlot(methodName, engine()->undefinedValue());
|
processor->processSlot(methodName, engine()->undefinedValue());
|
||||||
|
|
||||||
} else if (meth.methodType() == QMetaMethod::Signal && meth.access() != QMetaMethod::Private) {
|
} else if (method.methodType() == QMetaMethod::Signal && method.access() != QMetaMethod::Private) {
|
||||||
// process the signal
|
// process the signal
|
||||||
processor->processSignal(methodName, engine()->undefinedValue()); // ### FIXME: assign a decent type to the signal
|
processor->processSignal(methodName, engine()->undefinedValue());
|
||||||
|
|
||||||
QString slotName;
|
QString slotName;
|
||||||
slotName += QLatin1String("on");
|
slotName += QLatin1String("on");
|
||||||
@@ -99,7 +168,7 @@ public:
|
|||||||
slotName += methodName.midRef(1);
|
slotName += methodName.midRef(1);
|
||||||
|
|
||||||
// process the generated slot
|
// process the generated slot
|
||||||
processor->processGeneratedSlot(slotName, engine()->undefinedValue()); // ### FIXME: assign a decent type to the slot
|
processor->processGeneratedSlot(slotName, engine()->undefinedValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,11 +872,36 @@ const Value *FunctionValue::call(const ObjectValue *thisObject, const ValueList
|
|||||||
return invoke(&activation);
|
return invoke(&activation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Value *FunctionValue::returnValue() const
|
||||||
|
{
|
||||||
|
return engine()->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
int FunctionValue::argumentCount() const
|
int FunctionValue::argumentCount() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Value *FunctionValue::argument(int) const
|
||||||
|
{
|
||||||
|
return engine()->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FunctionValue::argumentName(int index) const
|
||||||
|
{
|
||||||
|
return QString::fromLatin1("arg%1").arg(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionValue::isVariadic() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value *FunctionValue::invoke(const Activation *activation) const
|
||||||
|
{
|
||||||
|
return activation->thisObject(); // ### FIXME: it should return undefined
|
||||||
|
}
|
||||||
|
|
||||||
const FunctionValue *FunctionValue::asFunctionValue() const
|
const FunctionValue *FunctionValue::asFunctionValue() const
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
@@ -1202,6 +1296,11 @@ const ObjectValue *Engine::mathObject() const
|
|||||||
return _mathObject;
|
return _mathObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::registerObject(ObjectValue *object)
|
||||||
|
{
|
||||||
|
_objects.append(object);
|
||||||
|
}
|
||||||
|
|
||||||
const Value *Engine::convertToBoolean(const Value *value)
|
const Value *Engine::convertToBoolean(const Value *value)
|
||||||
{
|
{
|
||||||
return _convertToNumber(value); // ### implement convert to bool
|
return _convertToNumber(value); // ### implement convert to bool
|
||||||
@@ -1423,8 +1522,8 @@ void Engine::initializePrototypes()
|
|||||||
addFunction(_mathObject, "exp", numberValue(), 1);
|
addFunction(_mathObject, "exp", numberValue(), 1);
|
||||||
addFunction(_mathObject, "floor", numberValue(), 1);
|
addFunction(_mathObject, "floor", numberValue(), 1);
|
||||||
addFunction(_mathObject, "log", numberValue(), 1);
|
addFunction(_mathObject, "log", numberValue(), 1);
|
||||||
addFunction(_mathObject, "max", numberValue(), 1);
|
addFunction(_mathObject, "max", numberValue(), 0);
|
||||||
addFunction(_mathObject, "min", numberValue(), 1);
|
addFunction(_mathObject, "min", numberValue(), 0);
|
||||||
addFunction(_mathObject, "pow", numberValue(), 2);
|
addFunction(_mathObject, "pow", numberValue(), 2);
|
||||||
addFunction(_mathObject, "random", numberValue(), 1);
|
addFunction(_mathObject, "random", numberValue(), 1);
|
||||||
addFunction(_mathObject, "round", numberValue(), 1);
|
addFunction(_mathObject, "round", numberValue(), 1);
|
||||||
@@ -1535,23 +1634,6 @@ ObjectValue *Engine::newQmlObject(const QString &name)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Value *FunctionValue::invoke(const Activation *activation) const
|
|
||||||
{
|
|
||||||
return activation->thisObject(); // ### FIXME: it should return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const Value *FunctionValue::argument(int /*index*/) const
|
|
||||||
{
|
|
||||||
return engine()->undefinedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Value *FunctionValue::returnValue() const
|
|
||||||
{
|
|
||||||
return engine()->undefinedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// convert to number
|
// convert to number
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -295,6 +295,8 @@ public:
|
|||||||
|
|
||||||
virtual int argumentCount() const;
|
virtual int argumentCount() const;
|
||||||
virtual const Value *argument(int index) const;
|
virtual const Value *argument(int index) const;
|
||||||
|
virtual QString argumentName(int index) const;
|
||||||
|
virtual bool isVariadic() const;
|
||||||
|
|
||||||
virtual const Value *invoke(const Activation *activation) const;
|
virtual const Value *invoke(const Activation *activation) const;
|
||||||
|
|
||||||
@@ -444,6 +446,8 @@ public:
|
|||||||
ObjectValue *globalObject() const;
|
ObjectValue *globalObject() const;
|
||||||
const ObjectValue *mathObject() const;
|
const ObjectValue *mathObject() const;
|
||||||
|
|
||||||
|
void registerObject(ObjectValue *object);
|
||||||
|
|
||||||
// prototypes
|
// prototypes
|
||||||
ObjectValue *objectPrototype() const;
|
ObjectValue *objectPrototype() const;
|
||||||
ObjectValue *functionPrototype() const;
|
ObjectValue *functionPrototype() const;
|
||||||
|
|||||||
@@ -487,7 +487,9 @@ class FunctionArgumentWidget : public QLabel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FunctionArgumentWidget();
|
FunctionArgumentWidget();
|
||||||
void showFunctionHint(const QString &functionName, int minimumArgumentCount, int startPosition);
|
void showFunctionHint(const QString &functionName,
|
||||||
|
const QStringList &signature,
|
||||||
|
int startPosition);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *e);
|
bool eventFilter(QObject *obj, QEvent *e);
|
||||||
@@ -497,6 +499,7 @@ private:
|
|||||||
void updateHintText();
|
void updateHintText();
|
||||||
|
|
||||||
QString m_functionName;
|
QString m_functionName;
|
||||||
|
QStringList m_signature;
|
||||||
int m_minimumArgumentCount;
|
int m_minimumArgumentCount;
|
||||||
int m_startpos;
|
int m_startpos;
|
||||||
int m_currentarg;
|
int m_currentarg;
|
||||||
@@ -563,13 +566,14 @@ FunctionArgumentWidget::FunctionArgumentWidget():
|
|||||||
qApp->installEventFilter(this);
|
qApp->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionArgumentWidget::showFunctionHint(const QString &functionName, int mininumArgumentCount, int startPosition)
|
void FunctionArgumentWidget::showFunctionHint(const QString &functionName, const QStringList &signature, int startPosition)
|
||||||
{
|
{
|
||||||
if (m_startpos == startPosition)
|
if (m_startpos == startPosition)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_functionName = functionName;
|
m_functionName = functionName;
|
||||||
m_minimumArgumentCount = mininumArgumentCount;
|
m_signature = signature;
|
||||||
|
m_minimumArgumentCount = signature.size();
|
||||||
m_startpos = startPosition;
|
m_startpos = startPosition;
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
m_escapePressed = false;
|
m_escapePressed = false;
|
||||||
@@ -663,7 +667,17 @@ void FunctionArgumentWidget::updateHintText()
|
|||||||
QString prettyMethod;
|
QString prettyMethod;
|
||||||
prettyMethod += QString::fromLatin1("function ");
|
prettyMethod += QString::fromLatin1("function ");
|
||||||
prettyMethod += m_functionName;
|
prettyMethod += m_functionName;
|
||||||
prettyMethod += QLatin1String("(arguments...)");
|
prettyMethod += QLatin1Char('(');
|
||||||
|
for (int i = 0; i < m_minimumArgumentCount; ++i) {
|
||||||
|
if (i != 0)
|
||||||
|
prettyMethod += QLatin1String(", ");
|
||||||
|
|
||||||
|
prettyMethod += QLatin1String("arg");
|
||||||
|
|
||||||
|
if (m_minimumArgumentCount != 1)
|
||||||
|
prettyMethod += QString::number(i + 1);
|
||||||
|
}
|
||||||
|
prettyMethod += QLatin1Char(')');
|
||||||
|
|
||||||
m_numberLabel->setText(prettyMethod);
|
m_numberLabel->setText(prettyMethod);
|
||||||
|
|
||||||
@@ -970,7 +984,12 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
|||||||
if (!m_functionArgumentWidget)
|
if (!m_functionArgumentWidget)
|
||||||
m_functionArgumentWidget = new QmlJSEditor::Internal::FunctionArgumentWidget;
|
m_functionArgumentWidget = new QmlJSEditor::Internal::FunctionArgumentWidget;
|
||||||
|
|
||||||
m_functionArgumentWidget->showFunctionHint(functionName.trimmed(), f->argumentCount(),
|
QStringList signature;
|
||||||
|
for (int i = 0; i < f->argumentCount(); ++i)
|
||||||
|
signature.append(f->argumentName(i));
|
||||||
|
|
||||||
|
m_functionArgumentWidget->showFunctionHint(functionName.trimmed(),
|
||||||
|
signature,
|
||||||
m_startPosition);
|
m_startPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user