< Summary

Information
Class: AspxLint.Core.Rules.Ws002MixedIndent
Assembly: AspxLint.Core
File(s): D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Ws002MixedIndent.cs
Line coverage
100%
Covered lines: 16
Uncovered lines: 0
Coverable lines: 16
Total lines: 76
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Id()100%11100%
get_Name()100%11100%
get_Severity()100%11100%
get_Description()100%11100%
get_HasFix()100%11100%
.cctor()100%11100%
Fix(...)100%44100%

File(s)

D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Ws002MixedIndent.cs

#LineLine coverage
 1using System.Text.RegularExpressions;
 2
 3namespace AspxLint.Core.Rules;
 4
 5public sealed class Ws002MixedIndent : IRule
 6{
 2057    public string Id => "WS-002";
 308    public string Name => "Indentation mixte (tabulations + espaces)";
 279    public Severity Severity => Severity.Warning;
 10    public string Description =>
 2511        "Melanger tabulations et espaces dans l'indentation d'un meme fichier rend l'affichage variable selon l'editeur.
 4612    public bool HasFix => true;
 13
 514    private static readonly Regex IndentRegex = new(@"^[ \t]*", RegexOptions.Compiled);
 515    private static readonly Regex LeadingTabRegex = new(@"^\t", RegexOptions.Compiled);
 516    private static readonly Regex LeadingSpacesRegex = new(@"^ +", RegexOptions.Compiled);
 517    private static readonly Regex IndentReplaceRegex = new(@"^[ \t]+", RegexOptions.Compiled);
 18
 19    public IEnumerable<Issue> Detect(string content, string[] lines, RuleContext ctx)
 20    {
 21        bool hasTab = false, hasSpace = false;
 22        foreach (var line in lines)
 23        {
 24            var indent = IndentRegex.Match(line).Value;
 25            if (indent.Contains('\t')) hasTab = true;
 26            if (LeadingSpacesRegex.IsMatch(line)) hasSpace = true;
 27        }
 28        if (!(hasTab && hasSpace)) yield break;
 29
 30        var emitted = false;
 31        for (int i = 0; i < lines.Length; i++)
 32        {
 33            var indent = IndentRegex.Match(lines[i]).Value;
 34            if (indent.Contains('\t') && indent.Contains(' '))
 35            {
 36                emitted = true;
 37                var stripped = lines[i].TrimStart();
 38                yield return new Issue(Id, Name, Severity, i + 1, 1,
 39                    "⇥ + ⎵ " + (stripped.Length <= 50 ? stripped : stripped[..50]),
 40                    "Cette ligne melange tabulations et espaces dans son indentation.");
 41            }
 42        }
 43        if (!emitted)
 44        {
 45            // Aucun melange intra-ligne, mais le fichier melange des lignes-tab et des lignes-espace.
 46            int firstTab = -1, firstSpace = -1;
 47            for (int i = 0; i < lines.Length; i++)
 48            {
 49                if (firstTab < 0 && LeadingTabRegex.IsMatch(lines[i])) firstTab = i;
 50                if (firstSpace < 0 && LeadingSpacesRegex.IsMatch(lines[i])) firstSpace = i;
 51                if (firstTab >= 0 && firstSpace >= 0) break;
 52            }
 53            if (firstTab >= 0)
 54            {
 55                var stripped = lines[firstTab].TrimStart();
 56                yield return new Issue(Id, Name, Severity, firstTab + 1, 1,
 57                    "⇥ " + (stripped.Length <= 50 ? stripped : stripped[..50]),
 58                    $"Le fichier melange indentation par tabulation (ici) et par espaces (ligne {firstSpace + 1}).");
 59            }
 60        }
 61    }
 62
 63    public string? Fix(string content, RuleContext ctx)
 64    {
 65        // Convertit toute tab d'indentation en 4 espaces — ne touche pas aux tabs au milieu d'une ligne.
 2166        var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
 17067        for (int i = 0; i < lines.Length; i++)
 68        {
 6469            var m = IndentReplaceRegex.Match(lines[i]);
 6470            if (!m.Success) continue;
 1671            var indent = m.Value.Replace("\t", "    ");
 1672            lines[i] = indent + lines[i][m.Length..];
 73        }
 2174        return string.Join("\n", lines);
 75    }
 76}