diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp
index c7b928d7d03df30eae8002a66b38d371b0a325b6..94889f637fdca4c7d94ed67a328e8d55a8a36ba0 100644
--- a/src/libs/qmljs/qmljsbind.cpp
+++ b/src/libs/qmljs/qmljsbind.cpp
@@ -37,6 +37,58 @@ using namespace QmlJS;
 using namespace QmlJS::AST;
 using namespace QmlJS::Interpreter;
 
+namespace {
+
+class ASTFunctionValue: public FunctionValue
+{
+    FunctionDeclaration *_ast;
+    QList<NameId *> _argumentNames;
+
+public:
+    ASTFunctionValue(FunctionDeclaration *ast, Interpreter::Engine *engine)
+        : FunctionValue(engine), _ast(ast)
+    {
+        setPrototype(engine->functionPrototype());
+
+        for (FormalParameterList *it = ast->formals; it; it = it->next)
+            _argumentNames.append(it->name);
+    }
+
+    FunctionDeclaration *ast() const { return _ast; }
+
+    virtual const Value *returnValue() const
+    {
+        return engine()->undefinedValue();
+    }
+
+    virtual int argumentCount() const
+    {
+        return _argumentNames.size();
+    }
+
+    virtual const Value *argument(int) const
+    {
+        return engine()->undefinedValue();
+    }
+
+    virtual QString argumentName(int index) const
+    {
+        if (index < _argumentNames.size()) {
+            if (NameId *nameId = _argumentNames.at(index))
+                return nameId->asString();
+        }
+
+        return FunctionValue::argumentName(index);
+    }
+
+    virtual bool isVariadic() const
+    {
+        return true;
+    }
+};
+
+} // end of anonymous namespace
+
 Bind::Bind(Document::Ptr doc, Interpreter::Engine *interp)
     : _doc(doc),
       _interp(interp),
@@ -261,11 +313,7 @@ bool Bind::visit(FunctionDeclaration *ast)
     if (_currentObjectValue->property(ast->name->asString()))
         return false;
 
-    Function *function = _interp->newFunction();
-    for (FormalParameterList *iter = ast->formals; iter; iter = iter->next) {
-        function->addArgument(_interp->undefinedValue()); // ### introduce unknownValue
-        // ### store argument names
-    }
+    ASTFunctionValue *function = new ASTFunctionValue(ast, _interp);
     _currentObjectValue->setProperty(ast->name->asString(), function);
     return false; // ### eventually want to visit function bodies
 }
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index f27405b2927ab61cdf8b3d36a4cdda904e348a08..4b101bc5cb155ddd27d3f17656419f905bd9983a 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -918,7 +918,7 @@ const Value *FunctionValue::argument(int) const
 
 QString FunctionValue::argumentName(int index) const
 {
-    return QString::fromLatin1("arg%1").arg(index);
+    return QString::fromLatin1("arg%1").arg(index + 1);
 }
 
 bool FunctionValue::isVariadic() const
diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp
index ef67358972e911732b0bed5e8e9099c9e7a090ab..3c3f912aa550a39cd3878bc46ab63307c38a9aa3 100644
--- a/src/plugins/qmljseditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp
@@ -424,10 +424,13 @@ void FunctionArgumentWidget::updateHintText()
         if (i != 0)
             prettyMethod += QLatin1String(", ");
 
-        prettyMethod += QLatin1String("arg");
+        QString arg = m_signature.at(i);
+        if (arg.isEmpty()) {
+            arg = QLatin1String("arg");
+            arg += QString::number(i + 1);
+        }
 
-        if (m_minimumArgumentCount != 1)
-            prettyMethod += QString::number(i + 1);
+        prettyMethod += arg;
     }
     prettyMethod += QLatin1Char(')');