public async Task GetChildrenReturnsMoreElementWhenMoreThanRangeSizeRequestedAsync() { remoteValue.AddChild(RemoteValueFakeUtil.CreateSimpleString("child5", "value5")); int _countPerRange = 2; var childAdapter = new RemoteValueChildAdapter.Factory().CreateForTesting( remoteValue, RemoteValueFormat.Default, varInfoBuilder, noFormatSpecifier, _countPerRange); IList <IVariableInformation> children = await childAdapter.GetChildrenAsync(0, 5); Assert.That(children.Count, Is.EqualTo(3)); Assert.That(children[2].DisplayName, Is.EqualTo("[More]")); IVariableInformation more = children[2]; CollectionAssert.AreEqual(new[] { "child3", "child4", "[More]" }, await GetAllChildNamesAsync(more.GetChildAdapter())); IVariableInformation nextMore = (await more.GetChildAdapter().GetChildrenAsync(2, 1))[0]; CollectionAssert.AreEqual(new[] { "child5" }, await GetAllChildNamesAsync(nextMore.GetChildAdapter())); }
public void TestEnumChildren() { var children = new List <IVariableInformation>() { Substitute.For <IVariableInformation>(), Substitute.For <IVariableInformation>(), Substitute.For <IVariableInformation>() }; mockVarInfo.MightHaveChildren().Returns(true); mockVarInfo.GetChildAdapter().Returns(new ListChildAdapter.Factory().Create(children)); mockVarInfo.GetCachedView().Returns(mockVarInfo); var property = createPropertyDelegate.Invoke(mockVarInfo); IEnumDebugPropertyInfo2 propertyEnum; var guid = new System.Guid(); var result = property.EnumChildren(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME, 10, ref guid, enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_ALL, "", 0, out propertyEnum); Assert.That(result, Is.EqualTo(VSConstants.S_OK)); uint count; propertyEnum.GetCount(out count); Assert.That(count, Is.EqualTo(children.Count)); }
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; } }
public static async Task <IVariableInformation[]> GetAllChildrenAsync( this IVariableInformation varInfo) { IChildAdapter childAdapter = varInfo.GetChildAdapter(); return((await childAdapter.GetChildrenAsync(0, await childAdapter.CountChildrenAsync())) .ToArray()); }
static async Task <IVariableInformation> GetChildAsync( IVariableInformation varInfo, int index) { var children = (await varInfo.GetChildAdapter().GetChildrenAsync(index, 1)); return(children.FirstOrDefault() ?? new ErrorVariableInformation(varInfo.DisplayName, "<out-of-bounds child index in 'expand()' format specifier>")); }
async Task InitChildAdapterAsync() { if (_childAdapter == null) { IVariableInformation expandInfo = await _evaluator.EvaluateExpressionAsync( _expandedItem.Value, _variable, _natvisScope, null); _childAdapter = expandInfo.GetChildAdapter(); } }
IChildAdapter CreateNatvisChildAdapter(VisualizerInfo visualizer, IVariableInformation variable) { ExpandType expandType = visualizer.GetExpandType(); if (expandType != null) { return(_natvisCollectionFactory.Create(variable, expandType, visualizer.NatvisScope)); } SmartPointerType smartPointerType = visualizer.GetSmartPointerType(); if (smartPointerType != null) { return(_smartPointerFactory.Create( variable, smartPointerType, visualizer.NatvisScope, variable.GetChildAdapter())); } return(variable.GetChildAdapter()); }
public int GetChildPropertyProvider(uint dwFields, uint dwRadix, uint dwTimeout, out IAsyncDebugPropertyInfoProvider ppPropertiesProvider) { ppPropertiesProvider = _taskExecutor.Run(() => { IVariableInformation cachedVarInfo = _varInfo.GetCachedView(); IChildrenProvider childrenProvider = _childrenProviderFactory.Create(cachedVarInfo.GetChildAdapter(), (enum_DEBUGPROP_INFO_FLAGS)dwFields, dwRadix); return(new AsyncDebugPropertyInfoProvider(childrenProvider, _taskExecutor)); }); return(VSConstants.S_OK); }
public int EnumChildrenImpl(enum_DEBUGPROP_INFO_FLAGS fields, uint radix, Guid guidFilter, enum_DBG_ATTRIB_FLAGS attributeFilter, string nameFilter, uint timeout, out IEnumDebugPropertyInfo2 propertyEnum) { propertyEnum = _taskExecutor.Run(() => { _varInfo.FallbackValueFormat = GetFallbackValueFormat(radix); IVariableInformation cachedVarInfo = _varInfo.GetCachedView(); IChildrenProvider childrenProvider = _childrenProviderFactory.Create(cachedVarInfo.GetChildAdapter(), fields, radix); return(_varInfoEnumFactory.Create(childrenProvider)); }); return(VSConstants.S_OK); }
internal IChildAdapter GetChildAdapter(IVariableInformation variable) { VisualizerInfo visualizer = VisualizerScanner.FindType(variable); if (visualizer?.Visualizer.Items == null) { return(variable.GetChildAdapter()); } IChildAdapter childAdapter = CreateNatvisChildAdapter(visualizer, variable); // Special case for SSE registers. VS calls VariableInformationEnum.Count, even if // the SSE registers are not visible. Without this, we would have to expand all // children just to get the count, which slows down the register window a lot. if (variable.CustomVisualizer == CustomVisualizer.SSE || variable.CustomVisualizer == CustomVisualizer.SSE2) { return(new SseAdapter(visualizer.GetExpandType().Items.Length, childAdapter)); } return(childAdapter); }
public void GetPropertyInfoNone() { var unexpectedCall = new Exception("Unexpected call"); mockVarInfo.DisplayName.Throws(unexpectedCall); mockVarInfo.TypeName.Throws(unexpectedCall); mockVarInfo.AssignmentValue.Throws(unexpectedCall); mockVarInfo.ValueAsync().Throws(unexpectedCall); mockVarInfo.Error.Throws(unexpectedCall); mockVarInfo.MightHaveChildren().Throws(unexpectedCall); mockVarInfo.GetChildAdapter().Throws(unexpectedCall); mockVarInfo.FindChildByName(Arg.Any <string>()).ThrowsForAnyArgs(unexpectedCall); mockVarInfo.IsReadOnly.Throws(unexpectedCall); string error; mockVarInfo.Assign(Arg.Any <string>(), out error).ThrowsForAnyArgs(unexpectedCall); DEBUG_PROPERTY_INFO propertyInfo; int result = GetPropertyInfo(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NONE, out propertyInfo); // Also verifies exceptions are not raised. Assert.That(result, Is.EqualTo(VSConstants.S_OK)); Assert.That(propertyInfo.dwFields, Is.EqualTo(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NONE)); }
static async Task <string> FormatChildrenListAsync(IVariableInformation varInfo, int charactersLeft, string noChildrenMarker = "") { IChildAdapter children = varInfo.GetChildAdapter(); if (children is INatvisEntity) { return(""); } int childrenCount = await children.CountChildrenAsync(); const int maxChildren = 3; StringBuilder sb = new StringBuilder(); sb.Append("{"); for (int i = 0; i < childrenCount; i++) { try { IVariableInformation currentChild = (await children.GetChildrenAsync(i, 1)).ElementAt(0).GetCachedView(); // For array elements or pointers, we do not display the child name. // Also array elements are separated by commas. We detect the array elements // using a somewhat hacky way - we check if their name is the index in // square brackets. bool isArrayElementOrPointee = currentChild.DisplayName == $"[{i}]" || currentChild.DisplayName == ""; if (i != 0) { sb.Append(isArrayElementOrPointee ? ", " : " "); } // If we are over the limit, let us just display the dots and exit. if (!isArrayElementOrPointee && i >= maxChildren) { sb.Append("..."); break; } string childValue = await BuildAsync(currentChild, charactersLeft - sb.Length - 1); if (string.IsNullOrEmpty(childValue) && currentChild.GetChildAdapter() is INatvisEntity) { childValue = "{...}"; } else if (childValue == "..." || string.IsNullOrEmpty(childValue)) { sb.Append(childValue); break; } if (!isArrayElementOrPointee) { sb.Append($"{currentChild.DisplayName}="); } sb.Append(childValue); } catch (ArgumentOutOfRangeException) { break; } } if (childrenCount == 0) { sb.Append(noChildrenMarker); } sb.Append("}"); return(sb.ToString()); }