From 1ff3fb78b9696e9b46e8d1e5c37c6e57c13cfcd6 Mon Sep 17 00:00:00 2001 From: Allan Guigou <34221163+AllanGuigou@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:32:18 -0800 Subject: [PATCH] Add case function --- src/Sdk/Expressions/ExpressionConstants.cs | 1 + src/Sdk/Expressions/ExpressionParser.cs | 20 +++++++++++++++++--- src/Sdk/Expressions/ParseException.cs | 3 +++ src/Sdk/Expressions/ParseExceptionKind.cs | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Sdk/Expressions/ExpressionConstants.cs b/src/Sdk/Expressions/ExpressionConstants.cs index df98e3869..ef544395f 100644 --- a/src/Sdk/Expressions/ExpressionConstants.cs +++ b/src/Sdk/Expressions/ExpressionConstants.cs @@ -10,6 +10,7 @@ namespace GitHub.Actions.Expressions { static ExpressionConstants() { + AddFunction("case", 3, Byte.MaxValue); AddFunction("contains", 2, 2); AddFunction("endsWith", 2, 2); AddFunction("format", 1, Byte.MaxValue); diff --git a/src/Sdk/Expressions/ExpressionParser.cs b/src/Sdk/Expressions/ExpressionParser.cs index 32b1fd740..9d0501476 100644 --- a/src/Sdk/Expressions/ExpressionParser.cs +++ b/src/Sdk/Expressions/ExpressionParser.cs @@ -17,9 +17,10 @@ namespace GitHub.Actions.Expressions String expression, ITraceWriter trace, IEnumerable namedValues, - IEnumerable functions) + IEnumerable 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); + } } /// @@ -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 ExtensionFunctions = new Dictionary(StringComparer.OrdinalIgnoreCase); public readonly Dictionary ExtensionNamedValues = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -433,7 +445,8 @@ namespace GitHub.Actions.Expressions ITraceWriter trace, IEnumerable namedValues, IEnumerable 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 diff --git a/src/Sdk/Expressions/ParseException.cs b/src/Sdk/Expressions/ParseException.cs index e5f7f3fa1..9f661012a 100644 --- a/src/Sdk/Expressions/ParseException.cs +++ b/src/Sdk/Expressions/ParseException.cs @@ -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; diff --git a/src/Sdk/Expressions/ParseExceptionKind.cs b/src/Sdk/Expressions/ParseExceptionKind.cs index 297fe0e02..db6294b50 100644 --- a/src/Sdk/Expressions/ParseExceptionKind.cs +++ b/src/Sdk/Expressions/ParseExceptionKind.cs @@ -6,6 +6,7 @@ namespace GitHub.Actions.Expressions ExceededMaxLength, TooFewParameters, TooManyParameters, + EvenParameters, UnexpectedEndOfExpression, UnexpectedSymbol, UnrecognizedFunction,