Exemplo n.º 1
0
        public bool TryGetSingularInvokableMatch(out ITemplateMatchInfo template)
        {
            IReadOnlyList <ITemplateMatchInfo> invokableMatches = _coreMatchedTemplates.Where(x => x.IsInvokableMatch() &&
                                                                                              (_hasUserInputLanguage ||
                                                                                               x.DispositionOfDefaults.Count == 0 ||
                                                                                               x.DispositionOfDefaults.Any(y => y.Location == MatchLocation.DefaultLanguage && y.Kind == MatchKind.Exact))
                                                                                              )
                                                                  .ToList();

            if (invokableMatches.Count == 1)
            {
                template = invokableMatches[0];
                return(true);
            }

            // if multiple templates in the group have single starts with matches on the same parameter, it's ambiguous.
            // For the case where one template has single starts with, and another has ambiguous - on the same param:
            //      The one with single starts with is chosen as invokable because if the template with an ambiguous match
            //      was not installed, the one with the singluar invokable would be chosen.
            HashSet <string> singleStartsWithParamNames = new HashSet <string>();

            foreach (ITemplateMatchInfo checkTemplate in invokableMatches)
            {
                IList <string> singleStartParamNames = checkTemplate.MatchDisposition.Where(x => x.Location == MatchLocation.OtherParameter && x.Kind == MatchKind.SingleStartsWith).Select(x => x.ChoiceIfLocationIsOtherChoice).ToList();
                foreach (string paramName in singleStartParamNames)
                {
                    if (!singleStartsWithParamNames.Add(paramName))
                    {
                        template = null;
                        return(false);
                    }
                }
            }

            ITemplateMatchInfo highestInGroupIfSingleGroup = TemplateListResolver.FindHighestPrecedenceTemplateIfAllSameGroupIdentity(invokableMatches);

            if (highestInGroupIfSingleGroup != null)
            {
                template = highestInGroupIfSingleGroup;
                return(true);
            }

            template = null;
            return(false);
        }
        public bool TryGetSingularInvokableMatch(out ITemplateMatchInfo template, out SingularInvokableMatchCheckStatus resultStatus)
        {
            IReadOnlyList <ITemplateMatchInfo> invokableMatches = _coreMatchedTemplates.Where(x => x.IsInvokableMatch()).ToList();
            IReadOnlyList <ITemplateMatchInfo> languageFilteredInvokableMatches;

            if (_hasUserInputLanguage)
            {
                languageFilteredInvokableMatches = invokableMatches;
            }
            else
            {
                // check for templates with the default language
                languageFilteredInvokableMatches = invokableMatches.Where(x => x.DispositionOfDefaults.Any(y => y.Location == MatchLocation.DefaultLanguage && y.Kind == MatchKind.Exact)).ToList();

                // no candidate templates matched the default language, continue with the original candidates.
                if (languageFilteredInvokableMatches.Count == 0)
                {
                    languageFilteredInvokableMatches = invokableMatches;
                }
            }

            if (languageFilteredInvokableMatches.Count == 1)
            {
                template     = languageFilteredInvokableMatches[0];
                resultStatus = SingularInvokableMatchCheckStatus.SingleMatch;
                return(true);
            }

            // if multiple templates in the group have single starts with matches on the same parameter, it's ambiguous.
            // For the case where one template has single starts with, and another has ambiguous - on the same param:
            //      The one with single starts with is chosen as invokable because if the template with an ambiguous match
            //      was not installed, the one with the singluar invokable would be chosen.
            HashSet <string> singleStartsWithParamNames = new HashSet <string>();

            foreach (ITemplateMatchInfo checkTemplate in languageFilteredInvokableMatches)
            {
                IList <string> singleStartParamNames = checkTemplate.MatchDisposition.Where(x => x.Location == MatchLocation.OtherParameter && x.Kind == MatchKind.SingleStartsWith).Select(x => x.InputParameterName).ToList();
                foreach (string paramName in singleStartParamNames)
                {
                    if (!singleStartsWithParamNames.Add(paramName))
                    {
                        template     = null;
                        resultStatus = SingularInvokableMatchCheckStatus.AmbiguousChoice;
                        return(false);
                    }
                }
            }

            ITemplateMatchInfo highestInGroupIfSingleGroup = TemplateListResolver.FindHighestPrecedenceTemplateIfAllSameGroupIdentity(languageFilteredInvokableMatches, out bool ambiguousGroupIdResult);

            if (highestInGroupIfSingleGroup != null)
            {
                template     = highestInGroupIfSingleGroup;
                resultStatus = SingularInvokableMatchCheckStatus.SingleMatch;
                return(true);
            }
            else if (ambiguousGroupIdResult)
            {
                template     = null;
                resultStatus = SingularInvokableMatchCheckStatus.AmbiguousPrecedence;
                return(false);
            }

            template     = null;
            resultStatus = SingularInvokableMatchCheckStatus.NoMatch;
            return(false);
        }