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;
            }
        }
Пример #4
0
 public Literal(Object val)
 {
     Value = ExpressionUtility.ConvertToCanonicalValue(val, out var kind, out _);
     Kind  = kind;
     Name  = kind.ToString();
 }
Пример #5
0
 internal sealed override String ConvertToRealizedExpression(EvaluationContext context)
 {
     return(ExpressionUtility.FormatValue(null, Value, Kind));
 }
Пример #6
0
 internal sealed override String ConvertToExpression()
 {
     return(ExpressionUtility.FormatValue(null, Value, Kind));
 }