public static PatternMatch Merge(this PatternMatch match1, PatternMatch match2, PatternMatchMergeStrategy strategy)
        {
            PatternMatchKind kind;

            if (strategy == PatternMatchMergeStrategy.Simple)
            {
                // Do some intelligent merging, since both matches came from the same string.
                kind = MergeMatchKinds(match1.Kind, match2.Kind);
            }
            else
            {
                // Give the worst kind of match, since these are relating to different containers.
                kind = match1.Kind.CompareTo(match2.Kind) > 0 ? match1.Kind : match2.Kind;
            }

            // Give punctuation stripped if either has it stripped
            var punctuation = match1.IsPunctuationStripped || match2.IsPunctuationStripped;

            // Give case sensitivity only if both are case sensitive
            var caseSensitive = match1.IsCaseSensitive && match2.IsCaseSensitive;

            // Give spans from both
            var spans = MergeSpans(match1, match2);

            return(new PatternMatch(kind, punctuation, caseSensitive, spans));
        }
Esempio n. 2
0
        public static Task <bool> GracefulStop(this IActorRef target, TimeSpan timeout, object stopMessage)
        {
            var internalTarget = target.AsInstanceOf <IInternalActorRef>();

            var promiseRef = PromiseActorRef.Apply(internalTarget.Provider, timeout, target, stopMessage.GetType().Name);

            internalTarget.SendSystemMessage(new Watch(internalTarget, promiseRef));
            target.Tell(stopMessage, ActorRefs.NoSender);
            return(promiseRef.Result.ContinueWith(t =>
            {
                var returnResult = false;
                PatternMatch.Match(t.Result)
                .With <Terminated>(terminated =>
                {
                    returnResult = (terminated.ActorRef.Path.Equals(target.Path));
                })
                .Default(m =>
                {
                    returnResult = false;
                });

                internalTarget.SendSystemMessage(new Unwatch(internalTarget, promiseRef));
                return returnResult;
            }, TaskContinuationOptions.ExecuteSynchronously));
        }
 public PatternSignature(
     IReadOnlyList <string> argumentValues,
     string pathValue,
     PatternMatch declaration)
     : this(argumentValues, pathValue, null, declaration)
 {
 }
Esempio n. 4
0
        /// <summary>
        /// Finds the first match for the pattern.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public PatternMatch Match(string s)
        {
            // Note: need to implement captures here.
            PatternMatch match = new PatternMatch();

            computeThread.Join();

            try
            {
                int j = i;
                for (int f = 0; f < funcs.Count;)
                {
                    PatternFunc func    = funcs[f];
                    bool        applies = func(s, ref i, funcs.ElementAtOrDefault(f - 1), funcs.ElementAtOrDefault(f + 1));

                    if (applies)
                    {
                        f++;
                    }
                    else
                    {
                        f = 0; j++; i = j;
                    }
                }
            }
            catch (IndexOutOfRangeException) { return(null); }

            return(match);
        }
Esempio n. 5
0
 public ComponentData(bool draw, int id, Vector3 vertex, PatternMatch match)
 {
     this.draw   = draw;
     this.id     = id;
     this.vertex = vertex;
     this.match  = new PatternMatch(match.invx, match.invy, Mathf.Clamp(match.shift, 0, 5));
 }
Esempio n. 6
0
        public void 文字列()
        {
            Assert.IsTrue(PatternMatch.IsMatch("abcde", "abcde"));

            Assert.IsFalse(PatternMatch.IsMatch("abcde", "fghijk"));
            Assert.IsFalse(PatternMatch.IsMatch("abcd", "abcde"));
            Assert.IsFalse(PatternMatch.IsMatch("abcde", "abcd"));
        }
Esempio n. 7
0
        public void はてな()
        {
            Assert.IsTrue(PatternMatch.IsMatch("abcde?", "abcdef"));
            Assert.IsTrue(PatternMatch.IsMatch("abc?ef", "abcdef"));
            Assert.IsTrue(PatternMatch.IsMatch("?????", "12345"));

            Assert.IsFalse(PatternMatch.IsMatch("abc?ef", "abccdef"));
            Assert.IsFalse(PatternMatch.IsMatch("?????", "123456"));
        }
