Skip to content

Commit fbe58c8

Browse files
Handling view argument
1 parent a5feab4 commit fbe58c8

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

src/libraries/Microsoft.PowerFx.Core/Binding/Binder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,8 @@ public void CheckPredicateUsage(CallNode node, TexlFunction func)
11361136
!node.Args.ChildNodes.Any(child => child is ErrorNode) &&
11371137
TryGetCall(node.Id, out var callInfo))
11381138
{
1139-
func.ScopeInfo.CheckPredicateFields(GetUsedScopeFields(callInfo), node, GetLambdaParamNames(callInfo.ScopeNest + 1), ErrorContainer);
1139+
//func.ScopeInfo.CheckPredicateFields(GetUsedScopeFields(callInfo), node, GetLambdaParamNames(callInfo.ScopeNest + 1), ErrorContainer);
1140+
func.ScopeInfo.CheckPredicateFields(this, callInfo);
11401141
}
11411142
}
11421143

src/libraries/Microsoft.PowerFx.Core/Functions/FunctionScopeInfo.cs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Filter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal sealed class FilterFunction : FilterFunctionBase
2727
public FilterFunction()
2828
: base("Filter", TexlStrings.AboutFilter, FunctionCategories.Table, DType.EmptyTable, -2, 2, int.MaxValue, DType.EmptyTable)
2929
{
30-
ScopeInfo = new FunctionScopeInfo(this, checkPredicateUsage: true);
30+
ScopeInfo = new FunctionFilterScopeInfo(this);
3131
}
3232

3333
public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()

0 commit comments

Comments
 (0)