using SQLLinter.Common; using SQLLinter.Core; using SQLLinter.Core.Interfaces; using System.Text.RegularExpressions; namespace SQLLinter.Infrastructure.Rules.RuleExceptions { public class RuleExceptionFinder : IRuleExceptionFinder { public static Regex RuleExceptionRegex = new Regex(@"(sqllinter-(?:dis|en)able)\s*(.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private readonly IDictionary Rules; public RuleExceptionFinder(IDictionary rules) { Rules = rules; } public IEnumerable GetIgnoredRuleList(Stream fileStream) { var ruleExceptionList = new List(); TextReader reader = new StreamReader(fileStream); var lineNumber = 0; string line; while ((line = reader.ReadLine()) != null) { lineNumber++; if (line.Length > Constants.MaxLineWidthForRegexEval || !line.Contains("sqllinter-")) { continue; } var match = RuleExceptionRegex.Match(line); if (!match.Success) { continue; } FindIgnoredRules(ruleExceptionList, lineNumber, match); } fileStream.Seek(0, SeekOrigin.Begin); foreach (var ruleException in ruleExceptionList) { if (ruleException.EndLine == 0) { ruleException.SetEndLine(lineNumber); } } return ruleExceptionList; } private void FindIgnoredRules(ICollection ruleExceptionList, int lineNumber, Match match) { var action = match.Groups[1].Value; var disableCommand = action.Equals("sqllinter-disable", StringComparison.OrdinalIgnoreCase); var enableCommand = action.Equals("sqllinter-enable", StringComparison.OrdinalIgnoreCase); var ruleExceptionDetails = match.Groups[2].Value.Split(' ').Select(p => p.Trim()).ToList(); var matchedFriendlyNames = ruleExceptionDetails.Intersect(Rules.Keys).ToList(); if (!matchedFriendlyNames.Any()) { if (disableCommand) { var ruleException = new GlobalRuleException(lineNumber, 0); ruleExceptionList.Add(ruleException); } if (enableCommand) { var ruleException = ruleExceptionList.OfType().FirstOrDefault(r => r.EndLine == 0); ruleException?.SetEndLine(lineNumber); } } foreach (var matchedFriendlyName in matchedFriendlyNames) { Rules.TryGetValue(matchedFriendlyName, out var matched); if (disableCommand) { var ruleException = new RuleException(matched.GetType(), matchedFriendlyName, lineNumber, 0); ruleExceptionList.Add(ruleException); } if (enableCommand) { var ruleException = ruleExceptionList.OfType().FirstOrDefault(r => r.RuleName == matchedFriendlyName && r.EndLine == 0); ruleException?.SetEndLine(lineNumber); } } } } }