Esempio n. 8
0
        private int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            // First see how the two items compare in a case insensitive fashion.  Matches that
            // are strictly better (ignoring case) should prioritize the item.  i.e. if we have
            // a prefix match, that should always be better than a substring match.
            //
            // The reason we ignore case is that it's very common for people to type expecting
            // completion to fix up their casing.  i.e. 'false' will be written with the
            // expectation that it will get fixed by the completion list to 'False'.
            var diff = match1.CompareTo(match2, ignoreCase: true);

            if (diff != 0)
            {
                return(diff);
            }

            // If they both seemed just as good, but they differ on preselection, then
            // item1 is better if it is preselected, otherwise it is worse.
            if (item1.Rules.MatchPriority == MatchPriority.Preselect &&
                item2.Rules.MatchPriority != MatchPriority.Preselect)
            {
                return(-1);
            }
            else if (item1.Rules.MatchPriority != MatchPriority.Preselect &&
                     item2.Rules.MatchPriority == MatchPriority.Preselect)
            {
                return(1);
            }

            // At this point we have two items which we're matching in a rather similar fasion.
            // If one is a prefix of the other, prefer the prefix.  i.e. if we have
            // "Table" and "table:=" and the user types 't' and we are in a case insensitive
            // language, then we prefer the former.
            if (item1.DisplayText.Length != item2.DisplayText.Length)
            {
                var comparison = _isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
                if (item2.DisplayText.StartsWith(item1.DisplayText, comparison))
                {
                    return(-1);
                }
                else if (item1.DisplayText.StartsWith(item2.DisplayText, comparison))
                {
                    return(1);
                }
            }

            // Now compare the matches again in a case sensitive manner.  If everything was
            // equal up to this point, we prefer the item that better matches based on case.
            diff = match1.CompareTo(match2, ignoreCase: false);
            if (diff != 0)
            {
                return(diff);
            }

            return(0);
        }
        private static ImmutableArray <Span> MergeSpans(PatternMatch match1, PatternMatch match2)
        {
            var collection1 = new NormalizedSpanCollection(match1.MatchedSpans);
            var collection2 = new NormalizedSpanCollection(match2.MatchedSpans);

            var builder = ArrayBuilder <Span> .GetInstance();

            builder.AddRange(NormalizedSpanCollection.Union(collection1, (collection2)));
            return(builder.ToImmutable());
        }
Esempio n. 10
0
        private int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            // First see how the two items compare in a case insensitive fashion.  Matches that
            // are strictly better (ignoring case) should prioritize the item.  i.e. if we have
            // a prefix match, that should always be better than a substring match.
            //
            // The reason we ignore case is that it's very common for people to type expecting
            // completion to fix up their casing.  i.e. 'false' will be written with the
            // expectation that it will get fixed by the completion list to 'False'.
            var diff = match1.CompareTo(match2, ignoreCase: true);

            if (diff != 0)
            {
                return(diff);
            }

            // Now, after comparing matches, check if an item wants to be preselected.  If so,
            // we prefer that.  i.e. say the user has typed 'f' and we have the items 'foo'
            // and 'False' (with the latter being 'Preselected').  Both will be a prefix match.
            // And because we are ignoring case, neither will be seen as better.  Now, because
            // 'False' is preselected we pick it even though 'foo' matches 'f' case sensitively.
            diff = item2.Rules.MatchPriority - item1.Rules.MatchPriority;
            if (diff != 0)
            {
                return(diff);
            }

            // At this point we have two items which we're matching in a rather similar fasion.
            // If one is a prefix of the other, prefer the prefix.  i.e. if we have
            // "Table" and "table:=" and the user types 't' and we are in a case insensitive
            // language, then we prefer the former.
            if (item1.DisplayText.Length != item2.DisplayText.Length)
            {
                var comparison = _isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
                if (item2.DisplayText.StartsWith(item1.DisplayText, comparison))
                {
                    return(-1);
                }
                else if (item1.DisplayText.StartsWith(item2.DisplayText, comparison))
                {
                    return(1);
                }
            }

            // Now compare the matches again in a case sensitive manner.  If everything was
            // equal up to this point, we prefer the item that better matches based on case.
            diff = match1.CompareTo(match2, ignoreCase: false);
            if (diff != 0)
            {
                return(diff);
            }

            return(0);
        }
