async Task StoreNodeAndGetNextAsync() { if (_nodeError != null) { _store.SaveVariable(_lastIndex, _nodeError); } else if (_node.IsNullPointer()) { if (_sizeDefined) { int size = _store.ChildrenCount; _logger.Warning("<LinkedListItems> declared a size of " + $"{size} but only {_lastIndex} item(s) found."); _nodeError = new ErrorVariableInformation( "<Error>", $"Size declared as {size} but only {_lastIndex} item(s) found."); } else { _nodeError = new ErrorVariableInformation( "<Error>", $"Item {_lastIndex} is out of bound."); } _store.SaveVariable(_lastIndex, _nodeError); } else { _store.SaveVariable(_lastIndex, await GetDisplayVariableAsync(_lastIndex, _node)); _node = await GetNextAsync(_node); } _lastIndex++; }
public Task <IList <IVariableInformation> > GetChildrenAsync(int from, int count) { ErrorVariableInformation errInfo = NatvisErrorUtils.LogAndGetExpandChildrenValidationError( NatvisLoggingLevel.WARNING, _logger, _entityType.ToString(), _variable.TypeName, $"Encountered unsupported tag: {_entityType}."); return(Task.FromResult <IList <IVariableInformation> >(new List <IVariableInformation> { errInfo })); }
/// <summary> /// This functions figures out what is the next node to be evaluated after currentNode /// using in-order traversal. /// At each step, we try to find the left most child of the current node in the right /// sub-tree and adding all the nodes we traverse to the _nodesStack. The last node added /// will be the left most node. If there are no right sub-tree, nothing is added to the /// _nodesStack. /// </summary> async Task AddNodesUpToNextInOrderToNodeStackAsync(IVariableInformation currentNode) { try { IVariableInformation nextNode = await _evaluator.EvaluateExpressionAsync( _treeItems.RightPointer, currentNode, _natvisScope, null); await AddNodesUpToLeftMostToNodeStackAsync(nextNode); } catch (ExpressionEvaluationFailed ex) { _nodeError = Optional ? new ErrorVariableInformation("<Warning>", ex.Message) : new ErrorVariableInformation("<Error>", ex.Message); } }
async Task <IVariableInformation> GetNextAsync(IVariableInformation current) { try { return(await _evaluator.EvaluateExpressionAsync(_linkedListItems.NextPointer, current, _natvisScope, null)); } catch (ExpressionEvaluationFailed ex) { _nodeError = Optional ? new ErrorVariableInformation("<Warning>", ex.Message) : new ErrorVariableInformation("<Error>", ex.Message); return(null); } }
protected async Task EvaluateUpToAsync(int to) { if (_store.ValidationError != null || _hasEvaluationError) { return; } try { await InitContextAsync(); while (_lastIndex < to && _blocks.State != BlockState.Done) { EvaluateResult result = await _blocks.EvaluateAsync(); if (result.Type == ResultType.Var) { _store.SaveVariable(_lastIndex, result.Data); _lastIndex++; } } } catch (ExpressionEvaluationFailed ex) { ErrorVariableInformation error = NatvisErrorUtils.LogAndGetExpandChildrenValidationError( Optional ? NatvisLoggingLevel.WARNING : NatvisLoggingLevel.ERROR, _logger, VisualizerName, _variable?.TypeName, ex.Message); _hasEvaluationError = true; if (_lastIndex != 0 || !Optional) { _store.SaveVariable(_lastIndex, error); _lastIndex++; } } }
/// <summary> /// This function evaluates next tree node and caches the value. /// There are several scenarios: /// - _nodeStack is not empty. It means there are still nodes to evaluate. In that case /// the top node in stack is popped and evaluated, and then we decide what is the next /// node by invoking AddNodesUpToNextInOrderToNodeStack(). /// - _nodeStack is empty. It means that more nodes are requested than exist in the tree, /// in that case we return an error node with a message about wrong size. /// - We encountered an error on one of the previous stages. In that case we just return /// the same error. /// </summary> async Task EvaluateNextInOrderAsync() { if (_nodeError != null) { _store.SaveVariable(_lastIndex, _nodeError); } else if (_nodeStack.Count > 0) { IVariableInformation currentNode = _nodeStack.Pop(); _store.SaveVariable(_lastIndex, await GetDisplayVariableAsync(_lastIndex, currentNode)); await AddNodesUpToNextInOrderToNodeStackAsync(currentNode); } else { if (_sizeDefined) { int size = _store.ChildrenCount; _logger.Warning("<TreeItems> declared a size of " + $"{size} but only {_lastIndex} item(s) found."); _nodeError = new ErrorVariableInformation( "<Error>", $"Size declared as {size} but only {_lastIndex} item(s) found."); } else { _nodeError = new ErrorVariableInformation( "<Error>", $"Item {_lastIndex} is out of bound."); } _store.SaveVariable(_lastIndex, _nodeError); } _lastIndex++; }
EntityInfo(int childrenCount, ErrorVariableInformation error) { ChildrenCount = childrenCount; Error = error; }
public static EntityInfo WithError(ErrorVariableInformation error) => new EntityInfo(0, error);