private EvalResult GetRow(
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            int index,
            EvalResultDataItem parent)
        {
            var typeParameter    = _typeParameters[index];
            var typeArgument     = _typeArguments[index];
            var typeArgumentInfo = _customTypeInfoMap.SubstituteCustomTypeInfo(typeParameter, customInfo: null);
            var formatSpecifiers = Formatter.NoFormatSpecifiers;

            return(new EvalResult(
                       ExpansionKind.TypeVariable,
                       typeParameter.Name,
                       typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                       declaredTypeAndInfo: new TypeAndCustomInfo(DkmClrType.Create(value.Type.AppDomain, typeArgument), typeArgumentInfo),
                       useDebuggerDisplay: parent != null,
                       value: value,
                       displayValue: inspectionContext.GetTypeName(DkmClrType.Create(value.Type.AppDomain, typeArgument), typeArgumentInfo, formatSpecifiers),
                       expansion: null,
                       childShouldParenthesize: false,
                       fullName: null,
                       childFullNamePrefixOpt: null,
                       formatSpecifiers: formatSpecifiers,
                       category: DkmEvaluationResultCategory.Data,
                       flags: DkmEvaluationResultFlags.ReadOnly,
                       editableValue: null,
                       inspectionContext: inspectionContext));
        }
        private static DkmClrType GetEnumerableType(DkmClrValue value)
        {
            Debug.Assert(!value.IsError());

            if (value.IsNull)
            {
                return(null);
            }

            var valueType = value.Type.GetLmrType();

            // Do not support Results View for strings
            // or arrays. (Matches legacy EE.)
            if (valueType.IsString() || valueType.IsArray)
            {
                return(null);
            }

            var enumerableType = valueType.GetIEnumerableImplementationIfAny();

            if (enumerableType == null)
            {
                return(null);
            }

            return(DkmClrType.Create(value.Type.AppDomain, enumerableType));
        }
Esempio n. 3
0
        internal static DkmClrType GetProxyType(this DkmClrType type)
        {
            // CONSIDER: If needed, we could probably compute a new DynamicAttribute for
            // the proxy type based on the DynamicAttribute of the argument.
            DkmClrType attributeTarget;
            DkmClrDebuggerTypeProxyAttribute attribute;

            if (type.TryGetEvalAttribute(out attributeTarget, out attribute))
            {
                var targetedType    = attributeTarget.GetLmrType();
                var proxyType       = attribute.ProxyType;
                var underlyingProxy = proxyType.GetLmrType();
                if (underlyingProxy.IsGenericType && targetedType.IsGenericType)
                {
                    var typeArgs = targetedType.GetGenericArguments();

                    // Drop the proxy type if the arity does not match.
                    if (typeArgs.Length != underlyingProxy.GetGenericArguments().Length)
                    {
                        return(null);
                    }

                    // Substitute target type arguments for proxy type arguments.
                    var constructedProxy = underlyingProxy.Substitute(underlyingProxy, typeArgs);
                    proxyType = DkmClrType.Create(type.AppDomain, constructedProxy);
                }

                return(proxyType);
            }

            return(null);
        }
Esempio n. 4
0
        private static DkmClrType GetEnumerableType(DkmClrValue value, DkmClrType valueType, bool requireExactInterface)
        {
            if (!IsEnumerableCandidate(value))
            {
                return(null);
            }

            var  type = valueType.GetLmrType();
            Type enumerableType;

            if (requireExactInterface)
            {
                if (!type.IsIEnumerable() && !type.IsIEnumerableOfT())
                {
                    return(null);
                }
                enumerableType = type;
            }
            else
            {
                enumerableType = type.GetIEnumerableImplementationIfAny();
                if (enumerableType == null)
                {
                    return(null);
                }
            }

            return(DkmClrType.Create(valueType.AppDomain, enumerableType));
        }
Esempio n. 5
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());
        }