Esempio n. 11
0
        public void あすたりすく()
        {
            Assert.IsTrue(PatternMatch.IsMatch("abcde*", "abcdef"));
            Assert.IsTrue(PatternMatch.IsMatch("*def*", "abcdefghi"));
            Assert.IsTrue(PatternMatch.IsMatch("*abc", "abc"));
            Assert.IsTrue(PatternMatch.IsMatch("*", "123456"));

            Assert.IsFalse(PatternMatch.IsMatch("*abc", "bc"));
            Assert.IsFalse(PatternMatch.IsMatch("*abc*", "ac"));
            Assert.IsFalse(PatternMatch.IsMatch("*abc*", "ab"));
        }
 private PatternSignature(
     IReadOnlyList <string> argumentValues,
     string pathValue,
     string body,
     PatternMatch declaration)
 {
     this.ArgumentValues = argumentValues;
     this.PathValue      = pathValue;
     this.Body           = body;
     this.Declaration    = declaration;
 }
Esempio n. 13
0
 protected override void OnReceive(object message)
 {
     PatternMatch.Match(message)
     .With <ListenerMessage>(l => Listeners.ListenerReceive(l))
     .With <string>(s =>
     {
         if (s.Equals("foo"))
         {
             Listeners.Gossip("bar");
         }
     });
 }
        protected virtual string TransformText(string str, ScenarioContext context)
        {
            if (string.IsNullOrEmpty(str))
            {
                return(str);
            }

            var match = PatternMatch.Parse(str);

            return(match == null ? str
                : TransformText(match.ReplaceMatched(TransformPattern(match.MatchedPattern, context)), context));
        }
Esempio n. 15
0
 protected override void OnReceive(object message)
 {
     PatternMatch.Match(message)
     .With <RegisterTransportActor>(r =>
     {
         /*
          * TODO: need to add support for RemoteDispatcher here.
          * See https://github.com/akka/akka/blob/master/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala#L42
          * and https://github.com/akka/akka/blob/master/akka-remote/src/main/scala/akka/remote/Remoting.scala#L95
          */
         Sender.Tell(Context.ActorOf(r.Props.WithDeploy(Deploy.Local), r.Name));
     });
 }
Esempio n. 16
0
        public int Call(string topic, object[] args)
        {
            var listenCount = 0;

            var rootEvent = false;

            if (bookedEvents == null)
            {
                rootEvent    = true;
                bookedEvents = new List <Action>();
            }

            foreach (ISubscribeEvent se in subscribeEvents)
            {
                if (se.Muting)
                {
                    continue;
                }

                var match = false;
                foreach (string t in se.Topics)
                {
                    if (PatternMatch.IsMatch(t, topic))
                    {
                        match = true;
                        break;
                    }
                }

                if (!match)
                {
                    continue;
                }

                listenCount++;
                se.Call(topic, args);
            }

            if (rootEvent)
            {
                var copied = bookedEvents.ToArray();
                bookedEvents = null;
                foreach (Action e in copied)
                {
                    e();
                }
            }

            return(listenCount);
        }
Esempio n. 17
0
        protected int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            int diff;

            diff = PatternMatch.CompareType(match1, match2);
            if (diff != 0)
            {
                return(diff);
            }

            diff = PatternMatch.CompareCamelCase(match1, match2);
            if (diff != 0)
            {
                return(diff);
            }

            // argument names are not prefered
            if (IsArgumentName(item1) && !IsArgumentName(item2))
            {
                return(1);
            }
            else if (IsArgumentName(item2) && !IsArgumentName(item1))
            {
                return(-1);
            }

            // preselected items are prefered
            if (item1.Rules.Preselect && !item2.Rules.Preselect)
            {
                return(-1);
            }
            else if (item2.Rules.Preselect && !item1.Rules.Preselect)
            {
                return(1);
            }

            diff = PatternMatch.CompareCase(match1, match2);
            if (diff != 0)
            {
                return(diff);
            }

            diff = PatternMatch.ComparePunctuation(match1, match2);
            if (diff != 0)
            {
                return(diff);
            }

            return(0);
        }
