/// <summary>
        /// Evaluates a Natvis expression in the context of a variable asynchronously.
        ///
        /// Examples:
        ///   "myData[0] == true"
        ///   "myData[$i]"
        ///   "MyContainer<$T1, $T2>",
        ///   "(char*)myData,[myLength]s"
        /// </summary>
        /// <param name="expression">The expression to evaluate. Natvis tokens are resolved prior to
        /// evaluation, ex. $i, $Tx. </param>
        /// <param name="variable"></param>
        /// <param name="scopedNames">The Natvis tokens to resolve in expression.</param>
        /// <param name="displayName">The display name given to the result. If null the underlying
        /// debugger's context specific name is used.</param>
        /// <returns>The expression result.</returns>
        public async Task <IVariableInformation> EvaluateExpressionAsync(
            string expression, IVariableInformation variable, NatvisScope natvisScope,
            string displayName)
        {
            var vsExpression = await _vsExpressionCreator.CreateAsync(
                expression, async (sizeExpression) =>
            {
                IVariableInformation value = await EvaluateLldbExpressionAsync(
                    _vsExpressionCreator.Create(sizeExpression, ""), variable, natvisScope,
                    displayName);
                uint size;
                if (!uint.TryParse(await value.ValueAsync(), out size))
                {
                    throw new ExpressionEvaluationFailed("Expression isn't a uint");
                }

                return(size);
            });

            return(await EvaluateLldbExpressionAsync(vsExpression, variable, natvisScope,
                                                     displayName));
        }
Пример #2
0
        public async Task <int> GetPropertyInfoAsync(enum_DEBUGPROP_INFO_FLAGS fields, uint radix,
                                                     uint timeout, IDebugReference2[] args,
                                                     uint argCount,
                                                     DEBUG_PROPERTY_INFO[] propertyInfo)
        {
            var info = new DEBUG_PROPERTY_INFO();

            _varInfo.FallbackValueFormat = GetFallbackValueFormat(radix);
            IVariableInformation cachedVarInfo = _varInfo.GetCachedView();

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME & fields) != 0)
            {
                string fullname = cachedVarInfo.Fullname();
                if (!string.IsNullOrWhiteSpace(fullname))
                {
                    info.bstrFullName = _vsExpressionCreator
                                        .Create(fullname, cachedVarInfo.FormatSpecifier)
                                        .ToString();

                    info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME;
                }
            }

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME & fields) != 0)
            {
                info.bstrName  = cachedVarInfo.DisplayName;
                info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME;
            }

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE & fields) != 0)
            {
                info.bstrType  = cachedVarInfo.TypeName;
                info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE;
            }

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE & fields) != 0)
            {
                if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_AUTOEXPAND & fields) != 0)
                {
                    // The value field is in read-only mode, so we can display additional
                    // information that would normally fail to parse as a proper expression.
                    info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE_AUTOEXPAND;

                    info.bstrValue = await ValueStringBuilder.BuildAsync(cachedVarInfo);
                }
                else
                {
                    // The value field is in editing mode, so only display the assignment value.
                    info.bstrValue = cachedVarInfo.AssignmentValue;
                }

                info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE;
            }

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP & fields) != 0)
            {
                info.pProperty = Self;
                info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP;
            }

            if ((enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB & fields) != 0)
            {
                if (cachedVarInfo.Error)
                {
                    info.dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_ERROR;
                }

                if (cachedVarInfo.MightHaveChildren())
                {
                    info.dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
                }

                if (cachedVarInfo.IsReadOnly)
                {
                    info.dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_READONLY;
                }

                if (!string.IsNullOrEmpty(cachedVarInfo.StringView))
                {
                    // Causes Visual Studio to show the text visualizer selector. i.e. the
                    // magnifying glass with Text Visualizer, XML Visualizer, etc.
                    info.dwAttrib |= enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_RAW_STRING;
                }

                info.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB;
            }

            propertyInfo[0] = info;
            return(VSConstants.S_OK);
        }