Esempio n. 6
0
        internal static Type GetBaseTypeOrNull(this Type underlyingType, DkmClrAppDomain appDomain, out DkmClrType type)
        {
            Debug.Assert((underlyingType.BaseType != null) || underlyingType.IsPointer || underlyingType.IsArray, "BaseType should only return null if the underlyingType is a pointer or array.");

            underlyingType = underlyingType.BaseType;
            type           = (underlyingType != null) ? DkmClrType.Create(appDomain, underlyingType) : null;

            return(underlyingType);
        }
        internal static EvalResult CreateMemberDataItem(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            MemberAndDeclarationInfo member,
            DkmClrValue memberValue,
            EvalResultDataItem parent,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap,
            ExpansionFlags flags,
            bool supportsFavorites)
        {
            var    fullNameProvider = resultProvider.FullNameProvider;
            var    declaredType     = member.Type;
            var    declaredTypeInfo = customTypeInfoMap.SubstituteCustomTypeInfo(member.OriginalDefinitionType, member.TypeInfo);
            string memberName;
            // Considering, we're not handling the case of a member inherited from a generic base type.
            var typeDeclaringMember     = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType;
            var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface
                ? customTypeInfoMap.SubstituteCustomTypeInfo(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), customInfo: null)
                : null;
            var    memberNameForFullName = fullNameProvider.GetClrValidIdentifier(inspectionContext, memberName);
            var    appDomain             = memberValue.Type.AppDomain;
            string fullName;

            if (memberNameForFullName == null)
            {
                fullName = null;
            }
            else
            {
                memberName = memberNameForFullName;
                fullName   = MakeFullName(
                    fullNameProvider,
                    inspectionContext,
                    memberNameForFullName,
                    new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo),    // Note: Won't include DynamicAttribute.
                    member.RequiresExplicitCast,
                    member.IsStatic,
                    parent);
            }
            return(resultProvider.CreateDataItem(
                       inspectionContext,
                       memberName,
                       typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute.
                       declaredTypeAndInfo: new TypeAndCustomInfo(DkmClrType.Create(appDomain, declaredType), declaredTypeInfo),
                       value: memberValue,
                       useDebuggerDisplay: parent != null,
                       expansionFlags: flags,
                       childShouldParenthesize: false,
                       fullName: fullName,
                       formatSpecifiers: Formatter.NoFormatSpecifiers,
                       category: DkmEvaluationResultCategory.Other,
                       flags: memberValue.EvalFlags,
                       evalFlags: DkmEvaluationFlags.None,
                       canFavorite: member.CanFavorite,
                       isFavorite: member.IsFavorite,
                       supportsFavorites: supportsFavorites));
        }
Esempio n. 8
0
        private static TypeAndCustomInfo GetTupleFieldTypeAndInfo(
            DkmClrAppDomain appDomain,
            FieldInfo field,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap)
        {
            var declaringTypeDef = field.DeclaringType.GetGenericTypeDefinition();
            var fieldDef         = declaringTypeDef.GetTupleField(field.Name);
            var fieldType        = DkmClrType.Create(appDomain, field.FieldType);
            var fieldTypeInfo    = customTypeInfoMap.SubstituteCustomTypeInfo(fieldDef.FieldType, null);

            return(new TypeAndCustomInfo(fieldType, fieldTypeInfo));
        }
Esempio n. 9
0
        public DkmClrValue GetArrayElement(int[] indices)
        {
            var array   = (System.Array)_rawValue;
            var element = array.GetValue(indices);
            var type    = DkmClrType.Create(this.Type.AppDomain, (TypeImpl)((element == null) ? array.GetType().GetElementType() : element.GetType()));

            return(new DkmClrValue(
                       element,
                       element,
                       type: type,
                       alias: null,
                       formatter: _formatter,
                       evalFlags: DkmEvaluationResultFlags.None,
                       valueFlags: DkmClrValueFlags.None,
                       inspectionContext: this.InspectionContext));
        }
Esempio n. 10
0
        public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext)
        {
            if (inspectionContext == null)
            {
                throw new ArgumentNullException(nameof(inspectionContext));
            }

            var array   = (System.Array)RawValue;
            var element = array.GetValue(indices);
            var type    = DkmClrType.Create(this.Type.AppDomain, (TypeImpl)((element == null) ? array.GetType().GetElementType() : element.GetType()));

            return(new DkmClrValue(
                       element,
                       element,
                       type: type,
                       alias: null,
                       evalFlags: DkmEvaluationResultFlags.None,
                       valueFlags: DkmClrValueFlags.None));
        }
        private DkmEvaluationResult GetRow(ResultProvider resultProvider, DkmClrValue value, int index, EvalResultDataItem parent)
        {
            var inspectionContext = value.InspectionContext;
            var appDomain         = value.Type.AppDomain;
            var typeParameter     = _typeParameters[index];
            var typeArgument      = _typeArguments[index];
            var type     = DkmClrType.Create(appDomain, typeArgument);
            var name     = typeParameter.Name;
            var dataItem = new EvalResultDataItem(
                name,
                typeDeclaringMember: null,
                declaredType: typeArgument,
                value: null,
                expansion: null,
                childShouldParenthesize: false,
                fullName: null,
                childFullNamePrefixOpt: null,
                formatSpecifiers: Formatter.NoFormatSpecifiers,
                category: DkmEvaluationResultCategory.Data,
                flags: DkmEvaluationResultFlags.ReadOnly,
                editableValue: null);
            var typeName = inspectionContext.GetTypeName(DkmClrType.Create(appDomain, typeArgument));

            return(DkmSuccessEvaluationResult.Create(
                       inspectionContext,
                       value.StackFrame,
                       name,
                       dataItem.FullName,
                       dataItem.Flags,
                       Value: typeName,
                       EditableValue: null,
                       Type: typeName,
                       Category: dataItem.Category,
                       Access: value.Access,
                       StorageType: value.StorageType,
                       TypeModifierFlags: value.TypeModifierFlags,
                       Address: value.Address,
                       CustomUIVisualizers: null,
                       ExternalModules: null,
                       DataItem: dataItem));
        }
