Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
None
-
Qt Creator 2.1.0-beta1
Description
When debugging qml code, the live preview feature updates the running application with new changes in the code.
Breakpoints are set in javascript blocks of code inside the qml source.
If the user modifies the code in these blocks during debugging, the changes are sent to the qmlobserver application and updated immediately.
Internally, UpdateObserver::updateScriptBinding in qmljslivepreview.cpp is called. This sends a message "SET_BINDING" through the ClientProxy, which is received on the other side by QDeclarativeEngineDebugServer::messageReceived. QDeclarativeEngineDebugServer::setBinding is called. This method creates a new QDeclarativeExpression that substitutes the old code. The location of the new expression ( source filename and linenumber ) is not copied over, so the new expression's internal state points to file "" and line -1.
Later on, during execution of the program, the expression will be evaluated through QDeclarativeExpressionPrivate::scriptValue, which in turn calls JSDebuggerAgent::positionChange. This method is the one who compares the current source location with the breakpoint list. In this case, since the expression doesn't have a valid location, no breakpoint is matched, and therefore the debugger doesn't stop.
In practical terms it means that changing javascript code with the live preview disables any existing breakpoints in that block of code. The solution from the user perspective is to restart the qml application.
The proposed solution is to copy over the source location from the old expression to the new expression.
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -502,7 +502,8 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId, property.write(expression); } else if (hasValidSignal(object, propertyName)) { QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); - QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + declarativeExpression->setSourceLocation(oldExpression->sourceFile(),oldExpression->lineNumber()); } else if (property.isProperty()) { QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); binding->setTarget(property);
We still have to check if the source location / breakpoint location would have to be updated if code in other parts of the file changes.