setting method bodies for objects

This commit is contained in:
Lasse Holmstedt
2010-07-08 16:51:25 +02:00
parent 95b0641596
commit 6b4ed2145e
5 changed files with 131 additions and 26 deletions

View File

@@ -256,10 +256,20 @@ bool ClientProxy::setBindingForObject(int objectDebugId,
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
if (propertyName == QLatin1String("id") || objectDebugId == -1) if (propertyName == QLatin1String("id") || objectDebugId == -1)
return false;
qDebug() << "setBindingForObject():" << objectDebugId << propertyName << value << "isLiteral:" << isLiteralValue;
return m_client->setBindingForObject(objectDebugId, propertyName, value.toString(), isLiteralValue);
}
bool ClientProxy::setMethodBodyForObject(int objectDebugId, const QString &methodName, const QString &methodBody)
{
if (objectDebugId == -1)
return 0; return 0;
qDebug() << "executeBinding():" << objectDebugId << propertyName << value << "isLiteral:" << isLiteralValue; qDebug() << "setMethodBodyForObject():" << objectDebugId << methodName;
return m_client->setBindingForObject(objectDebugId, propertyName, value.toString(), isLiteralValue); return m_client->setMethodBody(objectDebugId, methodName, methodBody);
} }
void ClientProxy::queryEngineContext(int id) void ClientProxy::queryEngineContext(int id)

View File

@@ -60,6 +60,8 @@ public:
const QVariant &value, const QVariant &value,
bool isLiteralValue); bool isLiteralValue);
bool setMethodBodyForObject(int objectDebugId, const QString &methodName, const QString &methodBody);
// returns the object references for the given url. // returns the object references for the given url.
QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url = QUrl()) const; QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url = QUrl()) const;
QDeclarativeDebugObjectReference objectReferenceForId(int debugId) const; QDeclarativeDebugObjectReference objectReferenceForId(int debugId) const;

View File