Esempio n. 12
0
        private static DkmEvaluationResult GetMemberRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            MemberAndDeclarationInfo member,
            EvalResultDataItem parent)
        {
            var memberValue = GetMemberValue(value, member);
            var dataItem    = CreateMemberDataItem(
                resultProvider,
                inspectionContext,
                member,
                memberValue,
                parent,
                ExpansionFlags.All);

            return(resultProvider.GetResult(
                       dataItem,
                       memberValue.Type,
                       DkmClrType.Create(memberValue.Type.AppDomain, member.Type),
                       parent));
        }
Esempio n. 13
0
        private EvalResultDataItem GetRow(ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue value, int index, EvalResultDataItem parent)
        {
            var typeParameter    = _typeParameters[index];
            var typeArgument     = _typeArguments[index];
            var formatSpecifiers = Formatter.NoFormatSpecifiers;

            return(new EvalResultDataItem(
                       ExpansionKind.TypeVariables,
                       typeParameter.Name,
                       typeDeclaringMember: null,
                       declaredType: typeArgument,
                       parent: parent,
                       value: value,
                       displayValue: inspectionContext.GetTypeName(DkmClrType.Create(value.Type.AppDomain, typeArgument), formatSpecifiers),
                       expansion: null,
                       childShouldParenthesize: false,
                       fullName: null,
                       childFullNamePrefixOpt: null,
                       formatSpecifiers: formatSpecifiers,
                       category: DkmEvaluationResultCategory.Data,
                       flags: DkmEvaluationResultFlags.ReadOnly,
                       editableValue: null,
                       inspectionContext: inspectionContext));
        }
Esempio n. 14
0
        internal static void AppendTypeMembers(
            this Type type,
            ArrayBuilder <MemberAndDeclarationInfo> includedMembers,
            Predicate <MemberInfo> predicate,
            Type declaredType,
            DkmClrAppDomain appDomain,
            bool includeInherited,
            bool hideNonPublic)
        {
            Debug.Assert(!type.IsInterface);

            var memberLocation         = DeclarationInfo.FromSubTypeOfDeclaredType;
            var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null;

            int inheritanceLevel = 0;

            while (!type.IsObject())
            {
                if (type.Equals(declaredType))
                {
                    Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType);
                    memberLocation = DeclarationInfo.FromDeclaredTypeOrBase;
                }

                // Get the state from DebuggerBrowsableAttributes for the members of the current type.
                var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState();

                // Hide non-public members if hideNonPublic is specified (intended to reflect the
                // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly
                // with no symbols.
                var hideNonPublicBehavior = DeclarationInfo.None;
                if (hideNonPublic)
                {
                    var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId);
                    if (moduleInstance == null || moduleInstance.Module == null)
                    {
                        // Synthetic module or no symbols loaded.
                        hideNonPublicBehavior = DeclarationInfo.HideNonPublic;
                    }
                }

                foreach (var member in type.GetMembers(MemberBindingFlags))
                {
                    if (!predicate(member))
                    {
                        continue;
                    }

                    var memberName = member.Name;
                    // This represents information about the immediately preceding (more derived)
                    // declaration with the same name as the current member.
                    var previousDeclaration   = DeclarationInfo.None;
                    var memberNameAlreadySeen = false;
                    if (includeInherited)
                    {
                        memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration);
                        if (memberNameAlreadySeen)
                        {
                            // There was a name conflict, so we'll need to include the declaring
                            // type of the member to disambiguate.
                            previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName;
                        }

                        // Update previous member with name hiding (casting) and declared location information for next time.
                        previousDeclarationMap[memberName] =
                            (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast |
                                                     DeclarationInfo.FromSubTypeOfDeclaredType)) |
                            member.AccessingBaseMemberWithSameNameRequiresExplicitCast() |
                            memberLocation;
                    }

                    Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None));

                    // Decide whether to include this member in the list of members to display.
                    if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast))
                    {
                        DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null;
                        if (browsableState != null)
                        {
                            DkmClrDebuggerBrowsableAttributeState value;
                            if (browsableState.TryGetValue(memberName, out value))
                            {
                                browsableStateValue = value;
                            }
                        }

                        if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the current type is a sub-type of the declared type, then
                            // we always need to insert a cast to access the member
                            previousDeclaration |= DeclarationInfo.RequiresExplicitCast;
                        }
                        else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the immediately preceding member (less derived) was
                            // declared on a sub-type of the declared type, then we'll
                            // ignore the casting bit.  Accessing a member through the
                            // declared type is the same as casting to that type, so
                            // the cast would be redundant.
                            previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast;
                        }

                        previousDeclaration |= hideNonPublicBehavior;

                        includedMembers.Add(new MemberAndDeclarationInfo(member, browsableStateValue, previousDeclaration, inheritanceLevel));
                    }
                }

                if (!includeInherited)
                {
                    break;
                }

                type = type.BaseType;
                inheritanceLevel++;
            }

            includedMembers.Sort(MemberAndDeclarationInfo.Comparer);
        }
