Exemplo n.º 1
0
            /// <summary>
            /// Registers command handler.
            /// </summary>
            /// <remarks>
            /// <see cref="CommandAttribute.Formatter"/> must be defined.
            /// </remarks>
            /// <param name="handler">The command handler.</param>
            /// <typeparam name="TCommand">The type of the command supported by the handler.</typeparam>
            /// <returns>This builder.</returns>
            /// <exception cref="ArgumentNullException"><paramref name="handler"/> is <see langword="null"/>.</exception>
            /// <exception cref="GenericArgumentException">Type <typaparamref name="TCommand"/> is not annotated with <see cref="CommandAttribute"/> attribute or <see cref="CommandAttribute.Formatter"/> refers to the invalid formatter.</exception>
            public Builder Add <TCommand>(Func <TCommand, CancellationToken, ValueTask> handler)
                where TCommand : struct
            {
                if (handler is null)
                {
                    throw new ArgumentNullException(nameof(handler));
                }

                var attr = typeof(TCommand).GetCustomAttribute <CommandAttribute>();

                if (attr is null || attr.Formatter is null)
                {
                    throw new GenericArgumentException <TCommand>(ExceptionMessages.MissingCommandAttribute <TCommand>());
                }

                var formatter = new FormatterInfo(attr);

                if (formatter.IsEmpty)
                {
                    throw new GenericArgumentException <TCommand>(ExceptionMessages.MissingCommandFormatter <TCommand>());
                }
                formatters.Add(typeof(TCommand), formatter);
                var interp = Activator.CreateInstance(typeof(CommandHandler <>).MakeGenericType(typeof(TCommand)), formatter, handler);

                interpreters.Add(attr.Id, Cast <CommandHandler>(interp));
                return(this);
            }
Exemplo n.º 2
0
 public Parser(List<Token> tokens)
 {
     this.fi = new FormatterInfo();
       this.tokens = tokens;
       this.tokenIndex = 0;
       this.indentLevel = 0;
       this.comments = new List<String>();
       this.ignoreTypes = new List<TokenType>(){
     TokenType.Comment,
     TokenType.Empty,
       };
 }
Exemplo n.º 3
0
            /// <summary>
            /// Registers command handler.
            /// </summary>
            /// <remarks>
            /// <see cref="CommandAttribute.Formatter"/> is ignored by this method.
            /// </remarks>
            /// <param name="handler">The command handler.</param>
            /// <param name="formatter">Serializer/deserializer of the command type.</param>
            /// <typeparam name="TCommand">The type of the command supported by the handler.</typeparam>
            /// <returns>This builder.</returns>
            /// <exception cref="ArgumentNullException"><paramref name="handler"/> or <paramref name="formatter"/> is <see langword="null"/>.</exception>
            /// <exception cref="GenericArgumentException">Type <typaparamref name="TCommand"/> is not annotated with <see cref="CommandAttribute"/> attribute.</exception>
            public Builder Add <TCommand>(Func <TCommand, CancellationToken, ValueTask> handler, IFormatter <TCommand> formatter)
                where TCommand : struct
            {
                if (handler is null)
                {
                    throw new ArgumentNullException(nameof(handler));
                }
                if (formatter is null)
                {
                    throw new ArgumentNullException(nameof(formatter));
                }

                var id = typeof(TCommand).GetCustomAttribute <CommandAttribute>()?.Id ?? throw new GenericArgumentException <TCommand>(ExceptionMessages.MissingCommandAttribute <TCommand>());

                interpreters.Add(id, new CommandHandler <TCommand>(formatter, handler));
                formatters.Add(typeof(TCommand), FormatterInfo.Create(formatter, id));
                return(this);
            }
Exemplo n.º 4
0
        /// <summary>
        /// Initializes a new interpreter and discovers methods marked
        /// with <see cref="CommandHandlerAttribute"/> attribute.
        /// </summary>
        protected CommandInterpreter()
        {
            var interpreters = new Dictionary <int, CommandHandler>();
            var formatters   = new Dictionary <Type, FormatterInfo>();
            const BindingFlags publicInstanceMethod = BindingFlags.Public | BindingFlags.Instance;

            foreach (var method in GetType().GetMethods(publicInstanceMethod))
            {
                var handlerAttr = method.GetCustomAttribute <CommandHandlerAttribute>();
                if (handlerAttr is not null && method.ReturnType == typeof(ValueTask))
                {
                    var parameters = method.GetParameterTypes();
                    if (GetLength(parameters) != 2 || !parameters[0].IsValueType || parameters[1] != typeof(CancellationToken))
                    {
                        continue;
                    }
                    var commandType = parameters[0];
                    var commandAttr = commandType.GetCustomAttribute <CommandAttribute>();
                    if (commandAttr is null || commandAttr.Formatter is null)
                    {
                        continue;
                    }
                    var formatter = new FormatterInfo(commandAttr);
                    if (formatter.IsEmpty)
                    {
                        continue;
                    }
                    var interpreter = Delegate.CreateDelegate(typeof(Func <, ,>).MakeGenericType(commandType, typeof(CancellationToken), typeof(ValueTask)), method.IsStatic ? null : this, method);
                    interpreters.Add(commandAttr.Id, Cast <CommandHandler>(Activator.CreateInstance(typeof(CommandHandler <>).MakeGenericType(commandType), formatter, interpreter)));
                    formatters.Add(commandType, formatter);
                }
            }

            this.interpreters = CreateRegistry(interpreters);
            interpreters.Clear();

            formatters.TrimExcess();
            this.formatters = formatters;
        }
Exemplo n.º 5
0
 public static List<Token> LexerFile(FormatterInfo fi)
 {
     return LexerLines(IO.ReadFile(fi.Path, fi.Enc), fi.Path);
 }
Exemplo n.º 6
0
 public Parser(List<Token> tokens, FormatterInfo fi)
     : this(tokens)
 {
     this.fi = fi;
       this.tokens = tokens;
 }