Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions Fluid/Ast/MemberExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MemberSegment> segments) : this(segments as MemberSegment[] ?? segments.ToArray())
{
Segments = [segment];
}

public MemberExpression(IReadOnlyList<MemberSegment> 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");
Comment thread
sebastienros marked this conversation as resolved.
}
}

public IReadOnlyList<MemberSegment> Segments { get; }
public IReadOnlyList<MemberSegment> Segments => _segments;

public override ValueTask<FluidValue> 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

Expand All @@ -46,14 +51,14 @@ public override ValueTask<FluidValue> 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;
Expand All @@ -71,11 +76,11 @@ public override ValueTask<FluidValue> EvaluateAsync(TemplateContext context)
private static async ValueTask<FluidValue> Awaited(
ValueTask<FluidValue> task,
TemplateContext context,
IReadOnlyList<MemberSegment> 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);
Expand Down
9 changes: 8 additions & 1 deletion Fluid/ExceptionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(string message)
Expand All @@ -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.");
}
}
}
}