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