diff --git a/Fluid/Ast/MemberExpression.cs b/Fluid/Ast/MemberExpression.cs index 5f8e782a..c5e1346b 100644 --- a/Fluid/Ast/MemberExpression.cs +++ b/Fluid/Ast/MemberExpression.cs @@ -4,28 +4,33 @@ namespace Fluid.Ast { public sealed class MemberExpression : Expression { - public MemberExpression(MemberSegment segment) + private readonly MemberSegment[] _segments; + + public MemberExpression(MemberSegment segment) : this([segment]) + { + } + + public MemberExpression(IReadOnlyList segments) : this(segments as MemberSegment[] ?? segments.ToArray()) { - Segments = [segment]; } - public MemberExpression(IReadOnlyList segments) + internal MemberExpression(MemberSegment[] segments) { - Segments = segments ?? []; + _segments = segments ?? []; - if (Segments.Count == 0) + if (_segments.Length == 0) { - throw new ArgumentException("At least one segment is required in a MemberExpression"); + ExceptionHelper.ThrowArgumentNullException(nameof(segments), "At least one segment is required in a MemberExpression"); } } - public IReadOnlyList Segments { get; } + public IReadOnlyList Segments => _segments; public override ValueTask EvaluateAsync(TemplateContext context) { // The first segment can only be an IdentifierSegment - var initial = Segments[0] as IdentifierSegment; + var initial = _segments[0] as IdentifierSegment; // Search the initial segment in the local scope first @@ -46,14 +51,14 @@ public override ValueTask EvaluateAsync(TemplateContext context) value = context.Model; } - for (var i = start; i < Segments.Count; i++) + for (var i = start; i < _segments.Length; i++) { - var s = Segments[i]; + var s = _segments[i]; var task = s.ResolveAsync(value, context); if (!task.IsCompletedSuccessfully) { - return Awaited(task, context, Segments, i + 1); + return Awaited(task, context, _segments, i + 1); } value = task.Result; @@ -71,11 +76,11 @@ public override ValueTask EvaluateAsync(TemplateContext context) private static async ValueTask Awaited( ValueTask task, TemplateContext context, - IReadOnlyList segments, + MemberSegment[] segments, int startIndex) { var value = await task; - for (var i = startIndex; i < segments.Count; i++) + for (var i = startIndex; i < segments.Length; i++) { var s = segments[i]; value = await s.ResolveAsync(value, context); diff --git a/Fluid/ExceptionHelper.cs b/Fluid/ExceptionHelper.cs index 5fb6e740..a46dd146 100644 --- a/Fluid/ExceptionHelper.cs +++ b/Fluid/ExceptionHelper.cs @@ -29,6 +29,13 @@ public static void ThrowArgumentOutOfRangeException(string paramName, string mes throw new ArgumentOutOfRangeException(paramName, message); } + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowArgumentException(string paramName, string message) + { + throw new ArgumentException(paramName, message); + } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowParseException(string message) @@ -50,4 +57,4 @@ public static void ThrowMaximumStatementsException() throw new InvalidOperationException("The maximum number of statements has been reached. Your script took too long to run."); } } -} \ No newline at end of file +}