@@ -217,23 +217,52 @@ public virtual bool GetScopeIdent(TexlNode[] nodes, out DName[] scopeIdents)
217217 return false ;
218218 }
219219
220- public virtual void CheckPredicateFields ( DType fields , CallNode callNode , IEnumerable < FirstNameInfo > lambdaNames , ErrorContainer errors )
220+ public virtual void CheckPredicateFields ( TexlBinding binding , CallInfo callInfo )
221221 {
222+ var fields = binding . GetUsedScopeFields ( callInfo ) ;
223+ var lambdaParamNames = binding . GetLambdaParamNames ( callInfo . ScopeNest + 1 ) ;
224+
222225 if ( fields == DType . Error || fields . GetAllNames ( DPath . Root ) . Any ( ) )
223226 {
224227 return ;
225228 }
226229
227- GetScopeIdent ( callNode . Args . ChildNodes . ToArray ( ) , out var idents ) ;
230+ GetScopeIdent ( callInfo . Node . Args . ChildNodes . ToArray ( ) , out var idents ) ;
228231
229- if ( ! lambdaNames . Any ( lambdaName => idents . Contains ( lambdaName . Name ) ) )
232+ if ( ! lambdaParamNames . Any ( lambdaName => idents . Contains ( lambdaName . Name ) ) )
230233 {
231- errors . EnsureError ( DocumentErrorSeverity . Warning , callNode , TexlStrings . WarnCheckPredicateUsage ) ;
234+ binding . ErrorContainer . EnsureError ( DocumentErrorSeverity . Warning , callInfo . Node , TexlStrings . WarnCheckPredicateUsage ) ;
232235 }
233236 }
234237 }
235238
236- internal class FunctionThisGroupScopeInfo : FunctionScopeInfo
239+ internal class FunctionFilterScopeInfo : FunctionScopeInfo
240+ {
241+ public FunctionFilterScopeInfo ( TexlFunction function )
242+ : base ( function , checkPredicateUsage : true )
243+ {
244+ }
245+
246+ public override void CheckPredicateFields ( TexlBinding binding , CallInfo callInfo )
247+ {
248+ // Filter can also accept a view as argument.
249+ // In the event of any argN (where N > 1) is a view, the binder will validate if the view is valid or not.
250+ // We check if there is any view as argument. If there is, we just skip the predicate checking.
251+ foreach ( var childNode in callInfo . Node . Args . ChildNodes )
252+ {
253+ var argType = binding . GetType ( childNode ) ;
254+
255+ if ( argType . Kind == DKind . ViewValue )
256+ {
257+ return ;
258+ }
259+ }
260+
261+ base . CheckPredicateFields ( binding , callInfo ) ;
262+ }
263+ }
264+
265+ internal class FunctionThisGroupScopeInfo : FunctionScopeInfo
237266 {
238267 public static DName ThisGroup => new DName ( "ThisGroup" ) ;
239268
@@ -278,7 +307,7 @@ public override bool CheckInput(Features features, CallNode callNode, TexlNode i
278307 }
279308 }
280309
281- internal class FunctionJoinScopeInfo : FunctionScopeInfo
310+ internal class FunctionJoinScopeInfo : FunctionScopeInfo
282311 {
283312 public static DName LeftRecord => new DName ( "LeftRecord" ) ;
284313
@@ -319,37 +348,40 @@ public override bool GetScopeIdent(TexlNode[] nodes, out DName[] scopeIdents)
319348 {
320349 scopeIdents [ 0 ] = LeftRecord ;
321350 }
322-
351+
323352 if ( nodes . Length > 1 && nodes [ 1 ] is AsNode rightAsNode )
324353 {
325354 scopeIdents [ 1 ] = rightAsNode . Right . Name ;
326355 }
327356 else
328357 {
329358 scopeIdents [ 1 ] = RightRecord ;
330- }
359+ }
331360
332361 // Returning false to indicate that the scope is not a whole scope.
333- // Meaning that the scope is a record type and we are accessing the fields directly.
362+ // Meaning that the scope is a record type and we are accessing the fields directly.
334363 return false ;
335364 }
336365
337- public override void CheckPredicateFields ( DType fields , CallNode callNode , IEnumerable < FirstNameInfo > lambdaNames , ErrorContainer errors )
366+ public override void CheckPredicateFields ( TexlBinding binding , CallInfo callInfo )
338367 {
368+ var fields = binding . GetUsedScopeFields ( callInfo ) ;
369+ var lambdaParamNames = binding . GetLambdaParamNames ( callInfo . ScopeNest + 1 ) ;
370+
339371 // If Join call node has less than 5 records, we are possibly looking for suggestions.
340- if ( callNode . Args . ChildNodes . Count < 5 || fields == DType . Error )
372+ if ( callInfo . Node . Args . ChildNodes . Count < 5 || fields == DType . Error )
341373 {
342374 return ;
343375 }
344376
345- GetScopeIdent ( callNode . Args . ChildNodes . ToArray ( ) , out var idents ) ;
377+ GetScopeIdent ( callInfo . Node . Args . ChildNodes . ToArray ( ) , out var idents ) ;
346378
347379 var foundIdents = new HashSet < DName > ( ) ;
348- var predicate = callNode . Args . ChildNodes [ 2 ] ;
380+ var predicate = callInfo . Node . Args . ChildNodes [ 2 ] ;
349381
350382 // In the Join function, arg2 and argN > 3 are lambdas nodes.
351383 // We need to check if scope identifiers are used arg2 (predicate).
352- foreach ( var lambda in lambdaNames )
384+ foreach ( var lambda in lambdaParamNames )
353385 {
354386 var parent = lambda . Node . Parent ;
355387
@@ -374,7 +406,7 @@ public override void CheckPredicateFields(DType fields, CallNode callNode, IEnum
374406 return ;
375407 }
376408
377- errors . EnsureError ( DocumentErrorSeverity . Warning , callNode , TexlStrings . WarnCheckPredicateUsage ) ;
409+ binding . ErrorContainer . EnsureError ( DocumentErrorSeverity . Warning , callInfo . Node , TexlStrings . WarnCheckPredicateUsage ) ;
378410 }
379411 }
380412}
0 commit comments