Esempio n. 18
0
        /// <summary>
        /// Find all markers in the datagram
        /// </summary>
        /// <param name="data"></param>
        /// <param name="markers"></param>
        /// <returns></returns>
        private static FoundMarker FindDatagramMarker(IEnumerable <byte> data, IEnumerable <Tuple <byte[], Marker> > markers)
        {
            var patternMatchResults = new List <FoundMarker>();
            var aCollection         = data as byte[] ?? data.ToArray();
            var firstOffset         = 0;

            foreach (var marker in markers)
            {
                var offset = marker.Item2.OffsetInStream;
                var result = PatternMatch <byte> .MatchOrMatchPartiallyAtEnd(aCollection, marker.Item1, firstOffset + offset);

                if (!result.NoMatch)
                {
                    if (!patternMatchResults.Any())
                    {
                        firstOffset = result.MatchPos - offset;
                    }
                    patternMatchResults.Add(new FoundMarker(marker.Item1, result, marker.Item2));
                }
                else
                {
                    break; //if we have no marker, then
                }
            }

            if (patternMatchResults.Count == 0)
            {
                return(null);
            }

            if (patternMatchResults.Count > 1)
            {
                // sort results: first the full matches then the partial matches, then by position
                patternMatchResults.Sort((m1, m2) =>
                {
                    if (m1.Result.FullMatch && !m2.Result.FullMatch)
                    {
                        return(-1);
                    }
                    if (m2.Result.FullMatch && !m1.Result.FullMatch)
                    {
                        return(1);
                    }
                    return(m1.Result.MatchPos - m2.Result.MatchPos);
                });
            }

            return(patternMatchResults.First());
        }
Esempio n. 19
0
 /// <summary>
 /// By default, <see cref="Failure"/> is logged at error level and other
 /// reason types are not logged. It is possible to override this behavior.
 /// </summary>
 /// <param name="reason"></param>
 protected virtual void LogTermination(Reason reason)
 {
     PatternMatch.Match(reason)
     .With <Failure>(f =>
     {
         if (f.Cause is Exception)
         {
             _log.Error(f.Cause.AsInstanceOf <Exception>(), "terminating due to Failure");
         }
         else
         {
             _log.Error(f.Cause.ToString());
         }
     });
 }
Esempio n. 20
0
 protected override void OnReceive(object message)
 {
     PatternMatch.Match(message)
     .With <InitializeLogger>(m => Sender.Tell(new LoggerInitialized()))
     .With <Error>(m =>
                   Trace.TraceError(m.ToString()))
     .With <Warning>(m => Trace.TraceWarning(m.ToString()))
     .With <DeadLetter>(m => Trace.TraceWarning(string.Format("Deadletter - unable to send message {0} from {1} to {2}", m.Message, m.Sender, m.Sender), typeof(DeadLetter).ToString()))
     .With <UnhandledMessage>(m => Trace.TraceWarning(string.Format("Unhandled message!"), typeof(UnhandledMessage).ToString()))
     .Default(m =>
     {
         if (m != null)
         {
             Trace.TraceInformation(m.ToString());
         }
     });
 }
Esempio n. 21
0
            protected override void OnReceive(object message)
            {
                PatternMatch.Match(message)
                .With <string>(str =>
                {
                    if (str.Equals("bar"))
                    {
                        _barCount.GetAndIncrement();
                        _barLatch.CountDown();
                    }

                    if (str.Equals("foo"))
                    {
                        _fooLatch.CountDown();
                    }
                });
            }
Esempio n. 22
0
 public static Vector3 TransformVertex(Vector3 vertex, Vector3 refl, PatternMatch match)
 {
     //reflect x
     if (match.invx)
     {
         float y = vertex.y;
         vertex = (2 * Vector3.Dot(refl, vertex) * refl) - vertex;
         vertex = new Vector3(vertex.x, y, vertex.z);
     }
     //reflect y
     if (match.invy)
     {
         vertex = Vector3.Scale(new Vector3(1, -1, 1), vertex);
     }
     //rotate
     vertex = Vx.AxiRot[match.shift] * vertex;
     return(vertex);
 }
