Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Error Span for "Function X has some invalid arguments" #2284

Merged
merged 6 commits into from
Mar 29, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ public TexlError EnsureError(DocumentErrorSeverity severity, Token token, ErrorR

if (!HasErrors(token, severity))
{
var err = new TexlError(token, severity, errKey, args);
CollectionUtils.Add(ref _errors, err);
return err;
Error(severity, token, errKey, args);
}

return null;
Expand All @@ -157,6 +155,11 @@ public TexlError Error(TexlNode node, ErrorResourceKey errKey, params object[] a
return Error(DefaultSeverity, node, errKey, args);
}

public TexlError Error(Token token, ErrorResourceKey errKey, params object[] args)
{
return Error(DefaultSeverity, token, errKey, args);
}

public TexlError Error(DocumentErrorSeverity severity, TexlNode node, ErrorResourceKey errKey, params object[] args)
{
Contracts.AssertValue(node);
Expand All @@ -167,6 +170,16 @@ public TexlError Error(DocumentErrorSeverity severity, TexlNode node, ErrorResou
return err;
}

public TexlError Error(DocumentErrorSeverity severity, Token token, ErrorResourceKey errKey, params object[] args)
{
Contracts.AssertValue(token);
Contracts.AssertValue(args);

var err = new TexlError(token, severity, errKey, args);
CollectionUtils.Add(ref _errors, err);
return err;
}

public void Errors(TexlNode node, DType nodeType, KeyValuePair<string, DType> schemaDifference, DType schemaDifferenceType)
{
Contracts.AssertValue(node);
Expand Down
20 changes: 10 additions & 10 deletions src/libraries/Microsoft.PowerFx.Core/Binding/Binder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4221,7 +4221,7 @@ private static void ArityError(int minArity, int maxArity, TexlNode node, int ac
private void UntypedObjectScopeError(CallNode node, TexlFunction maybeFunc, TexlNode firstArg)
{
_txb.ErrorContainer.EnsureError(DocumentErrorSeverity.Severe, firstArg, TexlStrings.ErrUntypedObjectScope);
_txb.ErrorContainer.Error(node, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);
_txb.ErrorContainer.Error(node.Head.Token, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);

_txb.SetInfo(node, new CallInfo(maybeFunc, node, null, default, false, _currentScope.Nest));
_txb.SetType(node, maybeFunc.ReturnType);
Expand Down Expand Up @@ -4485,7 +4485,7 @@ public override bool PreVisit(CallNode node)
// If there is a single function with this name, and the first arg is not
// a good match, then we have an erroneous invocation.
_txb.ErrorContainer.EnsureError(DocumentErrorSeverity.Severe, nodeInput, TexlStrings.ErrBadType);
_txb.ErrorContainer.Error(node, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);
_txb.ErrorContainer.Error(node.Head.Token, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);
_txb.SetInfo(node, new CallInfo(maybeFunc, node, typeScope, scopeIdent, identRequired, _currentScope.Nest));
_txb.SetType(node, maybeFunc.ReturnType);
}
Expand Down Expand Up @@ -4609,7 +4609,7 @@ public override bool PreVisit(CallNode node)
// on their argument types.
if (!fArgsValid)
{
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node.Head.Token, TexlStrings.ErrInvalidArgs_Func, maybeFunc.Name);
}

// Set the inferred return type for the node.
Expand Down Expand Up @@ -4920,7 +4920,7 @@ private void PreVisitMetadataArg(CallNode node, TexlFunction func)

// If PreVisit resulted in errors for the node (and a non-null CallInfo),
// we're done -- we have a match and appropriate errors logged already.
if (_txb.ErrorContainer.HasErrors(node))
if (_txb.ErrorContainer.HasErrors(node) || _txb.ErrorContainer.HasErrors(node.Head.Token))
{
Contracts.Assert(info != null);

Expand Down Expand Up @@ -4951,7 +4951,7 @@ private void PreVisitMetadataArg(CallNode node, TexlFunction func)

if (!fArgsValid)
{
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node, TexlStrings.ErrInvalidArgs_Func, func.Name);
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node.Head.Token, TexlStrings.ErrInvalidArgs_Func, func.Name);
}

_txb.SetType(node, returnType);
Expand All @@ -4969,7 +4969,7 @@ private void PreVisitBottomUp(CallNode node, int argCountVisited, Scope scopeNew

var info = _txb.GetInfo(node);
Contracts.AssertValueOrNull(info);
Contracts.Assert(info == null || _txb.ErrorContainer.HasErrors(node));
Contracts.Assert(info == null || _txb.ErrorContainer.HasErrors(node) || _txb.ErrorContainer.HasErrors(node.Head.Token));

// Attempt to get the overloads, so we can determine the scope to use for datasource name matching
// We're only interested in the overloads without lambdas, since those were
Expand Down Expand Up @@ -5035,7 +5035,7 @@ private void PreVisitBottomUp(CallNode node, int argCountVisited, Scope scopeNew
{
var functionsWithLambdas = LookupFunctions(funcNamespace, node.Head.Name.Value).Where(fnc => fnc.HasLambdas);

if (functionsWithLambdas.Any() && !_txb.ErrorContainer.HasErrors(node))
if (functionsWithLambdas.Any() && !_txb.ErrorContainer.HasErrors(node) && !_txb.ErrorContainer.HasErrors(node.Head.Token))
{
// PreVisitBottomUp is called along the arity error code path. For functions such as Sum,
// there is an overload with a lambda as well as an overload with scalars. Using untyped
Expand Down Expand Up @@ -5065,7 +5065,7 @@ private void PreVisitBottomUp(CallNode node, int argCountVisited, Scope scopeNew

// If PreVisit resulted in errors for the node (and a non-null CallInfo),
// we're done -- we have a match and appropriate errors logged already.
if (_txb.ErrorContainer.HasErrors(node))
if (_txb.ErrorContainer.HasErrors(node) || _txb.ErrorContainer.HasErrors(node.Head.Token))
{
Contracts.Assert(info != null);

Expand Down Expand Up @@ -5144,7 +5144,7 @@ private void PreVisitBottomUp(CallNode node, int argCountVisited, Scope scopeNew

if (!fArgsValid && !func.HasPreciseErrors)
{
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node, TexlStrings.ErrInvalidArgs_Func, func.Name);
_txb.ErrorContainer.Error(DocumentErrorSeverity.Severe, node.Head.Token, TexlStrings.ErrInvalidArgs_Func, func.Name);
}

_txb.SetType(node, returnType);
Expand Down Expand Up @@ -5242,7 +5242,7 @@ private void PreVisitWithOverloadResolution(CallNode node, TexlFunction[] overlo
// We exhausted the overloads without finding an exact match, so post a document error.
if (!someFunc.HasPreciseErrors)
{
_txb.ErrorContainer.Error(node, TexlStrings.ErrInvalidArgs_Func, someFunc.Name);
_txb.ErrorContainer.Error(node.Head.Token, TexlStrings.ErrInvalidArgs_Func, someFunc.Name);
}

// The final CheckInvocation call will post all the necessary document errors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1472,7 +1472,7 @@ protected bool CheckArgsCount(CallNode callNode, TexlBinding binding, DocumentEr
Contracts.AssertValue(callNode);
Contracts.AssertValue(binding);

if (binding.ErrorContainer.HasErrors(callNode, errorSeverity))
if (binding.ErrorContainer.HasErrors(callNode, errorSeverity) || binding.ErrorContainer.HasErrors(callNode.Head.Token, errorSeverity))
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Table({Value:1},{Value:0})
Table({Value:10},{Value:10.123})

>> Abs([])
Errors: Error 0-7: The function 'Abs' has some invalid arguments.|Error 4-6: Invalid schema, expected a one-column table.
Errors: Error 0-3: The function 'Abs' has some invalid arguments.|Error 4-6: Invalid schema, expected a one-column table.

>> Abs(If(1<0,[1]))
Blank()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Table({Double:2,Value:1},{Double:4,Value:2},{Double:6,Value:3},{Double:8,Value:4
{Double:6,Value:3}

>> AddColumns([1,2,3,4,5], "Value", Value * 2)
Errors: Warning 24-31: A column named 'Value' already exists.|Error 0-43: The function 'AddColumns' has some invalid arguments.
Errors: Warning 24-31: A column named 'Value' already exists.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({Value:1}, "Value", Value * 2)
Errors: Warning 22-29: A column named 'Value' already exists.|Error 0-41: The function 'AddColumns' has some invalid arguments.
Errors: Warning 22-29: A column named 'Value' already exists.|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns([1,2,3,4,5], "Blanks", Blank())
Table({Blanks:Blank(),Value:1},{Blanks:Blank(),Value:2},{Blanks:Blank(),Value:3},{Blanks:Blank(),Value:4},{Blanks:Blank(),Value:5})
Expand Down Expand Up @@ -63,7 +63,7 @@ Table({a:1,b:{c:3},'b d':1},{a:2,b:{c:4},'b d':8})
{a:2,b:{c:4},'b d':8}

>> AddColumns(Table({a: 1}, {a: 2}), "b", c)
Errors: Error 39-40: Name isn't valid. 'c' isn't recognized.|Error 0-41: The function 'AddColumns' has some invalid arguments.
Errors: Error 39-40: Name isn't valid. 'c' isn't recognized.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({a: 1}, "b", c)
Expand Down Expand Up @@ -98,14 +98,14 @@ Errors: Error 47-49: Name isn't valid. 'sq' isn't recognized.
Errors: Error 49-51: Name isn't valid. 'sq' isn't recognized.

>> AddColumns([1, 2, 3], 5, Value * Value)
Errors: Error 22-23: Argument '5' is invalid, expected a text literal.|Error 0-39: The function 'AddColumns' has some invalid arguments.
Errors: Error 22-23: Argument '5' is invalid, expected a text literal.|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns([1, 2, 3], "", Value * Value)
Errors: Error 22-24: Argument '' is not a valid identifier.|Error 0-40: The function 'AddColumns' has some invalid arguments.
Errors: Error 22-24: Argument '' is not a valid identifier.|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns([1, 2, 3], "a", Value^2, "a", Value^3)
Errors: Warning 36-39: Column name conflict for 'a'.|Error 0-49: The function 'AddColumns' has some invalid arguments.
Errors: Warning 36-39: Column name conflict for 'a'.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({Value:3}, "a", Value^2, "a", Value^3)
Errors: Warning 36-39: Column name conflict for 'a'.|Error 0-49: The function 'AddColumns' has some invalid arguments.
Errors: Warning 36-39: Column name conflict for 'a'.|Error 0-10: The function 'AddColumns' has some invalid arguments.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Table({Double:2,Value:1},{Double:4,Value:2},{Double:6,Value:3},{Double:8,Value:4
{Double:6,Value:3}

>> AddColumns([1,2,3,4,5], Value, Value * 2)
Errors: Warning 24-29: A column named 'Value' already exists.|Error 0-41: The function 'AddColumns' has some invalid arguments.
Errors: Warning 24-29: A column named 'Value' already exists.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({Value:1}, Value, Value * 2)
Errors: Warning 22-27: A column named 'Value' already exists.|Error 0-39: The function 'AddColumns' has some invalid arguments.
Errors: Warning 22-27: A column named 'Value' already exists.|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns([1,2,3,4,5], Blanks, Blank())
Table({Blanks:Blank(),Value:1},{Blanks:Blank(),Value:2},{Blanks:Blank(),Value:3},{Blanks:Blank(),Value:4},{Blanks:Blank(),Value:5})
Expand Down Expand Up @@ -49,7 +49,7 @@ Table({a:1,b:1},{a:2,b:8})
{a:2,b:8}

>> AddColumns(Table({a: 1, b: {c: 3}}, {a: 2, b: {c: 4}}), b.d, a * a * a)
Errors: Error 56-57: Name isn't valid. 'b' isn't recognized.|Error 57-59: Invalid use of '.'|Error 0-71: The function 'AddColumns' has some invalid arguments.
Errors: Error 56-57: Name isn't valid. 'b' isn't recognized.|Error 57-59: Invalid use of '.'|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns(Table({a: 1, b: {c: 3}}, {a: 2, b: {c: 4}}), 'b.d', a * a * a)
Table({a:1,b:{c:3},'b.d':1},{a:2,b:{c:4},'b.d':8})
Expand All @@ -58,7 +58,7 @@ Table({a:1,b:{c:3},'b.d':1},{a:2,b:{c:4},'b.d':8})
Table({a:1,b:{c:3},'b d':1},{a:2,b:{c:4},'b d':8})

>> AddColumns(Table({a: 1}, {a: 2}), b, c)
Errors: Error 37-38: Name isn't valid. 'c' isn't recognized.|Error 0-39: The function 'AddColumns' has some invalid arguments.
Errors: Error 37-38: Name isn't valid. 'c' isn't recognized.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({a: 1}, b, c)
Expand Down Expand Up @@ -98,11 +98,11 @@ Table({Value:1,_:1},{Value:2,_:4})
Table({Value:1,z:Blank()},{Value:2,z:Blank()})

>> AddColumns([1,2], 3, Value * Value)
Errors: Error 18-19: Expected identifier name|Error 0-35: The function 'AddColumns' has some invalid arguments.
Errors: Error 18-19: Expected identifier name|Error 0-10: The function 'AddColumns' has some invalid arguments.

>> AddColumns([1, 2, 3], a, Value^2, a, Value^3)
Errors: Warning 34-35: Column name conflict for 'a'.|Error 0-45: The function 'AddColumns' has some invalid arguments.
Errors: Warning 34-35: Column name conflict for 'a'.|Error 0-10: The function 'AddColumns' has some invalid arguments.

// Record overload
>> AddColumns({Value:3}, a, Value^2, a, Value^3)
Errors: Warning 34-35: Column name conflict for 'a'.|Error 0-45: The function 'AddColumns' has some invalid arguments.
Errors: Warning 34-35: Column name conflict for 'a'.|Error 0-10: The function 'AddColumns' has some invalid arguments.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Table({Value:false},{Value:Error({Kind:ErrorKind.InvalidArgument})})
Table({Value:false},{Value:true})

>> Boolean([])
Errors: Error 0-11: The function 'Boolean' has some invalid arguments.|Error 8-10: Invalid schema, expected a one-column table.
Errors: Error 0-7: The function 'Boolean' has some invalid arguments.|Error 8-10: Invalid schema, expected a one-column table.

>> Boolean([false])
Table({Value:false})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Errors: Error 0-7: Invalid number of arguments: received 0, expected 1.
Errors: Error 0-13: Invalid number of arguments: received 2, expected 1.

>> Clear(Foo)
Errors: Error 6-9: Name isn't valid. 'Foo' isn't recognized.|Error 0-10: The function 'Clear' has some invalid arguments.
Errors: Error 6-9: Name isn't valid. 'Foo' isn't recognized.|Error 0-5: The function 'Clear' has some invalid arguments.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Errors: Error 6-13: The value passed to the 'Clear' function cannot be changed.
Errors: Error 6-36: The value passed to the 'Clear' function cannot be changed.

>> Clear(1)
Errors: Error 6-7: Invalid argument type (Decimal). Expecting a Table value instead.|Error 6-7: The value passed to the 'Clear' function cannot be changed.|Error 0-8: The function 'Clear' has some invalid arguments.
Errors: Error 6-7: Invalid argument type (Decimal). Expecting a Table value instead.|Error 6-7: The value passed to the 'Clear' function cannot be changed.|Error 0-5: The function 'Clear' has some invalid arguments.

>> Clear(1/0)
Errors: Error 7-8: Invalid argument type (Decimal). Expecting a Table value instead.|Error 7-8: The value passed to the 'Clear' function cannot be changed.|Error 0-10: The function 'Clear' has some invalid arguments.
Errors: Error 7-8: Invalid argument type (Decimal). Expecting a Table value instead.|Error 7-8: The value passed to the 'Clear' function cannot be changed.|Error 0-5: The function 'Clear' has some invalid arguments.

>> IsError(Clear(1))
Errors: Error 14-15: Invalid argument type (Decimal). Expecting a Table value instead.|Error 14-15: The value passed to the 'Clear' function cannot be changed.|Error 8-16: The function 'Clear' has some invalid arguments.
Errors: Error 14-15: Invalid argument type (Decimal). Expecting a Table value instead.|Error 14-15: The value passed to the 'Clear' function cannot be changed.|Error 8-13: The function 'Clear' has some invalid arguments.

>> Clear(t1);Clear(t2)
If(true, {test:1}, "Void value (result of the expression can't be used).")
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ true
Error({Kind:ErrorKind.Custom})

>> Clear(1)
Errors: Error 6-7: Invalid argument type (Decimal). Expecting a Table value instead.|Error 0-8: The function 'Clear' has some invalid arguments.
Errors: Error 6-7: Invalid argument type (Decimal). Expecting a Table value instead.|Error 0-5: The function 'Clear' has some invalid arguments.

>> Clear(1/0)
Errors: Error 7-8: Invalid argument type (Decimal). Expecting a Table value instead.|Error 0-10: The function 'Clear' has some invalid arguments.
Errors: Error 7-8: Invalid argument type (Decimal). Expecting a Table value instead.|Error 0-5: The function 'Clear' has some invalid arguments.

>> IsError(Clear(1))
Errors: Error 14-15: Invalid argument type (Decimal). Expecting a Table value instead.|Error 8-16: The function 'Clear' has some invalid arguments.
Errors: Error 14-15: Invalid argument type (Decimal). Expecting a Table value instead.|Error 8-13: The function 'Clear' has some invalid arguments.

>> Clear(t1);Clear(t2)
true
Loading