using System.Collections.Generic; using System.Linq; namespace QFSW.QC { /// /// An IQcSuggestor that caches the created IQcSuggestion objects /// /// The item type that suggestions are produced from. public abstract class BasicCachedQcSuggestor : IQcSuggestor { private readonly Dictionary _suggestionCache = new Dictionary(); /// /// If suggestions can be produced for the provided context. /// /// /// Options used by the suggestor. /// If suggestions can be produced. protected abstract bool CanProvideSuggestions(SuggestionContext context, SuggestorOptions options); /// /// Converts an item to a suggestion. /// /// The item to convert to a suggestion. /// The converted suggestion. protected abstract IQcSuggestion ItemToSuggestion(TItem item); /// /// Gets the items for a given context. /// /// The context to produce items for. /// Options used by the suggestor. /// The items produced. protected abstract IEnumerable GetItems(SuggestionContext context, SuggestorOptions options); /// /// Determines if the provided suggestion matches the provided context. /// Override to remove the filtering or add custom filtering. /// /// The context to test the suggestion against. /// The suggestion to test. /// Options used to test the suggestion. /// If the suggestion matches the context. protected virtual bool IsMatch(SuggestionContext context, IQcSuggestion suggestion, SuggestorOptions options) { return SuggestorUtilities.IsCompatible(context.Prompt, suggestion.PrimarySignature, options); } public IEnumerable GetSuggestions(SuggestionContext context, SuggestorOptions options) { if (!CanProvideSuggestions(context, options)) { return Enumerable.Empty(); } return GetItems(context, options) .Select(ItemToSuggestionCached) .Where(suggestion => IsMatch(context, suggestion, options)); } private IQcSuggestion ItemToSuggestionCached(TItem item) { if (_suggestionCache.TryGetValue(item, out IQcSuggestion suggestion)) { return suggestion; } return _suggestionCache[item] = ItemToSuggestion(item); } } }