Esempio n. 15
0
        /// <remarks>
        /// Very simple expression evaluation (may not support all syntax supported by Concord).
        /// </remarks>
        public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string formatString, DkmCompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine)
        {
            Debug.Assert(!this.IsNull, "Not supported by VIL");

            if (inspectionContext == null)
            {
                throw new ArgumentNullException(nameof(inspectionContext));
            }

            var pooled  = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;

            int openPos = -1;
            int length  = formatString.Length;

            for (int i = 0; i < length; i++)
            {
                char ch = formatString[i];
                if (ch == '{')
                {
                    if (openPos >= 0)
                    {
                        throw new ArgumentException(string.Format("Nested braces in '{0}'", formatString));
                    }
                    openPos = i;
                }
                else if (ch == '}')
                {
                    if (openPos < 0)
                    {
                        throw new ArgumentException(string.Format("Unmatched closing brace in '{0}'", formatString));
                    }

                    string name = formatString.Substring(openPos + 1, i - openPos - 1);
                    openPos = -1;

                    var formatSpecifiers = Formatter.NoFormatSpecifiers;
                    int commaIndex       = name.IndexOf(',');
                    if (commaIndex >= 0)
                    {
                        var rawFormatSpecifiers     = name.Substring(commaIndex + 1).Split(',');
                        var trimmedFormatSpecifiers = ArrayBuilder <string> .GetInstance(rawFormatSpecifiers.Length);

                        trimmedFormatSpecifiers.AddRange(rawFormatSpecifiers.Select(fs => fs.Trim()));
                        formatSpecifiers = trimmedFormatSpecifiers.ToImmutableAndFree();
                        foreach (var formatSpecifier in formatSpecifiers)
                        {
                            if (formatSpecifier == "nq")
                            {
                                inspectionContext = new DkmInspectionContext(_formatter, inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoQuotes, inspectionContext.Radix, inspectionContext.RuntimeInstance);
                            }
                            // If we need to support additional format specifiers, add them here...
                        }

                        name = name.Substring(0, commaIndex);
                    }

                    var type = ((TypeImpl)this.Type.GetLmrType()).Type;
                    const System.Reflection.BindingFlags bindingFlags =
                        System.Reflection.BindingFlags.Public |
                        System.Reflection.BindingFlags.NonPublic |
                        System.Reflection.BindingFlags.Instance |
                        System.Reflection.BindingFlags.Static;

                    DkmClrValue exprValue;
                    var         appDomain = this.Type.AppDomain;

                    var field = type.GetField(name, bindingFlags);
                    if (field != null)
                    {
                        var fieldValue = field.GetValue(RawValue);
                        exprValue = new DkmClrValue(
                            fieldValue,
                            fieldValue,
                            DkmClrType.Create(appDomain, (TypeImpl)((fieldValue == null) ? field.FieldType : fieldValue.GetType())),
                            alias: null,
                            formatter: _formatter,
                            evalFlags: GetEvaluationResultFlags(fieldValue),
                            valueFlags: DkmClrValueFlags.None);
                    }
                    else
                    {
                        var property = type.GetProperty(name, bindingFlags);
                        if (property != null)
                        {
                            var propertyValue = property.GetValue(RawValue);
                            exprValue = new DkmClrValue(
                                propertyValue,
                                propertyValue,
                                DkmClrType.Create(appDomain, (TypeImpl)((propertyValue == null) ? property.PropertyType : propertyValue.GetType())),
                                alias: null,
                                formatter: _formatter,
                                evalFlags: GetEvaluationResultFlags(propertyValue),
                                valueFlags: DkmClrValueFlags.None);
                        }
                        else
                        {
                            var openParenIndex = name.IndexOf('(');
                            if (openParenIndex >= 0)
                            {
                                name = name.Substring(0, openParenIndex);
                            }

                            var method = type.GetMethod(name, bindingFlags);
                            // The real implementation requires parens on method invocations, so
                            // we'll return error if there wasn't at least an open paren...
                            if ((openParenIndex >= 0) && method != null)
                            {
                                var methodValue = method.Invoke(RawValue, new object[] { });
                                exprValue = new DkmClrValue(
                                    methodValue,
                                    methodValue,
                                    DkmClrType.Create(appDomain, (TypeImpl)((methodValue == null) ? method.ReturnType : methodValue.GetType())),
                                    alias: null,
                                    formatter: _formatter,
                                    evalFlags: GetEvaluationResultFlags(methodValue),
                                    valueFlags: DkmClrValueFlags.None);
                            }
                            else
                            {
                                var stringValue = "Problem evaluating expression";
                                var stringType  = DkmClrType.Create(appDomain, (TypeImpl)typeof(string));
                                exprValue = new DkmClrValue(
                                    stringValue,
                                    stringValue,
                                    stringType,
                                    alias: null,
                                    formatter: _formatter,
                                    evalFlags: DkmEvaluationResultFlags.None,
                                    valueFlags: DkmClrValueFlags.Error);
                            }
                        }
                    }

                    builder.Append(exprValue.GetValueString(inspectionContext, formatSpecifiers)); // Re-enter the formatter.
                }
                else if (openPos < 0)
                {
                    builder.Append(ch);
                }
            }

            if (openPos >= 0)
            {
                throw new ArgumentException(string.Format("Unmatched open brace in '{0}'", formatString));
            }

            workList.AddWork(() => completionRoutine(new DkmEvaluateDebuggerDisplayStringAsyncResult(pooled.ToStringAndFree())));
        }
