Debugger: Save/restore expression node values.

- This allows expression results to be highlighted for value changes
  as we already do for regular variable values.
This commit is contained in:
Rene Gollent
2014-11-08 11:16:44 -05:00
parent b7e72db3cc
commit e646545b60
@@ -2470,6 +2470,14 @@ VariablesView::_SaveViewState() const
if (values->Init() != B_OK) if (values->Init() != B_OK)
return; return;
ExpressionValues* expressionValues = new(std::nothrow) ExpressionValues;
if (expressionValues == NULL)
return;
BReference<ExpressionValues> expressionReference(expressionValues, true);
if (expressionValues->Init() != B_OK)
return;
// create an empty view state // create an empty view state
VariablesViewState* viewState = new(std::nothrow) VariablesViewState; VariablesViewState* viewState = new(std::nothrow) VariablesViewState;
if (viewState == NULL) if (viewState == NULL)
@@ -2480,6 +2488,7 @@ VariablesView::_SaveViewState() const
return; return;
viewState->SetValues(values); viewState->SetValues(values);
viewState->SetExpressionValues(expressionValues);
// populate it // populate it
TreeTablePath path; TreeTablePath path;
@@ -2546,33 +2555,47 @@ VariablesView::_AddViewStateDescendentNodeInfos(VariablesViewState* viewState,
nodeInfo.SetRendererSettings(settings->Message()); nodeInfo.SetRendererSettings(settings->Message());
} }
Variable* variable = node->GetVariable();
if (variable == NULL) {
// ignore synthetic nodes
continue;
}
ObjectID* id = variable->ID();
TypeComponentPath* componentPath = node->GetPath();
status_t error = viewState->SetNodeInfo(id, componentPath, nodeInfo);
if (error != B_OK)
return error;
Value* value = node->GetValue(); Value* value = node->GetValue();
if (value != NULL) { Variable* variable = node->GetVariable();
BVariant variableValueData; if (variable != NULL) {
if (value->ToVariant(variableValueData)) TypeComponentPath* componentPath = node->GetPath();
error = viewState->Values()->SetValue(id, componentPath, ObjectID* id = variable->ID();
variableValueData);
status_t error = viewState->SetNodeInfo(id, componentPath, nodeInfo);
if (error != B_OK) if (error != B_OK)
return error; return error;
}
// recurse if (value != NULL) {
error = _AddViewStateDescendentNodeInfos(viewState, node, path); BVariant variableValueData;
if (error != B_OK) if (value->ToVariant(variableValueData))
return error; error = viewState->Values()->SetValue(id, componentPath,
variableValueData);
if (error != B_OK)
return error;
}
// recurse
error = _AddViewStateDescendentNodeInfos(viewState, node, path);
if (error != B_OK)
return error;
} else {
ExpressionValueNodeChild* child
= dynamic_cast<ExpressionValueNodeChild*>(node->NodeChild());
if (child != NULL && value != NULL) {
BVariant variableValueData;
if (value->ToVariant(variableValueData)) {
FunctionID* id = fStackFrame->Function()->GetFunctionID();
if (id == NULL)
return B_NO_MEMORY;
BReference<FunctionID> functionReference(id, true);
status_t error = viewState->GetExpressionValues()
->SetValue(id, fThread, child->GetExpression(),
variableValueData);
if (error != B_OK)
return error;
}
}
}
path.RemoveLastComponent(); path.RemoveLastComponent();
} }
@@ -2593,49 +2616,62 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState,
// apply the node's info, if any // apply the node's info, if any
Variable* variable = node->GetVariable(); Variable* variable = node->GetVariable();
if (variable == NULL) { if (variable != NULL) {
// ignore synthetic nodes ObjectID* objectID = node->GetVariable()->ID();
return B_OK; TypeComponentPath* componentPath = node->GetPath();
} const VariablesViewNodeInfo* nodeInfo = viewState->GetNodeInfo(
ObjectID* objectID = node->GetVariable()->ID(); objectID, componentPath);
TypeComponentPath* componentPath = node->GetPath(); if (nodeInfo != NULL) {
const VariablesViewNodeInfo* nodeInfo = viewState->GetNodeInfo( // NB: if the node info indicates that the node in question
objectID, componentPath); // was being cast to a different type, this *must* be applied
if (nodeInfo != NULL) { // before any other view state restoration, since it
// NB: if the node info indicates that the node in question // potentially changes the child hierarchy under that node.
// was being cast to a different type, this *must* be applied Type* type = nodeInfo->GetCastedType();
// before any other view state restoration, since it potentially if (type != NULL) {
// changes the child hierarchy under that node. ValueNode* valueNode = NULL;
Type* type = nodeInfo->GetCastedType(); if (TypeHandlerRoster::Default()->CreateValueNode(
if (type != NULL) { node->NodeChild(), type, valueNode) == B_OK) {
ValueNode* valueNode = NULL; node->NodeChild()->SetNode(valueNode);
if (TypeHandlerRoster::Default()->CreateValueNode( node->SetCastedType(type);
node->NodeChild(), type, valueNode) == B_OK) { }
node->NodeChild()->SetNode(valueNode); }
node->SetCastedType(type);
// we don't have a renderer yet so we can't apply the settings
// at this stage. Store them on the model node so we can lazily
// apply them once the value is retrieved.
node->SetLastRendererSettings(nodeInfo->GetRendererSettings());
fVariableTable->SetNodeExpanded(path,
nodeInfo->IsNodeExpanded());
BVariant previousValue;
if (viewState->Values()->GetValue(objectID, componentPath,
previousValue)) {
node->SetPreviousValue(previousValue);
} }
} }
} else {
// we don't have a renderer yet so we can't apply the settings ExpressionValueNodeChild* child
// at this stage. Store them on the model node so we can lazily = dynamic_cast<ExpressionValueNodeChild*>(node->NodeChild());
// apply them once the value is retrieved. if (child != NULL) {
node->SetLastRendererSettings(nodeInfo->GetRendererSettings()); BVariant previousValue;
FunctionID* id = fStackFrame->Function()->GetFunctionID();
fVariableTable->SetNodeExpanded(path, nodeInfo->IsNodeExpanded()); if (id == NULL)
return B_NO_MEMORY;
BVariant previousValue; BReference<FunctionID> idReference(id, true);
if (viewState->Values()->GetValue(objectID, componentPath, if (viewState->GetExpressionValues()->GetValue(id, fThread,
previousValue)) { child->GetExpression(), previousValue)) {
node->SetPreviousValue(previousValue); node->SetPreviousValue(previousValue);
}
} }
// recurse
status_t error = _ApplyViewStateDescendentNodeInfos(viewState, node,
path);
if (error != B_OK)
return error;
} }
// recurse
status_t error = _ApplyViewStateDescendentNodeInfos(viewState, node,
path);
if (error != B_OK)
return error;
path.RemoveLastComponent(); path.RemoveLastComponent();
} }