Got at least one data fetching method working; turns out, we can't use a patched LogicStack to get the data
This commit is contained in:
101
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentOptionAttribute.cs
vendored
Normal file
101
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentOptionAttribute.cs
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Models an option specification.
|
||||
/// Based on CommandLine (Copyright 2005-2015 Giacomo Stelluti Scala and Contributors.).
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class ArgumentOptionAttribute
|
||||
: Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArgumentOptionAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="longName">The long name of the option.</param>
|
||||
public ArgumentOptionAttribute(string longName)
|
||||
: this(string.Empty, longName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArgumentOptionAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="shortName">The short name of the option.</param>
|
||||
/// <param name="longName">The long name of the option or null if not used.</param>
|
||||
public ArgumentOptionAttribute(char shortName, string longName)
|
||||
: this(new string(shortName, 1), longName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArgumentOptionAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="shortName">The short name of the option..</param>
|
||||
public ArgumentOptionAttribute(char shortName)
|
||||
: this(new string(shortName, 1), string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
private ArgumentOptionAttribute(string shortName, string longName)
|
||||
{
|
||||
ShortName = shortName ?? throw new ArgumentNullException(nameof(shortName));
|
||||
LongName = longName ?? throw new ArgumentNullException(nameof(longName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets long name of this command line option. This name is usually a single English word.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The long name.
|
||||
/// </value>
|
||||
public string LongName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a short name of this command line option, made of one character.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The short name.
|
||||
/// </value>
|
||||
public string ShortName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// When applying attribute to <see cref="System.Collections.Generic.IEnumerable{T}"/> target properties,
|
||||
/// it allows you to split an argument and consume its content as a sequence.
|
||||
/// </summary>
|
||||
public char Separator { get; set; } = '\0';
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets mapped property default value.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The default value.
|
||||
/// </value>
|
||||
public object? DefaultValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether a command line option is required.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if required; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Required { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a short description of this command line option. Usually a sentence summary.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The help text.
|
||||
/// </value>
|
||||
public string? HelpText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default argument.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The default argument.
|
||||
/// </value>
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
}
|
||||
180
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParse.Validator.cs
vendored
Normal file
180
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParse.Validator.cs
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Swan.Reflection;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to parse command line arguments.
|
||||
///
|
||||
/// Based on CommandLine (Copyright 2005-2015 Giacomo Stelluti Scala and Contributors).
|
||||
/// </summary>
|
||||
public partial class ArgumentParser
|
||||
{
|
||||
private sealed class Validator
|
||||
{
|
||||
private const char OptionSwitchChar = '-';
|
||||
private readonly object _instance;
|
||||
private readonly IEnumerable<string> _args;
|
||||
private readonly List<PropertyInfo> _updatedList = new List<PropertyInfo>();
|
||||
private readonly ArgumentParserSettings _settings;
|
||||
|
||||
private readonly PropertyInfo[] _properties;
|
||||
|
||||
public Validator(
|
||||
PropertyInfo[] properties,
|
||||
IEnumerable<string> args,
|
||||
object instance,
|
||||
ArgumentParserSettings settings,
|
||||
bool hasVerb = false)
|
||||
{
|
||||
_args = args;
|
||||
_instance = instance;
|
||||
_settings = settings;
|
||||
_properties = properties;
|
||||
|
||||
PopulateInstance();
|
||||
if (!hasVerb) SetDefaultArgument();
|
||||
SetDefaultValues();
|
||||
GetRequiredList();
|
||||
}
|
||||
|
||||
public List<string> UnknownList { get; } = new List<string>();
|
||||
public List<string> RequiredList { get; } = new List<string>();
|
||||
|
||||
public bool IsValid() => (_settings.IgnoreUnknownArguments || !UnknownList.Any()) && !RequiredList.Any();
|
||||
|
||||
public IEnumerable<ArgumentOptionAttribute> GetPropertiesOptions()
|
||||
=> _properties.Select(p => AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(p))
|
||||
.Where(x => x != null);
|
||||
|
||||
private void GetRequiredList()
|
||||
{
|
||||
foreach (var targetProperty in _properties)
|
||||
{
|
||||
var optionAttr = AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(targetProperty);
|
||||
|
||||
if (optionAttr == null || optionAttr.Required == false)
|
||||
continue;
|
||||
|
||||
if (targetProperty.GetValue(_instance) == null)
|
||||
{
|
||||
RequiredList.Add(optionAttr.LongName ?? optionAttr.ShortName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDefaultValues()
|
||||
{
|
||||
foreach (var targetProperty in _properties.Except(_updatedList))
|
||||
{
|
||||
var optionAttr = AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(targetProperty);
|
||||
|
||||
var defaultValue = optionAttr?.DefaultValue;
|
||||
|
||||
if (defaultValue == null)
|
||||
continue;
|
||||
|
||||
if (SetPropertyValue(targetProperty, defaultValue.ToString(), _instance, optionAttr))
|
||||
_updatedList.Add(targetProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDefaultArgument()
|
||||
{
|
||||
foreach (var targetProperty in _properties.Except(_updatedList))
|
||||
{
|
||||
var optionAttr = AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(targetProperty);
|
||||
|
||||
if (!optionAttr.IsDefault)
|
||||
continue;
|
||||
|
||||
var defaultArgValue = _args.FirstOrDefault();
|
||||
if (string.IsNullOrWhiteSpace(defaultArgValue) || defaultArgValue[0] == OptionSwitchChar)
|
||||
continue;
|
||||
|
||||
if (SetPropertyValue(targetProperty, defaultArgValue, _instance, optionAttr))
|
||||
_updatedList.Add(targetProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateInstance()
|
||||
{
|
||||
var propertyName = string.Empty;
|
||||
|
||||
foreach (var arg in _args)
|
||||
{
|
||||
var ignoreSetValue = string.IsNullOrWhiteSpace(propertyName);
|
||||
|
||||
if (ignoreSetValue)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(arg) || arg[0] != OptionSwitchChar) continue;
|
||||
|
||||
propertyName = arg.Substring(1);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(propertyName) && propertyName[0] == OptionSwitchChar)
|
||||
propertyName = propertyName.Substring(1);
|
||||
}
|
||||
|
||||
var targetProperty = TryGetProperty(propertyName);
|
||||
|
||||
if (targetProperty == null)
|
||||
{
|
||||
// Skip if the property is not found
|
||||
UnknownList.Add(propertyName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ignoreSetValue && SetPropertyValue(targetProperty, arg, _instance))
|
||||
{
|
||||
_updatedList.Add(targetProperty);
|
||||
propertyName = string.Empty;
|
||||
}
|
||||
else if (targetProperty.PropertyType == typeof(bool))
|
||||
{
|
||||
// If the arg is a boolean property set it to true.
|
||||
targetProperty.SetValue(_instance, true);
|
||||
|
||||
_updatedList.Add(targetProperty);
|
||||
propertyName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
UnknownList.Add(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetPropertyValue(
|
||||
PropertyInfo targetProperty,
|
||||
string propertyValueString,
|
||||
object result,
|
||||
ArgumentOptionAttribute? optionAttr = null)
|
||||
{
|
||||
if (!targetProperty.PropertyType.IsEnum)
|
||||
{
|
||||
return targetProperty.PropertyType.IsArray
|
||||
? targetProperty.TrySetArray(propertyValueString.Split(optionAttr?.Separator ?? ','), result)
|
||||
: targetProperty.TrySetBasicType(propertyValueString, result);
|
||||
}
|
||||
|
||||
var parsedValue = Enum.Parse(
|
||||
targetProperty.PropertyType,
|
||||
propertyValueString,
|
||||
_settings.CaseInsensitiveEnumValues);
|
||||
|
||||
targetProperty.SetValue(result, Enum.ToObject(targetProperty.PropertyType, parsedValue));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private PropertyInfo TryGetProperty(string propertyName)
|
||||
=> _properties.FirstOrDefault(p =>
|
||||
string.Equals(AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(p)?.LongName, propertyName, _settings.NameComparer) ||
|
||||
string.Equals(AttributeCache.DefaultCache.Value.RetrieveOne<ArgumentOptionAttribute>(p)?.ShortName, propertyName, _settings.NameComparer));
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParser.TypeResolver.cs
vendored
Normal file
63
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParser.TypeResolver.cs
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Swan.Reflection;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to parse command line arguments.
|
||||
/// </summary>
|
||||
public partial class ArgumentParser
|
||||
{
|
||||
private sealed class TypeResolver<T>
|
||||
{
|
||||
public bool HasVerb { get; }
|
||||
|
||||
private bool _hasVerb = false;
|
||||
|
||||
private readonly string _selectedVerb;
|
||||
|
||||
private PropertyInfo[]? _properties;
|
||||
|
||||
public TypeResolver(string selectedVerb)
|
||||
{
|
||||
_selectedVerb = selectedVerb;
|
||||
}
|
||||
|
||||
public PropertyInfo[]? Properties => _properties?.Any() == true ? _properties : null;
|
||||
|
||||
public object? GetOptionsObject(T instance)
|
||||
{
|
||||
_properties = PropertyTypeCache.DefaultCache.Value.RetrieveAllProperties<T>(true).ToArray();
|
||||
|
||||
if (!_properties.Any(x => x.GetCustomAttributes(typeof(VerbOptionAttribute), false).Any()))
|
||||
return instance;
|
||||
|
||||
_hasVerb = true;
|
||||
|
||||
var selectedVerb = string.IsNullOrWhiteSpace(_selectedVerb)
|
||||
? null
|
||||
: _properties.FirstOrDefault(x =>
|
||||
AttributeCache.DefaultCache.Value.RetrieveOne<VerbOptionAttribute>(x).Name == _selectedVerb);
|
||||
|
||||
if (selectedVerb == null) return null;
|
||||
|
||||
var type = instance.GetType();
|
||||
|
||||
var verbProperty = type.GetProperty(selectedVerb.Name);
|
||||
|
||||
if (verbProperty?.GetValue(instance) == null)
|
||||
{
|
||||
var propertyInstance = Activator.CreateInstance(selectedVerb.PropertyType);
|
||||
verbProperty?.SetValue(instance, propertyInstance);
|
||||
}
|
||||
|
||||
_properties = PropertyTypeCache.DefaultCache.Value.RetrieveAllProperties(selectedVerb.PropertyType, true)
|
||||
.ToArray();
|
||||
|
||||
return verbProperty?.GetValue(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
253
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParser.cs
vendored
Normal file
253
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParser.cs
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
using Swan.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to parse command line arguments.
|
||||
/// Based on CommandLine (Copyright 2005-2015 Giacomo Stelluti Scala and Contributors.).
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// The following example shows how to parse CLI arguments into objects.
|
||||
/// <code>
|
||||
/// class Example
|
||||
/// {
|
||||
/// using System;
|
||||
/// using Swan.Parsers;
|
||||
///
|
||||
/// static void Main(string[] args)
|
||||
/// {
|
||||
/// // parse the supplied command-line arguments into the options object
|
||||
/// var res = Runtime.ArgumentParser.ParseArguments(args, out var options);
|
||||
/// }
|
||||
///
|
||||
/// class Options
|
||||
/// {
|
||||
/// [ArgumentOption('v', "verbose", HelpText = "Set verbose mode.")]
|
||||
/// public bool Verbose { get; set; }
|
||||
///
|
||||
/// [ArgumentOption('u', Required = true, HelpText = "Set user name.")]
|
||||
/// public string Username { get; set; }
|
||||
///
|
||||
/// [ArgumentOption('n', "names", Separator = ',',
|
||||
/// Required = true, HelpText = "A list of files separated by a comma")]
|
||||
/// public string[] Files { get; set; }
|
||||
///
|
||||
/// [ArgumentOption('p', "port", DefaultValue = 22, HelpText = "Set port.")]
|
||||
/// public int Port { get; set; }
|
||||
///
|
||||
/// [ArgumentOption("color", DefaultValue = ConsoleColor.Red,
|
||||
/// HelpText = "Set a color.")]
|
||||
/// public ConsoleColor Color { get; set; }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// The following code describes how to parse CLI verbs.
|
||||
/// <code>
|
||||
/// class Example2
|
||||
/// {
|
||||
/// using Swan;
|
||||
/// using Swan.Parsers;
|
||||
///
|
||||
/// static void Main(string[] args)
|
||||
/// {
|
||||
/// // create an instance of the VerbOptions class
|
||||
/// var options = new VerbOptions();
|
||||
///
|
||||
/// // parse the supplied command-line arguments into the options object
|
||||
/// var res = Runtime.ArgumentParser.ParseArguments(args, options);
|
||||
///
|
||||
/// // if there were no errors parsing
|
||||
/// if (res)
|
||||
/// {
|
||||
/// if(options.Run != null)
|
||||
/// {
|
||||
/// // run verb was selected
|
||||
/// }
|
||||
///
|
||||
/// if(options.Print != null)
|
||||
/// {
|
||||
/// // print verb was selected
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // flush all error messages
|
||||
/// Terminal.Flush();
|
||||
/// }
|
||||
///
|
||||
/// class VerbOptions
|
||||
/// {
|
||||
/// [VerbOption("run", HelpText = "Run verb.")]
|
||||
/// public RunVerbOption Run { get; set; }
|
||||
///
|
||||
/// [VerbOption("print", HelpText = "Print verb.")]
|
||||
/// public PrintVerbOption Print { get; set; }
|
||||
/// }
|
||||
///
|
||||
/// class RunVerbOption
|
||||
/// {
|
||||
/// [ArgumentOption('o', "outdir", HelpText = "Output directory",
|
||||
/// DefaultValue = "", Required = false)]
|
||||
/// public string OutDir { get; set; }
|
||||
/// }
|
||||
///
|
||||
/// class PrintVerbOption
|
||||
/// {
|
||||
/// [ArgumentOption('t', "text", HelpText = "Text to print",
|
||||
/// DefaultValue = "", Required = false)]
|
||||
/// public string Text { get; set; }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public partial class ArgumentParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArgumentParser"/> class.
|
||||
/// </summary>
|
||||
public ArgumentParser()
|
||||
: this(new ArgumentParserSettings())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArgumentParser" /> class,
|
||||
/// configurable with <see cref="ArgumentParserSettings" /> using a delegate.
|
||||
/// </summary>
|
||||
/// <param name="parseSettings">The parse settings.</param>
|
||||
public ArgumentParser(ArgumentParserSettings parseSettings)
|
||||
{
|
||||
Settings = parseSettings ?? throw new ArgumentNullException(nameof(parseSettings));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current.
|
||||
/// </value>
|
||||
public static ArgumentParser Current { get; } = new ArgumentParser();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance that implements <see cref="ArgumentParserSettings" /> in use.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The settings.
|
||||
/// </value>
|
||||
public ArgumentParserSettings Settings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string array of command line arguments constructing values in an instance of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the options.</typeparam>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <param name="instance">The instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if was converted successfully; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// The exception that is thrown when a null reference (Nothing in Visual Basic)
|
||||
/// is passed to a method that does not accept it as a valid argument.
|
||||
/// </exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// The exception that is thrown when a method call is invalid for the object's current state.
|
||||
/// </exception>
|
||||
public bool ParseArguments<T>(IEnumerable<string> args, out T instance)
|
||||
{
|
||||
instance = Activator.CreateInstance<T>();
|
||||
return ParseArguments(args, instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string array of command line arguments constructing values in an instance of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the options.</typeparam>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <param name="instance">The instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if was converted successfully; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// The exception that is thrown when a null reference (Nothing in Visual Basic)
|
||||
/// is passed to a method that does not accept it as a valid argument.
|
||||
/// </exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// The exception that is thrown when a method call is invalid for the object's current state.
|
||||
/// </exception>
|
||||
public bool ParseArguments<T>(IEnumerable<string> args, T instance)
|
||||
{
|
||||
if (args == null)
|
||||
throw new ArgumentNullException(nameof(args));
|
||||
|
||||
if (Equals(instance, default(T)))
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
|
||||
var typeResolver = new TypeResolver<T>(args.FirstOrDefault());
|
||||
var options = typeResolver.GetOptionsObject(instance);
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
ReportUnknownVerb<T>();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeResolver.Properties == null)
|
||||
throw new InvalidOperationException($"Type {typeof(T).Name} is not valid");
|
||||
|
||||
var validator = new Validator(typeResolver.Properties, args, options, Settings, typeResolver.HasVerb);
|
||||
|
||||
if (validator.IsValid())
|
||||
return true;
|
||||
|
||||
ReportIssues(validator);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void ReportUnknownVerb<T>()
|
||||
{
|
||||
Terminal.WriteLine("No verb was specified", ConsoleColor.Red);
|
||||
Terminal.WriteLine("Valid verbs:", ConsoleColor.Cyan);
|
||||
|
||||
PropertyTypeCache.DefaultCache.Value
|
||||
.RetrieveAllProperties<T>(true)
|
||||
.Select(x => AttributeCache.DefaultCache.Value.RetrieveOne<VerbOptionAttribute>(x))
|
||||
.Where(x => x != null)
|
||||
.ToList()
|
||||
.ForEach(x => Terminal.WriteLine(x.ToString(), ConsoleColor.Cyan));
|
||||
}
|
||||
|
||||
private void ReportIssues(Validator validator)
|
||||
{
|
||||
if (Settings.WriteBanner)
|
||||
Terminal.WriteWelcomeBanner();
|
||||
|
||||
var options = validator.GetPropertiesOptions();
|
||||
|
||||
foreach (var option in options)
|
||||
{
|
||||
Terminal.WriteLine(string.Empty);
|
||||
|
||||
// TODO: If Enum list values
|
||||
var shortName = string.IsNullOrWhiteSpace(option.ShortName) ? string.Empty : $"-{option.ShortName}";
|
||||
var longName = string.IsNullOrWhiteSpace(option.LongName) ? string.Empty : $"--{option.LongName}";
|
||||
var comma = string.IsNullOrWhiteSpace(shortName) || string.IsNullOrWhiteSpace(longName)
|
||||
? string.Empty
|
||||
: ", ";
|
||||
var defaultValue = option.DefaultValue == null ? string.Empty : $"(Default: {option.DefaultValue}) ";
|
||||
|
||||
Terminal.WriteLine($" {shortName}{comma}{longName}\t\t{defaultValue}{option.HelpText}", ConsoleColor.Cyan);
|
||||
}
|
||||
|
||||
Terminal.WriteLine(string.Empty);
|
||||
Terminal.WriteLine(" --help\t\tDisplay this help screen.", ConsoleColor.Cyan);
|
||||
|
||||
if (validator.UnknownList.Any())
|
||||
Terminal.WriteLine($"Unknown arguments: {string.Join(", ", validator.UnknownList)}", ConsoleColor.Red);
|
||||
|
||||
if (validator.RequiredList.Any())
|
||||
Terminal.WriteLine($"Required arguments: {string.Join(", ", validator.RequiredList)}", ConsoleColor.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParserSettings.cs
vendored
Normal file
53
Vendor/Swan.Lite-3.1.0/Parsers/ArgumentParserSettings.cs
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides settings for <see cref="ArgumentParser"/>.
|
||||
/// Based on CommandLine (Copyright 2005-2015 Giacomo Stelluti Scala and Contributors.).
|
||||
/// </summary>
|
||||
public class ArgumentParserSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [write banner].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [write banner]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool WriteBanner { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether perform case sensitive comparisons.
|
||||
/// Note that case insensitivity only applies to <i>parameters</i>, not the values
|
||||
/// assigned to them (for example, enum parsing).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [case sensitive]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool CaseSensitive { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether perform case sensitive comparisons of <i>values</i>.
|
||||
/// Note that case insensitivity only applies to <i>values</i>, not the parameters.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [case insensitive enum values]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool CaseInsensitiveEnumValues { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the parser shall move on to the next argument and ignore the given argument if it
|
||||
/// encounter an unknown arguments.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> to allow parsing the arguments with different class options that do not have all the arguments.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This allows fragmented version class parsing, useful for project with add-on where add-ons also requires command line arguments but
|
||||
/// when these are unknown by the main program at build time.
|
||||
/// </remarks>
|
||||
public bool IgnoreUnknownArguments { get; set; } = true;
|
||||
|
||||
internal StringComparison NameComparer => CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||
}
|
||||
}
|
||||
117
Vendor/Swan.Lite-3.1.0/Parsers/ExpressionParser.cs
vendored
Normal file
117
Vendor/Swan.Lite-3.1.0/Parsers/ExpressionParser.cs
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic expression parser.
|
||||
/// </summary>
|
||||
public abstract class ExpressionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves the expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of expression result.</typeparam>
|
||||
/// <param name="tokens">The tokens.</param>
|
||||
/// <returns>The representation of the expression parsed.</returns>
|
||||
public virtual T ResolveExpression<T>(IEnumerable<Token> tokens) =>
|
||||
ResolveExpression<T>(tokens, System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of expression result.</typeparam>
|
||||
/// <param name="tokens">The tokens.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>The representation of the expression parsed.</returns>
|
||||
public virtual T ResolveExpression<T>(IEnumerable<Token> tokens, IFormatProvider formatProvider)
|
||||
{
|
||||
var conversion = Expression.Convert(Parse(tokens,formatProvider), typeof(T));
|
||||
return Expression.Lambda<Func<T>>(conversion).Compile()();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the specified tokens.
|
||||
/// </summary>
|
||||
/// <param name="tokens">The tokens.</param>
|
||||
/// <returns>
|
||||
/// The final expression.
|
||||
/// </returns>
|
||||
public virtual Expression Parse(IEnumerable<Token> tokens) =>
|
||||
Parse(tokens, System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the specified tokens.
|
||||
/// </summary>
|
||||
/// <param name="tokens">The tokens.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// The final expression.
|
||||
/// </returns>
|
||||
public virtual Expression Parse(IEnumerable<Token> tokens, IFormatProvider formatProvider)
|
||||
{
|
||||
var expressionStack = new List<Stack<Expression>>();
|
||||
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (expressionStack.Any() == false)
|
||||
expressionStack.Add(new Stack<Expression>());
|
||||
|
||||
switch (token.Type)
|
||||
{
|
||||
case TokenType.Wall:
|
||||
expressionStack.Add(new Stack<Expression>());
|
||||
break;
|
||||
case TokenType.Number:
|
||||
expressionStack.Last().Push(Expression.Constant(Convert.ToDecimal(token.Value, formatProvider)));
|
||||
break;
|
||||
case TokenType.Variable:
|
||||
ResolveVariable(token.Value, expressionStack.Last());
|
||||
break;
|
||||
case TokenType.String:
|
||||
expressionStack.Last().Push(Expression.Constant(token.Value));
|
||||
break;
|
||||
case TokenType.Operator:
|
||||
ResolveOperator(token.Value, expressionStack.Last());
|
||||
break;
|
||||
case TokenType.Function:
|
||||
ResolveFunction(token.Value, expressionStack.Last());
|
||||
|
||||
if (expressionStack.Count > 1 && expressionStack.Last().Count == 1)
|
||||
{
|
||||
var lastValue = expressionStack.Last().Pop();
|
||||
expressionStack.Remove(expressionStack.Last());
|
||||
expressionStack.Last().Push(lastValue);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return expressionStack.Last().Pop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the variable.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="expressionStack">The expression stack.</param>
|
||||
public abstract void ResolveVariable(string value, Stack<Expression> expressionStack);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the operator.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="expressionStack">The expression stack.</param>
|
||||
public abstract void ResolveOperator(string value, Stack<Expression> expressionStack);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the function.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="expressionStack">The expression stack.</param>
|
||||
public abstract void ResolveFunction(string value, Stack<Expression> expressionStack);
|
||||
}
|
||||
}
|
||||
32
Vendor/Swan.Lite-3.1.0/Parsers/Operator.cs
vendored
Normal file
32
Vendor/Swan.Lite-3.1.0/Parsers/Operator.cs
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an operator with precedence.
|
||||
/// </summary>
|
||||
public class Operator
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the precedence.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The precedence.
|
||||
/// </value>
|
||||
public int Precedence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [right associative].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [right associative]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool RightAssociative { get; set; }
|
||||
}
|
||||
}
|
||||
35
Vendor/Swan.Lite-3.1.0/Parsers/Token.cs
vendored
Normal file
35
Vendor/Swan.Lite-3.1.0/Parsers/Token.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Token structure.
|
||||
/// </summary>
|
||||
public struct Token
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Token"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public Token(TokenType type, string value)
|
||||
{
|
||||
Type = type;
|
||||
Value = type == TokenType.Function || type == TokenType.Operator ? value.ToLowerInvariant() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type.
|
||||
/// </value>
|
||||
public TokenType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The value.
|
||||
/// </value>
|
||||
public string Value { get; }
|
||||
}
|
||||
}
|
||||
48
Vendor/Swan.Lite-3.1.0/Parsers/TokenType.cs
vendored
Normal file
48
Vendor/Swan.Lite-3.1.0/Parsers/TokenType.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Enums the token types.
|
||||
/// </summary>
|
||||
public enum TokenType
|
||||
{
|
||||
/// <summary>
|
||||
/// The number
|
||||
/// </summary>
|
||||
Number,
|
||||
|
||||
/// <summary>
|
||||
/// The string
|
||||
/// </summary>
|
||||
String,
|
||||
|
||||
/// <summary>
|
||||
/// The variable
|
||||
/// </summary>
|
||||
Variable,
|
||||
|
||||
/// <summary>
|
||||
/// The function
|
||||
/// </summary>
|
||||
Function,
|
||||
|
||||
/// <summary>
|
||||
/// The parenthesis
|
||||
/// </summary>
|
||||
Parenthesis,
|
||||
|
||||
/// <summary>
|
||||
/// The operator
|
||||
/// </summary>
|
||||
Operator,
|
||||
|
||||
/// <summary>
|
||||
/// The comma
|
||||
/// </summary>
|
||||
Comma,
|
||||
|
||||
/// <summary>
|
||||
/// The wall, used to specified the end of argument list of the following function
|
||||
/// </summary>
|
||||
Wall,
|
||||
}
|
||||
}
|
||||
361
Vendor/Swan.Lite-3.1.0/Parsers/Tokenizer.cs
vendored
Normal file
361
Vendor/Swan.Lite-3.1.0/Parsers/Tokenizer.cs
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic tokenizer.
|
||||
/// </summary>
|
||||
public abstract class Tokenizer
|
||||
{
|
||||
private const char PeriodChar = '.';
|
||||
private const char CommaChar = ',';
|
||||
private const char StringQuotedChar = '"';
|
||||
private const char OpenFuncChar = '(';
|
||||
private const char CloseFuncChar = ')';
|
||||
private const char NegativeChar = '-';
|
||||
|
||||
private const string OpenFuncStr = "(";
|
||||
|
||||
private readonly List<Operator> _operators = new List<Operator>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Tokenizer"/> class.
|
||||
/// This constructor will use the following default operators:
|
||||
///
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Operator</term>
|
||||
/// <description>Precedence</description>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>=</term>
|
||||
/// <description>1</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>!=</term>
|
||||
/// <description>1</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>></term>
|
||||
/// <description>2</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term><</term>
|
||||
/// <description>2</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>>=</term>
|
||||
/// <description>2</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term><=</term>
|
||||
/// <description>2</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>+</term>
|
||||
/// <description>3</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>&</term>
|
||||
/// <description>3</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>-</term>
|
||||
/// <description>3</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>*</term>
|
||||
/// <description>4</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>(backslash)</term>
|
||||
/// <description>4</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>/</term>
|
||||
/// <description>4</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>^</term>
|
||||
/// <description>4</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
protected Tokenizer(string input)
|
||||
{
|
||||
_operators.AddRange(GetDefaultOperators());
|
||||
Tokenize(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Tokenizer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="operators">The operators to use.</param>
|
||||
protected Tokenizer(string input, IEnumerable<Operator> operators)
|
||||
{
|
||||
_operators.AddRange(operators);
|
||||
Tokenize(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tokens.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tokens.
|
||||
/// </value>
|
||||
public List<Token> Tokens { get; } = new List<Token>();
|
||||
|
||||
/// <summary>
|
||||
/// Validates the input and return the start index for tokenizer.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="startIndex">The start index.</param>
|
||||
/// <returns><c>true</c> if the input is valid, otherwise <c>false</c>.</returns>
|
||||
public abstract bool ValidateInput(string input, out int startIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the type of the function or member.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>The token type.</returns>
|
||||
public abstract TokenType ResolveFunctionOrMemberType(string input);
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the function or member.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns><c>true</c> if the input is a valid function or variable, otherwise <c>false</c>.</returns>
|
||||
public virtual bool EvaluateFunctionOrMember(string input, int position) => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default operators.
|
||||
/// </summary>
|
||||
/// <returns>An array with the operators to use for the tokenizer.</returns>
|
||||
public virtual Operator[] GetDefaultOperators() => new[]
|
||||
{
|
||||
new Operator {Name = "=", Precedence = 1},
|
||||
new Operator {Name = "!=", Precedence = 1},
|
||||
new Operator {Name = ">", Precedence = 2},
|
||||
new Operator {Name = "<", Precedence = 2},
|
||||
new Operator {Name = ">=", Precedence = 2},
|
||||
new Operator {Name = "<=", Precedence = 2},
|
||||
new Operator {Name = "+", Precedence = 3},
|
||||
new Operator {Name = "&", Precedence = 3},
|
||||
new Operator {Name = "-", Precedence = 3},
|
||||
new Operator {Name = "*", Precedence = 4},
|
||||
new Operator {Name = "/", Precedence = 4},
|
||||
new Operator {Name = "\\", Precedence = 4},
|
||||
new Operator {Name = "^", Precedence = 4},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Shunting the yard.
|
||||
/// </summary>
|
||||
/// <param name="includeFunctionStopper">if set to <c>true</c> [include function stopper] (Token type <c>Wall</c>).</param>
|
||||
/// <returns>
|
||||
/// Enumerable of the token in in.
|
||||
/// </returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Wrong token
|
||||
/// or
|
||||
/// Mismatched parenthesis.
|
||||
/// </exception>
|
||||
public virtual IEnumerable<Token> ShuntingYard(bool includeFunctionStopper = true)
|
||||
{
|
||||
var stack = new Stack<Token>();
|
||||
|
||||
foreach (var tok in Tokens)
|
||||
{
|
||||
switch (tok.Type)
|
||||
{
|
||||
case TokenType.Number:
|
||||
case TokenType.Variable:
|
||||
case TokenType.String:
|
||||
yield return tok;
|
||||
break;
|
||||
case TokenType.Function:
|
||||
stack.Push(tok);
|
||||
break;
|
||||
case TokenType.Operator:
|
||||
while (stack.Any() && stack.Peek().Type == TokenType.Operator &&
|
||||
CompareOperators(tok.Value, stack.Peek().Value))
|
||||
yield return stack.Pop();
|
||||
|
||||
stack.Push(tok);
|
||||
break;
|
||||
case TokenType.Comma:
|
||||
while (stack.Any() && (stack.Peek().Type != TokenType.Comma &&
|
||||
stack.Peek().Type != TokenType.Parenthesis))
|
||||
yield return stack.Pop();
|
||||
|
||||
break;
|
||||
case TokenType.Parenthesis:
|
||||
if (tok.Value == OpenFuncStr)
|
||||
{
|
||||
if (stack.Any() && stack.Peek().Type == TokenType.Function)
|
||||
{
|
||||
if (includeFunctionStopper)
|
||||
yield return new Token(TokenType.Wall, tok.Value);
|
||||
}
|
||||
|
||||
stack.Push(tok);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (stack.Peek().Value != OpenFuncStr)
|
||||
yield return stack.Pop();
|
||||
|
||||
stack.Pop();
|
||||
|
||||
if (stack.Any() && stack.Peek().Type == TokenType.Function)
|
||||
{
|
||||
yield return stack.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Wrong token");
|
||||
}
|
||||
}
|
||||
|
||||
while (stack.Any())
|
||||
{
|
||||
var tok = stack.Pop();
|
||||
if (tok.Type == TokenType.Parenthesis)
|
||||
throw new InvalidOperationException("Mismatched parenthesis");
|
||||
|
||||
yield return tok;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CompareOperators(Operator op1, Operator op2) => op1.RightAssociative
|
||||
? op1.Precedence < op2.Precedence
|
||||
: op1.Precedence <= op2.Precedence;
|
||||
|
||||
private void Tokenize(string input)
|
||||
{
|
||||
if (!ValidateInput(input, out var startIndex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = startIndex; i < input.Length; i++)
|
||||
{
|
||||
if (char.IsWhiteSpace(input, i)) continue;
|
||||
|
||||
if (input[i] == CommaChar)
|
||||
{
|
||||
Tokens.Add(new Token(TokenType.Comma, new string(new[] { input[i] })));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input[i] == StringQuotedChar)
|
||||
{
|
||||
i = ExtractString(input, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char.IsLetter(input, i) || EvaluateFunctionOrMember(input, i))
|
||||
{
|
||||
i = ExtractFunctionOrMember(input, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char.IsNumber(input, i) || (
|
||||
input[i] == NegativeChar &&
|
||||
((Tokens.Any() && Tokens.Last().Type != TokenType.Number) || !Tokens.Any())))
|
||||
{
|
||||
i = ExtractNumber(input, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input[i] == OpenFuncChar ||
|
||||
input[i] == CloseFuncChar)
|
||||
{
|
||||
Tokens.Add(new Token(TokenType.Parenthesis, new string(new[] { input[i] })));
|
||||
continue;
|
||||
}
|
||||
|
||||
i = ExtractOperator(input, i);
|
||||
}
|
||||
}
|
||||
|
||||
private int ExtractData(
|
||||
string input,
|
||||
int i,
|
||||
Func<string, TokenType> tokenTypeEvaluation,
|
||||
Func<char, bool> evaluation,
|
||||
int right = 0,
|
||||
int left = -1)
|
||||
{
|
||||
var charCount = 0;
|
||||
for (var j = i + right; j < input.Length; j++)
|
||||
{
|
||||
if (evaluation(input[j]))
|
||||
break;
|
||||
|
||||
charCount++;
|
||||
}
|
||||
|
||||
// Extract and set the value
|
||||
var value = input.SliceLength(i + right, charCount);
|
||||
Tokens.Add(new Token(tokenTypeEvaluation(value), value));
|
||||
|
||||
i += charCount + left;
|
||||
return i;
|
||||
}
|
||||
|
||||
private int ExtractOperator(string input, int i) =>
|
||||
ExtractData(
|
||||
input,
|
||||
i,
|
||||
x => TokenType.Operator,
|
||||
x => x == OpenFuncChar ||
|
||||
x == CommaChar ||
|
||||
x == PeriodChar ||
|
||||
x == StringQuotedChar ||
|
||||
char.IsWhiteSpace(x) ||
|
||||
char.IsNumber(x));
|
||||
|
||||
private int ExtractFunctionOrMember(string input, int i) =>
|
||||
ExtractData(
|
||||
input,
|
||||
i,
|
||||
ResolveFunctionOrMemberType,
|
||||
x => x == OpenFuncChar ||
|
||||
x == CloseFuncChar ||
|
||||
x == CommaChar ||
|
||||
char.IsWhiteSpace(x));
|
||||
|
||||
private int ExtractNumber(string input, int i) =>
|
||||
ExtractData(
|
||||
input,
|
||||
i,
|
||||
x => TokenType.Number,
|
||||
x => !char.IsNumber(x) && x != PeriodChar && x != NegativeChar);
|
||||
|
||||
private int ExtractString(string input, int i)
|
||||
{
|
||||
var length = ExtractData(input, i, x => TokenType.String, x => x == StringQuotedChar, 1, 1);
|
||||
|
||||
// open string, report issue
|
||||
if (length == input.Length && input[length - 1] != StringQuotedChar)
|
||||
throw new FormatException($"Parser error (Position {i}): Expected '\"' but got '{input[length - 1]}'.");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
private bool CompareOperators(string op1, string op2)
|
||||
=> CompareOperators(GetOperatorOrDefault(op1), GetOperatorOrDefault(op2));
|
||||
|
||||
private Operator GetOperatorOrDefault(string op)
|
||||
=> _operators.FirstOrDefault(x => x.Name == op) ?? new Operator { Name = op, Precedence = 0 };
|
||||
}
|
||||
}
|
||||
40
Vendor/Swan.Lite-3.1.0/Parsers/VerbOptionAttribute.cs
vendored
Normal file
40
Vendor/Swan.Lite-3.1.0/Parsers/VerbOptionAttribute.cs
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Swan.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Models a verb option.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class VerbOptionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VerbOptionAttribute" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <exception cref="ArgumentNullException">name.</exception>
|
||||
public VerbOptionAttribute(string name)
|
||||
{
|
||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the verb option.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Name.
|
||||
/// </value>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a short description of this command line verb. Usually a sentence summary.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The help text.
|
||||
/// </value>
|
||||
public string HelpText { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => $" {Name}\t\t{HelpText}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user