Esempio n. 16
0
        private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            switch (dataItem.Kind)
            {
            case ExpansionKind.Error:
                completionRoutine(DkmFailedEvaluationResult.Create(
                                      inspectionContext,
                                      StackFrame: stackFrame,
                                      Name: dataItem.Name,
                                      FullName: dataItem.FullName,
                                      ErrorMessage: dataItem.DisplayValue,
                                      Flags: DkmEvaluationResultFlags.None,
                                      Type: null,
                                      DataItem: null));
                break;

            case ExpansionKind.NonPublicMembers:
            case ExpansionKind.StaticMembers:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      dataItem.Name,
                                      typeName: string.Empty,
                                      display: null,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.RawView:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      Resources.RawView,
                                      typeName: string.Empty,
                                      display: null,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.ResultsView:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      dataItem.Name,
                                      typeName: string.Empty,
                                      display: Resources.ResultsViewValueWarning,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.TypeVariables:
                var value = dataItem.Value;
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      dataItem.Name,
                                      dataItem.FullName,
                                      dataItem.Flags,
                                      dataItem.DisplayValue,
                                      EditableValue: null,
                                      Type: dataItem.DisplayValue,
                                      Category: dataItem.Category,
                                      Access: value.Access,
                                      StorageType: value.StorageType,
                                      TypeModifierFlags: value.TypeModifierFlags,
                                      Address: value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            default:
                Debug.Assert((dataItem.Kind == ExpansionKind.Default) || (dataItem.Kind == ExpansionKind.PointerDereference));
                // This call will evaluate DebuggerDisplayAttributes.
                GetResultAndContinue(
                    dataItem,
                    workList,
                    declaredType: DkmClrType.Create(dataItem.Value.Type.AppDomain, dataItem.DeclaredType),
                    inspectionContext: inspectionContext,
                    parent: dataItem.Parent,
                    completionRoutine: completionRoutine);
                break;
            }
        }