Esempio n. 23
0
            private void ReportMatchResult(Project project, INavigateToSearchResult result)
            {
                var matchedSpans = result.NameMatchSpans.SelectAsArray(t => t.ToSpan());

                var patternMatch = new PatternMatch(GetPatternMatchKind(result.MatchKind),
                                                    punctuationStripped: true, result.IsCaseSensitive, matchedSpans);

                var navigateToItem = new NavigateToItem(
                    result.Name,
                    result.Kind,
                    GetNavigateToLanguage(project.Language),
                    result.SecondarySort,
                    result,
                    patternMatch,
                    _displayFactory);

                _callback.AddItem(navigateToItem);
            }
        public static Task <bool> GracefulStop(this ActorRef target, TimeSpan timeout, object stopMessage)
        {
            var internalTarget = target.AsInstanceOf <InternalActorRef>();

            if (internalTarget.IsTerminated)
            {
                return(Task.Run(() => true));
            }

            var provider = Futures.ResolveProvider(target);
            var promise  = new TaskCompletionSource <object>();

            //set up the timeout
            var cancellationSource = new CancellationTokenSource();

            cancellationSource.Token.Register(() => promise.TrySetCanceled());
            cancellationSource.CancelAfter(timeout);

            //create a new tempcontainer path
            var path = provider.TempPath();
            //callback to unregister from tempcontainer
            Action unregister = () => provider.UnregisterTempActor(path);

            var fref = new FutureActorRef(promise, ActorRef.NoSender, unregister, path);

            internalTarget.Tell(new Watch(internalTarget, fref));
            target.Tell(stopMessage, ActorRef.NoSender);
            return(promise.Task.ContinueWith(t =>
            {
                var returnResult = false;
                PatternMatch.Match(t.Result)
                .With <Terminated>(terminated =>
                {
                    returnResult = (terminated.ActorRef.Path.Equals(target.Path));
                })
                .Default(m =>
                {
                    returnResult = false;
                });

                internalTarget.Tell(new Unwatch(target, fref));
                return returnResult;
            }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent));
        }
Esempio n. 25
0
        public void Mute(string topic, bool mute = true)
        {
            if (bookedEvents != null)
            {
                bookedEvents.Add(() => Mute(topic, mute));
                return;
            }

            for (int i = subscribeEvents.Count - 1; i >= 0; --i)
            {
                foreach (string t in subscribeEvents[i].Topics)
                {
                    if (PatternMatch.IsMatch(t, topic))
                    {
                        subscribeEvents[i].Muting = mute;
                    }
                }
            }
        }
Esempio n. 26
0
            protected override void OnReceive(object message)
            {
                PatternMatch.Match(message)
                .With <InitializeLogger>(m =>
                {
                    var bus = m.LoggingBus;
                    bus.Subscribe(this.Self, typeof(SetTarget));
                    bus.Subscribe(this.Self, typeof(UnhandledMessage));

                    Sender.Tell(new LoggerInitialized());
                })
                .With <SetTarget>(m =>
                {
                    dst = m.Ref;
                    dst.Tell("OK");
                })
                .With <LogEvent>(m => dst.Tell(m))
                .With <UnhandledMessage>(m => dst.Tell(m));
            }
Esempio n. 27
0
            private void IntersectPatternMatches(IList <PatternMatch> remains, PatternMatch[] newMatches)
            {
                for (int r = remains.Count - 1; r >= 0; r--)
                {
                    bool intersects = false;
                    foreach (var m in newMatches)
                    {
                        if (remains[r].index == m.index)
                        {
                            intersects = true;
                            remains[r] = new PatternMatch(m.index, Math.Min(remains[r].score, m.score));
                        }
                    }

                    if (!intersects)
                    {
                        remains.RemoveAt(r);
                    }
                }
            }
Esempio n. 28
0
    private int VertexCast(Vector2 viewpos)
    {
        Ray ray = _previewutility.camera.ViewportPointToRay(viewpos);

        if (ray.direction == Vector3.zero || target == null || target.vertices == null)
        {
            return(-1);
        }
        PatternMatch   match          = new PatternMatch(invx, invy, 0);
        float          nearest_t      = Mathf.Infinity;
        int            nearest_sphere = -1;
        float          near_clip      = _previewutility.camera.nearClipPlane;
        float          far_clip       = _previewutility.camera.farClipPlane;
        List <Vector3> vertices       = target.vertices;

        for (int k = 0; k < vertices.Count; k++)
        {
            Vector3 vertex       = Vx.TransformVertex(vertices[k], Vx.ReflVector, match);
            Vector3 point_vector = ray.origin - vertex;
            float   proj_pv      = Vector3.Dot(ray.direction, point_vector);
            float   sqr_magn     = Vector3.SqrMagnitude(point_vector - (proj_pv * ray.direction));
            //check if ray intersects point
            if (sqr_magn > VxlGUI.POINT_RADIUSSQR)
            {
                continue;
            }
            //get t of impact and check if in range
            float t = Mathf.Abs(proj_pv) - Mathf.Sqrt(Mathf.Max(0, VxlGUI.POINT_RADIUSSQR - sqr_magn));
            if (t < near_clip || t > far_clip)
            {
                continue;
            }
            if (t >= nearest_t)
            {
                continue;
            }
            nearest_t      = t;
            nearest_sphere = k;
        }
        return(nearest_sphere);
    }
