using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using GitHub.DistributedTask.Expressions2;
using GitHub.DistributedTask.Expressions2.Sdk;
using GitHub.Services.WebApi.Internal;
namespace GitHub.DistributedTask.ObjectTemplating.Tokens
{
///
/// Base class for all template expression tokens
///
[DataContract]
[ClientIgnore]
[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class ExpressionToken : ScalarToken
{
internal ExpressionToken(
Int32 templateType,
Int32? fileId,
Int32? line,
Int32? column,
String directive)
: base(templateType, fileId, line, column)
{
Directive = directive;
}
[DataMember(Name = "directive", EmitDefaultValue = false)]
internal String Directive { get; }
internal static Boolean IsValidExpression(
String expression,
String[] allowedContext,
out Exception ex)
{
// Create dummy named values and functions
var namedValues = new List();
var functions = new List();
if (allowedContext?.Length > 0)
{
foreach (var contextItem in allowedContext)
{
var match = s_function.Match(contextItem);
if (match.Success)
{
var functionName = match.Groups[1].Value;
var minParameters = Int32.Parse(match.Groups[2].Value, NumberStyles.None, CultureInfo.InvariantCulture);
var maxParametersRaw = match.Groups[3].Value;
var maxParameters = String.Equals(maxParametersRaw, TemplateConstants.MaxConstant, StringComparison.Ordinal)
? Int32.MaxValue
: Int32.Parse(maxParametersRaw, NumberStyles.None, CultureInfo.InvariantCulture);
functions.Add(new FunctionInfo(functionName, minParameters, maxParameters));
}
else
{
namedValues.Add(new NamedValueInfo(contextItem));
}
}
}
// Parse
Boolean result;
ExpressionNode root = null;
try
{
root = new ExpressionParser().CreateTree(expression, null, namedValues, functions) as ExpressionNode;
result = true;
ex = null;
}
catch (Exception exception)
{
result = false;
ex = exception;
}
return result;
}
private sealed class DummyFunction : Function
{
protected override Object EvaluateCore(
EvaluationContext context,
out ResultMemory resultMemory)
{
resultMemory = null;
return null;
}
}
private static readonly Regex s_function = new Regex(@"^([a-zA-Z0-9_]+)\(([0-9]+),([0-9]+|MAX)\)$", RegexOptions.Compiled);
}
}