Esempio n. 17
0
        /// <remarks>
        /// Very simple expression evaluation (may not support all syntax supported by Concord).
        /// </remarks>
        public string EvaluateDebuggerDisplayString(string formatString)
        {
            Debug.Assert(!this.IsNull, "Not supported by VIL");

            var pooled  = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;

            int openPos = -1;
            int length  = formatString.Length;

            for (int i = 0; i < length; i++)
            {
                char ch = formatString[i];
                if (ch == '{')
                {
                    if (openPos >= 0)
                    {
                        throw new ArgumentException(string.Format("Nested braces in '{0}'", formatString));
                    }
                    openPos = i;
                }
                else if (ch == '}')
                {
                    if (openPos < 0)
                    {
                        throw new ArgumentException(string.Format("Unmatched closing brace in '{0}'", formatString));
                    }

                    string name = formatString.Substring(openPos + 1, i - openPos - 1);
                    openPos = -1;

                    // Ignore any format specifiers.
                    int commaIndex = name.IndexOf(',');
                    if (commaIndex >= 0)
                    {
                        name = name.Substring(0, commaIndex);
                    }

                    var type         = ((TypeImpl)this.Type.GetLmrType()).Type;
                    var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

                    DkmClrValue exprValue;
                    var         appDomain = this.Type.AppDomain;

                    var field = type.GetField(name, bindingFlags);
                    if (field != null)
                    {
                        var fieldValue = field.GetValue(_rawValue);
                        exprValue = new DkmClrValue(
                            fieldValue,
                            fieldValue,
                            DkmClrType.Create(appDomain, (TypeImpl)((fieldValue == null) ? field.FieldType : fieldValue.GetType())),
                            alias: null,
                            formatter: _formatter,
                            evalFlags: GetEvaluationResultFlags(fieldValue),
                            valueFlags: DkmClrValueFlags.None,
                            inspectionContext: this.InspectionContext);
                    }
                    else
                    {
                        var property = type.GetProperty(name, bindingFlags);
                        if (property != null)
                        {
                            var propertyValue = property.GetValue(_rawValue);
                            exprValue = new DkmClrValue(
                                propertyValue,
                                propertyValue,
                                DkmClrType.Create(appDomain, (TypeImpl)((propertyValue == null) ? property.PropertyType : propertyValue.GetType())),
                                alias: null,
                                formatter: _formatter,
                                evalFlags: GetEvaluationResultFlags(propertyValue),
                                valueFlags: DkmClrValueFlags.None,
                                inspectionContext: this.InspectionContext);
                        }
                        else
                        {
                            var openParenIndex = name.IndexOf('(');
                            if (openParenIndex >= 0)
                            {
                                name = name.Substring(0, openParenIndex);
                            }

                            var method = type.GetMethod(name, bindingFlags);
                            // The real implementation requires parens on method invocations, so
                            // we'll return error if there wasn't at least an open paren...
                            if ((openParenIndex >= 0) && method != null)
                            {
                                var methodValue = method.Invoke(_rawValue, new object[] { });
                                exprValue = new DkmClrValue(
                                    methodValue,
                                    methodValue,
                                    DkmClrType.Create(appDomain, (TypeImpl)((methodValue == null) ? method.ReturnType : methodValue.GetType())),
                                    alias: null,
                                    formatter: _formatter,
                                    evalFlags: GetEvaluationResultFlags(methodValue),
                                    valueFlags: DkmClrValueFlags.None,
                                    inspectionContext: this.InspectionContext);
                            }
                            else
                            {
                                var stringValue = "Problem evaluating expression";
                                var stringType  = DkmClrType.Create(appDomain, (TypeImpl)typeof(string));
                                exprValue = new DkmClrValue(
                                    stringValue,
                                    stringValue,
                                    stringType,
                                    alias: null,
                                    formatter: _formatter,
                                    evalFlags: DkmEvaluationResultFlags.None,
                                    valueFlags: DkmClrValueFlags.Error,
                                    inspectionContext: this.InspectionContext);
                            }
                        }
                    }

                    builder.Append(exprValue.GetValueString()); // Re-enter the formatter.
                }
                else if (openPos < 0)
                {
                    builder.Append(ch);
                }
            }

            if (openPos >= 0)
            {
                throw new ArgumentException(string.Format("Unmatched open brace in '{0}'", formatString));
            }

            return(pooled.ToStringAndFree());
        }
