Beispiel #1
0
        protected override CommandCanExecuteResult CanExecute()
        {
            if (CurrentNode == null || CurrentQueryBlock?.FromClause == null || !CurrentQueryBlock.FromClause.IsGrammarValid)
            {
                return(false);
            }

            ResolveExpressionText();

            AddedTextSegment = ResolveAddedTextSegment();

            return(ExpressionText != null && !AddedTextSegment.Equals(TextSegment.Empty) && OracleSqlParser.Instance.IsRuleValid(OracleGrammarDescription.NonTerminals.ExpressionList, ExpressionText));
        }
Beispiel #2
0
        /// <summary>
        /// Modifies the passed in TextAnchor to contain its relative
        /// complement to the set of text segments passed in.  The resulting
        /// TextAnchor contains those segments or portions of segments that do
        /// not overlap with the passed in segments in anyway.  If after trimming
        /// the anchor has no more segments, null is returned instead.  Callers
        /// should assign the result of this method to the anchor they passed in.
        /// </summary>
        /// <param name="anchor">the anchor to trim</param>
        /// <param name="textSegments">the text segments to calculate relative complement with</param>
        /// <remarks>Note: textSegments is expected to be ordered and contain no overlapping segments</remarks>
        internal static TextAnchor TrimToRelativeComplement(TextAnchor anchor, ICollection <TextSegment> textSegments)
        {
            Invariant.Assert(anchor != null, "Anchor must not be null.");
            Invariant.Assert(textSegments != null, "TextSegments must not be null.");

            textSegments = SortTextSegments(textSegments, true);

            IEnumerator <TextSegment> enumerator = textSegments.GetEnumerator();
            bool        hasMore      = enumerator.MoveNext();
            int         currentIndex = 0;
            TextSegment current;
            TextSegment otherSegment = TextSegment.Null;

            while (currentIndex < anchor._segments.Count && hasMore)
            {
                Invariant.Assert(otherSegment.Equals(TextSegment.Null) || otherSegment.Equals(enumerator.Current) || otherSegment.End.CompareTo(enumerator.Current.Start) <= 0, "TextSegments are overlapping or not ordered.");

                current      = anchor._segments[currentIndex];
                otherSegment = enumerator.Current;

                // Current segment is after other segment, no overlap
                // Also, done with the other segment, move to the next one
                if (current.Start.CompareTo(otherSegment.End) >= 0)
                {
                    hasMore = enumerator.MoveNext();
                    continue;  // No increment, still processing the current segment
                }

                // Current segment starts after other segment starts and ...
                if (current.Start.CompareTo(otherSegment.Start) >= 0)
                {
                    // ends before other segment ends, complete overlap, remove the segment
                    if (current.End.CompareTo(otherSegment.End) <= 0)
                    {
                        anchor._segments.RemoveAt(currentIndex);
                        continue;  // No increment, happens implicitly because of the removal
                    }
                    else
                    {
                        // ends after other segment, first portion of current overlaps,
                        // create new segment from end of other segment to end of current
                        anchor._segments[currentIndex] = CreateNormalizedSegment(otherSegment.End, current.End);
                        // Done with the other segment, move to the next one
                        hasMore = enumerator.MoveNext();
                        continue; // No increment, need to process just created segment
                    }
                }
                // Current segment starts before other segment starts and ...
                else
                {
                    // ends after it starts, first portion of current does not overlap,
                    // create new segment for that portion
                    if (current.End.CompareTo(otherSegment.Start) > 0)
                    {
                        anchor._segments[currentIndex] = CreateNormalizedSegment(current.Start, otherSegment.Start);
                        // If there's any portion of current after other segment, create a new segment for that which
                        // will be the next one processed
                        if (current.End.CompareTo(otherSegment.End) > 0)
                        {
                            // Overlap ends before current segment's end, we create a new segment with the remainder of current segment
                            anchor._segments.Insert(currentIndex + 1, CreateNormalizedSegment(otherSegment.End, current.End));
                            // Done with the other segment, move to the next one
                            hasMore = enumerator.MoveNext();
                        }
                    }
                    // ends before it starts, current is completely before other, no overlap, do nothing
                }

                currentIndex++;
            }

            if (anchor._segments.Count > 0)
            {
                return(anchor);
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Modifies the text anchor's TextSegments so all of them
        /// overlap with the passed in text segments.  This is used
        /// for instance to clamp a TextAnchor to a set of visible
        /// text segments.  If after trimming the anchor has no more
        /// segments, null is returned instead.  Callers should
        /// assign the result of this method to the anchor they
        /// passed in.
        /// </summary>
        /// <remarks>
        /// Note: This method assumes textSegments is ordered and do not overlap amongs themselves
        ///
        /// The target of the method is to trim this anchor's segments to overlap with the passed in segments.
        /// The loop handles the following three cases -
        /// 1. Current segment is after other segment, the other segment doesn't contribute at all, we move to the next other segment
        /// 2. Current segment is before other segment, no overlap, remove current segment
        /// 3. Current segment starts before other segment, and ends after other segment begins,
        ///    therefore the portion from current's start to other's start should be trimmed
        /// 4. Current segment starts in the middle of other segment, two possibilities
        ///      a. current segment is completely within other segment, the whole segment overlaps
        ///         so we move on to the next current segment
        ///      b. current segment ends after other segment ends, we split current into the
        ///         overlapped portion and the remainder which will be looked at separately
        /// </remarks>
        /// <param name="anchor">the anchor to trim</param>
        /// <param name="textSegments">collection of text segments to intersect with</param>
        internal static TextAnchor TrimToIntersectionWith(TextAnchor anchor, ICollection <TextSegment> textSegments)
        {
            Invariant.Assert(anchor != null, "Anchor must not be null.");
            Invariant.Assert(textSegments != null, "TextSegments must not be null.");

            textSegments = SortTextSegments(textSegments, true);
            TextSegment currentSegment, otherSegment = TextSegment.Null;

            int current = 0;
            IEnumerator <TextSegment> enumerator = textSegments.GetEnumerator();
            bool hasMore = enumerator.MoveNext();

            while (current < anchor._segments.Count && hasMore)
            {
                Invariant.Assert(otherSegment.Equals(TextSegment.Null) || otherSegment.Equals(enumerator.Current) || otherSegment.End.CompareTo(enumerator.Current.Start) <= 0, "TextSegments are overlapping or not ordered.");

                currentSegment = anchor._segments[current];
                otherSegment   = enumerator.Current;

                // Current segment is after other segment, so try the next other segment
                if (currentSegment.Start.CompareTo(otherSegment.End) >= 0)
                {
                    hasMore = enumerator.MoveNext(); // point to the next other
                    continue;                        // Do not increment, we are still on the same current
                }

                // Current segment is before other segment, no overlap so remove it and continue
                if (currentSegment.End.CompareTo(otherSegment.Start) <= 0)
                {
                    anchor._segments.RemoveAt(current);
                    continue; // Do not increment, it happens implicitly because of the remove
                }

                //
                // We know from here down that there is some overlap.
                //

                // Current starts before the other segment and ends after other segment begins, the first portion of current segment doesn't overlap so we remove it
                if (currentSegment.Start.CompareTo(otherSegment.Start) < 0)
                {
                    anchor._segments[current] = CreateNormalizedSegment(otherSegment.Start, currentSegment.End);
                    continue;  // Do not increment, we need to look at this just created segment
                }
                // Current segment begins in the middle of other segment...
                else
                {
                    // and ends after other segment does, we split current into the portion that is overlapping and the remainder
                    if (currentSegment.End.CompareTo(otherSegment.End) > 0)
                    {
                        anchor._segments[current] = CreateNormalizedSegment(currentSegment.Start, otherSegment.End);
                        // This segment will be the first one looked at next
                        anchor._segments.Insert(current + 1, CreateNormalizedSegment(otherSegment.End, currentSegment.End));
                        hasMore = enumerator.MoveNext();
                    }
                    // and ends at the same place as other segment, its completely overlapping, we move on to the next other
                    else if (currentSegment.End.CompareTo(otherSegment.End) == 0)
                    {
                        hasMore = enumerator.MoveNext();
                    }
                    // and ends within other segment, its completely overlapping, but we aren't done with other so we just continue
                }

                current++;
            }

            // If we finished and there are no more other segments, then any remaining segments
            // in our list must not overlap, so we remove them.
            if (!hasMore && current < anchor._segments.Count)
            {
                anchor._segments.RemoveRange(current, anchor._segments.Count - current);
            }

            if (anchor._segments.Count == 0)
            {
                return(null);
            }
            else
            {
                return(anchor);
            }
        }
Beispiel #4
0
        // Token: 0x06006251 RID: 25169 RVA: 0x001B8FC0 File Offset: 0x001B71C0
        internal static TextAnchor TrimToIntersectionWith(TextAnchor anchor, ICollection <TextSegment> textSegments)
        {
            Invariant.Assert(anchor != null, "Anchor must not be null.");
            Invariant.Assert(textSegments != null, "TextSegments must not be null.");
            textSegments = TextAnchor.SortTextSegments(textSegments, true);
            TextSegment textSegment = TextSegment.Null;
            int         num         = 0;
            IEnumerator <TextSegment> enumerator = textSegments.GetEnumerator();
            bool flag = enumerator.MoveNext();

            while (num < anchor._segments.Count && flag)
            {
                bool condition;
                if (!textSegment.Equals(TextSegment.Null) && !textSegment.Equals(enumerator.Current))
                {
                    ITextPointer end          = textSegment.End;
                    TextSegment  textSegment2 = enumerator.Current;
                    condition = (end.CompareTo(textSegment2.Start) <= 0);
                }
                else
                {
                    condition = true;
                }
                Invariant.Assert(condition, "TextSegments are overlapping or not ordered.");
                TextSegment textSegment3 = anchor._segments[num];
                textSegment = enumerator.Current;
                if (textSegment3.Start.CompareTo(textSegment.End) >= 0)
                {
                    flag = enumerator.MoveNext();
                }
                else if (textSegment3.End.CompareTo(textSegment.Start) <= 0)
                {
                    anchor._segments.RemoveAt(num);
                }
                else if (textSegment3.Start.CompareTo(textSegment.Start) < 0)
                {
                    anchor._segments[num] = TextAnchor.CreateNormalizedSegment(textSegment.Start, textSegment3.End);
                }
                else
                {
                    if (textSegment3.End.CompareTo(textSegment.End) > 0)
                    {
                        anchor._segments[num] = TextAnchor.CreateNormalizedSegment(textSegment3.Start, textSegment.End);
                        anchor._segments.Insert(num + 1, TextAnchor.CreateNormalizedSegment(textSegment.End, textSegment3.End));
                        flag = enumerator.MoveNext();
                    }
                    else if (textSegment3.End.CompareTo(textSegment.End) == 0)
                    {
                        flag = enumerator.MoveNext();
                    }
                    num++;
                }
            }
            if (!flag && num < anchor._segments.Count)
            {
                anchor._segments.RemoveRange(num, anchor._segments.Count - num);
            }
            if (anchor._segments.Count == 0)
            {
                return(null);
            }
            return(anchor);
        }