in src/Kusto.Language/Binder/Binder.cs [6261:6470]
private void CheckArgument(Signature signature, IReadOnlyList<Parameter> argumentParameters, IReadOnlyList<Expression> arguments, IReadOnlyList<TypeSymbol> argumentTypes, int argumentIndex, List<Diagnostic> diagnostics)
{
var argument = arguments[argumentIndex];
var argumentType = argumentTypes[argumentIndex];
var parameter = argumentParameters[argumentIndex];
if (parameter != null)
{
if (argument is StarExpression && signature.Symbol.Kind != SymbolKind.Operator)
{
if (parameter.ArgumentKind != ArgumentKind.StarOnly
&& parameter.ArgumentKind != ArgumentKind.StarAllowed)
{
diagnostics.Add(DiagnosticFacts.GetStarExpressionNotAllowed().WithLocation(argument));
}
}
else if (IsDefaultValueIndicator(parameter, argument))
{
// do nothing, this is a legal value for this parameter
}
else
{
if (argument is CompoundNamedExpression cn)
{
diagnostics.Add(DiagnosticFacts.GetCompoundNamedArgumentsNotSupported().WithLocation(cn.Names));
}
// see through any named argument
argument = GetUnderlyingExpression(argument);
switch (parameter.TypeKind)
{
case ParameterTypeKind.Declared:
switch (GetParameterMatchKind(signature, argumentParameters, argumentTypes, parameter, argument, argumentType))
{
case ParameterMatchKind.Compatible:
case ParameterMatchKind.None:
if (!AllowLooseParameterMatching(signature))
{
diagnostics.Add(DiagnosticFacts.GetTypeExpected(parameter.DeclaredTypes).WithLocation(argument));
}
break;
}
break;
case ParameterTypeKind.Scalar:
CheckIsScalar(argument, diagnostics, argumentType);
break;
case ParameterTypeKind.Integer:
CheckIsInteger(argument, diagnostics);
break;
case ParameterTypeKind.RealOrDecimal:
CheckIsRealOrDecimal(argument, diagnostics);
break;
case ParameterTypeKind.IntegerOrDynamic:
CheckIsIntegerOrDynamic(argument, diagnostics);
break;
case ParameterTypeKind.StringOrDynamic:
CheckIsStringOrDynamic(argument, diagnostics);
break;
case ParameterTypeKind.Number:
CheckIsNumber(argument, diagnostics);
break;
case ParameterTypeKind.NumberOrBool:
CheckIsNumberOrBool(argument, diagnostics);
break;
case ParameterTypeKind.Summable:
CheckIsSummable(argument, diagnostics);
break;
case ParameterTypeKind.Orderable:
CheckIsOrderable(argument, diagnostics);
break;
case ParameterTypeKind.NotBool:
if (CheckIsScalar(argument, diagnostics))
{
CheckIsNotType(argument, ScalarTypes.Bool, diagnostics);
}
break;
case ParameterTypeKind.NotRealOrBool:
if (CheckIsScalar(argument, diagnostics))
{
CheckIsNotType(argument, ScalarTypes.Real, diagnostics);
CheckIsNotType(argument, ScalarTypes.Bool, diagnostics);
}
break;
case ParameterTypeKind.NotDynamic:
if (CheckIsScalar(argument, diagnostics))
{
CheckIsNotType(argument, ScalarTypes.Dynamic, diagnostics);
}
break;
case ParameterTypeKind.Tabular:
CheckIsTabular(argument, diagnostics, argumentType);
break;
case ParameterTypeKind.Database:
CheckIsDatabase(argument, diagnostics);
break;
case ParameterTypeKind.Cluster:
CheckIsCluster(argument, diagnostics);
break;
case ParameterTypeKind.Parameter0:
CheckIsExactType(argument, argumentTypes[0], diagnostics);
break;
case ParameterTypeKind.Parameter1:
CheckIsExactType(argument, argumentTypes[1], diagnostics);
break;
case ParameterTypeKind.Parameter2:
CheckIsExactType(argument, argumentTypes[2], diagnostics);
break;
case ParameterTypeKind.CommonScalar:
if (CheckIsScalar(argument, diagnostics))
{
var commonType = GetCommonArgumentType(argumentParameters, argumentTypes);
if (commonType != null)
{
CheckIsType(argument, commonType, Conversion.Promotable, diagnostics);
}
}
break;
case ParameterTypeKind.CommonScalarOrDynamic:
if (CheckIsScalar(argument, diagnostics))
{
var commonType = GetCommonArgumentType(argumentParameters, argumentTypes);
if (commonType != null)
{
CheckIsTypeOrDynamic(argument, commonType, true, diagnostics);
}
}
break;
case ParameterTypeKind.CommonNumber:
if (CheckIsNumber(argument, diagnostics))
{
var commonType = GetCommonArgumentType(argumentParameters, argumentTypes);
if (commonType != null)
{
CheckIsType(argument, commonType, Conversion.Promotable, diagnostics);
}
}
break;
case ParameterTypeKind.CommonSummable:
if (CheckIsSummable(argument, diagnostics))
{
var commonType = GetCommonArgumentType(argumentParameters, argumentTypes);
if (commonType != null)
{
CheckIsType(argument, commonType, Conversion.Promotable, diagnostics);
}
}
break;
case ParameterTypeKind.CommonOrderable:
if (CheckIsOrderable(argument, diagnostics))
{
var commonType = GetCommonArgumentType(argumentParameters, argumentTypes);
if (commonType != null)
{
CheckIsType(argument, commonType, Conversion.Promotable, diagnostics);
}
}
break;
}
switch (parameter.ArgumentKind)
{
case ArgumentKind.Column:
CheckIsColumn(argument, diagnostics);
break;
case ArgumentKind.Constant:
CheckIsConstant(argument, diagnostics);
break;
case ArgumentKind.Literal:
if (CheckIsLiteral(argument, diagnostics) && parameter.Values.Count > 0)
{
CheckLiteralValue(argument, parameter.Values, parameter.IsCaseSensitive, diagnostics);
}
break;
case ArgumentKind.LiteralNotEmpty:
if (CheckIsLiteral(argument, diagnostics))
{
CheckLiteralStringNotEmpty(argument, diagnostics);
}
break;
}
}
}
}