Esempio n. 18
0
        internal Expansion GetTypeExpansion(
            DkmInspectionContext inspectionContext,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            ExpansionFlags flags)
        {
            var declaredType = declaredTypeAndInfo.Type;

            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;

                Type elementType;
                DkmClrCustomTypeInfo elementTypeInfo;
                if (declaredType.IsArray)
                {
                    elementType     = declaredType.GetElementType();
                    elementTypeInfo = CustomTypeInfo.SkipOne(declaredTypeAndInfo.Info);
                }
                else
                {
                    elementType     = runtimeType.GetElementType();
                    elementTypeInfo = null;
                }

                return(ArrayExpansion.CreateExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType), elementTypeInfo), sizes, lowerBounds));
            }

            if (this.IsPrimitiveType(runtimeType))
            {
                return(null);
            }

            if (declaredType.IsFunctionPointer())
            {
                // Function pointers have no expansion
                return(null);
            }

            if (declaredType.IsPointer)
            {
                // If this assert fails, the element type info is just .SkipOne().
                Debug.Assert(declaredTypeAndInfo.Info?.PayloadTypeId != CustomTypeInfo.PayloadTypeId);
                var elementType = declaredType.GetElementType();
                return(value.IsNull || elementType.IsVoid()
                    ? null
                    : new PointerDereferenceExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType))));
            }

            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, declaredTypeAndInfo, value, flags, TypeHelpers.IsVisibleMember, this));
        }
Esempio n. 19
0
        internal EvalResult CreateDataItem(
            DkmInspectionContext inspectionContext,
            string name,
            TypeAndCustomInfo typeDeclaringMemberAndInfo,
            TypeAndCustomInfo declaredTypeAndInfo,
            DkmClrValue value,
            bool useDebuggerDisplay,
            ExpansionFlags expansionFlags,
            bool childShouldParenthesize,
            string fullName,
            ReadOnlyCollection <string> formatSpecifiers,
            DkmEvaluationResultCategory category,
            DkmEvaluationResultFlags flags,
            DkmEvaluationFlags evalFlags)
        {
            if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0)
            {
                formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw");
            }

            Expansion expansion;
            // If the declared type is Nullable<T>, the value should
            // have no expansion if null, or be expanded as a T.
            var declaredType       = declaredTypeAndInfo.Type;
            var lmrNullableTypeArg = declaredType.GetNullableTypeArgument();

            if (lmrNullableTypeArg != null && !value.HasExceptionThrown())
            {
                Debug.Assert(value.Type.GetProxyType() == null);

                DkmClrValue nullableValue;
                if (value.IsError())
                {
                    expansion = null;
                }
                else if ((nullableValue = value.GetNullableValue(lmrNullableTypeArg, inspectionContext)) == null)
                {
                    Debug.Assert(declaredType.Equals(value.Type.GetLmrType()));
                    // No expansion of "null".
                    expansion = null;
                }
                else
                {
                    value = nullableValue;
                    Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary.
                    // CONSIDER: The DynamicAttribute for the type argument should just be Skip(1) of the original flag array.
                    expansion = this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, lmrNullableTypeArg)), value, ExpansionFlags.IncludeResultsView);
                }
            }
            else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0)
            {
                expansion = null;
            }
            else
            {
                expansion = DebuggerTypeProxyExpansion.CreateExpansion(
                    this,
                    inspectionContext,
                    name,
                    typeDeclaringMemberAndInfo,
                    declaredTypeAndInfo,
                    value,
                    childShouldParenthesize,
                    fullName,
                    flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                    formatSpecifiers,
                    flags,
                    Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info));
                if (expansion == null)
                {
                    expansion = value.HasExceptionThrown()
                        ? this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(value.Type), value, expansionFlags)
                        : this.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, expansionFlags);
                }
            }

            return(new EvalResult(
                       ExpansionKind.Default,
                       name,
                       typeDeclaringMemberAndInfo,
                       declaredTypeAndInfo,
                       useDebuggerDisplay: useDebuggerDisplay,
                       value: value,
                       displayValue: null,
                       expansion: expansion,
                       childShouldParenthesize: childShouldParenthesize,
                       fullName: fullName,
                       childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName,
                       formatSpecifiers: formatSpecifiers,
                       category: category,
                       flags: flags,
                       editableValue: Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info),
                       inspectionContext: inspectionContext));
        }
