Add case function

This commit is contained in:
Allan Guigou
2025-12-09 12:32:18 -08:00
parent f99c3e6ee8
commit 1ff3fb78b9
4 changed files with 22 additions and 3 deletions

View File

@@ -10,6 +10,7 @@ namespace GitHub.Actions.Expressions
{
static ExpressionConstants()
{
AddFunction<Case>("case", 3, Byte.MaxValue);
AddFunction<Contains>("contains", 2, 2);
AddFunction<EndsWith>("endsWith", 2, 2);
AddFunction<Format>("format", 1, Byte.MaxValue);

View File

@@ -17,9 +17,10 @@ namespace GitHub.Actions.Expressions
String expression,
ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions)
IEnumerable<IFunctionInfo> functions,
Boolean allowCaseFunction = false)
{
var context = new ParseContext(expression, trace, namedValues, functions);
var context = new ParseContext(expression, trace, namedValues, functions, allowCaseFunction: allowCaseFunction);
context.Trace.Info($"Parsing expression: <{expression}>");
return CreateTree(context);
}
@@ -349,6 +350,10 @@ namespace GitHub.Actions.Expressions
{
throw new ParseException(ParseExceptionKind.TooManyParameters, token: @operator, expression: context.Expression);
}
else if (functionInfo.Name.Equals("case", StringComparison.OrdinalIgnoreCase) && function.Parameters.Count % 2 == 0)
{
throw new ParseException(ParseExceptionKind.EvenParameters, token: @operator, expression: context.Expression);
}
}
/// <summary>
@@ -411,6 +416,12 @@ namespace GitHub.Actions.Expressions
String name,
out IFunctionInfo functionInfo)
{
if (String.Equals(name, "case", StringComparison.OrdinalIgnoreCase) && !context.AllowCaseFunction)
{
functionInfo = null;
return false;
}
return ExpressionConstants.WellKnownFunctions.TryGetValue(name, out functionInfo) ||
context.ExtensionFunctions.TryGetValue(name, out functionInfo);
}
@@ -418,6 +429,7 @@ namespace GitHub.Actions.Expressions
private sealed class ParseContext
{
public Boolean AllowUnknownKeywords;
public Boolean AllowCaseFunction;
public readonly String Expression;
public readonly Dictionary<String, IFunctionInfo> ExtensionFunctions = new Dictionary<String, IFunctionInfo>(StringComparer.OrdinalIgnoreCase);
public readonly Dictionary<String, INamedValueInfo> ExtensionNamedValues = new Dictionary<String, INamedValueInfo>(StringComparer.OrdinalIgnoreCase);
@@ -433,7 +445,8 @@ namespace GitHub.Actions.Expressions
ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions,
Boolean allowUnknownKeywords = false)
Boolean allowUnknownKeywords = false,
Boolean allowCaseFunction = false)
{
Expression = expression ?? String.Empty;
if (Expression.Length > ExpressionConstants.MaxLength)
@@ -454,6 +467,7 @@ namespace GitHub.Actions.Expressions
LexicalAnalyzer = new LexicalAnalyzer(Expression);
AllowUnknownKeywords = allowUnknownKeywords;
AllowCaseFunction = allowCaseFunction;
}
private class NoOperationTraceWriter : ITraceWriter

View File

@@ -29,6 +29,9 @@ namespace GitHub.Actions.Expressions
case ParseExceptionKind.TooManyParameters:
description = "Too many parameters supplied";
break;
case ParseExceptionKind.EvenParameters:
description = "Even number of parameters supplied, requires an odd number of parameters";
break;
case ParseExceptionKind.UnexpectedEndOfExpression:
description = "Unexpected end of expression";
break;

View File

@@ -6,6 +6,7 @@ namespace GitHub.Actions.Expressions
ExceededMaxLength,
TooFewParameters,
TooManyParameters,
EvenParameters,
UnexpectedEndOfExpression,
UnexpectedSymbol,
UnrecognizedFunction,