• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kysect / Configuin / 9148112992

19 May 2024 01:43PM UTC coverage: 84.596% (-0.6%) from 85.178%
9148112992

push

github

FrediKats
Replace .editorconfig with DotnetConfig

324 of 432 branches covered (75.0%)

Branch coverage included in aggregate %.

314 of 347 new or added lines in 28 files covered. (90.49%)

2 existing lines in 1 file now uncovered.

1977 of 2288 relevant lines covered (86.41%)

1201.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.34
/Sources/Kysect.Configuin.CodeStyleDoc/CodeStyleGenerator.cs
1
using Kysect.CommonLib.BaseTypes.Extensions;
2
using Kysect.CommonLib.Collections.Extensions;
3
using Kysect.Configuin.CodeStyleDoc.Models;
4
using Kysect.Configuin.Common;
5
using Kysect.Configuin.DotnetConfig.Syntax;
6
using Kysect.Configuin.DotnetConfig.Syntax.Nodes;
7
using Kysect.Configuin.RoslynModels;
8
using Microsoft.Extensions.Logging;
9
using System.Collections.Immutable;
10

11
namespace Kysect.Configuin.CodeStyleDoc;
12

13
public class CodeStyleGenerator : ICodeStyleGenerator
14
{
15
    private readonly ILogger _logger;
16

17
    public CodeStyleGenerator(ILogger logger)
18
    {
19
        _logger = logger;
1✔
20
    }
1✔
21

22
    public CodeStyle Generate(DotnetConfigDocument dotnetConfigDocument, RoslynRules roslynRules)
23
    {
24
        dotnetConfigDocument.ThrowIfNull();
1✔
25
        roslynRules.ThrowIfNull();
1✔
26

27
        _logger.LogInformation("Start code style generating.");
1✔
28

29
        IReadOnlyCollection<RoslynStyleRuleOption> roslynRuleOptions = roslynRules.GetOptions();
1✔
30
        IReadOnlyCollection<IDotnetConfigSyntaxNode> notProcessedSettings = dotnetConfigDocument.DescendantNodes();
1✔
31

32
        _logger.LogInformation("Try parse {count} settings", notProcessedSettings.Count);
1✔
33
        notProcessedSettings = notProcessedSettings.Where(IsSupported).ToImmutableList();
1✔
34

35
        IReadOnlyCollection<CodeStyleRoslynOptionConfiguration> optionConfigurations = notProcessedSettings
1✔
36
            .OfType<DotnetConfigRuleOptionNode>()
1✔
37
            .Select(o => ParseOptionSettings(o, roslynRuleOptions))
107✔
38
            .ToList();
1✔
39
        _logger.LogInformation("Parsed {count} option configurations", optionConfigurations.Count);
1✔
40

41
        notProcessedSettings = notProcessedSettings.Where(r => r is not DotnetConfigRuleOptionNode).ToImmutableList();
359✔
42

43
        IReadOnlyCollection<ICodeStyleElement> ruleConfiguration = notProcessedSettings
1✔
44
            .OfType<DotnetConfigRuleSeverityNode>()
1✔
45
            .Select(severitySetting => ParseRuleSettings(severitySetting, optionConfigurations, roslynRules))
251✔
46
            .ToList();
1✔
47
        _logger.LogInformation("Parsed {count} rule severity", ruleConfiguration.Count);
1✔
48

49
        notProcessedSettings = notProcessedSettings.Where(r => r is not DotnetConfigRuleSeverityNode).ToImmutableList();
252✔
50

51
        if (notProcessedSettings.Any())
1!
52
        {
53
            string unsupportedTypes = notProcessedSettings
×
54
                .Select(r => r.GetType())
×
UNCOV
55
                .Distinct()
×
56
                .ToSingleString();
×
57

UNCOV
58
            throw new ConfiguinException($"Rule type is not supported: {unsupportedTypes}");
×
59
        }
60

61
        return new CodeStyle(ruleConfiguration);
1✔
62
    }
63

64
    private bool IsSupported(IDotnetConfigSyntaxNode setting)
65
    {
66
        if (setting is not IDotnetConfigPropertySyntaxNode)
395✔
67
        {
68
            return false;
3✔
69
        }
70

71
        // TODO: #35 support parsing for this rule 
72
        if (setting is DotnetConfigRuleSeverityNode severityEditorConfigRule
392✔
73
            && severityEditorConfigRule.RuleId.Equals(RoslynRuleId.Parse("IDE1006")))
392✔
74
        {
75
            _logger.LogWarning("Rule IDE1006 is not supported and will be skipped.");
1✔
76
            return false;
1✔
77
        }
78

79
        // TODO: #35 Probably, most of this rules related to IDE1006
80
        if (setting is DotnetConfigRuleCompositeOptionNode compositeSetting)
391✔
81
        {
82
            _logger.LogWarning("{setting} is not supported and will be skipped.", compositeSetting.ToFullString());
30✔
83
            return false;
30✔
84
        }
85

86
        // TODO: Maybe we need to support it in some way
87
        if (setting is DotnetConfigGeneralOptionNode generalSetting)
361✔
88
        {
89
            _logger.LogWarning("{option} is not supported and will be skipped.", generalSetting.ToFullString());
3✔
90
            return false;
3✔
91
        }
92

93
        return true;
358✔
94
    }
95

96
    private CodeStyleRoslynOptionConfiguration ParseOptionSettings(DotnetConfigRuleOptionNode optionDotnetConfigSetting, IReadOnlyCollection<RoslynStyleRuleOption> styleRuleOptions)
97
    {
98
        RoslynStyleRuleOption? roslynStyleRuleOption = styleRuleOptions.SingleOrDefault(o => o.Name == optionDotnetConfigSetting.Key);
12,198✔
99

100
        if (roslynStyleRuleOption is null)
107!
NEW
101
            throw new ConfiguinException($"Option {optionDotnetConfigSetting.Key} was not found in documentation");
×
102

103
        return new CodeStyleRoslynOptionConfiguration(roslynStyleRuleOption, optionDotnetConfigSetting.Value);
107✔
104
    }
105

106
    private ICodeStyleElement ParseRuleSettings(
107
        DotnetConfigRuleSeverityNode severityDotnetConfigSetting,
108
        IReadOnlyCollection<CodeStyleRoslynOptionConfiguration> optionConfigurations,
109
        RoslynRules roslynRules)
110
    {
111
        RoslynStyleRuleGroup? ruleGroup = roslynRules.StyleRuleGroups.SingleOrDefault(g => g.Rules.Any(r => r.RuleId.Equals(severityDotnetConfigSetting.RuleId)));
51,446✔
112

113
        if (ruleGroup is not null)
251✔
114
        {
115
            RoslynStyleRule rule = ruleGroup.Rules.Single(r => r.RuleId.Equals(severityDotnetConfigSetting.RuleId));
167✔
116
            var options = ruleGroup
75✔
117
                .Options
75✔
118
                .Select(o => FindOptionConfiguration(optionConfigurations, o.Name))
117✔
119
                .WhereNotNull()
75✔
120
                .ToList();
75✔
121

122
            return new CodeStyleRoslynStyleRuleConfiguration(rule, severityDotnetConfigSetting.ParseSeverity(), options, ruleGroup.Overview, ruleGroup.Example);
75✔
123
        }
124

125
        RoslynQualityRule? roslynQualityRule = roslynRules.QualityRules.FirstOrDefault(q => q.RuleId.Equals(severityDotnetConfigSetting.RuleId));
27,262✔
126
        if (roslynQualityRule is not null)
176!
127
        {
128
            return new CodeStyleRoslynQualityRuleConfiguration(roslynQualityRule, severityDotnetConfigSetting.ParseSeverity());
176✔
129
        }
130

NEW
131
        throw new ConfiguinException($"Rule with id {severityDotnetConfigSetting.RuleId} was not found");
×
132
    }
133

134
    private CodeStyleRoslynOptionConfiguration? FindOptionConfiguration(
135
        IReadOnlyCollection<CodeStyleRoslynOptionConfiguration> optionConfigurations,
136
        string name)
137
    {
138
        return optionConfigurations.FirstOrDefault(o => o.Option.Name == name);
5,720✔
139
    }
140
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc