public override DbgDotNetValueNode[] GetChildren(LanguageValueNodeFactory valueNodeFactory, DbgEvaluationContext context, DbgStackFrame frame, ulong index, int count, DbgValueNodeEvaluationOptions options, CancellationToken cancellationToken) { var res = count == 0 ? Array.Empty <DbgDotNetValueNode>() : new DbgDotNetValueNode[count]; DbgDotNetValue newValue = null; try { var output = ObjectCache.AllocDotNetTextOutput(); var elementType = valueInfo.Value.Type.GetElementType(); var castType = NeedCast(slotType, valueInfo.Value.Type) ? valueInfo.Value.Type : null; for (int i = 0; i < res.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); string expression; uint arrayIndex = (uint)index + (uint)i; newValue = valueInfo.Value.GetArrayElementAt(arrayIndex); Debug.Assert(newValue != null); if (dimensionInfos.Length == 1) { int baseIndex = (int)arrayIndex + dimensionInfos[0].BaseIndex; expression = valueNodeFactory.GetExpression(valueInfo.Expression, baseIndex, castType, addParens); owner.FormatArrayName(output, baseIndex); } else { uint indexLeft = arrayIndex; for (int j = dimensionInfos.Length - 1; j >= 0; j--) { indexes[j] = (int)(indexLeft % dimensionInfos[j].Length) + dimensionInfos[j].BaseIndex; indexLeft = indexLeft / dimensionInfos[j].Length; } expression = valueNodeFactory.GetExpression(valueInfo.Expression, indexes, castType, addParens); owner.FormatArrayName(output, indexes); } var name = output.CreateAndReset(); const bool isReadOnly = false; DbgDotNetValueNode newNode; if (newValue == null) { newNode = valueNodeFactory.CreateError(context, frame, name, PredefinedEvaluationErrorMessages.InternalDebuggerError, expression, false, cancellationToken); } else { newNode = valueNodeFactory.Create(context, frame, name, newValue, options, expression, PredefinedDbgValueNodeImageNames.ArrayElement, isReadOnly, false, elementType, false, cancellationToken); } newValue = null; res[i] = newNode; } ObjectCache.Free(ref output); } catch { context.Process.DbgManager.Close(res.Where(a => a != null)); newValue?.Dispose(); throw; } return(res); }
TypeState CreateTypeStateCore(DmdType type) { var typeExpression = GetTypeExpression(type); if (HasNoChildren(type) || type.IsFunctionPointer) { return(new TypeState(type, typeExpression)); } MemberValueNodeInfoCollection instanceMembers, staticMembers; TupleField[] tupleFields; Debug.Assert(!type.IsByRef); if (type.TypeSignatureKind == DmdTypeSignatureKind.Type || type.TypeSignatureKind == DmdTypeSignatureKind.GenericInstance) { tupleFields = TryCreateTupleFields(type) ?? Array.Empty <TupleField>(); var instanceMembersList = new List <MemberValueNodeInfo>(); var staticMembersList = new List <MemberValueNodeInfo>(); bool instanceHasHideRoot = false; bool staticHasHideRoot = false; byte inheritanceLevel; DmdType currentType; inheritanceLevel = 0; currentType = type; foreach (var field in type.Fields) { var declType = field.DeclaringType; while (declType != currentType) { Debug.Assert((object)currentType.BaseType != null); currentType = currentType.BaseType; if (inheritanceLevel != byte.MaxValue) { inheritanceLevel++; } } var nodeInfo = new MemberValueNodeInfo(field, inheritanceLevel); if (field.IsStatic) { staticHasHideRoot |= nodeInfo.HasDebuggerBrowsableState_RootHidden; staticMembersList.Add(nodeInfo); } else { instanceHasHideRoot |= nodeInfo.HasDebuggerBrowsableState_RootHidden; instanceMembersList.Add(nodeInfo); } } inheritanceLevel = 0; currentType = type; foreach (var property in type.Properties) { if (property.GetMethodSignature().GetParameterTypes().Count != 0) { continue; } var declType = property.DeclaringType; while (declType != currentType) { Debug.Assert((object)currentType.BaseType != null); currentType = currentType.BaseType; if (inheritanceLevel != byte.MaxValue) { inheritanceLevel++; } } var getter = property.GetGetMethod(DmdGetAccessorOptions.All); if ((object)getter == null || getter.GetMethodSignature().GetParameterTypes().Count != 0) { continue; } var nodeInfo = new MemberValueNodeInfo(property, inheritanceLevel); if (getter.IsStatic) { staticHasHideRoot |= nodeInfo.HasDebuggerBrowsableState_RootHidden; staticMembersList.Add(nodeInfo); } else { instanceHasHideRoot |= nodeInfo.HasDebuggerBrowsableState_RootHidden; instanceMembersList.Add(nodeInfo); } } var instanceMembersArray = InitializeOverloadedMembers(instanceMembersList.ToArray()); var staticMembersArray = InitializeOverloadedMembers(staticMembersList.ToArray()); instanceMembers = instanceMembersList.Count == 0 ? MemberValueNodeInfoCollection.Empty : new MemberValueNodeInfoCollection(instanceMembersArray, instanceHasHideRoot); staticMembers = staticMembersList.Count == 0 ? MemberValueNodeInfoCollection.Empty : new MemberValueNodeInfoCollection(staticMembersArray, staticHasHideRoot); Array.Sort(instanceMembers.Members, MemberValueNodeInfoEqualityComparer.Instance); Array.Sort(staticMembers.Members, MemberValueNodeInfoEqualityComparer.Instance); var output = ObjectCache.AllocDotNetTextOutput(); UpdateNames(instanceMembers.Members, output); UpdateNames(staticMembers.Members, output); ObjectCache.Free(ref output); } else { staticMembers = instanceMembers = MemberValueNodeInfoCollection.Empty; tupleFields = Array.Empty <TupleField>(); } return(new TypeState(type, typeExpression, instanceMembers, staticMembers, tupleFields)); }