示例#1
0
        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);
        }
示例#2
0
        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());
        }
示例#3
0
        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());
        }
示例#4
0
        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));
        }
示例#5
0
        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;
            }
        }
示例#7
0
        /// <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.");
        }