internal bool TryGetHighestPrecedenceInvokableTemplate(out ITemplateMatchInfo?highestPrecedenceTemplate, bool useDefaultLanguage = false)
        {
            highestPrecedenceTemplate = null;
            if (!InvokableTemplates.Any())
            {
                return(false);
            }
            IEnumerable <ITemplateMatchInfo> highestPrecendenceTemplates = GetHighestPrecedenceInvokableTemplates(useDefaultLanguage);

            if (highestPrecendenceTemplates.Count() == 1)
            {
                highestPrecedenceTemplate = highestPrecendenceTemplates.First();
                return(true);
            }
            return(false);
        }
        internal IEnumerable <ITemplateMatchInfo> GetHighestPrecedenceInvokableTemplates(bool useDefaultLanguage = false)
        {
            IEnumerable <ITemplateMatchInfo> highestPrecedenceTemplates;

            if (!InvokableTemplates.Any())
            {
                return(new List <ITemplateMatchInfo>());
            }

            int highestPrecedence = InvokableTemplates.Max(t => t.Info.Precedence);

            highestPrecedenceTemplates = InvokableTemplates.Where(t => t.Info.Precedence == highestPrecedence);

            if (useDefaultLanguage && highestPrecedenceTemplates.Count() > 1)
            {
                IEnumerable <ITemplateMatchInfo> highestPrecedenceTemplatesForDefaultLanguage = highestPrecedenceTemplates.Where(t => t.HasDefaultLanguageMatch());
                if (highestPrecedenceTemplatesForDefaultLanguage.Any())
                {
                    return(highestPrecedenceTemplatesForDefaultLanguage);
                }
            }
            return(highestPrecedenceTemplates);
        }
        internal IEnumerable <InvalidParameterInfo> GetInvalidParameterList()
        {
            List <InvalidParameterInfo> invalidParameterList = new List <InvalidParameterInfo>();

            //collect the parameters which have ambiguous value match in all templates in the template group
            IEnumerable <ParameterMatchInfo> ambiguousParametersForTemplates = Templates.SelectMany(template => template.MatchDisposition
                                                                                                    .OfType <ParameterMatchInfo>()
                               //https://github.com/dotnet/templating/issues/2494
                               //after tab completion is implemented we no longer will be using this match kind - only exact matches will be allowed
#pragma warning disable CS0618 // Type or member is obsolete
                                                                                                    .Where(x => x.Kind == MatchKind.AmbiguousValue))
#pragma warning restore CS0618 // Type or member is obsolete
                                                                               .Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (ParameterMatchInfo parameter in ambiguousParametersForTemplates)
            {
                invalidParameterList.Add(new InvalidParameterInfo(
                                             InvalidParameterInfo.Kind.AmbiguousParameterValue,
                                             parameter.InputFormat,
                                             parameter.Value,
                                             parameter.Name));
            }

            if (InvokableTemplates.Any())
            {
                //add the parameters that have single starts with match in several invokable templates in template group
                return(invalidParameterList.Union(GetAmbiguousSingleStartsWithParameters()).ToList());
            }

            //collect the parameters with invalid names for all templates in the template group
            IEnumerable <ParameterMatchInfo> parametersWithInvalidNames = Templates.SelectMany(
                template => template.MatchDisposition
                .OfType <ParameterMatchInfo>()
                .Where(x => x.Kind == MatchKind.InvalidName)).Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (ParameterMatchInfo parameter in parametersWithInvalidNames)
            {
                if (Templates.All(
                        template => template.MatchDisposition
                        .OfType <ParameterMatchInfo>()
                        .Any(x => x.Kind == MatchKind.InvalidName &&
                             x.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase))))
                {
                    invalidParameterList.Add(new InvalidParameterInfo(
                                                 InvalidParameterInfo.Kind.InvalidParameterName,
                                                 parameter.InputFormat,
                                                 parameter.Value,
                                                 parameter.Name));
                }
            }

            //if there are templates which have a match for all template specific parameters, only they to be analyzed
            var filteredTemplates = Templates.Where(template => !template.HasInvalidParameterName());

            if (!filteredTemplates.Any())
            {
                filteredTemplates = Templates;
            }

            //collect the choice parameters with invalid values
            IEnumerable <ParameterMatchInfo> invalidParameterValuesForTemplates = filteredTemplates.SelectMany(
                template => template.MatchDisposition
                .OfType <ParameterMatchInfo>()
                .Where(x => x.Kind == MatchKind.InvalidValue))
                                                                                  .Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (ParameterMatchInfo parameter in invalidParameterValuesForTemplates)
            {
                if (filteredTemplates.All(
                        template => template.MatchDisposition
                        .OfType <ParameterMatchInfo>()
                        .Any(x => x.Kind == MatchKind.InvalidValue &&
                             x.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase))))
                {
                    invalidParameterList.Add(new InvalidParameterInfo(
                                                 InvalidParameterInfo.Kind.InvalidParameterValue,
                                                 parameter.InputFormat,
                                                 parameter.Value,
                                                 parameter.Name));
                }
            }

            return(invalidParameterList);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns the invalid template specific parameters for the template group.
        /// Invalid parameters can have: invalid name, invalid value (determined only for choice parameter symbols), ambiguous value (determined only for choice parameter symbols)
        /// </summary>
        /// <returns>The enumerator for invalid parameters in templates in the template group</returns>
        internal IEnumerable <InvalidParameterInfo> GetInvalidParameterList()
        {
            List <InvalidParameterInfo> invalidParameterList = new List <InvalidParameterInfo>();

            //collect the parameters which have ambiguous value match in all templates in the template group
            IEnumerable <MatchInfo> ambiguousParametersForTemplates = Templates.SelectMany(template => template.MatchDisposition.Where(x => x.Location == MatchLocation.OtherParameter &&
                                                                                                                                       x.Kind == MatchKind.AmbiguousParameterValue)).Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (MatchInfo parameter in ambiguousParametersForTemplates)
            {
                invalidParameterList.Add(new InvalidParameterInfo(
                                             InvalidParameterInfo.Kind.AmbiguousParameterValue,
                                             parameter.InputParameterFormat,
                                             parameter.ParameterValue,
                                             parameter.InputParameterName));
            }

            if (InvokableTemplates.Any())
            {
                //add the parameters that have single starts with match in several invokable templates in template group
                return(invalidParameterList.Union(GetAmbiguousSingleStartsWithParameters()).ToList());
            }

            //collect the parameters with invalid names for all templates in the template group
            IEnumerable <MatchInfo> parametersWithInvalidNames = Templates.SelectMany(template => template.MatchDisposition.Where(x => x.Location == MatchLocation.OtherParameter &&
                                                                                                                                  x.Kind == MatchKind.InvalidParameterName)).Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (MatchInfo parameter in parametersWithInvalidNames)
            {
                if (Templates.All(
                        template => template.MatchDisposition.Any(x => x.Location == MatchLocation.OtherParameter &&
                                                                  x.Kind == MatchKind.InvalidParameterName &&
                                                                  x.InputParameterName.Equals(parameter.InputParameterName, StringComparison.OrdinalIgnoreCase))))
                {
                    invalidParameterList.Add(new InvalidParameterInfo(
                                                 InvalidParameterInfo.Kind.InvalidParameterName,
                                                 parameter.InputParameterFormat,
                                                 parameter.ParameterValue,
                                                 parameter.InputParameterName));
                }
            }

            //if there are templates which have a match for all template specific parameters, only they to be analyzed
            var filteredTemplates = Templates.Where(template => !template.HasInvalidParameterName());

            if (!filteredTemplates.Any())
            {
                filteredTemplates = Templates;
            }

            //collect the choice parameters with invalid values
            IEnumerable <MatchInfo> invalidParameterValuesForTemplates = filteredTemplates.SelectMany(template => template.MatchDisposition.Where(x => x.Location == MatchLocation.OtherParameter &&
                                                                                                                                                  x.Kind == MatchKind.InvalidParameterValue)).Distinct(new OrdinalIgnoreCaseMatchInfoComparer());

            foreach (MatchInfo parameter in invalidParameterValuesForTemplates)
            {
                if (filteredTemplates.All(
                        template => template.MatchDisposition.Any(x => x.Location == MatchLocation.OtherParameter &&
                                                                  x.Kind == MatchKind.InvalidParameterValue &&
                                                                  x.InputParameterName.Equals(parameter.InputParameterName, StringComparison.OrdinalIgnoreCase))))
                {
                    invalidParameterList.Add(new InvalidParameterInfo(
                                                 InvalidParameterInfo.Kind.InvalidParameterValue,
                                                 parameter.InputParameterFormat,
                                                 parameter.ParameterValue,
                                                 parameter.InputParameterName));
                }
            }

            return(invalidParameterList);
        }