private void TraceTreeResult( EvaluationContext context, Object result, ValueKind kind) { // Get the realized expression String realizedExpression = ConvertToRealizedExpression(context); // Format the result String traceValue = ExpressionUtility.FormatValue(context.SecretMasker, result, kind); // Only trace the realized expression if it is meaningfully different if (!String.Equals(realizedExpression, traceValue, StringComparison.Ordinal)) { if (kind == ValueKind.Number && String.Equals(realizedExpression, $"'{traceValue}'", StringComparison.Ordinal)) { // Don't bother tracing the realized expression when the result is a number and the // realized expresion is a precisely matching string. } else { context.Trace.Info($"Expanded: {realizedExpression}"); } } // Always trace the result context.Trace.Info($"Result: {traceValue}"); }
/// <summary> /// This function is intended only for ExpressionNode authors to call. The EvaluationContext /// caches result-state specific to the evaluation instance. /// </summary> public EvaluationResult Evaluate(EvaluationContext context) { // Evaluate Level = Container == null ? 0 : Container.Level + 1; TraceVerbose(context, Level, $"Evaluating {Name}:"); var coreResult = EvaluateCore(context, out ResultMemory coreMemory); if (coreMemory == null) { coreMemory = new ResultMemory(); } // Convert to canonical value var val = ExpressionUtility.ConvertToCanonicalValue(coreResult, out ValueKind kind, out Object raw); // The depth can be safely trimmed when the total size of the core result is known, // or when the total size of the core result can easily be determined. var trimDepth = coreMemory.IsTotal || (Object.ReferenceEquals(raw, null) && ExpressionUtility.IsPrimitive(kind)); // Account for the memory overhead of the core result var coreBytes = coreMemory.Bytes ?? EvaluationMemory.CalculateBytes(raw ?? val); context.Memory.AddAmount(Level, coreBytes, trimDepth); // Account for the memory overhead of the conversion result if (!Object.ReferenceEquals(raw, null)) { var conversionBytes = EvaluationMemory.CalculateBytes(val); context.Memory.AddAmount(Level, conversionBytes); } var result = new EvaluationResult(context, Level, val, kind, raw); // Store the trace result if (this.TraceFullyRealized) { context.SetTraceResult(this, result); } return(result); }
internal void SetTraceResult( ExpressionNode node, EvaluationResult result) { // Remove if previously added. This typically should not happen. This could happen // due to a badly authored function. So we'll handle it and track memory correctly. if (m_traceResults.TryGetValue(node, out String oldValue)) { m_traceMemory.Remove(oldValue); m_traceResults.Remove(node); } // Check max memory String value = ExpressionUtility.FormatValue(SecretMasker, result); if (m_traceMemory.TryAdd(value)) { // Store the result m_traceResults[node] = value; } }
public Literal(Object val) { Value = ExpressionUtility.ConvertToCanonicalValue(val, out var kind, out _); Kind = kind; Name = kind.ToString(); }
internal sealed override String ConvertToRealizedExpression(EvaluationContext context) { return(ExpressionUtility.FormatValue(null, Value, Kind)); }
internal sealed override String ConvertToExpression() { return(ExpressionUtility.FormatValue(null, Value, Kind)); }