protected virtual IEnumerable <(QueryToken token, ImmutableStack <OmniboxMatch> stack)> GetAmbiguousTokens(QueryToken?queryToken, ImmutableStack <OmniboxMatch> distancePack,
                                                                                                                   QueryDescription queryDescription, List <OmniboxToken> omniboxTokens, int index, int operatorIndex)
        {
            OmniboxToken omniboxToken = omniboxTokens[index];

            bool isPascal = OmniboxUtils.IsPascalCasePattern(omniboxToken.Value);

            var dic     = QueryUtils.SubTokens(queryToken, queryDescription, SubTokensOptions.CanAnyAll | SubTokensOptions.CanElement).ToOmniboxPascalDictionary(qt => qt.ToString(), qt => qt);
            var matches = OmniboxUtils.Matches(dic, qt => qt.IsAllowed() == null, omniboxToken.Value, isPascal);

            if (index == operatorIndex - 1)
            {
                foreach (var m in matches)
                {
                    var token = (QueryToken)m.Value;
                    yield return(token : token, stack : distancePack.Push(m));
                }
            }
            else
            {
                foreach (var m in matches)
                {
                    foreach (var newPair in GetAmbiguousTokens((QueryToken)m.Value, distancePack.Push(m), queryDescription, omniboxTokens, index + 2, operatorIndex))
                    {
                        yield return(newPair);
                    }
                }
            }
        }
Esempio n. 2
0
        public override IEnumerable <SpecialOmniboxResult> GetResults(string rawQuery, List <OmniboxToken> tokens, string tokenPattern)
        {
            if (!regex.IsMatch(tokenPattern))
            {
                return(Enumerable.Empty <SpecialOmniboxResult>());
            }

            string ident = tokens.Count == 1 ? "" : tokens[1].Value;

            bool isPascalCase = OmniboxUtils.IsPascalCasePattern(ident);

            return(OmniboxUtils.Matches(Actions, a => a.Allowed(), ident, isPascalCase)
                   .Select(m => new SpecialOmniboxResult {
                Match = m, Distance = m.Distance
            }));
        }
