70 lines
2.4 KiB
C#
70 lines
2.4 KiB
C#
using Microsoft.SqlServer.TransactSql.ScriptDom;
|
|
using SQLLinter.Common;
|
|
using SQLLinter.Common.Helpers;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace SQLLinter.Infrastructure.Rules;
|
|
|
|
/// <summary>
|
|
/// Ожидается наличие BEGIN - END в блоке IF
|
|
/// </summary>
|
|
public class ConditionalBeginEndRule : BaseRuleVisitor, IRule
|
|
{
|
|
private readonly Regex IsWhiteSpaceOrSemiColon = new Regex(@"\s|;", RegexOptions.Compiled);
|
|
|
|
|
|
public override string Text => "Ожидается наличие BEGIN - END в блоке IF";
|
|
|
|
public override void Visit(IfStatement node)
|
|
{
|
|
if (node.ThenStatement is not BeginEndBlockStatement)
|
|
{
|
|
AddViolation(node);
|
|
}
|
|
|
|
if (node.ElseStatement != null && node.ElseStatement is not BeginEndBlockStatement && node.ElseStatement is not IfStatement)
|
|
{
|
|
AddViolation(Name, Text, GetLineNumber(node.ElseStatement), GetColumnNumber(node.ElseStatement));
|
|
}
|
|
}
|
|
|
|
public override void FixViolation(List<string> fileLines, IRuleViolation ruleViolation, FileLineActions actions)
|
|
{
|
|
var ifNode = FixHelpers.FindViolatingNode<IfStatement>(fileLines, ruleViolation);
|
|
TSqlStatement statement;
|
|
|
|
if (ifNode == null)
|
|
{
|
|
(statement, ifNode) = FindElse(fileLines, ruleViolation);
|
|
}
|
|
else
|
|
{
|
|
statement = ifNode.ThenStatement;
|
|
}
|
|
|
|
var stream = statement.ScriptTokenStream;
|
|
var indent = FixHelpers.GetIndent(fileLines, ifNode);
|
|
var beingLine = stream[statement.FirstTokenIndex].Line - 1;
|
|
var ifNodeLastToken = stream[statement.LastTokenIndex];
|
|
var endLine = stream[statement.LastTokenIndex].Line;
|
|
|
|
if (statement.StartLine == ifNodeLastToken.Line)
|
|
{
|
|
var index = statement.LastTokenIndex;
|
|
actions.InsertInLine(statement.StartLine - 1, stream[index].Column, " END");
|
|
actions.InsertInLine(statement.StartLine - 1, statement.StartColumn - 1, "BEGIN ");
|
|
}
|
|
else
|
|
{
|
|
actions.Insert(endLine, $"{indent}END");
|
|
actions.Insert(beingLine, $"{indent}BEGIN");
|
|
}
|
|
|
|
static (TSqlStatement, IfStatement) FindElse(List<string> fileLines, IRuleViolation ruleViolation)
|
|
{
|
|
return FixHelpers.FindViolatingNode<IfStatement, TSqlStatement>(
|
|
fileLines, ruleViolation, x => x.ElseStatement);
|
|
}
|
|
}
|
|
}
|