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