public async Task <EvaluateResult> EvaluateAsync() { if (State == BlockState.Done) { return(EvaluateResult.None()); } State = BlockState.InProgress; if (_loopInstructions.State == BlockState.Done) { _loopInstructions.Reset(); } if (_loopInstructions.State == BlockState.New && !await _evaluator.EvaluateConditionAsync(_loop.Condition, _ctx.Variable, _ctx.NatvisScope)) { State = BlockState.Done; return(EvaluateResult.None()); } EvaluateResult result = await _loopInstructions.EvaluateAsync(); if (result.Type == ResultType.Break) { State = BlockState.Done; return(EvaluateResult.None()); } return(result); }
public async Task <EvaluateResult> EvaluateAsync() { if (State == BlockState.Done) { return(EvaluateResult.None()); } State = BlockState.Done; return(await _evaluator.EvaluateConditionAsync(_breakType.Condition, _ctx.Variable, _ctx.NatvisScope) ? EvaluateResult.Break() : EvaluateResult.None()); }
public async Task <EvaluateResult> EvaluateAsync() { if (State == BlockState.Done) { return(EvaluateResult.None()); } State = BlockState.Done; if (await _evaluator.EvaluateConditionAsync(_exec.Condition, _ctx.Variable, _ctx.NatvisScope)) { await _evaluator.EvaluateExpressionAsync(_exec.Value, _ctx.Variable, _ctx.NatvisScope, null); } return(EvaluateResult.None()); }
public async Task <EvaluateResult> EvaluateAsync() { if (State == BlockState.Done) { return(EvaluateResult.None()); } State = BlockState.Done; if (!await _evaluator.EvaluateConditionAsync(_customListItem.Condition, _ctx.Variable, _ctx.NatvisScope)) { return(EvaluateResult.None()); } string name = await EvaluateItemNameAsync(_customListItem.Name, _ctx); IVariableInformation result = await _evaluator.EvaluateExpressionAsync( _customListItem.Value, _ctx.Variable, _ctx.NatvisScope, name); return(EvaluateResult.Some(result)); }
public async Task <EvaluateResult> EvaluateAsync() { if (State == BlockState.Done) { return(EvaluateResult.None()); } State = BlockState.InProgress; if (_trueBlock == null) { for (int i = 0; i < _conditionGroup.ConditionalCode.Count; i++) { ConditionalCodeBlock branch = _conditionGroup.ConditionalCode[i]; if (await _evaluator.EvaluateConditionAsync(branch.Condition, _ctx.Variable, _ctx.NatvisScope)) { _trueBlock = _innerBlocks[i]; break; } } if (_trueBlock == null) { State = BlockState.Done; return(EvaluateResult.None()); } } EvaluateResult result = await _trueBlock.EvaluateAsync(); if (_trueBlock.State == BlockState.Done) { State = BlockState.Done; } return(result); }
/// <summary> /// Asynchronously returns a formatted string based on the format string context and /// variable provided. /// In case this method does not succeeded, it returns the fallback value specified. /// </summary> /// <param name="formatStringContext">The format string context that the formatted string /// should rely on</param> /// <param name="variable">The variable context used to evaluate expressions.</param> /// <param name="subexpressionFormatter">Delegate used to format subexpressions found /// within the string.</param> /// <param name="elementName">The Natvis element name that should be reported in logs. /// </param> /// <param name="fallbackValue">Fallback value used in case this method fails.</param> internal async Task <string> FormatStringAsync( FormatStringContext formatStringContext, IVariableInformation variable, Func <IVariableInformation, Task <string> > subexpressionFormatter, string elementName, Func <Task <string> > fallbackValue) { try { if (++_curFormatStringElementDepth > _maxFormatDepth) { return("..."); } foreach (var element in formatStringContext.StringElements) { try { // e.g. <DisplayString>{{ size={_Mypair._Myval2._Mylast - // _Mypair._Myval2._Myfirst} }}</DisplayString> if (!NatvisViewsUtil.IsViewVisible(variable.FormatSpecifier, element.IncludeView, element.ExcludeView) || !await _evaluator.EvaluateConditionAsync( element.Condition, variable, formatStringContext.NatvisScope)) { continue; } return(await FormatValueAsync(element.Value, variable, formatStringContext.NatvisScope, subexpressionFormatter)); } catch (ExpressionEvaluationFailed ex) { if (!element.Optional) { throw; } string expression = variable == null ? null : await variable.ValueAsync(); _logger.Verbose( () => $"Failed to evaluate natvis {elementName} expression" + $" '{expression}' for type " + $"'{variable?.TypeName}'. Reason: {ex.Message}"); } catch (Exception ex) when(ex is NotSupportedException || ex is InvalidOperationException) { _logger.Log(NatvisLoggingLevel.ERROR, $"Failed to format natvis {elementName}. " + $"Reason: {ex.Message}."); break; } catch (Exception ex) { _logger.Error(() => $"Failed to format natvis {elementName} for type" + $" '{variable?.TypeName}'. " + $"Reason: {ex.Message}.{Environment.NewLine}" + $"Stacktrace:{Environment.NewLine}{ex.StackTrace}"); throw; } } return(await fallbackValue.Invoke()); } finally { --_curFormatStringElementDepth; } }
/// <summary> /// Processes a SizeType array and returns the first valid size value. /// /// Throws ExpressionEvaluationFailed in case of an evaluation error and /// InvalidOperationException if valid <Size> node is not found. /// </summary> /// <returns></returns> internal async Task <uint> ParseSizeAsync(SizeType[] sizes, IVariableInformation varInfo, NatvisScope natvisScope) { if (sizes == null) { throw new InvalidOperationException("Valid <Size> node not found."); } foreach (SizeType curSize in sizes) { string errorMsg = null; string sizeText = null; try { if (!NatvisViewsUtil.IsViewVisible(varInfo.FormatSpecifier, curSize.IncludeView, curSize.ExcludeView) || !await _evaluator.EvaluateConditionAsync(curSize.Condition, varInfo, natvisScope)) { continue; } if (string.IsNullOrEmpty(curSize.Value)) { errorMsg = "The expression cannot be empty."; } else { IVariableInformation sizeVarInfo = await _evaluator.EvaluateExpressionAsync( curSize.Value, varInfo, natvisScope, null); sizeVarInfo.FallbackValueFormat = ValueFormat.Default; sizeText = await sizeVarInfo.ValueAsync(); } } catch (ExpressionEvaluationFailed ex) when(curSize.Optional) { errorMsg = ex.Message; } uint size = 0; if (errorMsg == null) { if (!ParseUint(sizeText, out size)) { errorMsg = "The expression's value was not a number. " + $"Expression='{curSize.Value}' Value='{sizeText}'"; } } if (errorMsg != null) { if (!curSize.Optional) { throw new ExpressionEvaluationFailed("Failed to evaluate <Size> node. " + errorMsg); } _logger.Verbose(() => $"Failed to evaluate <Size> node for type" + $" '{varInfo.TypeName}'. Reason: {errorMsg}"); } else { return(size); } } throw new InvalidOperationException("Valid <Size> node not found."); }