Esempio n. 29
0
        public void EggsInBasket()
        {
            var eggs   = 2;
            var basket = PatternMatch.Match()
                         .With(() => eggs == 0, "No eggs")
                         .With(() => eggs == 1, "One egg")
                         .With(() => eggs > 1, string.Format("{0} eggs", eggs))
                         .Else("Invalid number of eggs");

            var twoEggs = basket.Do();

            eggs = 0;
            var zeroEggs = basket.Do();

            eggs = int.MinValue;
            var invalidEggs = basket.Do();

            twoEggs.ShouldBe("2 eggs");
            zeroEggs.ShouldBe("No eggs");
            invalidEggs.ShouldBe("Invalid number of eggs");
        }
Esempio n. 30
0
 protected override void OnReceive(object message)
 {
     PatternMatch.Match(message)
     .With <Spawn>(m =>
     {
         Context.ActorOf(Props.Create(() => new KillableActor(testActor)), m.Name);
         testActor.Tell(Tuple.Create("Created", m.Name));
     })
     .With <ContextStop>(m =>
     {
         var child = Context.Child(m.Name);
         Context.Stop(child);
     })
     .With <Stop>(m =>
     {
         var child = Context.Child(m.Name);
         child.Stop();
     })
     .With <Count>(m =>
                   testActor.Tell(Context.GetChildren().Count()));
 }
Esempio n. 31
0
 private void FindAndReplaceBytes()
 {
     if (Result == FileResult.Undefined)
       {
     PatternMatch patternMatch = new PatternMatch(oldData, Bytes);
     if (!patternMatch.Success)
     {
       Logger.Info("{0} The dimensions provided were not found anywhere in the file.", LogPrefix);
       Bytes = new byte[0];
       Result = FileResult.PatternNotFound;
     }
     else
     {
       Logger.Info("{0} Success", LogPrefix);
       Result = FileResult.Success;
       Bytes[patternMatch.Index] = newData[0];
       Bytes[patternMatch.Index + 1] = newData[1];
       Bytes[patternMatch.Index + 2] = newData[2];
       Bytes[patternMatch.Index + 3] = newData[3];
     }
       }
 }
 protected virtual int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
 {
     return match1.CompareTo(match2);
 }
Esempio n. 33
0
        /// <summary>
        /// Internal helper for MatchPatternInternal
        /// </summary>
        /// <remarks>
        /// PERF: Designed to minimize allocations in common cases.
        /// If there's no match, then null is returned.
        /// If there's a single match, or the caller only wants the first match, then it is returned (as a Nullable)
        /// If there are multiple matches, and the caller wants them all, then a List is allocated.
        /// </remarks>
        /// <param name="candidate">The word being tested.</param>
        /// <param name="segment">The segment of the pattern to check against the candidate.</param>
        /// <param name="wantAllMatches">Does the caller want all matches or just the first?</param>
        /// <param name="allMatches">If <paramref name="wantAllMatches"/> is true, and there's more than one match, then the list of all matches.</param>
        /// <returns>If there's only one match, then the return value is that match. Otherwise it is null.</returns>
        private PatternMatch? MatchSegment(string candidate, Segment segment, bool wantAllMatches, out PatternMatch[] allMatches)
        {
            allMatches = null;

            // First check if the segment matches as is.  This is also useful if the segment contains
            // characters we would normally strip when splitting into parts that we also may want to
            // match in the candidate.  For example if the segment is "@int" and the candidate is
            // "@int", then that will show up as an exact match here.
            //
            // Note: if the segment contains a space or an asterisk then we must assume that it's a
            // multi-word segment.
            if (!ContainsSpaceOrAsterisk(segment.TotalTextChunk.Text))
            {
                var match = MatchTextChunk(candidate, segment.TotalTextChunk, punctuationStripped: false);
                if (match != null)
                {
                    return match;
                }
            }

            // The logic for pattern matching is now as follows:
            //
            // 1) Break the segment passed in into words.  Breaking is rather simple and a
            //    good way to think about it that if gives you all the individual alphanumeric words
            //    of the pattern.
            //
            // 2) For each word try to match the word against the candidate value.
            //
            // 3) Matching is as follows:
            //
            //   a) Check if the word matches the candidate entirely, in an case insensitive or
            //    sensitive manner.  If it does, return that there was an exact match.
            //
            //   b) Check if the word is a prefix of the candidate, in a case insensitive or
            //      sensitive manner.  If it does, return that there was a prefix match.
            //
            //   c) If the word is entirely lowercase, then check if it is contained anywhere in the
            //      candidate in a case insensitive manner.  If so, return that there was a substring
            //      match. 
            //
            //      Note: We only have a substring match if the lowercase part is prefix match of
            //      some word part. That way we don't match something like 'Class' when the user
            //      types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
            //      'a').
            //
            //   d) If the word was not entirely lowercase, then check if it is contained in the
            //      candidate in a case *sensitive* manner. If so, return that there was a substring
            //      match.
            //
            //   e) If the word was not entirely lowercase, then attempt a camel cased match as
            //      well.
            //
            //   f) The word is all lower case. Is it a case insensitive substring of the candidate starting 
            //      on a part boundary of the candidate?
            //
            // Only if all words have some sort of match is the pattern considered matched.

            var subWordTextChunks = segment.SubWordTextChunks;
            PatternMatch[] matches = null;

            for (int i = 0; i < subWordTextChunks.Length; i++)
            {
                var subWordTextChunk = subWordTextChunks[i];

                // Try to match the candidate with this word
                var result = MatchTextChunk(candidate, subWordTextChunk, punctuationStripped: true);
                if (result == null)
                {
                    return null;
                }

                if (!wantAllMatches || subWordTextChunks.Length == 1)
                {
                    // Stop at the first word
                    return result;
                }

                matches = matches ?? new PatternMatch[subWordTextChunks.Length];
                matches[i] = result.Value;
            }

            allMatches = matches;
            return null;
        }
