async Task InitAsync()
        {
            if (_initialized)
            {
                return;
            }

            _initialized = true;

            if (string.IsNullOrWhiteSpace(_smartPointerItem?.Value) ||
                !NatvisViewsUtil.IsViewVisible(_variable.FormatSpecifier,
                                               _smartPointerItem.IncludeView,
                                               _smartPointerItem.ExcludeView))
            {
                _adapter = _fallbackAdapter;
                return;
            }

            try
            {
                IVariableInformation expandInfo = await _evaluator.EvaluateExpressionAsync(
                    _smartPointerItem.Value, _variable, _natvisScope, null);

                _adapter = expandInfo.GetChildAdapter();
            }
            catch (ExpressionEvaluationFailed ex)
            {
                NatvisErrorUtils.LogExpandChildrenValidationError(
                    NatvisLoggingLevel.WARNING, _logger, "<SmartPointer>", _variable.TypeName,
                    ex.Message);

                _adapter = _fallbackAdapter;
            }
        }
Exemple #2
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));
        }
        /// <summary>
        /// Asynchronously processes a mixed format string that contains literal text and
        /// expressions embedded inside curly braces. The expressions are evaluated within the
        /// context of the variable specified, and subsequently formatted using the subexpression
        /// formatter provided.
        /// </summary>
        /// <remarks>
        /// Examples:
        ///   FormatValueAsync("Some literal text and an {expression}", varInfo, natvisScope,
        ///   subexpressionFormatter);
        ///   FormatValueAsync("{{Escaped, literal text.}}", varInfo, natvisScope,
        ///   subexpressionFormatter);
        /// </remarks>
        async Task <string> FormatValueAsync(
            string format, IVariableInformation variable, NatvisScope natvisScope,
            Func <IVariableInformation, Task <string> > subexpressionFormatter)
        {
            if (string.IsNullOrWhiteSpace(format))
            {
                return(string.Empty);
            }

            var value = new StringBuilder();

            for (int i = 0; i < format.Length; ++i)
            {
                if (format[i] == '{')
                {
                    if (i + 1 < format.Length && format[i + 1] == '{')
                    {
                        value.Append('{');
                        i++;
                        continue;
                    }

                    // start of expression
                    Match m = _expressionRegex.Match(format.Substring(i));
                    if (m.Success)
                    {
                        string expression = format.Substring(i + 1, m.Length - 2);
                        IVariableInformation exprValue = await _evaluator.EvaluateExpressionAsync(
                            expression, variable, natvisScope, null);

                        value.Append(await subexpressionFormatter(exprValue));
                        i += m.Length - 1;
                    }
                }
                else if (format[i] == '}')
                {
                    // Accept both } and }} as closing braces to match native behavior.
                    value.Append('}');
                    if (i + 1 < format.Length && format[i + 1] == '}')
                    {
                        i++;
                    }
                }
                else
                {
                    value.Append(format[i]);
                }
            }

            return(value.ToString());
        }
Exemple #4
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());
        }
Exemple #5
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.");
        }