Example #1
0
        /// <summary>
        /// Validates a tag based on the descriptor.
        /// </summary>
        /// <param name="name">The tag name.</param>
        /// <param name="descriptor">The tag descriptor.</param>
        /// <param name="arguments">The set of arguments.</param>
        /// <param name="parameters">The set of parameters.</param>
        public void ValidateTag(string name, TagDescriptor descriptor, object[] arguments, IDictionary <string, object> parameters)
        {
            if (descriptor == null || descriptor.IsImplicit)
            {
                // Can't validate the tag.
                return;
            }

            if (descriptor.RequiredArguments > 0 && arguments.Length < descriptor.RequiredArguments)
            {
                throw new InvalidOperationException(string.Format("The tag {0} requires at least {1} argument(s)", name, descriptor.RequiredArguments));
            }

            if (arguments.Length > descriptor.MaxArguments)
            {
                throw new InvalidOperationException(string.Format("The tag {0} requires at most {1} argument(s)", name, descriptor.MaxArguments));
            }

            bool hasParameters = parameters.Count > 0;

            if (descriptor.AllowMappedParameters != hasParameters)
            {
                throw new InvalidOperationException(string.Format("{0} parameters to tag {1}", hasParameters ? "Unexpected" : "Expected", name));
            }
        }
        public void ConvertBytesToVersionString()
        {
            Assert.Null(TagDescriptor <MockDirectory> .ConvertBytesToVersionString(null, 1));
            Assert.Null(TagDescriptor <MockDirectory> .ConvertBytesToVersionString(Array.Empty <int>(), 1));

            Assert.Equal("1.00", TagDescriptor <MockDirectory> .ConvertBytesToVersionString(new[] { 0, 1, 0, 0 }, 2));
            Assert.Equal(".100", TagDescriptor <MockDirectory> .ConvertBytesToVersionString(new[] { 0, 1, 0, 0 }, 1));

            Assert.Equal("2.10", TagDescriptor <MockDirectory> .ConvertBytesToVersionString(new[] { 0x30, 0x32, 0x31, 0x30 }, 2));
            Assert.Equal(".210", TagDescriptor <MockDirectory> .ConvertBytesToVersionString(new[] { 0x30, 0x32, 0x31, 0x30 }, 1));
            Assert.Equal("21.0", TagDescriptor <MockDirectory> .ConvertBytesToVersionString(new[] { 0x30, 0x32, 0x31, 0x30 }, 3));
        }
Example #3
0
        /// <summary>
        /// Initialises a new instance of <see cref="Block"/>
        /// </summary>
        /// <param name="type">The block type.</param>
        /// <param name="name">The block name.</param>
        /// <param name="contents">The child contents.</param>
        /// <param name="descriptor">The tag descriptor.</param>
        protected Block(BlockType type, string name, IEnumerable <SyntaxTreeNode> contents, TagDescriptor descriptor)
        {
            Type       = type;
            Name       = name;
            Children   = contents;
            Descriptor = descriptor;

            foreach (var node in contents)
            {
                node.Parent = this;
            }
        }
        public void GetDescription_SimplifiedLongCollections()
        {
            var directory  = new MockDirectory();
            var descriptor = new TagDescriptor <MockDirectory>(directory);

            const int tagType = 1;

            directory.Set(tagType, Enumerable.Range(0, 16).Select(i => i).ToArray());

            Assert.Equal("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15", descriptor.GetDescription(tagType));

            directory.Set(tagType, Enumerable.Range(0, 17).Select(i => i).ToArray());

            Assert.Equal("[17 values]", descriptor.GetDescription(tagType));
        }
Example #5
0
        /// <summary>
        /// Parses a block tag.
        /// </summary>
        public void AtBlockTag(HandlebarsSymbolType expectedPrefixSymbol = HandlebarsSymbolType.Hash)
        {
            var parent = Context.CurrentBlock;

            string        tagName    = null;
            TagDescriptor descriptor = null;

            // Start a new block.
            Context.StartBlock(BlockType.Tag);

            using (Context.StartBlock(BlockType.TagElement))
            {
                // Accept the open tag.
                AcceptAndMoveNext();
                // Output that tag as metacode.
                Output(SpanKind.MetaCode);

                if (Optional(HandlebarsSymbolType.Tilde))
                {
                    // Output the tilde.
                    Output(SpanKind.MetaCode);
                }

                if (Required(expectedPrefixSymbol, true))
                {
                    // Accept the prefix symbol type. tag.
                    AcceptAndMoveNext();
                    // Output that tag as metacode.
                    Output(SpanKind.MetaCode);
                }

                // Accept everything until either the close of the tag, or the first element of whitespace.
                AcceptUntil(HandlebarsSymbolType.WhiteSpace, HandlebarsSymbolType.CloseTag, HandlebarsSymbolType.RawCloseTag);
                // Output the first part as an expression.
                Output(SpanKind.Expression);

                // Get the tag name and set it for the block.
                tagName    = LastSpanContent();
                descriptor = Context.TagProviders.GetDescriptor(tagName, expectedPrefixSymbol == HandlebarsSymbolType.Negate);

                Context.CurrentBlock.Name       = tagName;
                Context.CurrentBlock.Descriptor = descriptor;

                while (CurrentSymbol.Type != HandlebarsSymbolType.CloseTag && CurrentSymbol.Type != HandlebarsSymbolType.RawCloseTag && CurrentSymbol.Type != HandlebarsSymbolType.Tilde)
                {
                    if (CurrentSymbol.Type == HandlebarsSymbolType.WhiteSpace)
                    {
                        // Accept all the whitespace.
                        AcceptAll(HandlebarsSymbolType.WhiteSpace);
                        // Take all the whitespace, and output that.
                        Output(SpanKind.WhiteSpace);
                    }

                    if (CurrentSymbol.Type == HandlebarsSymbolType.Assign)
                    {
                        // We're in a parameterised argument (e.g. one=two
                        AcceptAndMoveNext();
                        // Accept everything until the next whitespace or closing tag.
                        AcceptUntil(HandlebarsSymbolType.WhiteSpace, HandlebarsSymbolType.CloseTag, HandlebarsSymbolType.RawCloseTag, HandlebarsSymbolType.Tilde);
                        // Output this as a map.
                        Output(SpanKind.Map);
                    }
                    else
                    {
                        // Accept everything until the next whitespace or closing tag.
                        AcceptUntil(HandlebarsSymbolType.Assign, HandlebarsSymbolType.WhiteSpace, HandlebarsSymbolType.CloseTag, HandlebarsSymbolType.RawCloseTag, HandlebarsSymbolType.Tilde);
                        if (CurrentSymbol.Type != HandlebarsSymbolType.Assign)
                        {
                            // Output this as a parameter.
                            Output(SpanKind.Parameter);
                        }
                    }
                }

                if (Optional(HandlebarsSymbolType.Tilde))
                {
                    // Output the tilde.
                    Output(SpanKind.MetaCode);
                }

                // Accept the closing tag.
                AcceptAndMoveNext();
                // Output this as metacode.
                Output(SpanKind.MetaCode);
            }

            // Special case, as we need to handle branching, so let's merge the last block into the parent block.
            if (tagName == "elseif" && parent != null && parent.Name == "if")
            {
                // Let's merge the current block with the parent and re-instate it.
                Context.MergeCurrentWithParent();
            }
            else
            {
                Context.CurrentBlock.Name       = tagName;
                Context.CurrentBlock.Descriptor = descriptor;
            }

            // Switch back to parsing the content of the block.
            ParseBlock();
        }