Esempio n. 34
0
        protected int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            int diff;

            diff = PatternMatch.CompareType(match1, match2);
            if (diff != 0)
            {
                return diff;
            }

            diff = PatternMatch.CompareCamelCase(match1, match2);
            if (diff != 0)
            {
                return diff;
            }

            // argument names are not prefered
            if (IsArgumentName(item1) && !IsArgumentName(item2))
            {
                return 1;
            }
            else if (IsArgumentName(item2) && !IsArgumentName(item1))
            {
                return -1;
            }

            // preselected items are prefered
            if (item1.Rules.Preselect && !item2.Rules.Preselect)
            {
                return -1;
            }
            else if (item2.Rules.Preselect && !item1.Rules.Preselect)
            {
                return 1;
            }

            diff = PatternMatch.CompareCase(match1, match2);
            if (diff != 0)
            {
                return diff;
            }

            diff = PatternMatch.ComparePunctuation(match1, match2);
            if (diff != 0)
            {
                return diff;
            }

            return 0;
        }
Esempio n. 35
0
        private int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            // First see how the two items compare in a case insensitive fashion.  Matches that 
            // are strictly better (ignoring case) should prioritize the item.  i.e. if we have
            // a prefix match, that should always be better than a substring match.
            //
            // The reason we ignore case is that it's very common for people to type expecting
            // completion to fix up their casing.  i.e. 'false' will be written with the 
            // expectation that it will get fixed by the completion list to 'False'.  
            var diff = match1.CompareTo(match2, ignoreCase: true);
            if (diff != 0)
            {
                return diff;
            }

            // If they both seemed just as good, but they differ on preselection, then
            // item1 is better if it is preselected, otherwise it is worse.
            if (item1.Rules.MatchPriority == MatchPriority.Preselect &&
                item2.Rules.MatchPriority != MatchPriority.Preselect)
            {
                return -1;
            }
            else if (item1.Rules.MatchPriority != MatchPriority.Preselect &&
                     item2.Rules.MatchPriority == MatchPriority.Preselect)
            {
                return 1;
            }

            // At this point we have two items which we're matching in a rather similar fasion.
            // If one is a prefix of the other, prefer the prefix.  i.e. if we have 
            // "Table" and "table:=" and the user types 't' and we are in a case insensitive 
            // language, then we prefer the former.
            if (item1.DisplayText.Length != item2.DisplayText.Length)
            {
                var comparison = _isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
                if (item2.DisplayText.StartsWith(item1.DisplayText, comparison))
                {
                    return -1;
                }
                else if (item1.DisplayText.StartsWith(item2.DisplayText, comparison))
                {
                    return 1;
                }
            }

            // Now compare the matches again in a case sensitive manner.  If everything was
            // equal up to this point, we prefer the item that better matches based on case.
            diff = match1.CompareTo(match2, ignoreCase: false);
            if (diff != 0)
            {
                return diff;
            }

            return 0;
        }
