예제 #1
0
        /// <summary>
        /// Convert a type from the debugger's type system into X# type system
        /// </summary>
        /// <param name="lmrType">LMR Type</param>
        /// <returns>X# type</returns>
        public static XSharpType GetXSharpTypeForLmrType(Type lmrType)
        {
            if (lmrType.IsPrimitive)
            {
                return(XSharpType.Create(lmrType.FullName));
            }
            else if (lmrType.IsArray)
            {
                XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType());

                return(elementType.MakeArrayType());
            }
            else if (lmrType.IsByRef)
            {
                XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType());

                return(elementType.MakeByRefType());
            }
            else if (lmrType.FullName.Equals("System.String"))
            {
                return(XSharpType.String);
            }

            // Unknown
            return(XSharpType.Create(lmrType.FullName));
        }
예제 #2
0
        /// <summary>
        /// Convert a type from the debugger's type system into X# type system
        /// </summary>
        /// <param name="lmrType">LMR Type</param>
        /// <returns>X# type</returns>
        public static XSharpType GetXSharpTypeForLmrType(Type lmrType)
        {
            if (lmrType.IsPrimitive)
            {
                return(XSharpType.Create(lmrType.FullName));
            }
            else if (lmrType.IsArray)
            {
                XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType());

                return(elementType.MakeArrayType());
            }
            else if (lmrType.IsByRef)
            {
                XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType());

                return(elementType.MakeByRefType());
            }
            else if (lmrType.IsGenericType)
            {
                var args = lmrType.GetGenericArguments();
                var td   = lmrType.GetGenericTypeDefinition();
                return(XSharpType.Create(td, args));
            }

            else if (lmrType.FullName.Equals("System.String"))
            {
                return(XSharpType.String);
            }

            // Unknown
            return(XSharpType.Create(lmrType.FullName));
        }
예제 #3
0
        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());
        }
예제 #4
0
        /// <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 "&lt;Anonymous Type&gt;.
        /// 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?");

            int oldLength = builder.Length;
            AppendQualifiedTypeNameInternal(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, out sawInvalidIdentifier);
            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();
            }
        }
예제 #5
0
        /// <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 "&lt;Anonymous Type&gt;.
        /// 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();
            }
        }
예제 #6
0
        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();
        }
예제 #7
0
        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());
        }
예제 #8
0
        /// <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 "&lt;Anonymous Type&gt;.
        /// 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>
        /// 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);
        }
예제 #10
0
        /// <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;
        }
예제 #11
0
        internal Expansion GetTypeExpansion(DkmInspectionContext inspectionContext, Type declaredType, DkmClrValue value, ExpansionFlags flags)
        {
            Debug.Assert(!declaredType.IsTypeVariables());

            if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                return(null);
            }

            var runtimeType = value.Type.GetLmrType();

            // If the value is an array, expand the array elements.
            if (runtimeType.IsArray)
            {
                var sizes = value.ArrayDimensions;
                if (sizes == null)
                {
                    // Null array. No expansion.
                    return(null);
                }
                var lowerBounds = value.ArrayLowerBounds;
                return(ArrayExpansion.CreateExpansion(sizes, lowerBounds));
            }

            if (this.Formatter.IsPredefinedType(runtimeType))
            {
                return(null);
            }

            if (declaredType.IsPointer)
            {
                return(!value.IsNull ? new PointerDereferenceExpansion(declaredType.GetElementType()) : null);
            }

            if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) &&
                runtimeType.IsEmptyResultsViewException())
            {
                // The value is an exception thrown expanding an empty
                // IEnumerable. Use the runtime type of the exception and
                // skip base types. (This matches the native EE behavior
                // to expose a single property from the exception.)
                flags &= ~ExpansionFlags.IncludeBaseMembers;
            }

            return(MemberExpansion.CreateExpansion(inspectionContext, declaredType, value, flags, TypeHelpers.IsVisibleMember, this.Formatter));
        }
예제 #12
0
        internal Expansion GetTypeExpansion(DkmInspectionContext inspectionContext, Type declaredType, DkmClrValue value, ExpansionFlags flags)
        {
            Debug.Assert(!declaredType.IsTypeVariables());

            if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                return null;
            }

            var runtimeType = value.Type.GetLmrType();

            // If the value is an array, expand the array elements.
            if (runtimeType.IsArray)
            {
                var sizes = value.ArrayDimensions;
                if (sizes == null)
                {
                    // Null array. No expansion.
                    return null;
                }
                var lowerBounds = value.ArrayLowerBounds;
                return ArrayExpansion.CreateExpansion(sizes, lowerBounds);
            }

            if (this.Formatter.IsPredefinedType(runtimeType))
            {
                return null;
            }

            if (declaredType.IsPointer)
            {
                return !value.IsNull ? new PointerDereferenceExpansion(declaredType.GetElementType()) : null;
            }

            if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) &&
                runtimeType.IsEmptyResultsViewException())
            {
                // The value is an exception thrown expanding an empty
                // IEnumerable. Use the runtime type of the exception and
                // skip base types. (This matches the native EE behavior
                // to expose a single property from the exception.)
                flags &= ~ExpansionFlags.IncludeBaseMembers;
            }

            return MemberExpansion.CreateExpansion(declaredType, value, flags, TypeHelpers.IsVisibleMember, this.Formatter);
        }