Beispiel #1
0
        internal CompiledTemplate([NotNull] TemplateDocument document, [NotNull] CompiledEvaluationDelegate <TContext> evaluationDelegate)
        {
            Debug.Assert(document != null, "Argument document cannot be null.");
            Debug.Assert(evaluationDelegate != null, "Argument evaluationDelegate cannot be null.");

            _document           = document;
            _evaluationDelegate = evaluationDelegate;
        }
Beispiel #2
0
        /// <summary>
        /// Constructs a delegate used in evaluation of a given double-tag <paramref name="directive"/>.
        /// </summary>
        /// <remarks>
        /// <see cref="BuildDoubleTagDirectiveEvaluationDelegate"/> method is used to build a new delegate for directives
        /// that are composed of two tags(e.g. <c>{IF}...{END}</c>. The contents (all inner document nodes) found between the directive's tags is
        /// passed along in <paramref name="innerDelegate"/> parameter. If there are no nodes between its two consecutive tags, a <c>null</c> value
        /// is passed. The <paramref name="openComponents"/> and <paramref name="closeComponents"/> contain the components for the opening and closing tags.
        /// </remarks>
        /// <param name="directive">The directive.</param>
        /// <param name="innerDelegate">A delegate that represents the contents of the inner nodes.</param>
        /// <param name="openComponents">The components associated with the opening tag.</param>
        /// <param name="closeComponents">The components associated with the closing tag.</param>
        /// <returns>A new delegate tasked with evaluating the given directive.</returns>
        protected override CompiledEvaluationDelegate <EvaluationContext> BuildDoubleTagDirectiveEvaluationDelegate(
            Directive directive,
            CompiledEvaluationDelegate <EvaluationContext> innerDelegate,
            object[] openComponents,
            object[] closeComponents)
        {
            Debug.Assert(directive != null, "Argument directive cannot be null.");
            Debug.Assert(openComponents != null, "Argument openComponents cannot be null.");
            Debug.Assert(openComponents.Length > 0, "Argument openComponents cannot be empty.");
            Debug.Assert(closeComponents != null, "Argument closeComponents cannot be null.");
            Debug.Assert(closeComponents.Length > 0, "Argument closeComponents cannot be empty.");

            return((writer, context) =>
            {
                context.OpenEvaluationFrame();
                try
                {
                    EvaluateDoubleTagDirective(
                        writer,
                        context,
                        directive,
                        openComponents,
                        closeComponents,
                        innerDelegate);
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    if (!context.IgnoreEvaluationExceptions)
                    {
                        ExceptionHelper.DirectiveEvaluationError(exception, directive);
                    }
                }
                finally
                {
                    context.CloseEvaluationFrame();
                }
            });
        }
 protected abstract CompiledEvaluationDelegate <TContext> BuildDoubleTagDirectiveEvaluationDelegate(
     [NotNull] Directive directive,
     [NotNull] CompiledEvaluationDelegate <TContext> innerDelegate,
     [NotNull] object[] openComponents,
     [NotNull] object[] closeComponents);
Beispiel #4
0
        private static void EvaluateDoubleTagDirective(
            [NotNull] TextWriter writer,
            [NotNull] EvaluationContext context,
            [NotNull] Directive directive,
            [NotNull] IReadOnlyList <object> beginComponents,
            [NotNull] IReadOnlyList <object> closeComponents,
            [CanBeNull] CompiledEvaluationDelegate <EvaluationContext> beginToCloseEvaluateProc)
        {
            /* Get tag components. */
            var beginTagEvaluatedComponents = EvaluateTag(context, beginComponents);

            object[] closeTagEvaluatedComponents = null;

            /* Evaluate tag. */
            object state = null;

            while (true)
            {
                /* Check for cancellation. */
                context.CancellationToken.ThrowIfCancellationRequested();

                var flowDecision = directive.Execute(0, beginTagEvaluatedComponents, ref state, context, out string directiveText);

                /* Check for cancellation. */
                context.CancellationToken.ThrowIfCancellationRequested();

                if (directiveText != null)
                {
                    writer.Write(directiveText);
                }

                if (flowDecision == Directive.FlowDecision.Terminate)
                {
                    break;
                }

                switch (flowDecision)
                {
                case Directive.FlowDecision.Restart:
                    continue;

                case Directive.FlowDecision.Evaluate:
                    beginToCloseEvaluateProc?.Invoke(writer, context);
                    break;

                case Directive.FlowDecision.Terminate:
                    break;

                case Directive.FlowDecision.Skip:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(flowDecision));
                }

                if (closeTagEvaluatedComponents == null)
                {
                    closeTagEvaluatedComponents = EvaluateTag(context, closeComponents);
                }

                /* Check for cancellation. */
                context.CancellationToken.ThrowIfCancellationRequested();

                flowDecision = directive.Execute(1, closeTagEvaluatedComponents, ref state, context, out directiveText);

                if (directiveText != null)
                {
                    writer.Write(directiveText);
                }

                if (flowDecision == Directive.FlowDecision.Terminate)
                {
                    break;
                }
            }
        }