Esempio n. 36
0
        /// <summary>
        /// Internal helper for MatchPatternInternal
        /// </summary>
        /// <remarks>
        /// PERF: Designed to minimize allocations in common cases.
        /// If there's no match, then null is returned.
        /// If there's a single match, or the caller only wants the first match, then it is returned (as a Nullable)
        /// If there are multiple matches, and the caller wants them all, then a List is allocated.
        /// </remarks>
        /// <param name="candidate">The word being tested.</param>
        /// <param name="pattern">The multiple-word query pattern.</param>
        /// <param name="wantAllMatches">Does the caller want all matches or just the first?</param>
        /// <param name="allMatches">If <paramref name="wantAllMatches"/> is true, and there's more than one match, then the list of all matches.</param>
        /// <returns>If there's only one match, then the return value is that match. Otherwise it is null.</returns>
        private PatternMatch? MatchPatternInternal(string candidate, string pattern, bool wantAllMatches, out PatternMatch[] allMatches)
        {
            allMatches = null;

            // We never match whitespace only
            if (string.IsNullOrWhiteSpace(pattern) || string.IsNullOrWhiteSpace(candidate))
            {
                return null;
            }

            // First check if the pattern matches as is.  This is also useful if the pattern contains
            // characters we would normally strip when splitting into parts that we also may want to
            // match in the candidate.  For example if the pattern is "@int" and the candidate is
            // "@int", then that will show up as an exact match here.
            //
            // Note: if the pattern contains a space or an asterisk then we must assume that it's a
            // multi-word pattern.
            if (!ContainsSpaceOrAsterisk(pattern))
            {
                var match = MatchSingleWordPattern(candidate, pattern, punctuationStripped: false);
                if (match != null)
                {
                    return match;
                }
            }

            var patternParts = GetPatternParts(pattern);
            PatternMatch[] matches = null;

            for (int i = 0; i < patternParts.Length; i++)
            {
                var word = patternParts[i];

                // Try to match the candidate with this word
                var result = MatchSingleWordPattern(candidate, word, punctuationStripped: true);
                if (result == null)
                {
                    return null;
                }

                if (!wantAllMatches || patternParts.Length == 1)
                {
                    // Stop at the first word
                    return result;
                }

                if (matches == null)
                {
                    matches = new PatternMatch[patternParts.Length];
                }

                matches[i] = result.Value;
            }

            allMatches = matches;
            return null;
        }
Esempio n. 37
0
        private int CompareMatches(PatternMatch match1, PatternMatch match2, CompletionItem item1, CompletionItem item2)
        {
            // First see how the two items compare in a case insensitive fashion.  Matches that 
            // are strictly better (ignoring case) should prioritize the item.  i.e. if we have
            // a prefix match, that should always be better than a substring match.
            //
            // The reason we ignore case is that it's very common for people to type expecting
            // completion to fix up their casing.  i.e. 'false' will be written with the 
            // expectation that it will get fixed by the completion list to 'False'.  
            var diff = match1.CompareTo(match2, ignoreCase: true);
            if (diff != 0)
            {
                return diff;
            }

            // Now, after comparing matches, check if an item wants to be preselected.  If so,
            // we prefer that.  i.e. say the user has typed 'f' and we have the items 'foo' 
            // and 'False' (with the latter being 'Preselected').  Both will be a prefix match.
            // And because we are ignoring case, neither will be seen as better.  Now, because
            // 'False' is preselected we pick it even though 'foo' matches 'f' case sensitively.
            diff = item2.Rules.MatchPriority - item1.Rules.MatchPriority;
            if (diff != 0)
            {
                return diff;
            }

            // At this point we have two items which we're matching in a rather similar fasion.
            // If one is a prefix of the other, prefer the prefix.  i.e. if we have 
            // "Table" and "table:=" and the user types 't' and we are in a case insensitive 
            // language, then we prefer the former.
            if (item1.DisplayText.Length != item2.DisplayText.Length)
            {
                var comparison = _isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
                if (item2.DisplayText.StartsWith(item1.DisplayText, comparison))
                {
                    return -1;
                }
                else if (item1.DisplayText.StartsWith(item2.DisplayText, comparison))
                {
                    return 1;
                }
            }

            // Now compare the matches again in a case sensitive manner.  If everything was
            // equal up to this point, we prefer the item that better matches based on case.
            diff = match1.CompareTo(match2, ignoreCase: false);
            if (diff != 0)
            {
                return diff;
            }

            return 0;
        }