using Microsoft.SqlServer.TransactSql.ScriptDom; using SQLLinter.Common; namespace SQLLinter.Infrastructure.Rules; public class InnerJoinRule : BaseRuleVisitor { public override string Text => "Используйте полную запись INNER JOIN."; public override void Visit(QualifiedJoin node) { if (node.QualifiedJoinType != QualifiedJoinType.Inner) return; var tokens = node.ScriptTokenStream; if (tokens == null) return; var secondIndex = node.SecondTableReference.FirstTokenIndex; int start = node.FirstTableReference.LastTokenIndex; int end = node.SecondTableReference.FirstTokenIndex; bool hasInner = tokens .Skip(start) .Take(end - start + 1) .Any(t => t.TokenType == TSqlTokenType.Inner); if (!hasInner) { var joinToken = tokens .Skip(start) .Take(end - start + 1) .FirstOrDefault(t => t.TokenType == TSqlTokenType.Join); if (joinToken != null) { AddViolation(Name, Text, joinToken.Line, joinToken.Column); } else { AddViolation(node); } } } }