internal override string GetArrayDisplayString(DkmClrAppDomain appDomain, Type lmrType, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds, ObjectDisplayOptions options) { Debug.Assert(lmrType.IsArray); Type originalLmrType = lmrType; // Strip off all array types. We'll process them at the end. while (lmrType.IsArray) { lmrType = lmrType.GetElementType(); } var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; builder.Append('{'); // We're showing the type of a value, so "dynamic" does not apply. bool unused; builder.Append(GetTypeName(new TypeAndCustomInfo(DkmClrType.Create(appDomain, lmrType)), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); // NOTE: call our impl directly, since we're coupled anyway. var numSizes = sizes.Count; builder.Append('['); for (int i = 0; i < numSizes; i++) { if (i > 0) { builder.Append(", "); } var lowerBound = lowerBounds[i]; var size = sizes[i]; if (lowerBound == 0) { builder.Append(FormatLiteral(size, options)); } else { builder.Append(FormatLiteral(lowerBound, options)); builder.Append(".."); builder.Append(FormatLiteral(size + lowerBound - 1, options)); } } builder.Append(']'); lmrType = originalLmrType.GetElementType(); // Strip off one layer (already handled). while (lmrType.IsArray) { builder.Append('['); builder.Append(',', lmrType.GetArrayRank() - 1); builder.Append(']'); lmrType = lmrType.GetElementType(); } builder.Append('}'); return(pooled.ToStringAndFree()); }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// Question mark syntax is used for <see cref="Nullable{T}"/>. /// No special handling is required for anonymous types - they are expected to be /// emitted with <see cref="DebuggerDisplayAttribute.Type"/> set to "<Anonymous Type>. /// This is fortunate, since we don't have a good way to recognize them in metadata. /// Does not call itself (directly). /// </remarks> protected void AppendQualifiedTypeName( StringBuilder builder, Type type, DynamicFlagsCustomTypeInfo dynamicFlags, ref int index, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { Type originalType = type; // Can have an array of pointers, but not a pointer to an array, so consume these first. // We'll reconstruct this information later from originalType. while (type.IsArray) { index++; type = type.GetElementType(); } int pointerCount = 0; while (type.IsPointer) { var elementType = type.GetElementType(); if (elementType == null) { // Null for function pointers. break; } index++; pointerCount++; type = elementType; } int nullableCount = 0; Type typeArg; while ((typeArg = type.GetNullableTypeArgument()) != null) { index++; nullableCount++; type = typeArg; } Debug.Assert(nullableCount < 2, "Benign: someone is nesting nullables."); Debug.Assert(pointerCount == 0 || nullableCount == 0, "Benign: pointer to nullable?"); AppendQualifiedTypeNameInternal(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, out sawInvalidIdentifier); builder.Append('?', nullableCount); builder.Append('*', pointerCount); type = originalType; while (type.IsArray) { AppendRankSpecifier(builder, type.GetArrayRank()); type = type.GetElementType(); } }
internal override string GetArrayDisplayString(Type lmrType, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, ObjectDisplayOptions options) { Debug.Assert(lmrType.IsArray); Type originalLmrType = lmrType; // Strip off all array types. We'll process them at the end. while (lmrType.IsArray) { lmrType = lmrType.GetElementType(); } var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; builder.Append('{'); // We're showing the type of a value, so "dynamic" does not apply. bool unused; builder.Append(GetTypeName(new TypeAndCustomInfo(lmrType), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); // NOTE: call our impl directly, since we're coupled anyway. var numSizes = sizes.Count; builder.Append('['); for (int i = 0; i < numSizes; i++) { if (i > 0) { builder.Append(", "); } var lowerBound = lowerBounds[i]; var size = sizes[i]; if (lowerBound == 0) { builder.Append(FormatLiteral(size, options)); } else { builder.Append(FormatLiteral(lowerBound, options)); builder.Append(".."); builder.Append(FormatLiteral(size + lowerBound - 1, options)); } } builder.Append(']'); lmrType = originalLmrType.GetElementType(); // Strip off one layer (already handled). while (lmrType.IsArray) { builder.Append('['); builder.Append(',', lmrType.GetArrayRank() - 1); builder.Append(']'); lmrType = lmrType.GetElementType(); } builder.Append('}'); return pooled.ToStringAndFree(); }
internal override string GetArrayDisplayString(Type lmrType, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds, ObjectDisplayOptions options) { Debug.Assert(lmrType.IsArray); Type originalLmrType = lmrType; // Strip off all array types. We'll process them at the end. while (lmrType.IsArray) { lmrType = lmrType.GetElementType(); } var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; builder.Append('{'); builder.Append(GetTypeName(lmrType)); // NOTE: call our impl directly, since we're coupled anyway. var numSizes = sizes.Count; builder.Append('['); for (int i = 0; i < numSizes; i++) { if (i > 0) { builder.Append(", "); } var lowerBound = lowerBounds[i]; var size = sizes[i]; if (lowerBound == 0) { builder.Append(FormatLiteral(size, options)); } else { builder.Append(FormatLiteral(lowerBound, options)); builder.Append(".."); builder.Append(FormatLiteral(size + lowerBound - 1, options)); } } builder.Append(']'); lmrType = originalLmrType.GetElementType(); // Strip off one layer (already handled). while (lmrType.IsArray) { builder.Append('['); builder.Append(',', lmrType.GetArrayRank() - 1); builder.Append(']'); lmrType = lmrType.GetElementType(); } builder.Append('}'); return(pooled.ToStringAndFree()); }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// Question mark syntax is used for <see cref="Nullable{T}"/>. /// No special handling is required for anonymous types - they are expected to be /// emitted with <see cref="DebuggerDisplayAttribute.Type"/> set to "<Anonymous Type>. /// This is fortunate, since we don't have a good way to recognize them in metadata. /// Does not call itself (directly). /// </remarks> protected void AppendQualifiedTypeName(StringBuilder builder, Type type, bool escapeKeywordIdentifiers) { Type originalType = type; // Can have an array of pointers, but not a pointer to an array, so consume these first. // We'll reconstruct this information later from originalType. while (type.IsArray) { type = type.GetElementType(); } int pointerCount = 0; while (type.IsPointer) { pointerCount++; type = type.GetElementType(); } int nullableCount = 0; Type typeArg; while ((typeArg = type.GetNullableTypeArgument()) != null) { nullableCount++; type = typeArg; } Debug.Assert(nullableCount < 2, "Benign: someone is nesting nullables."); Debug.Assert(pointerCount == 0 || nullableCount == 0, "Benign: pointer to nullable?"); int oldLength = builder.Length; AppendQualifiedTypeNameInternal(builder, type, escapeKeywordIdentifiers); string name = builder.ToString(oldLength, builder.Length - oldLength); builder.Append('?', nullableCount); builder.Append('*', pointerCount); type = originalType; while (type.IsArray) { AppendRankSpecifier(builder, type.GetArrayRank()); type = type.GetElementType(); } }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// Question mark syntax is used for <see cref="Nullable{T}"/>. /// No special handling is required for anonymous types - they are expected to be /// emitted with <see cref="DebuggerDisplayAttribute.Type"/> set to "<Anonymous Type>. /// This is fortunate, since we don't have a good way to recognize them in metadata. /// Does not call itself (directly). /// </remarks> protected void AppendQualifiedTypeName(StringBuilder builder, Type type, DynamicFlagsCustomTypeInfo dynamicFlags, ref int index, bool escapeKeywordIdentifiers) { Type originalType = type; // Can have an array of pointers, but not a pointer to an array, so consume these first. // We'll reconstruct this information later from originalType. while (type.IsArray) { index++; type = type.GetElementType(); } int pointerCount = 0; while (type.IsPointer) { index++; pointerCount++; type = type.GetElementType(); } int nullableCount = 0; Type typeArg; while ((typeArg = type.GetNullableTypeArgument()) != null) { index++; nullableCount++; type = typeArg; } Debug.Assert(nullableCount < 2, "Benign: someone is nesting nullables."); Debug.Assert(pointerCount == 0 || nullableCount == 0, "Benign: pointer to nullable?"); int oldLength = builder.Length; AppendQualifiedTypeNameInternal(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers); string name = builder.ToString(oldLength, builder.Length - oldLength); builder.Append('?', nullableCount); builder.Append('*', pointerCount); type = originalType; while (type.IsArray) { AppendRankSpecifier(builder, type.GetArrayRank()); type = type.GetElementType(); } }
/// <summary> /// Convert a type from the debugger's type system into Iris's type system /// </summary> /// <param name="lmrType">LMR Type</param> /// <returns>Iris type</returns> public static IrisType GetIrisTypeForLmrType(Type lmrType) { if (lmrType.IsPrimitive) { switch (lmrType.FullName) { case "System.Int32": return(IrisType.Integer); case "System.Boolean": return(IrisType.Boolean); } } else if (lmrType.IsArray) { if (lmrType.GetArrayRank() != 1) { return(IrisType.Invalid); } IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType()); if (elementType == IrisType.Invalid) { return(IrisType.Invalid); } return(elementType.MakeArrayType()); } else if (lmrType.IsByRef) { IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType()); if (elementType == IrisType.Invalid) { return(IrisType.Invalid); } return(elementType.MakeByRefType()); } else if (lmrType.FullName.Equals("System.String")) { return(IrisType.String); } // Unknown return(IrisType.Invalid); }
/// <summary> /// Convert a type from the debugger's type system into Iris's type system /// </summary> /// <param name="lmrType">LMR Type</param> /// <returns>Iris type</returns> public static IrisType GetIrisTypeForLmrType(Type lmrType) { if (lmrType.IsPrimitive) { switch (lmrType.FullName) { case "System.Int32": return IrisType.Integer; case "System.Boolean": return IrisType.Boolean; } } else if (lmrType.IsArray) { if (lmrType.GetArrayRank() != 1) return IrisType.Invalid; IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType()); if (elementType == IrisType.Invalid) return IrisType.Invalid; return elementType.MakeArrayType(); } else if (lmrType.IsByRef) { IrisType elementType = GetIrisTypeForLmrType(lmrType.GetElementType()); if (elementType == IrisType.Invalid) return IrisType.Invalid; return elementType.MakeByRefType(); } else if (lmrType.FullName.Equals("System.String")) { return IrisType.String; } // Unknown return IrisType.Invalid; }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// Question mark syntax is used for <see cref="Nullable{T}"/>. /// No special handling is required for anonymous types - they are expected to be /// emitted with <see cref="DebuggerDisplayAttribute.Type"/> set to "<Anonymous Type>. /// This is fortunate, since we don't have a good way to recognize them in metadata. /// </remarks> protected void AppendQualifiedTypeName( StringBuilder builder, Type type, ReadOnlyCollection<byte> dynamicFlags, ref int dynamicFlagIndex, ReadOnlyCollection<string> tupleElementNames, ref int tupleElementIndex, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { Type originalType = type; // Can have an array of pointers, but not a pointer to an array, so consume these first. // We'll reconstruct this information later from originalType. while (type.IsArray) { dynamicFlagIndex++; type = type.GetElementType(); } int pointerCount = 0; while (type.IsPointer) { var elementType = type.GetElementType(); if (elementType == null) { // Null for function pointers. break; } dynamicFlagIndex++; pointerCount++; type = elementType; } int nullableCount = 0; Type typeArg; while ((typeArg = type.GetNullableTypeArgument()) != null) { dynamicFlagIndex++; nullableCount++; type = typeArg; } Debug.Assert(nullableCount < 2, "Benign: someone is nesting nullables."); Debug.Assert(pointerCount == 0 || nullableCount == 0, "Benign: pointer to nullable?"); AppendQualifiedTypeNameInternal( builder, type, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, out sawInvalidIdentifier); builder.Append('?', nullableCount); builder.Append('*', pointerCount); type = originalType; while (type.IsArray) { AppendRankSpecifier(builder, type.GetArrayRank()); type = type.GetElementType(); } }