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,20 +2555,16 @@ VariablesView::_AddViewStateDescendentNodeInfos(VariablesViewState* viewState,
nodeInfo.SetRendererSettings(settings->Message()); nodeInfo.SetRendererSettings(settings->Message());
} }
Value* value = node->GetValue();
Variable* variable = node->GetVariable(); Variable* variable = node->GetVariable();
if (variable == NULL) { if (variable != NULL) {
// ignore synthetic nodes
continue;
}
ObjectID* id = variable->ID();
TypeComponentPath* componentPath = node->GetPath(); TypeComponentPath* componentPath = node->GetPath();
ObjectID* id = variable->ID();
status_t error = viewState->SetNodeInfo(id, componentPath, nodeInfo); status_t error = viewState->SetNodeInfo(id, componentPath, nodeInfo);
if (error != B_OK) if (error != B_OK)
return error; return error;
Value* value = node->GetValue();
if (value != NULL) { if (value != NULL) {
BVariant variableValueData; BVariant variableValueData;
if (value->ToVariant(variableValueData)) if (value->ToVariant(variableValueData))
@@ -2573,6 +2578,24 @@ VariablesView::_AddViewStateDescendentNodeInfos(VariablesViewState* viewState,
error = _AddViewStateDescendentNodeInfos(viewState, node, path); error = _AddViewStateDescendentNodeInfos(viewState, node, path);
if (error != B_OK) if (error != B_OK)
return error; 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,10 +2616,7 @@ 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
return B_OK;
}
ObjectID* objectID = node->GetVariable()->ID(); ObjectID* objectID = node->GetVariable()->ID();
TypeComponentPath* componentPath = node->GetPath(); TypeComponentPath* componentPath = node->GetPath();
const VariablesViewNodeInfo* nodeInfo = viewState->GetNodeInfo( const VariablesViewNodeInfo* nodeInfo = viewState->GetNodeInfo(
@@ -2604,8 +2624,8 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState,
if (nodeInfo != NULL) { if (nodeInfo != NULL) {
// NB: if the node info indicates that the node in question // NB: if the node info indicates that the node in question
// was being cast to a different type, this *must* be applied // was being cast to a different type, this *must* be applied
// before any other view state restoration, since it potentially // before any other view state restoration, since it
// changes the child hierarchy under that node. // potentially changes the child hierarchy under that node.
Type* type = nodeInfo->GetCastedType(); Type* type = nodeInfo->GetCastedType();
if (type != NULL) { if (type != NULL) {
ValueNode* valueNode = NULL; ValueNode* valueNode = NULL;
@@ -2621,20 +2641,36 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState,
// apply them once the value is retrieved. // apply them once the value is retrieved.
node->SetLastRendererSettings(nodeInfo->GetRendererSettings()); node->SetLastRendererSettings(nodeInfo->GetRendererSettings());
fVariableTable->SetNodeExpanded(path, nodeInfo->IsNodeExpanded()); fVariableTable->SetNodeExpanded(path,
nodeInfo->IsNodeExpanded());
BVariant previousValue; BVariant previousValue;
if (viewState->Values()->GetValue(objectID, componentPath, if (viewState->Values()->GetValue(objectID, componentPath,
previousValue)) { previousValue)) {
node->SetPreviousValue(previousValue); node->SetPreviousValue(previousValue);
} }
}
} else {
ExpressionValueNodeChild* child
= dynamic_cast<ExpressionValueNodeChild*>(node->NodeChild());
if (child != NULL) {
BVariant previousValue;
FunctionID* id = fStackFrame->Function()->GetFunctionID();
if (id == NULL)
return B_NO_MEMORY;
BReference<FunctionID> idReference(id, true);
if (viewState->GetExpressionValues()->GetValue(id, fThread,
child->GetExpression(), previousValue)) {
node->SetPreviousValue(previousValue);
}
}
}
// recurse // recurse
status_t error = _ApplyViewStateDescendentNodeInfos(viewState, node, status_t error = _ApplyViewStateDescendentNodeInfos(viewState, node,
path); path);
if (error != B_OK) if (error != B_OK)
return error; return error;
}
path.RemoveLastComponent(); path.RemoveLastComponent();
} }