void FormatCore(DbgEvaluationInfo evalInfo, IDbgValueNodeFormatParameters options, CultureInfo?cultureInfo) { evalInfo.Runtime.GetDotNetRuntime().Dispatcher.VerifyAccess(); DbgValueFormatterOptions formatterOptions; DbgValueFormatterTypeOptions typeFormatterOptions; var formatter = owner.Formatter; var dnValue = value?.DotNetValue; if (!(options.NameOutput is null)) { formatterOptions = PredefinedFormatSpecifiers.GetValueFormatterOptions(dnValueNode.FormatSpecifiers, options.NameFormatterOptions); if (dnValueNode.FormatName(evalInfo, options.NameOutput, formatter, formatterOptions, cultureInfo)) { // Nothing } else { dnValueNode.Name.WriteTo(options.NameOutput); } evalInfo.CancellationToken.ThrowIfCancellationRequested(); } if (!(options.ExpectedTypeOutput is null)) { formatterOptions = PredefinedFormatSpecifiers.GetValueFormatterOptions(dnValueNode.FormatSpecifiers, options.TypeFormatterOptions); typeFormatterOptions = PredefinedFormatSpecifiers.GetValueFormatterTypeOptions(dnValueNode.FormatSpecifiers, options.ExpectedTypeFormatterOptions); if (dnValueNode.FormatExpectedType(evalInfo, options.ExpectedTypeOutput, formatter, typeFormatterOptions, formatterOptions, cultureInfo)) { // Nothing } else if (dnValueNode.ExpectedType is DmdType expectedType) { formatter.FormatType(evalInfo, options.ExpectedTypeOutput, expectedType, null, typeFormatterOptions, cultureInfo); } evalInfo.CancellationToken.ThrowIfCancellationRequested(); } if (!(options.ActualTypeOutput is null)) { formatterOptions = PredefinedFormatSpecifiers.GetValueFormatterOptions(dnValueNode.FormatSpecifiers, options.TypeFormatterOptions); typeFormatterOptions = PredefinedFormatSpecifiers.GetValueFormatterTypeOptions(dnValueNode.FormatSpecifiers, options.ActualTypeFormatterOptions); if (dnValueNode.FormatActualType(evalInfo, options.ActualTypeOutput, formatter, typeFormatterOptions, formatterOptions, cultureInfo)) { // Nothing } else if (dnValueNode.ActualType is DmdType actualType) { formatter.FormatType(evalInfo, options.ActualTypeOutput, actualType, dnValue, typeFormatterOptions, cultureInfo); } evalInfo.CancellationToken.ThrowIfCancellationRequested(); } if (!(options.ValueOutput is null)) { formatterOptions = PredefinedFormatSpecifiers.GetValueFormatterOptions(dnValueNode.FormatSpecifiers, options.ValueFormatterOptions); if (dnValueNode.FormatValue(evalInfo, options.ValueOutput, formatter, formatterOptions, cultureInfo)) { // Nothing } else if (!(dnValue is null)) { formatter.FormatValue(evalInfo, options.ValueOutput, dnValue, formatterOptions, cultureInfo); }
DbgDotNetValueNode CreateValue(DbgEvaluationInfo evalInfo, DbgDotNetText name, DbgDotNetValue value, ReadOnlyCollection <string>?formatSpecifiers, DbgValueNodeEvaluationOptions options, string expression, string imageName, bool isReadOnly, bool causesSideEffects, DmdType expectedType, bool isRootExpression, ColumnFormatter?columnFormatter) { // Could be a by-ref property, local, or parameter. if (expectedType.IsByRef) { if (value.Type.IsByRef) { var newValue = value.LoadIndirect(); value.Dispose(); if (newValue.HasError) { return(CreateError(evalInfo, name, newValue.ErrorMessage !, expression, causesSideEffects)); } value = newValue.Value !; } expectedType = expectedType.GetElementType() !; } options = PredefinedFormatSpecifiers.GetValueNodeEvaluationOptions(formatSpecifiers, options); var nodeInfo = new DbgDotNetValueNodeInfo(value, expression); bool addParens = isRootExpression && NeedsParentheses(expression); DbgDotNetValueNodeProviderResult info; bool useProvider = false; var specialViewOptions = (options & ~(DbgValueNodeEvaluationOptions.ResultsView | DbgValueNodeEvaluationOptions.DynamicView)); if ((options & DbgValueNodeEvaluationOptions.ResultsView) != 0) { info = valueNodeProviderFactory.CreateResultsView(evalInfo, addParens, expectedType, nodeInfo, specialViewOptions); useProvider = !(info.ErrorMessage is null); } else if ((options & DbgValueNodeEvaluationOptions.DynamicView) != 0) { info = valueNodeProviderFactory.CreateDynamicView(evalInfo, addParens, expectedType, nodeInfo, specialViewOptions); useProvider = true; } else { info = valueNodeProviderFactory.Create(evalInfo, addParens, expectedType, nodeInfo, options); } if (useProvider) { if (!(info.ErrorMessage is null)) { return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, PredefinedDbgValueNodeImageNames.Error, true, false, null, null, info.ErrorMessage, new DbgDotNetText(new DbgDotNetTextPart(DbgTextColor.Error, info.ErrorMessage)), formatSpecifiers, columnFormatter)); } Debug2.Assert(!(info.Provider is null)); return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, info.Provider?.ImageName ?? imageName, true, false, null, null, info.ErrorMessage, info.Provider?.ValueText ?? default, formatSpecifiers, columnFormatter)); } return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, imageName, isReadOnly, causesSideEffects, expectedType, value.Type, info.ErrorMessage, default, formatSpecifiers, columnFormatter));
bool Format(DbgDotNetValue value, TypeState typeState, DisplayPart[] displayParts) { if (displayParts.Length == 0) { return(false); } var evaluator = evalInfo.Context.GetDebuggerDisplayAttributeEvaluator(); foreach (var part in displayParts) { if ((part.Flags & DisplayPartFlags.EvaluateText) == 0) { output.Write(DbgTextColor.DebuggerDisplayAttributeEval, part.Text); } else { var eeState = typeState.GetExpressionEvaluatorState(evalInfo.Context.Language.ExpressionEvaluator, part.Text); DbgDotNetEvalResult evalRes = default; try { var evalInfo2 = new DbgEvaluationInfo(typeState.TypeContext !, evalInfo.Frame, evalInfo.CancellationToken); evalRes = evaluator.Evaluate(evalInfo2, value, part.Text, DbgEvaluationOptions.Expression, eeState); if (evalRes.Error is not null) { output.Write(DbgTextColor.Error, "<<<"); output.Write(DbgTextColor.Error, evalRes.Error); output.Write(DbgTextColor.Error, ">>>"); } else { // Prevent recursive calls var options = this.options | DbgValueFormatterOptions.NoDebuggerDisplay; options &= ~DbgValueFormatterOptions.NoStringQuotes; options = PredefinedFormatSpecifiers.GetValueFormatterOptions(evalRes.FormatSpecifiers, options); languageFormatter.FormatValue(evalInfo, output, evalRes.Value !, options, cultureInfo); } } finally { if (evalRes.Value != value) { evalRes.Value?.Dispose(); } } } } return(true); }