Пример #1
0
        public void Add(DmdType type)
        {
            if (recursionCounter > 100)
            {
                return;
            }
            recursionCounter++;

            while (type.GetElementType() is DmdType etype)
            {
                type = etype;
            }
            switch (type.TypeSignatureKind)
            {
            case DmdTypeSignatureKind.Type:
                modules.Add(type.Module);
                break;

            case DmdTypeSignatureKind.Pointer:
            case DmdTypeSignatureKind.ByRef:
            case DmdTypeSignatureKind.TypeGenericParameter:
            case DmdTypeSignatureKind.MethodGenericParameter:
            case DmdTypeSignatureKind.SZArray:
            case DmdTypeSignatureKind.MDArray:
                break;

            case DmdTypeSignatureKind.GenericInstance:
                modules.Add(type.GetGenericTypeDefinition().Module);
                foreach (var ga in type.GetGenericArguments())
                {
                    Add(ga);
                }
                break;

            case DmdTypeSignatureKind.FunctionPointer:
                var sig = type.GetFunctionPointerMethodSignature();
                Add(sig.ReturnType);
                foreach (var t in sig.GetParameterTypes())
                {
                    Add(t);
                }
                foreach (var t in sig.GetVarArgsParameterTypes())
                {
                    Add(t);
                }
                break;

            default:
                Debug.Fail($"Unknown kind: {type.TypeSignatureKind}");
                break;
            }

            recursionCounter--;
        }
Пример #2
0
        public CorType Create(DmdType type)
        {
            if ((object)type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (recursionCounter++ > 100)
            {
                throw new InvalidOperationException();
            }

            CorType result;
            int     i;
            ReadOnlyCollection <DmdType> types;

            CorType[] corTypes;
            DnModule  dnModule;

            switch (type.TypeSignatureKind)
            {
            case DmdTypeSignatureKind.Type:
                if (!engine.TryGetDnModule(type.Module.GetDebuggerModule() ?? throw new InvalidOperationException(), out dnModule))
                {
                    throw new InvalidOperationException();
                }
                Debug.Assert((type.MetadataToken >> 24) == 0x02);
                result = dnModule.CorModule.GetClassFromToken((uint)type.MetadataToken).GetParameterizedType(type.IsValueType ? CorElementType.ValueType : CorElementType.Class);
                break;

            case DmdTypeSignatureKind.Pointer:
                result = Create(type.GetElementType());
                result = appDomain.GetPtr(result);
                break;

            case DmdTypeSignatureKind.ByRef:
                result = Create(type.GetElementType());
                result = appDomain.GetByRef(result);
                break;

            case DmdTypeSignatureKind.TypeGenericParameter:
            case DmdTypeSignatureKind.MethodGenericParameter:
                throw new InvalidOperationException();

            case DmdTypeSignatureKind.SZArray:
                result = Create(type.GetElementType());
                result = appDomain.GetSZArray(result);
                break;

            case DmdTypeSignatureKind.MDArray:
                result = Create(type.GetElementType());
                result = appDomain.GetArray(result, (uint)type.GetArrayRank());
                break;

            case DmdTypeSignatureKind.GenericInstance:
                result   = Create(type.GetGenericTypeDefinition());
                types    = type.GetGenericArguments();
                corTypes = new CorType[types.Count];
                for (i = 0; i < corTypes.Length; i++)
                {
                    corTypes[i] = Create(types[i]);
                }
                result = result.Class.GetParameterizedType(type.IsValueType ? CorElementType.ValueType : CorElementType.Class, corTypes);
                break;

            case DmdTypeSignatureKind.FunctionPointer:
                var methodSig = type.GetFunctionPointerMethodSignature();
                types       = methodSig.GetParameterTypes();
                corTypes    = new CorType[1 + types.Count + methodSig.GetVarArgsParameterTypes().Count];
                corTypes[0] = Create(methodSig.ReturnType);
                for (i = 0; i < types.Count; i++)
                {
                    corTypes[i + 1] = Create(types[i]);
                }
                types = methodSig.GetVarArgsParameterTypes();
                for (i = 0; i < types.Count; i++)
                {
                    corTypes[i + 1 + methodSig.GetParameterTypes().Count] = Create(types[i]);
                }
                result = appDomain.GetFnPtr(corTypes);
                break;

            default:
                throw new InvalidOperationException();
            }

            if (result == null)
            {
                throw new InvalidOperationException();
            }

            recursionCounter--;
            return(result);
        }
Пример #3
0
        public void Format(DmdType type, DbgDotNetValue value)
        {
            if ((object)type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            List <(DmdType type, DbgDotNetValue value)> arrayTypesList = null;
            DbgDotNetValue disposeThisValue = 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 (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
                                {
                                    if (rank == 1)
                                    {
                                        OutputWrite("*", BoxedTextColor.Operator);
                                    }
                                    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(), disposeThisValue = value?.LoadIndirect().Value);
                    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 ((object)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:
                    var sig = type.GetFunctionPointerMethodSignature();
                    Format(sig.ReturnType, null);
                    WriteSpace();
                    OutputWrite(METHOD_OPEN_PAREN, BoxedTextColor.Punctuation);
                    var types = sig.GetParameterTypes();
                    for (int i = 0; i < types.Count; i++)
                    {
                        if (i > 0)
                        {
                            WriteCommaSpace();
                        }
                        Format(types[i], null);
                    }
                    types = sig.GetVarArgsParameterTypes();
                    if (types.Count > 0)
                    {
                        if (sig.GetParameterTypes().Count > 0)
                        {
                            WriteCommaSpace();
                        }
                        OutputWrite("...", BoxedTextColor.Punctuation);
                        for (int i = 0; i < types.Count; i++)
                        {
                            WriteCommaSpace();
                            Format(types[i], null);
                        }
                    }
                    OutputWrite(METHOD_CLOSE_PAREN, BoxedTextColor.Punctuation);
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
            finally {
                recursionCounter--;
                if (arrayTypesList != null)
                {
                    foreach (var info in arrayTypesList)
                    {
                        if (info.value != value)
                        {
                            info.value?.Dispose();
                        }
                    }
                }
                disposeThisValue?.Dispose();
            }
        }