Files
SQLLint/SQLLinter/Infrastructure/Rules/KeywordCapitalizationRule.cs

60 lines
2.2 KiB
C#

using Microsoft.SqlServer.TransactSql.ScriptDom;
using SQLLinter.Common;
using SQLLinter.Core;
using SQLLinter.Infrastructure.Rules.Common;
using System.Text.RegularExpressions;
namespace SQLLinter.Infrastructure.Rules;
public class KeywordCapitalizationRule : BaseRuleVisitor, IRule
{
public override string Text => "Ожидается, что ключевое слово TSQL будет написано в верхнем регистре: {0}";
public override void Visit(TSqlScript node)
{
var typesToUpcase = Constants.TSqlKeywords.Concat(Constants.TSqlDataTypes).ToArray();
for (var index = 0; index < node.ScriptTokenStream?.Count; index++)
{
var token = node.ScriptTokenStream[index];
if (!typesToUpcase.Contains(token.Text, StringComparer.CurrentCultureIgnoreCase))
{
continue;
}
if (IsUpperCase(token.Text))
{
continue;
}
var dynamicSQLAdjustment = GetDynamicSqlColumnOffset(token);
// получить количество всех вкладок в строке, которые встречаются до последнего токена в этом узле
var tabsOnLine = ColumnNumberCalculator.CountTabsBeforeToken(token.Line, index, node.ScriptTokenStream);
var column = ColumnNumberCalculator.GetColumnNumberBeforeToken(tabsOnLine, token);
AddViolation(Name, GetText(token.Text), GetLineNumber(token), column + dynamicSQLAdjustment);
}
}
public override void FixViolation(List<string> fileLines, IRuleViolation ruleViolation, FileLineActions actions)
{
var lineIndex = ruleViolation.Line - 1;
var line = fileLines[lineIndex];
var startCharIndex = ColumnNumberCalculator.GetIndex(line, ruleViolation.Column);
if (startCharIndex != -1)
{
var errorWord = new Regex(@"\w+").Matches(line[startCharIndex..]).First().Value;
actions.RepaceInlineAt(lineIndex, startCharIndex, errorWord.ToUpper());
}
}
private static bool IsUpperCase(string input)
{
return input.All(t => !char.IsLetter(t) || char.IsUpper(t));
}
}