Esempio n. 3
0
        public override IEnumerable <DynamicQueryOmniboxResult> GetResults(string rawQuery, List <OmniboxToken> tokens, string tokenPattern)
        {
            Match m = regex.Match(tokenPattern);

            if (!m.Success)
            {
                yield break;
            }

            string pattern = tokens[0].Value;

            bool isPascalCase = OmniboxUtils.IsPascalCasePattern(pattern);

            List <FilterSyntax>?syntaxSequence = null;

            foreach (var match in OmniboxUtils.Matches(OmniboxParser.Manager.GetQueries(), OmniboxParser.Manager.AllowedQuery, pattern, isPascalCase).OrderBy(ma => ma.Distance))
            {
                var queryName = match.Value;

                if (syntaxSequence == null)
                {
                    syntaxSequence = SyntaxSequence(m);
                }

                if (syntaxSequence.Any())
                {
                    QueryDescription description = OmniboxParser.Manager.GetDescription(match.Value);

                    IEnumerable <IEnumerable <OmniboxFilterResult> > bruteFilters = syntaxSequence.Select(a => GetFilterQueries(rawQuery, description, a, tokens));

                    foreach (var list in bruteFilters.CartesianProduct())
                    {
                        yield return(new DynamicQueryOmniboxResult
                        {
                            QueryName = match.Value,
                            QueryNameMatch = match,
                            Distance = match.Distance + list.Average(a => a.Distance),
                            Filters = list.ToList(),
                        });
                    }
                }
                else
                {
                    if (match.Text == pattern && tokens.Count == 1 && tokens[0].Next(rawQuery) == ' ')
                    {
                        QueryDescription description = OmniboxParser.Manager.GetDescription(match.Value);

                        foreach (var qt in QueryUtils.SubTokens(null, description, SubTokensOptions.CanAnyAll | SubTokensOptions.CanElement))
                        {
                            yield return(new DynamicQueryOmniboxResult
                            {
                                QueryName = match.Value,
                                QueryNameMatch = match,
                                Distance = match.Distance,
                                Filters = new List <OmniboxFilterResult> {
                                    new OmniboxFilterResult(0, null, qt, null)
                                },
                            });
                        }
                    }
                    else
                    {
                        yield return(new DynamicQueryOmniboxResult
                        {
                            QueryName = match.Value,
                            QueryNameMatch = match,
                            Distance = match.Distance,
                            Filters = new List <OmniboxFilterResult>()
                        });
                    }
                }
            }
        }
        public override IEnumerable <EntityOmniboxResult> GetResults(string rawQuery, List <OmniboxToken> tokens, string tokenPattern)
        {
            Match m = regex.Match(tokenPattern);

            if (!m.Success)
            {
                yield break;
            }

            string ident = tokens[0].Value;

            bool isPascalCase = OmniboxUtils.IsPascalCasePattern(ident);


            var matches = OmniboxUtils.Matches(OmniboxParser.Manager.Types(), OmniboxParser.Manager.AllowedType, ident, isPascalCase);

            if (tokens.Count == 1)
            {
                yield break;
            }
            else if (tokens[1].Type == OmniboxTokenType.Number || tokens[1].Type == OmniboxTokenType.Guid)
            {
                foreach (var match in matches.OrderBy(ma => ma.Distance))
                {
                    Type type = (Type)match.Value;

                    if (PrimaryKey.TryParse(tokens[1].Value, type, out PrimaryKey id))
                    {
                        Lite <Entity>?lite = OmniboxParser.Manager.RetrieveLite(type, id);

                        yield return(new EntityOmniboxResult
                        {
                            Type = (Type)match.Value,
                            TypeMatch = match,
                            Id = id,
                            Lite = lite,
                            Distance = match.Distance,
                        });
                    }
                }
            }
            else if (tokens[1].Type == OmniboxTokenType.String)
            {
                string pattern = OmniboxUtils.CleanCommas(tokens[1].Value);

                foreach (var match in matches.OrderBy(ma => ma.Distance))
                {
                    var autoComplete = OmniboxParser.Manager.Autocomplete((Type)match.Value, pattern, AutoCompleteLimit);

                    if (autoComplete.Any())
                    {
                        foreach (Lite <Entity> lite in autoComplete)
                        {
                            OmniboxMatch?distance = OmniboxUtils.Contains(lite, lite.ToString() ?? "", pattern);

                            if (distance != null)
                            {
                                yield return new EntityOmniboxResult
                                       {
                                           Type       = (Type)match.Value,
                                           TypeMatch  = match,
                                           ToStr      = pattern,
                                           Lite       = lite,
                                           Distance   = match.Distance + distance.Distance,
                                           ToStrMatch = distance,
                                       }
                            }
                            ;
                        }
                    }
                    else
                    {
                        yield return(new EntityOmniboxResult
                        {
                            Type = (Type)match.Value,
                            TypeMatch = match,
                            Distance = match.Distance + 100,
                            ToStr = pattern,
                        });
                    }
                }
            }
        }
        protected virtual ValueTuple[] GetValues(QueryToken queryToken, OmniboxToken omniboxToken)
        {
            if (omniboxToken.IsNull())
            {
                return new[] { new ValueTuple {
                                   Value = null, Match = null
                               } }
            }
            ;

            var ft = QueryUtils.GetFilterType(queryToken.Type);

            switch (ft)
            {
            case FilterType.Integer:
            case FilterType.Decimal:
                if (omniboxToken.Type == OmniboxTokenType.Number)
                {
                    if (ReflectionTools.TryParse(omniboxToken.Value, queryToken.Type, out object?result))
                    {
                        return new[] { new ValueTuple {
                                           Value = result, Match = null
                                       } }
                    }
                    ;
                }
                break;

            case FilterType.String:
                if (omniboxToken.Type == OmniboxTokenType.String)
                {
                    return new[] { new ValueTuple {
                                       Value = OmniboxUtils.CleanCommas(omniboxToken.Value), Match = null
                                   } }
                }
                ;
                break;

            case FilterType.DateTime:
                if (omniboxToken.Type == OmniboxTokenType.String)
                {
                    var str = OmniboxUtils.CleanCommas(omniboxToken.Value);

                    if (ReflectionTools.TryParse(str, queryToken.Type, out object?result))
                    {
                        return new[] { new ValueTuple {
                                           Value = result, Match = null
                                       } }
                    }
                    ;
                }
                break;

            case FilterType.Lite:
                if (omniboxToken.Type == OmniboxTokenType.String)
                {
                    var patten = OmniboxUtils.CleanCommas(omniboxToken.Value);

                    var result = OmniboxParser.Manager.Autocomplete(queryToken.GetImplementations() !.Value, patten, AutoCompleteLimit);

                    return(result.Select(lite => new ValueTuple {
                        Value = lite, Match = OmniboxUtils.Contains(lite, lite.ToString(), patten)
                    }).ToArray());
                }
                else if (omniboxToken.Type == OmniboxTokenType.Entity)
                {
                    var error = Lite.TryParseLite(omniboxToken.Value, out Lite <Entity>?lite);
                    if (string.IsNullOrEmpty(error))
                    {
                        return new [] { new ValueTuple {
                                            Value = lite
                                        } }
                    }
                    ;
                }
                else if (omniboxToken.Type == OmniboxTokenType.Number)
                {
                    var imp = queryToken.GetImplementations() !.Value;

                    if (!imp.IsByAll)
                    {
                        return(imp.Types.Select(t => CreateLite(t, omniboxToken.Value))
                               .NotNull().Select(t => new ValueTuple {
                            Value = t
                        }).ToArray());
                    }
                }
                break;

            case FilterType.Embedded:
            case FilterType.Boolean:
                bool?boolean = ParseBool(omniboxToken.Value);
                if (boolean.HasValue)
                {
                    return new [] { new ValueTuple {
                                        Value = boolean.Value
                                    } }
                }
                ;
                break;

            case FilterType.Enum:
                if (omniboxToken.Type == OmniboxTokenType.String ||
                    omniboxToken.Type == OmniboxTokenType.Identifier)
                {
                    string value = omniboxToken.Type == OmniboxTokenType.Identifier ? omniboxToken.Value : OmniboxUtils.CleanCommas(omniboxToken.Value);

                    bool isPascalValue = OmniboxUtils.IsPascalCasePattern(value);
                    Type enumType      = queryToken.Type.UnNullify();
                    var  dic           = EnumEntity.GetValues(enumType).ToOmniboxPascalDictionary(a => a.NiceToString(), a => (object)a);

                    var result = OmniboxUtils.Matches(dic, e => true, value, isPascalValue)
                                 .Select(m => new ValueTuple {
                        Value = m.Value, Match = m
                    })
                                 .ToArray();

                    return(result);
                }
                break;

            case FilterType.Guid:
                if (omniboxToken.Type == OmniboxTokenType.Guid)
                {
                    if (Guid.TryParse(omniboxToken.Value, out Guid result))
                    {
                        return new[] { new ValueTuple {
                                           Value = result, Match = null
                                       } }
                    }
                    ;
                }
                else if (omniboxToken.Type == OmniboxTokenType.String)
                {
                    var str = OmniboxUtils.CleanCommas(omniboxToken.Value);
                    if (Guid.TryParse(str, out Guid result))
                    {
                        return new[] { new ValueTuple {
                                           Value = result, Match = null
                                       } }
                    }
                    ;
                }
                break;

            default:
                break;
            }

            return(new[] { new ValueTuple {
                               Value = UnknownValue, Match = null
                           } });
        }

        Lite <Entity>?CreateLite(Type type, string value)
        {
            if (PrimaryKey.TryParse(value, type, out PrimaryKey id))
            {
                return(Lite.Create(type, id, "{0} {1}".FormatWith(type.NiceName(), id)));
            }

            return(null);
        }

        bool?ParseBool(string val)
        {
            val = val.ToLower().RemoveDiacritics();

            if (val == "true" || val == "t" || val == "yes" || val == "y" || val == OmniboxMessage.Yes.NiceToString())
            {
                return(true);
            }

            if (val == "false" || val == "f" || val == "no" || val == "n" || val == OmniboxMessage.No.NiceToString())
            {
                return(false);
            }

            return(null);
        }