@@ -32,6 +32,7 @@
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <qmljs/parser/qmljsastvisitor_p.h> #include <qmljs/parser/qmljsastvisitor_p.h>
#include <typeinfo>
#include <QtCore/QDebug> #include <QtCore/QDebug>
using namespace QmlJS; using namespace QmlJS;
@@ -75,6 +76,29 @@ QString ScriptBindingParser::scriptCode(UiScriptBinding *script) const
return QString(); return QString();
} }
QString ScriptBindingParser::methodName(UiSourceElement *source) const
{
if (source) {
if (FunctionDeclaration *declaration = cast<FunctionDeclaration*>(source->sourceElement)) {
return declaration->name->asString();
}
}
return QString();
}
QString ScriptBindingParser::methodCode(UiSourceElement *source) const
{
if (source) {
if (FunctionDeclaration *declaration = cast<FunctionDeclaration*>(source->sourceElement)) {
const int begin = declaration->lbraceToken.begin() + 1;
const int end = declaration->rbraceToken.end() - 1;
return doc->source().mid(begin, end - begin);
}
}
return QString();
}
static bool isLiteralValue(ExpressionNode *expr) static bool isLiteralValue(ExpressionNode *expr)
{ {
if (cast<NumericLiteral*>(expr)) if (cast<NumericLiteral*>(expr))
@@ -287,14 +311,33 @@ static QString propertyName(UiQualifiedId *id)
return s; return s;
} }
QDeclarativeDebugObjectReference Delta::objectReferenceForUiObject(const ScriptBindingParser &bindingParser, UiObjectMember *object)
{
if (UiScriptBinding *idBinding = bindingParser.id(object)) {
if (ExpressionStatement *s = cast<ExpressionStatement *>(idBinding->statement)) {
if (IdentifierExpression *idExpr = cast<IdentifierExpression *>(s->expression)) {
const QString idString = idExpr->name->asString();
const QList<QDeclarativeDebugObjectReference> refs = ClientProxy::instance()->objectReferences(_url);
foreach (const QDeclarativeDebugObjectReference &ref, refs) {
if (ref.idString() == idString)
return ref;
}
}
}
}
return QDeclarativeDebugObjectReference();
}
void Delta::operator()(Document::Ptr doc, Document::Ptr previousDoc) void Delta::operator()(Document::Ptr doc, Document::Ptr previousDoc)
{ {
_doc = doc; _doc = doc;
_previousDoc = previousDoc; _previousDoc = previousDoc;
_changes.clear(); _changes.clear();
const QUrl url = QUrl::fromLocalFile(doc->fileName()); _url = QUrl::fromLocalFile(doc->fileName());
const QList<QDeclarativeDebugObjectReference> references = ClientProxy::instance()->objectReferences(url); const QList<QDeclarativeDebugObjectReference> references = ClientProxy::instance()->objectReferences(_url);
ScriptBindingParser bindingParser(doc, references); ScriptBindingParser bindingParser(doc, references);
bindingParser.process(); bindingParser.process();
@@ -334,33 +377,54 @@ void Delta::operator()(Document::Ptr doc, Document::Ptr previousDoc)
if (scriptCode != previousScriptCode) { if (scriptCode != previousScriptCode) {
const QString property = propertyName(script->qualifiedId); const QString property = propertyName(script->qualifiedId);
qDebug() << "property:" << qPrintable(property) << scriptCode;
if (UiScriptBinding *idBinding = bindingParser.id(object)) { QDeclarativeDebugObjectReference ref = objectReferenceForUiObject(bindingParser, object);
if (ExpressionStatement *s = cast<ExpressionStatement *>(idBinding->statement)) { if (ref.debugId() != -1)
if (IdentifierExpression *idExpr = cast<IdentifierExpression *>(s->expression)) {
const QString idString = idExpr->name->asString();
qDebug() << "the enclosing object id is:" << idString;
const QList<QDeclarativeDebugObjectReference> refs = ClientProxy::instance()->objectReferences(url);
foreach (const QDeclarativeDebugObjectReference &ref, refs) {
if (ref.idString() == idString) {
updateScriptBinding(ref, script, property, scriptCode); updateScriptBinding(ref, script, property, scriptCode);
break;
} }
} }
} }
} }
} else if (UiSourceElement *uiSource = cast<UiSourceElement*>(objectMemberIt->member)) {
for (UiObjectMemberList *previousObjectMemberIt = objectMembers(previousObject);
previousObjectMemberIt; previousObjectMemberIt = previousObjectMemberIt->next)
{
if (UiSourceElement *previousSource = cast<UiSourceElement*>(previousObjectMemberIt->member)) {
if (compare(uiSource, previousSource))
{
const QString methodCode = bindingParser.methodCode(uiSource);
const QString previousMethodCode = previousBindingParser.methodCode(previousSource);
if (methodCode != previousMethodCode) {
const QString methodName = bindingParser.methodName(uiSource);
qDebug() << methodName << methodCode;
QDeclarativeDebugObjectReference ref = objectReferenceForUiObject(bindingParser, object);
if (ref.debugId() != -1)
updateMethodBody(ref, script, methodName, methodCode);
}
}
}
} }
} }
} }
}
}
} }
} }
} void Delta::updateMethodBody(const QDeclarativeDebugObjectReference &objectReference,
UiScriptBinding *scriptBinding,
const QString &methodName,
const QString &methodBody)
{
Change change;
change.script = scriptBinding;
change.ref = objectReference;
change.isLiteral = false;
_changes.append(change);
ClientProxy::instance()->setMethodBodyForObject(objectReference.debugId(), methodName, methodBody); // ### remove
} }
void Delta::updateScriptBinding(const QDeclarativeDebugObjectReference &objectReference, void Delta::updateScriptBinding(const QDeclarativeDebugObjectReference &objectReference,
@@ -371,7 +435,6 @@ void Delta::updateScriptBinding(const QDeclarativeDebugObjectReference &objectRe
qDebug() << "update script:" << propertyName << scriptCode << scriptBinding; qDebug() << "update script:" << propertyName << scriptCode << scriptBinding;
QVariant expr = scriptCode; QVariant expr = scriptCode;
//qDebug() << " " << scriptBinding->statement->kind << typeid(*scriptBinding->statement).name();
const bool isLiteral = isLiteralValue(scriptBinding); const bool isLiteral = isLiteralValue(scriptBinding);
if (isLiteral) if (isLiteral)
@@ -401,6 +464,27 @@ bool Delta::compare(UiQualifiedId *id, UiQualifiedId *other)
return false; return false;
} }
bool Delta::compare(UiSourceElement *source, UiSourceElement *other)
{
if (source == other)
return true;
else if (source && other) {
if (source->sourceElement && other->sourceElement) {
FunctionDeclaration *decl = cast<FunctionDeclaration*>(source->sourceElement);
FunctionDeclaration *otherDecl = cast<FunctionDeclaration*>(other->sourceElement);
if (decl && otherDecl
&& decl->name && otherDecl->name
&& decl->name->asString() == otherDecl->name->asString())
{
return true;
}
}
}
return false;
}
UiObjectMemberList *Delta::objectMembers(UiObjectMember *object) UiObjectMemberList *Delta::objectMembers(UiObjectMember *object)
{ {
if (UiObjectDefinition *def = cast<UiObjectDefinition *>(object)) if (UiObjectDefinition *def = cast<UiObjectDefinition *>(object))

View File

@@ -66,6 +66,8 @@ public:
QString header(UiObjectMember *member) const; QString header(UiObjectMember *member) const;
QString scriptCode(UiScriptBinding *script) const; QString scriptCode(UiScriptBinding *script) const;
QString methodName(UiSourceElement *source) const;
QString methodCode(UiSourceElement *source) const;
protected: protected:
QDeclarativeDebugObjectReference objectReference(const QString &id) const; QDeclarativeDebugObjectReference objectReference(const QString &id) const;
@@ -112,14 +114,21 @@ private:
QmlJS::AST::UiScriptBinding *scriptBinding, QmlJS::AST::UiScriptBinding *scriptBinding,
const QString &propertyName, const QString &propertyName,
const QString &scriptCode); const QString &scriptCode);
void updateMethodBody(const QDeclarativeDebugObjectReference &objectReference,
UiScriptBinding *scriptBinding,
const QString &methodName,
const QString &methodBody);
bool compare(UiSourceElement *source, UiSourceElement *other);
bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other); bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other);
QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object); QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object);
QDeclarativeDebugObjectReference objectReferenceForUiObject(const ScriptBindingParser &bindingParser, UiObjectMember *object);
private: private:
QmlJS::Document::Ptr _doc; QmlJS::Document::Ptr _doc;
QmlJS::Document::Ptr _previousDoc; QmlJS::Document::Ptr _previousDoc;
QList<Change> _changes; QList<Change> _changes;
QUrl _url;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -42,12 +42,12 @@ void QmlJSLiveTextPreview::updateDocuments()
return; return;
m_snapshot = modelManager()->snapshot(); m_snapshot = modelManager()->snapshot();
setEditor(Core::EditorManager::instance()->currentEditor());
// initial update // initial update
foreach (QmlJS::Document::Ptr doc, m_snapshot) { foreach (QmlJS::Document::Ptr doc, m_snapshot) {
documentChanged(doc); documentChanged(doc);
} }
connect(modelManager(), SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), connect(modelManager(), SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)),
SLOT(documentChanged(QmlJS::Document::Ptr))); SLOT(documentChanged(QmlJS::Document::Ptr)));
} }
@@ -111,7 +111,7 @@ void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
if (!core->hasContext(dbgcontext)) if (!core->hasContext(dbgcontext))
return; return;
if (doc && m_previousDoc) { if (doc && m_previousDoc && doc->fileName() == m_previousDoc->fileName()) {
qDebug() << "Doc, prevDoc:" << doc->fileName() << m_previousDoc->fileName(); qDebug() << "Doc, prevDoc:" << doc->fileName() << m_previousDoc->fileName();
Delta delta; Delta delta;