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)); }
/// <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); } }
/// <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); } }
// 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); }