/// <summary>
        /// All items that can incrementally parse their children should run their
        /// full parse in the same way. This function does that work.
        /// </summary>
        public static bool FullParseIncrementalItem(
            IIncrementalParseItem item,
            ItemFactory itemFactory,
            ITextProvider text,
            TokenStream tokens)
        {
            ComplexItem complexItem = (ComplexItem)item;
            ParseItem   prevChild   = null;

            while (true)
            {
                ParseItem newChild = item.CreateNextChild(prevChild, itemFactory, text, tokens);

                if (newChild != null)
                {
                    complexItem.Children.Add(newChild);
                    prevChild = newChild;
                }
                else
                {
                    break;
                }
            }

            item.UpdateCachedChildren();
            item.UpdateParseErrors();

            return(complexItem.Children.Count > 0);
        }
Exemple #2
0
        internal void InsertChildIntoSubtree(ParseItem child)
        {
            ComplexItem parent = this;

            if (child.Start >= Children.TextStart &&
                child.Start < Children.TextAfterEnd)
            {
                // Might need to be added in one of my children
                parent = ComplexItemFromRange(child.Start, child.Length) ?? this;
            }

            int insertIndex = parent.Children.FindInsertIndex(child.Start, beforeExisting: false);

            if (insertIndex > 0)
            {
                // If the comment is going to be added right after an unclosed item,
                // then put the comment into the unclosed item. It makes the tree look as expected
                // and it helps incremental parsing work when the item does get closed.

                if (parent.Children[insertIndex - 1] is ComplexItem previousChild && previousChild.IsUnclosed)
                {
                    previousChild.InsertChildIntoSubtree(child);

                    return;
                }
            }

            parent.Children.Insert(insertIndex, child);
        }
Exemple #3
0
        internal bool IsParentOf(ParseItem item)
        {
            ComplexItem parent = item?.Parent;

            while (parent != null && parent != this)
            {
                parent = parent.Parent;
            }

            return(parent == this);
        }
Exemple #4
0
        /// <summary>
        /// Search my subtree for the deepest item that contains a range of text
        /// </summary>
        internal ComplexItem ComplexItemFromRange(int start, int length)
        {
            ParseItem   item        = ItemFromRange(start, length);
            ComplexItem complexItem = item as ComplexItem;

            if (item != null)
            {
                return(complexItem ?? item.Parent);
            }

            return(null);
        }
        /// <summary>
        /// Create parse item of any type as long as it is derived from ParseItem
        /// </summary>
        /// <typeparam name="T">Type of item to create</typeparam>
        /// <param name="parent">Parent element</param>
        /// <param name="type">Suggested type to create</param>
        /// <returns></returns>
        internal ParseItem Create <T>(ComplexItem parent, Type type) where T : ParseItem, new()
        {
            ParseItem item = null;

            if (ExternalFactory != null)
            {
                item = ExternalFactory.CreateItem(this, TextProvider, TokenStream, parent, type);
            }

            if (item == null)
            {
                item = new T();
            }

            return(item);
        }
        /// <summary>
        /// Create specific item. Called when parser cannot accept random type and rather
        /// needs a specific type. Returned item can be derived from type T.
        /// </summary>
        /// <typeparam name="T">Type of item to create</typeparam>
        /// <param name="parent">Parent element</param>
        /// <param name="type">Suggested item type</param>
        /// <returns></returns>
        internal T CreateSpecific <T>(ComplexItem parent, Type type) where T : ParseItem, new()
        {
            T item = default;

            if (ExternalFactory != null)
            {
                ParseItem pi = ExternalFactory.CreateItem(this, TextProvider, TokenStream, parent, type);

                if (pi != null)
                {
                    item = pi as T;
                    Debug.Assert(item != null);
                }
            }

            if (item == null)
            {
                item = new T();
            }

            return(item);
        }
 internal T CreateSpecific <T>(ComplexItem parent) where T : ParseItem, new()
 {
     return(CreateSpecific <T>(parent, typeof(T)));
 }
            public ParseItem CreateItem(ItemFactory itemFactory, ITextProvider text, TokenStream tokens, ComplexItem parent, Type type)
            {
                Assert.AreSame(itemFactory.TextProvider, text);
                Assert.AreSame(itemFactory.TokenStream, tokens);

                if (type == typeof(Declaration))
                {
                    Assert.IsInstanceOfType(parent, typeof(RuleBlock));
                    return(new TestDeclaration());
                }

                return(null);
            }