public override ILValue UnboxAny(DmdType type) { if (type.IsNullable) { var method = type.GetConstructor(new[] { type.GetNullableElementType() }); if ((object)method == null) { return(null); } return(runtime.CreateInstance(method, new[] { ilValue })); } else { return(ilValue.Clone()); } }
public void Format(DmdType type, DbgDotNetValue value) { if ((object)type == null) { throw new ArgumentNullException(nameof(type)); } List <(DmdType type, DbgDotNetValue value)> arrayTypesList = null; try { if (recursionCounter++ >= MAX_RECURSION) { return; } switch (type.TypeSignatureKind) { case DmdTypeSignatureKind.SZArray: case DmdTypeSignatureKind.MDArray: // Array types are shown in reverse order arrayTypesList = new List <(DmdType type, DbgDotNetValue value)>(); do { arrayTypesList.Add((type, arrayTypesList.Count == 0 ? value : null)); type = type.GetElementType(); } while (type.IsArray); var t = arrayTypesList[arrayTypesList.Count - 1]; Format(t.type.GetElementType(), null); foreach (var tuple in arrayTypesList) { var aryType = tuple.type; var aryValue = tuple.value; uint elementCount; if (aryType.IsVariableBoundArray) { OutputWrite(ARRAY_OPEN_PAREN, BoxedTextColor.Punctuation); int rank = Math.Min(aryType.GetArrayRank(), MAX_ARRAY_RANK); if (rank <= 0) { OutputWrite("???", BoxedTextColor.Error); } else { if (rank == 1) { OutputWrite("*", BoxedTextColor.Operator); } if (aryValue == null || aryValue.IsNull || !aryValue.GetArrayInfo(out elementCount, out var dimensionInfos)) { dimensionInfos = null; } if (ShowArrayValueSizes && dimensionInfos != null && dimensionInfos.Length == rank) { for (int i = 0; i < rank; i++) { if (i > 0) { OutputWrite(",", BoxedTextColor.Punctuation); WriteSpace(); } if (dimensionInfos[i].BaseIndex == 0) { WriteUInt32(dimensionInfos[i].Length); } else { WriteInt32(dimensionInfos[i].BaseIndex); OutputWrite("..", BoxedTextColor.Operator); WriteInt32(dimensionInfos[i].BaseIndex + (int)dimensionInfos[i].Length - 1); } } } else { OutputWrite(TypeFormatterUtils.GetArrayCommas(rank), BoxedTextColor.Punctuation); } } OutputWrite(ARRAY_CLOSE_PAREN, BoxedTextColor.Punctuation); } else { Debug.Assert(aryType.IsSZArray); OutputWrite(ARRAY_OPEN_PAREN, BoxedTextColor.Punctuation); if (ShowArrayValueSizes && aryValue != null && !aryValue.IsNull) { if (aryValue.GetArrayCount(out elementCount)) { WriteUInt32(elementCount); } } OutputWrite(ARRAY_CLOSE_PAREN, BoxedTextColor.Punctuation); } } break; case DmdTypeSignatureKind.Pointer: Format(type.GetElementType(), null); OutputWrite("*", BoxedTextColor.Operator); break; case DmdTypeSignatureKind.ByRef: OutputWrite(BYREF_KEYWORD, BoxedTextColor.Keyword); WriteSpace(); Format(type.GetElementType(), value?.LoadIndirect()); break; case DmdTypeSignatureKind.TypeGenericParameter: WriteIdentifier(type.MetadataName, BoxedTextColor.TypeGenericParameter); break; case DmdTypeSignatureKind.MethodGenericParameter: WriteIdentifier(type.MetadataName, BoxedTextColor.MethodGenericParameter); break; case DmdTypeSignatureKind.Type: case DmdTypeSignatureKind.GenericInstance: if (type.IsNullable) { Format(type.GetNullableElementType(), null); OutputWrite("?", BoxedTextColor.Operator); } else if (TypeFormatterUtils.IsTupleType(type)) { OutputWrite(TUPLE_OPEN_PAREN, BoxedTextColor.Punctuation); var tupleType = type; int tupleIndex = 0; for (;;) { tupleType = WriteTupleFields(tupleType, ref tupleIndex); if ((object)tupleType != null) { WriteCommaSpace(); } else { break; } } OutputWrite(TUPLE_CLOSE_PAREN, BoxedTextColor.Punctuation); } else { var genericArgs = type.GetGenericArguments(); int genericArgsIndex = 0; KeywordType keywordType; if ((object)type.DeclaringType == null) { keywordType = GetKeywordType(type); if (keywordType == KeywordType.NoKeyword) { WriteNamespace(type); } WriteTypeName(type, keywordType); WriteGenericArguments(type, genericArgs, ref genericArgsIndex); } else { var typesList = new List <DmdType>(); typesList.Add(type); while (type.DeclaringType != null) { type = type.DeclaringType; typesList.Add(type); } keywordType = GetKeywordType(type); if (keywordType == KeywordType.NoKeyword) { WriteNamespace(type); } for (int i = typesList.Count - 1; i >= 0; i--) { WriteTypeName(typesList[i], i == 0 ? keywordType : KeywordType.NoKeyword); WriteGenericArguments(typesList[i], genericArgs, ref genericArgsIndex); if (i != 0) { OutputWrite(".", BoxedTextColor.Operator); } } } } break; case DmdTypeSignatureKind.FunctionPointer: //TODO: OutputWrite("fnptr", BoxedTextColor.Keyword); break; default: throw new InvalidOperationException(); } } finally { recursionCounter--; if (arrayTypesList != null) { foreach (var info in arrayTypesList) { if (info.value != value) { info.value?.Dispose(); } } } } }