public DebuggerDisplayAttributeFormatter(DbgEvaluationInfo evalInfo, LanguageFormatter languageFormatter, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) { Debug.Assert((options & DbgValueFormatterOptions.NoDebuggerDisplay) == 0); this.evalInfo = evalInfo; this.languageFormatter = languageFormatter; this.output = output; this.options = options; this.cultureInfo = cultureInfo; }
public DebuggerDisplayAttributeFormatter(DbgEvaluationContext context, DbgStackFrame frame, LanguageFormatter languageFormatter, ITextColorWriter output, DbgValueFormatterOptions options, CultureInfo cultureInfo, CancellationToken cancellationToken) { this.context = context; this.frame = frame; this.languageFormatter = languageFormatter; this.output = output; this.options = options; this.cultureInfo = cultureInfo; this.cancellationToken = cancellationToken; }
public static ValueFormatterOptions ToValueFormatterOptions(this DbgValueFormatterOptions options) { var res = ValueFormatterOptions.None; if ((options & DbgValueFormatterOptions.Edit) != 0) { res |= ValueFormatterOptions.Edit; } if ((options & DbgValueFormatterOptions.Decimal) != 0) { res |= ValueFormatterOptions.Decimal; } if ((options & DbgValueFormatterOptions.FuncEval) != 0) { res |= ValueFormatterOptions.FuncEval; } if ((options & DbgValueFormatterOptions.ToString) != 0) { res |= ValueFormatterOptions.ToString; } if ((options & DbgValueFormatterOptions.DigitSeparators) != 0) { res |= ValueFormatterOptions.DigitSeparators; } if ((options & DbgValueFormatterOptions.NoStringQuotes) != 0) { res |= ValueFormatterOptions.NoStringQuotes; } if ((options & DbgValueFormatterOptions.NoDebuggerDisplay) != 0) { res |= ValueFormatterOptions.NoDebuggerDisplay; } if ((options & DbgValueFormatterOptions.FullString) != 0) { res |= ValueFormatterOptions.FullString; } if ((options & DbgValueFormatterOptions.Namespaces) != 0) { res |= ValueFormatterOptions.Namespaces; } if ((options & DbgValueFormatterOptions.IntrinsicTypeKeywords) != 0) { res |= ValueFormatterOptions.IntrinsicTypeKeywords; } if ((options & DbgValueFormatterOptions.Tokens) != 0) { res |= ValueFormatterOptions.Tokens; } return(res); }
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); }
public abstract void FormatValue(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo);
public sealed override void FormatValue(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) => WriteTo(output, CachedValue);
/// <summary> /// Formats the name /// </summary> /// <param name="evalInfo">Evaluation info</param> /// <param name="output">Output</param> /// <param name="options">Formatter options</param> /// <param name="cultureInfo">Culture or null to use invariant culture</param> public void FormatName(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo cultureInfo = null) => Format(evalInfo, new DbgValueNodeFormatParameters {
internal bool TryFormat(DbgEvaluationContext context, IDbgTextWriter output, DbgStackFrameFormatterOptions options, DbgValueFormatterOptions valueOptions, CultureInfo cultureInfo, CancellationToken cancellationToken) => engineStackFrame.TryFormat(context, output, options, valueOptions, cultureInfo, cancellationToken);
public override bool FormatExpectedType(DbgEvaluationInfo evalInfo, ITextColorWriter output, DbgDotNetFormatter formatter, DbgValueFormatterTypeOptions options, DbgValueFormatterOptions valueOptions, CultureInfo cultureInfo) => columnFormatter?.FormatExpectedType(evalInfo, output, formatter, options, valueOptions, cultureInfo) ?? FormatDebuggerDisplayAttributeType(evalInfo, output, formatter, valueOptions, cultureInfo);
public override bool TryFormat(DbgEvaluationContext context, ITextColorWriter output, DbgStackFrameFormatterOptions options, DbgValueFormatterOptions valueOptions, CultureInfo cultureInfo, CancellationToken cancellationToken) { output.Write(BoxedTextColor.Punctuation, "["); output.Write(BoxedTextColor.Text, name); output.Write(BoxedTextColor.Punctuation, "]"); return(true); }
/// <summary> /// Formats a value /// </summary> /// <param name="context">Evaluation context</param> /// <param name="output">Output</param> /// <param name="frame">Stack frame</param> /// <param name="value">Value to format</param> /// <param name="options">Options</param> /// <param name="cultureInfo">Culture or null to use invariant culture</param> /// <param name="cancellationToken">Cancellation token</param> public abstract void FormatValue(DbgEvaluationContext context, ITextColorWriter output, DbgStackFrame frame, DbgDotNetValue value, DbgValueFormatterOptions options, CultureInfo cultureInfo, CancellationToken cancellationToken);
public bool Format(DbgDotNetValue value) { var typeState = GetOrCreateTypeState(value.Type, context.Language); if (typeState.DisplayParts.Length == 0) { return(false); } var evaluator = context.GetDebuggerDisplayAttributeEvaluator(); foreach (var part in typeState.DisplayParts) { if ((part.Flags & DisplayPartFlags.EvaluateText) == 0) { output.Write(BoxedTextColor.DebuggerDisplayAttributeEval, part.Text); } else { object eeState = typeState.GetExpressionEvaluatorState(context.Language.ExpressionEvaluator, part.Text); DbgDotNetEvalResult evalRes = default; try { evalRes = evaluator.Evaluate(typeState.TypeContext, frame, value, part.Text, DbgEvaluationOptions.Expression, eeState, cancellationToken); if (evalRes.Error != null) { output.Write(BoxedTextColor.Error, "<<<"); output.Write(BoxedTextColor.Error, evalRes.Error); output.Write(BoxedTextColor.Error, ">>>"); } else { // Prevent recursive calls by disabling func-eval var options = this.options & ~(DbgValueFormatterOptions.FuncEval | DbgValueFormatterOptions.ToString); if ((part.Flags & DisplayPartFlags.Decimal) != 0) { options |= DbgValueFormatterOptions.Decimal; } else if ((part.Flags & DisplayPartFlags.Hexadecimal) != 0) { options &= ~DbgValueFormatterOptions.Decimal; } if ((part.Flags & DisplayPartFlags.NoQuotes) != 0) { options |= DbgValueFormatterOptions.NoStringQuotes; } else { options &= ~DbgValueFormatterOptions.NoStringQuotes; } languageFormatter.FormatValue(context, output, frame, evalRes.Value, options, cultureInfo, cancellationToken); } } finally { if (evalRes.Value != value) { evalRes.Value?.Dispose(); } } } } return(true); }
public override void FormatValue(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) { }
public override void FormatFrame(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgStackFrameFormatterOptions options, DbgValueFormatterOptions valueOptions, CultureInfo?cultureInfo) => new CSharpStackFrameFormatter(output, evalInfo, this, options, valueOptions.ToValueFormatterOptions(), cultureInfo).Format();
public override void FormatValue(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgDotNetValue value, DbgValueFormatterOptions options, CultureInfo?cultureInfo) => new CSharpValueFormatter(output, evalInfo, this, options.ToValueFormatterOptions(), cultureInfo).Format(value);
string GetName(DbgEvaluationInfo evalInfo, DbgStringBuilderTextWriter output, DbgValueNode valueNode, DbgValueFormatterOptions options, CultureInfo?cultureInfo) { output.Reset(); valueNode.FormatName(evalInfo, output, options, cultureInfo); return(output.ToString()); }
DbgLocalsValueNodeInfo[] GetSortedVariables(DbgEvaluationInfo evalInfo, DbgLocalsValueNodeInfo[] variables, DbgValueFormatterOptions nameFormatterOptions, CultureInfo?cultureInfo) { if (variables.Length <= 1) { return(variables); } var sortParameters = debuggerSettings.SortParameters; var sortLocals = debuggerSettings.SortLocals; // If the default options are used, don't sort at all. Let the locals provider // decide how to sort them. if (!sortParameters && !sortLocals) { return(variables); } var output = new DbgStringBuilderTextWriter(); if (debuggerSettings.GroupParametersAndLocalsTogether) { return(variables.OrderBy(a => GetName(evalInfo, output, a.ValueNode, nameFormatterOptions, cultureInfo), StringComparer.OrdinalIgnoreCase).ToArray()); } else { var locals = variables.Where(a => a.Kind == DbgLocalsValueNodeKind.Local).ToArray(); var parameters = variables.Where(a => a.Kind == DbgLocalsValueNodeKind.Parameter).ToArray(); var others = variables.Where(a => a.Kind != DbgLocalsValueNodeKind.Local && a.Kind != DbgLocalsValueNodeKind.Parameter).ToArray(); if (sortLocals && locals.Length > 1) { locals = locals.OrderBy(a => GetName(evalInfo, output, a.ValueNode, nameFormatterOptions, cultureInfo), StringComparer.OrdinalIgnoreCase).ToArray(); } if (sortParameters && parameters.Length > 1) { parameters = parameters.OrderBy(a => GetName(evalInfo, output, a.ValueNode, nameFormatterOptions, cultureInfo), StringComparer.OrdinalIgnoreCase).ToArray(); } if ((sortLocals || sortParameters) && others.Length > 1) { others = others.OrderBy(a => GetName(evalInfo, output, a.ValueNode, nameFormatterOptions, cultureInfo), StringComparer.OrdinalIgnoreCase).ToArray(); } var res = new DbgLocalsValueNodeInfo[locals.Length + parameters.Length + others.Length]; int w = 0; for (int i = 0; i < parameters.Length; i++) { res[w++] = parameters[i]; } for (int i = 0; i < locals.Length; i++) { res[w++] = locals[i]; } for (int i = 0; i < others.Length; i++) { res[w++] = others[i]; } if (w != res.Length) { throw new InvalidOperationException(); } return(res); } }
public override ValueNodesProviderResult GetNodes(DbgEvaluationInfo evalInfo, DbgLanguage language, DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions, DbgValueFormatterOptions nameFormatterOptions) { var recreateAllNodes = forceRecreateAllNodes; forceRecreateAllNodes = false; const CultureInfo?cultureInfo = null; var exceptions = language.ExceptionsProvider.GetNodes(evalInfo, nodeEvalOptions); var returnValues = debuggerSettings.ShowReturnValues ? language.ReturnValuesProvider.GetNodes(evalInfo, nodeEvalOptions) : Array.Empty <DbgValueNode>(); var variables = language.LocalsProvider.GetNodes(evalInfo, nodeEvalOptions, GetLocalsValueNodeOptions()); var typeVariables = language.TypeVariablesProvider.GetNodes(evalInfo, nodeEvalOptions); var objectIds = dbgObjectIdService.GetObjectIds(evalInfo.Frame.Runtime); Array.Sort(objectIds, DbgObjectIdComparer.Instance); int count = exceptions.Length + returnValues.Length + objectIds.Length + variables.Length + typeVariables.Length; if (count == 0) { return(new ValueNodesProviderResult(Array.Empty <DbgValueNodeInfo>(), false)); } var res = new DbgValueNodeInfo[count]; int ri = 0; for (int i = 0; i < exceptions.Length; i++, ri++) { ulong id = (uint)i; var exception = exceptions[i]; if (exception.ImageName == PredefinedDbgValueNodeImageNames.StowedException) { id |= 1UL << 32; } res[ri] = new DbgValueNodeInfo(exception, GetNextExceptionId(id), causesSideEffects: false); } for (int i = 0; i < returnValues.Length; i++, ri++) { res[ri] = new DbgValueNodeInfo(returnValues[i], GetNextReturnValueId(), causesSideEffects: false); } var objectIdNodes = language.ValueNodeFactory.Create(evalInfo, objectIds, nodeEvalOptions); Debug.Assert(objectIdNodes.Length == objectIds.Length); for (int i = 0; i < objectIdNodes.Length; i++, ri++) { var id = GetObjectIdNodeId(objectIds[i]); res[ri] = new DbgValueNodeInfo(objectIdNodes[i], id, causesSideEffects: false); } variables = GetSortedVariables(evalInfo, variables, nameFormatterOptions, cultureInfo); for (int i = 0; i < variables.Length; i++, ri++) { res[ri] = new DbgValueNodeInfo(variables[i].ValueNode, causesSideEffects: false); } for (int i = 0; i < typeVariables.Length; i++, ri++) { res[ri] = new DbgValueNodeInfo(typeVariables[i], GetNextTypeVariableId((uint)i), causesSideEffects: false); } if (res.Length != ri) { throw new InvalidOperationException(); } return(new ValueNodesProviderResult(res, recreateAllNodes)); }
protected override void FormatReturnValueMethodName(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgValueFormatterTypeOptions typeOptions, DbgValueFormatterOptions valueOptions, CultureInfo cultureInfo, DmdMethodBase method, DmdPropertyInfo property) { var typeFormatter = new Formatters.CSharp.CSharpTypeFormatter(output, typeOptions.ToTypeFormatterOptions(), null); typeFormatter.Format(method.DeclaringType, null); var valueFormatter = new Formatters.CSharp.CSharpPrimitiveValueFormatter(output, valueOptions.ToValueFormatterOptions(), cultureInfo); output.Write(DbgTextColor.Operator, "."); if ((object)property != null) { if (property.GetIndexParameters().Count != 0) { output.Write(DbgTextColor.Keyword, Keyword_this); WriteMethodParameterList(output, method, typeFormatter, GetAllMethodParameterTypes(property.GetMethodSignature()), IndexerParenOpen, IndexerParenClose); } else { output.Write(MemberUtils.GetColor(property), Formatters.CSharp.CSharpTypeFormatter.GetFormattedIdentifier(property.Name)); } valueFormatter.WriteTokenComment(property.MetadataToken); output.Write(DbgTextColor.Operator, "."); output.Write(DbgTextColor.Keyword, "get"); valueFormatter.WriteTokenComment(method.MetadataToken); } else { var methodColor = TypeFormatterUtils.GetColor(method, canBeModule: false); if (TypeFormatterUtils.TryGetMethodName(method.Name, out var containingMethodName, out var localFunctionName)) { output.Write(methodColor, Formatters.CSharp.CSharpTypeFormatter.GetFormattedIdentifier(containingMethodName)); output.Write(DbgTextColor.Operator, "."); output.Write(methodColor, Formatters.CSharp.CSharpTypeFormatter.GetFormattedIdentifier(localFunctionName)); valueFormatter.WriteTokenComment(method.MetadataToken); WriteGenericMethodArguments(output, method, typeFormatter); }
public override bool FormatValue(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgDotNetFormatter formatter, DbgValueFormatterOptions options, CultureInfo cultureInfo) { noResultsName.WriteTo(output); return(true); }
public virtual bool FormatActualType(DbgEvaluationInfo evalInfo, ITextColorWriter output, DbgDotNetFormatter formatter, DbgValueFormatterTypeOptions options, DbgValueFormatterOptions valueOptions, CultureInfo cultureInfo) => false;
/// <summary> /// Formats a stack frame /// </summary> /// <param name="evalInfo">Evaluation info</param> /// <param name="output">Output</param> /// <param name="options">Stack frame options</param> /// <param name="valueOptions">Value option</param> /// <param name="cultureInfo">Culture or null to use invariant culture</param> public abstract void FormatFrame(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgStackFrameFormatterOptions options, DbgValueFormatterOptions valueOptions, CultureInfo?cultureInfo);
bool FormatDebuggerDisplayAttributeType(DbgEvaluationInfo evalInfo, IDbgTextWriter output, DbgDotNetFormatter formatter, DbgValueFormatterOptions options, CultureInfo?cultureInfo) { if (Value is null) { return(false); } if ((options & DbgValueFormatterOptions.NoDebuggerDisplay) != 0) { return(false); } var languageFormatter = formatter as LanguageFormatter; Debug2.Assert(languageFormatter is not null); if (languageFormatter is null) { return(false); } var displayAttrFormatter = new DebuggerDisplayAttributeFormatter(evalInfo, languageFormatter, output, options, cultureInfo); return(displayAttrFormatter.FormatType(Value)); }
/// <summary> /// Formats the value. The thread is blocked until the value has been formatted /// </summary> /// <param name="context">Evaluation context</param> /// <param name="output">Output</param> /// <param name="value">Value to format</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> public abstract void Format(DbgEvaluationContext context, ITextColorWriter output, DbgValue value, DbgValueFormatterOptions options, CancellationToken cancellationToken = default);
public override bool FormatValue(DbgEvaluationInfo evalInfo, ITextColorWriter output, DbgDotNetFormatter formatter, DbgValueFormatterOptions options, CultureInfo cultureInfo) { if (columnFormatter?.FormatValue(evalInfo, output, formatter, options, cultureInfo) == true) { return(true); } if (valueText.Parts != null) { valueText.WriteTo(output); return(true); } return(false); }
public override void FormatName(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) => output.Write(DbgTextColor.Text, expression);
public override bool FormatName(DbgEvaluationInfo evalInfo, ITextColorWriter output, DbgDotNetFormatter formatter, DbgValueFormatterOptions options, CultureInfo cultureInfo) { if (columnFormatter?.FormatName(evalInfo, output, formatter, options, cultureInfo) == true) { return(true); } if (Value == null) { return(false); } if ((options & DbgValueFormatterOptions.NoDebuggerDisplay) != 0) { return(false); } var languageFormatter = formatter as LanguageFormatter; Debug.Assert(languageFormatter != null); if (languageFormatter == null) { return(false); } var displayAttrFormatter = new DebuggerDisplayAttributeFormatter(evalInfo, languageFormatter, output, options, cultureInfo); return(displayAttrFormatter.FormatName(Value)); }
public override void FormatValue(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) => output.Write(DbgTextColor.Error, errorMessage);
public override void Format(DbgEvaluationContext context, DbgStackFrame frame, ITextColorWriter output, DbgValue value, DbgValueFormatterOptions options, CultureInfo cultureInfo, CancellationToken cancellationToken) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!(context is DbgEvaluationContextImpl)) { throw new ArgumentException(); } if (context.Language != Language) { throw new ArgumentException(); } if (context.Runtime.RuntimeKindGuid != runtimeKindGuid) { throw new ArgumentException(); } if (frame == null) { throw new ArgumentNullException(nameof(frame)); } if (frame.Runtime.RuntimeKindGuid != runtimeKindGuid) { throw new ArgumentException(); } if (output == null) { throw new ArgumentNullException(nameof(output)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (!(value is DbgValueImpl valueImpl)) { throw new ArgumentException(); } if (value.Runtime.RuntimeKindGuid != runtimeKindGuid) { throw new ArgumentException(); } engineValueFormatter.Format(context, frame, output, valueImpl.EngineValue, options, cultureInfo, cancellationToken); }
public sealed override void FormatName(DbgEvaluationInfo?evalInfo, IDbgTextWriter output, DbgValueFormatterOptions options, CultureInfo?cultureInfo) => WriteTo(output, CachedName, string.IsNullOrEmpty(Expression) ? UNKNOWN : Expression);