Skip to content

Commit d56c7d3

Browse files
author
Bart Koelman
committed
Changed LogicalExpression.Terms type from IReadOnlyCollection to IImmutableList
1 parent 866c8b1 commit d56c7d3

File tree

9 files changed

+35
-50
lines changed

9 files changed

+35
-50
lines changed

src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
2+
using System.Collections.Immutable;
33
using System.Linq;
44
using System.Text;
55
using Humanizer;
@@ -14,9 +14,14 @@ namespace JsonApiDotNetCore.Queries.Expressions
1414
public class LogicalExpression : FilterExpression
1515
{
1616
public LogicalOperator Operator { get; }
17-
public IReadOnlyCollection<FilterExpression> Terms { get; }
17+
public IImmutableList<FilterExpression> Terms { get; }
1818

19-
public LogicalExpression(LogicalOperator @operator, IReadOnlyCollection<FilterExpression> terms)
19+
public LogicalExpression(LogicalOperator @operator, params FilterExpression[] terms)
20+
: this(@operator, terms.ToImmutableArray())
21+
{
22+
}
23+
24+
public LogicalExpression(LogicalOperator @operator, IImmutableList<FilterExpression> terms)
2025
{
2126
ArgumentGuard.NotNull(terms, nameof(terms));
2227

src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public override QueryExpression VisitLogical(LogicalExpression expression, TArgu
5555
{
5656
if (expression != null)
5757
{
58-
IReadOnlyCollection<FilterExpression> newTerms = VisitSequence(expression.Terms, argument);
58+
var newTerms = VisitList(expression.Terms, argument);
5959

6060
if (newTerms.Count == 1)
6161
{
62-
return newTerms.First();
62+
return newTerms[0];
6363
}
6464

6565
if (newTerms.Count != 0)

src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Collections.Immutable;
43
using System.Reflection;
54
using Humanizer;
@@ -106,28 +105,28 @@ protected LogicalExpression ParseLogical(string operatorName)
106105
EatText(operatorName);
107106
EatSingleCharacterToken(TokenKind.OpenParen);
108107

109-
var terms = new List<FilterExpression>();
108+
ImmutableArray<FilterExpression>.Builder termsBuilder = ImmutableArray.CreateBuilder<FilterExpression>();
110109

111110
FilterExpression term = ParseFilter();
112-
terms.Add(term);
111+
termsBuilder.Add(term);
113112

114113
EatSingleCharacterToken(TokenKind.Comma);
115114

116115
term = ParseFilter();
117-
terms.Add(term);
116+
termsBuilder.Add(term);
118117

119118
while (TokenStack.TryPeek(out Token nextToken) && nextToken.Kind == TokenKind.Comma)
120119
{
121120
EatSingleCharacterToken(TokenKind.Comma);
122121

123122
term = ParseFilter();
124-
terms.Add(term);
123+
termsBuilder.Add(term);
125124
}
126125

127126
EatSingleCharacterToken(TokenKind.CloseParen);
128127

129128
var logicalOperator = Enum.Parse<LogicalOperator>(operatorName.Pascalize());
130-
return new LogicalExpression(logicalOperator, terms);
129+
return new LogicalExpression(logicalOperator, termsBuilder.ToImmutable());
131130
}
132131

133132
protected ComparisonExpression ParseComparison(string operatorName)

src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,19 +310,11 @@ private FilterExpression CreateFilterByIds<TId>(IReadOnlyCollection<TId> ids, At
310310
}
311311
else if (ids.Count > 1)
312312
{
313-
ImmutableHashSet<LiteralConstantExpression> constants = ids.Select(id => new LiteralConstantExpression(id.ToString())).ToImmutableHashSet();
313+
IImmutableSet<LiteralConstantExpression> constants = ids.Select(id => new LiteralConstantExpression(id.ToString())).ToImmutableHashSet();
314314
filter = new AnyExpression(idChain, constants);
315315
}
316316

317-
// @formatter:keep_existing_linebreaks true
318-
319-
return filter == null
320-
? existingFilter
321-
: existingFilter == null
322-
? filter
323-
: new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(filter, existingFilter));
324-
325-
// @formatter:keep_existing_linebreaks restore
317+
return filter == null ? existingFilter : existingFilter == null ? filter : new LogicalExpression(LogicalOperator.And, filter, existingFilter);
326318
}
327319

328320
/// <inheritdoc />
@@ -442,9 +434,8 @@ protected virtual FilterExpression GetFilter(IReadOnlyCollection<QueryExpression
442434
ArgumentGuard.NotNull(expressionsInScope, nameof(expressionsInScope));
443435
ArgumentGuard.NotNull(resourceContext, nameof(resourceContext));
444436

445-
FilterExpression[] filters = expressionsInScope.OfType<FilterExpression>().ToArray();
446-
447-
FilterExpression filter = filters.Length > 1 ? new LogicalExpression(LogicalOperator.And, filters) : filters.FirstOrDefault();
437+
IImmutableList<FilterExpression> filters = expressionsInScope.OfType<FilterExpression>().ToImmutableArray();
438+
FilterExpression filter = filters.Count > 1 ? new LogicalExpression(LogicalOperator.And, filters) : filters.FirstOrDefault();
448439

449440
return _resourceDefinitionAccessor.OnApplyFilter(resourceContext.ResourceType, filter);
450441
}

src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.Linq;
45
using JetBrains.Annotations;
56
using JsonApiDotNetCore.Configuration;
@@ -23,8 +24,8 @@ public class FilterQueryStringParameterReader : QueryStringParameterReader, IFil
2324
private readonly IJsonApiOptions _options;
2425
private readonly QueryStringParameterScopeParser _scopeParser;
2526
private readonly FilterParser _filterParser;
26-
private readonly List<FilterExpression> _filtersInGlobalScope = new();
27-
private readonly Dictionary<ResourceFieldChainExpression, List<FilterExpression>> _filtersPerScope = new();
27+
private readonly ImmutableArray<FilterExpression>.Builder _filtersInGlobalScope = ImmutableArray.CreateBuilder<FilterExpression>();
28+
private readonly Dictionary<ResourceFieldChainExpression, ImmutableArray<FilterExpression>.Builder> _filtersPerScope = new();
2829

2930
private string _lastParameterName;
3031

@@ -142,7 +143,7 @@ private void StoreFilterInScope(FilterExpression filter, ResourceFieldChainExpre
142143
{
143144
if (!_filtersPerScope.ContainsKey(scope))
144145
{
145-
_filtersPerScope[scope] = new List<FilterExpression>();
146+
_filtersPerScope[scope] = ImmutableArray.CreateBuilder<FilterExpression>();
146147
}
147148

148149
_filtersPerScope[scope].Add(filter);
@@ -159,18 +160,18 @@ private IEnumerable<ExpressionInScope> EnumerateFiltersInScopes()
159160
{
160161
if (_filtersInGlobalScope.Any())
161162
{
162-
FilterExpression filter = MergeFilters(_filtersInGlobalScope);
163+
FilterExpression filter = MergeFilters(_filtersInGlobalScope.ToImmutable());
163164
yield return new ExpressionInScope(null, filter);
164165
}
165166

166-
foreach ((ResourceFieldChainExpression scope, List<FilterExpression> filters) in _filtersPerScope)
167+
foreach ((ResourceFieldChainExpression scope, ImmutableArray<FilterExpression>.Builder filtersBuilder) in _filtersPerScope)
167168
{
168-
FilterExpression filter = MergeFilters(filters);
169+
FilterExpression filter = MergeFilters(filtersBuilder.ToImmutable());
169170
yield return new ExpressionInScope(scope, filter);
170171
}
171172
}
172173

173-
private static FilterExpression MergeFilters(IReadOnlyCollection<FilterExpression> filters)
174+
private static FilterExpression MergeFilters(IImmutableList<FilterExpression> filters)
174175
{
175176
return filters.Count > 1 ? new LogicalExpression(LogicalOperator.Or, filters) : filters.First();
176177
}

src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private IReadOnlyCollection<IReadOnlyCollection<RelationshipAttribute>> GetInclu
130130

131131
foreach (ResourceFieldChainExpression chain in chains)
132132
{
133-
if (chain.Fields.First().Equals(relationship))
133+
if (chain.Fields[0].Equals(relationship))
134134
{
135135
inclusionChains.Add(chain.Fields.Cast<RelationshipAttribute>().ToArray());
136136
}

test/JsonApiDotNetCoreExampleTests/IntegrationTests/Archiving/TelevisionBroadcastDefinition.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using JetBrains.Annotations;
8-
using JsonApiDotNetCore;
98
using JsonApiDotNetCore.Configuration;
109
using JsonApiDotNetCore.Errors;
1110
using JsonApiDotNetCore.Middleware;
@@ -45,14 +44,11 @@ public override FilterExpression OnApplyFilter(FilterExpression existingFilter)
4544
if (IsReturningCollectionOfTelevisionBroadcasts() && !HasFilterOnArchivedAt(existingFilter))
4645
{
4746
AttrAttribute archivedAtAttribute = ResourceContext.Attributes.Single(attr => attr.Property.Name == nameof(TelevisionBroadcast.ArchivedAt));
48-
4947
var archivedAtChain = new ResourceFieldChainExpression(archivedAtAttribute);
5048

5149
FilterExpression isUnarchived = new ComparisonExpression(ComparisonOperator.Equals, archivedAtChain, new NullConstantExpression());
5250

53-
return existingFilter == null
54-
? isUnarchived
55-
: new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(existingFilter, isUnarchived));
51+
return existingFilter == null ? isUnarchived : new LogicalExpression(LogicalOperator.And, existingFilter, isUnarchived);
5652
}
5753
}
5854

@@ -192,7 +188,7 @@ private sealed class FilterWalker : QueryExpressionRewriter<object>
192188

193189
public override QueryExpression VisitResourceFieldChain(ResourceFieldChainExpression expression, object argument)
194190
{
195-
if (expression.Fields.First().Property.Name == nameof(TelevisionBroadcast.ArchivedAt))
191+
if (expression.Fields[0].Property.Name == nameof(TelevisionBroadcast.ArchivedAt))
196192
{
197193
HasFilterOnArchivedAt = true;
198194
}

test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private static bool IsCarId(PropertyInfo property)
8383

8484
private QueryExpression RewriteFilterOnCarStringIds(ResourceFieldChainExpression existingCarIdChain, IEnumerable<string> carStringIds)
8585
{
86-
var outerTerms = new List<FilterExpression>();
86+
ImmutableArray<FilterExpression>.Builder outerTermsBuilder = ImmutableArray.CreateBuilder<FilterExpression>();
8787

8888
foreach (string carStringId in carStringIds)
8989
{
@@ -93,10 +93,10 @@ private QueryExpression RewriteFilterOnCarStringIds(ResourceFieldChainExpression
9393
};
9494

9595
FilterExpression keyComparison = CreateEqualityComparisonOnCompositeKey(existingCarIdChain, tempCar.RegionId, tempCar.LicensePlate);
96-
outerTerms.Add(keyComparison);
96+
outerTermsBuilder.Add(keyComparison);
9797
}
9898

99-
return outerTerms.Count == 1 ? outerTerms[0] : new LogicalExpression(LogicalOperator.Or, outerTerms);
99+
return outerTermsBuilder.Count == 1 ? outerTermsBuilder[0] : new LogicalExpression(LogicalOperator.Or, outerTermsBuilder.ToImmutable());
100100
}
101101

102102
private FilterExpression CreateEqualityComparisonOnCompositeKey(ResourceFieldChainExpression existingCarIdChain, long regionIdValue,
@@ -112,11 +112,7 @@ private FilterExpression CreateEqualityComparisonOnCompositeKey(ResourceFieldCha
112112
var licensePlateComparison = new ComparisonExpression(ComparisonOperator.Equals, licensePlateChain,
113113
new LiteralConstantExpression(licensePlateValue));
114114

115-
return new LogicalExpression(LogicalOperator.And, new[]
116-
{
117-
regionIdComparison,
118-
licensePlateComparison
119-
});
115+
return new LogicalExpression(LogicalOperator.And, regionIdComparison, licensePlateComparison);
120116
}
121117

122118
public override QueryExpression VisitSort(SortExpression expression, object argument)

test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/Reading/PlanetDefinition.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Linq;
33
using System.Net;
44
using JetBrains.Annotations;
5-
using JsonApiDotNetCore;
65
using JsonApiDotNetCore.Configuration;
76
using JsonApiDotNetCore.Errors;
87
using JsonApiDotNetCore.Queries.Expressions;
@@ -55,9 +54,7 @@ public override FilterExpression OnApplyFilter(FilterExpression existingFilter)
5554
FilterExpression hasNoPrivateName = new ComparisonExpression(ComparisonOperator.Equals, new ResourceFieldChainExpression(privateNameAttribute),
5655
new NullConstantExpression());
5756

58-
return existingFilter == null
59-
? hasNoPrivateName
60-
: new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(hasNoPrivateName, existingFilter));
57+
return existingFilter == null ? hasNoPrivateName : new LogicalExpression(LogicalOperator.And, hasNoPrivateName, existingFilter);
6158
}
6259

6360
return existingFilter;

0 commit comments

Comments
 (0)