Esempio n. 20
0
        private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            switch (dataItem.Kind)
            {
            case ExpansionKind.Error:
                completionRoutine(DkmFailedEvaluationResult.Create(
                                      inspectionContext,
                                      StackFrame: stackFrame,
                                      Name: dataItem.Name,
                                      FullName: dataItem.FullName,
                                      ErrorMessage: dataItem.DisplayValue,
                                      Flags: DkmEvaluationResultFlags.None,
                                      Type: null,
                                      DataItem: null));
                break;

            case ExpansionKind.NativeView:
            {
                var value    = dataItem.Value;
                var name     = Resources.NativeView;
                var fullName = dataItem.FullName;
                var display  = dataItem.Name;
                DkmEvaluationResult evalResult;
                if (value.IsError())
                {
                    evalResult = DkmFailedEvaluationResult.Create(
                        inspectionContext,
                        stackFrame,
                        Name: name,
                        FullName: fullName,
                        ErrorMessage: display,
                        Flags: dataItem.Flags,
                        Type: null,
                        DataItem: dataItem);
                }
                else
                {
                    // For Native View, create a DkmIntermediateEvaluationResult.
                    // This will allow the C++ EE to take over expansion.
                    var process = inspectionContext.RuntimeInstance.Process;
                    var cpp     = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
                    evalResult = DkmIntermediateEvaluationResult.Create(
                        inspectionContext,
                        stackFrame,
                        Name: name,
                        FullName: fullName,
                        Expression: display,
                        IntermediateLanguage: cpp,
                        TargetRuntime: process.GetNativeRuntimeInstance(),
                        DataItem: dataItem);
                }
                completionRoutine(evalResult);
            }
            break;

            case ExpansionKind.NonPublicMembers:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: Resources.NonPublicMembers,
                                      FullName: dataItem.FullName,
                                      Flags: dataItem.Flags,
                                      Value: null,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: dataItem.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            case ExpansionKind.StaticMembers:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: Formatter.StaticMembersString,
                                      FullName: dataItem.FullName,
                                      Flags: dataItem.Flags,
                                      Value: null,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Class,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: dataItem.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            case ExpansionKind.RawView:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: Resources.RawView,
                                      FullName: dataItem.FullName,
                                      Flags: dataItem.Flags,
                                      Value: null,
                                      EditableValue: dataItem.EditableValue,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: dataItem.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            case ExpansionKind.DynamicView:
            case ExpansionKind.ResultsView:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      dataItem.Name,
                                      dataItem.FullName,
                                      dataItem.Flags,
                                      dataItem.DisplayValue,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Method,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: dataItem.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            case ExpansionKind.TypeVariable:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      dataItem.Name,
                                      dataItem.FullName,
                                      dataItem.Flags,
                                      dataItem.DisplayValue,
                                      EditableValue: null,
                                      Type: dataItem.DisplayValue,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: dataItem.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            case ExpansionKind.PointerDereference:
            case ExpansionKind.Default:
                // This call will evaluate DebuggerDisplayAttributes.
                GetResultAndContinue(
                    dataItem,
                    workList,
                    declaredType: DkmClrType.Create(dataItem.Value.Type.AppDomain, dataItem.DeclaredTypeAndInfo.Type),
                    declaredTypeInfo: dataItem.DeclaredTypeAndInfo.Info,
                    inspectionContext: inspectionContext,
                    parent: dataItem.Parent,
                    completionRoutine: completionRoutine);
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(dataItem.Kind);
            }
        }
Esempio n. 21
0
        private static DkmEvaluationResult GetRow(
            ResultProvider resultProvider,
            DkmInspectionContext inspectionContext,
            DkmClrValue pointer,
            Type elementType,
            EvalResultDataItem parent)
        {
            var value              = pointer.Dereference();
            var valueType          = value.Type.GetLmrType();
            var wasExceptionThrown = value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown);

            string debuggerDisplayName;
            string debuggerDisplayValue;
            string debuggerDisplayType;

            value.GetDebuggerDisplayStrings(out debuggerDisplayName, out debuggerDisplayValue, out debuggerDisplayType);

            var declaredType = elementType;
            var typeName     = debuggerDisplayType ?? pointer.InspectionContext.GetTypeName(DkmClrType.Create(pointer.Type.AppDomain, declaredType));
            var expansion    = wasExceptionThrown
                ? null
                : resultProvider.GetTypeExpansion(inspectionContext, declaredType, value, ExpansionFlags.None);
            var fullName      = string.Format("*{0}", parent.ChildFullNamePrefix);
            var editableValue = resultProvider.Formatter.GetEditableValue(value);

            // NB: Full name is based on the real (i.e. not DebuggerDisplay) name.  This is a change from dev12,
            // which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios.
            var dataItem = new EvalResultDataItem(
                name: null, // Okay for pointer dereferences.
                typeDeclaringMember: null,
                declaredType: declaredType,
                value: value,
                expansion: expansion,
                childShouldParenthesize: true,
                fullName: fullName,
                childFullNamePrefixOpt: fullName,
                formatSpecifiers: Formatter.NoFormatSpecifiers,
                category: DkmEvaluationResultCategory.Other,
                flags: DkmEvaluationResultFlags.None,
                editableValue: editableValue);

            var name    = debuggerDisplayName ?? fullName;
            var display = debuggerDisplayValue ??
                          (wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName) : value.GetValueString());

            return(ResultProvider.CreateEvaluationResult(
                       value,
                       name,
                       typeName,
                       display,
                       dataItem));
        }