예제 #1
0
        public IAnalysisIssue Convert(Message cFamilyIssue, string sqLanguage, ICFamilyRulesConfig rulesConfiguration)
        {
            // Lines and character positions are 1-based
            Debug.Assert(cFamilyIssue.Line > 0);

            // BUT special case of EndLine=0, Column=0, EndColumn=0 meaning "select the whole line"
            Debug.Assert(cFamilyIssue.EndLine >= 0);
            Debug.Assert(cFamilyIssue.Column > 0 || cFamilyIssue.Column == 0);
            Debug.Assert(cFamilyIssue.EndColumn > 0 || cFamilyIssue.EndLine == 0);

            // Look up default severity and type
            var defaultSeverity = rulesConfiguration.RulesMetadata[cFamilyIssue.RuleKey].DefaultSeverity;
            var defaultType     = rulesConfiguration.RulesMetadata[cFamilyIssue.RuleKey].Type;

            var fileContents = LoadFileContentsOfReportedFiles(cFamilyIssue);

            var locations = cFamilyIssue.Parts
                            .Select(x => ToAnalysisIssueLocation(x, fileContents))
                            .ToArray();

            // If PartsMakeFlow is set to true the issues are expected to be in the reversed order
            if (locations != null && cFamilyIssue.PartsMakeFlow)
            {
                Array.Reverse(locations);
            }
            var flows = locations.Any() ? new[] { new AnalysisIssueFlow(locations) } : null;

            return(ToAnalysisIssue(cFamilyIssue, sqLanguage, defaultSeverity, defaultType, flows, fileContents));
        }
        public ICFamilyRulesConfig GetEffectiveRulesConfig(string languageKey, ICFamilyRulesConfig defaultRulesConfig, UserSettings userSettings)
        {
            if (defaultRulesConfig == null)
            {
                throw new ArgumentNullException(nameof(defaultRulesConfig));
            }

            // Optimisation - if there are no user-specified rules settings then just return the default
            if ((userSettings?.Rules?.Count ?? 0) == 0)
            {
                logger.WriteLine(CoreStrings.EffectiveRules_NoUserSettings);
                return(defaultRulesConfig);
            }

            var effectiveConfig = configCache.FindConfig(languageKey, defaultRulesConfig, userSettings);

            if (effectiveConfig != null)
            {
                logger.WriteLine(CoreStrings.EffectiveRules_CacheHit);
            }
            else
            {
                logger.WriteLine(CoreStrings.EffectiveRules_CacheMiss);
                effectiveConfig = new DynamicCFamilyRulesConfig(defaultRulesConfig, userSettings);
                configCache.Add(languageKey, defaultRulesConfig, userSettings, effectiveConfig);
            }

            return(effectiveConfig);
        }
        public ICFamilyRulesConfig GetEffectiveRulesConfig(string languageKey, ICFamilyRulesConfig defaultRulesConfig, RulesSettings customSettings)
        {
            if (languageKey == null)
            {
                throw new ArgumentNullException(nameof(languageKey));
            }
            if (defaultRulesConfig == null)
            {
                throw new ArgumentNullException(nameof(defaultRulesConfig));
            }
            if (customSettings == null)
            {
                throw new ArgumentNullException(nameof(customSettings));
            }

            var effectiveConfig = configCache.FindConfig(languageKey, defaultRulesConfig, customSettings);

            if (effectiveConfig != null)
            {
                logger.WriteLine(CoreStrings.EffectiveRules_CacheHit);
                return(effectiveConfig);
            }

            logger.WriteLine(CoreStrings.EffectiveRules_CacheMiss);

            effectiveConfig = new DynamicCFamilyRulesConfig(defaultRulesConfig, customSettings, logger);

            configCache.Add(languageKey, defaultRulesConfig, customSettings, effectiveConfig);

            return(effectiveConfig);
        }
        internal /* for testing */ static string[] GetKeyValueOptionsList(ICFamilyRulesConfig rulesConfiguration)
        {
            var options = GetDefaultOptions(rulesConfiguration);

            options.Add("internal.qualityProfile", string.Join(",", rulesConfiguration.ActivePartialRuleKeys));
            var data = options.Select(kv => kv.Key + "=" + kv.Value).ToArray();

            return(data);
        }
예제 #5
0
        internal /* for testing */ static bool IsIssueForActiveRule(Message message, ICFamilyRulesConfig rulesConfiguration)
        {
            // Currently (v6.3) the subprocess.exe will always run the native CLang rules, so those issues
            // could be returned even if they were not activated in the profile.

            // In addition, in v6.4+ there are internal rules that are always enabled and will always return
            // issues. Filtering for active rules will also remove those internal issues since the corresponding
            // rules will never be active in a quality profile.
            return(rulesConfiguration.ActivePartialRuleKeys.Contains(message.RuleKey, CFamilyShared.RuleKeyComparer));
        }
예제 #6
0
        private static IEnumerable <string> CalculateActiveRules(ICFamilyRulesConfig defaultRulesConfig, RulesSettings customRulesSettings)
        {
            // We're only interested settings for rules that are for the same language as the supplied rules configuration.
            // The rule keys in the custom rules settings include the repo prefix, but the rule keys in the default rules config do not.
            var partialKeyToConfigMap = GetFilteredRulesKeyedByPartialKey(customRulesSettings, defaultRulesConfig.LanguageKey);

            var deactivatedByUser = partialKeyToConfigMap.Where(kvp => kvp.Value.Level == RuleLevel.Off).Select(kvp => kvp.Key);
            var activatedByUser   = partialKeyToConfigMap.Where(kvp => kvp.Value.Level == RuleLevel.On).Select(kvp => kvp.Key);

            return(defaultRulesConfig.ActivePartialRuleKeys
                   .Concat(activatedByUser)
                   .Except(deactivatedByUser, CFamilyShared.RuleKeyComparer)
                   .Distinct(CFamilyShared.RuleKeyComparer).ToArray());
        }
            public ICFamilyRulesConfig FindConfig(string languageKey, ICFamilyRulesConfig sourceConfig, UserSettings sourceSettings)
            {
                if (!languageToConfigMap.TryGetValue(languageKey, out var cachedValue))
                {
                    return(null);
                }

                if (object.ReferenceEquals(sourceConfig, cachedValue.SourceConfig) &&
                    object.ReferenceEquals(sourceSettings, cachedValue.SourceSettings))
                {
                    return(cachedValue.EffectiveConfig);
                }

                languageToConfigMap.Remove(languageKey); // entry doesn't match -> remove it
                return(null);
            }
        private static Dictionary <string, string> GetDefaultOptions(ICFamilyRulesConfig rulesConfiguration)
        {
            Dictionary <string, string> defaults = new Dictionary <string, string>();

            foreach (string ruleKey in rulesConfiguration.AllPartialRuleKeys)
            {
                if (rulesConfiguration.RulesParameters.TryGetValue(ruleKey, out IDictionary <string, string> ruleParams))
                {
                    foreach (var param in ruleParams)
                    {
                        string optionKey = ruleKey + "." + param.Key;
                        defaults.Add(optionKey, param.Value);
                    }
                }
            }

            return(defaults);
        }
예제 #9
0
        public DynamicCFamilyRulesConfig(ICFamilyRulesConfig defaultRulesConfig, UserSettings userSettings)
        {
            this.defaultRulesConfig = defaultRulesConfig ?? throw new ArgumentNullException(nameof(defaultRulesConfig));

            if ((userSettings?.Rules?.Count ?? 0) == 0)
            {
                ActivePartialRuleKeys = defaultRulesConfig.ActivePartialRuleKeys;
                RulesMetadata         = defaultRulesConfig.RulesMetadata;
                RulesParameters       = defaultRulesConfig.RulesParameters;
            }
            else
            {
                ActivePartialRuleKeys = CalculateActiveRules(defaultRulesConfig, userSettings);

                RulesMetadata   = new Dictionary <string, RuleMetadata>();
                RulesParameters = new Dictionary <string, IDictionary <string, string> >();
                CalculateEffectiveSettings(defaultRulesConfig, userSettings);
            }
        }
예제 #10
0
        internal /* for testing */ DynamicCFamilyRulesConfig(ICFamilyRulesConfig defaultRulesConfig, RulesSettings customRulesSettings, ILogger logger, IEnumerable <string> excludedRuleKeys)
        {
            this.defaultRulesConfig = defaultRulesConfig ?? throw new ArgumentNullException(nameof(defaultRulesConfig));
            if (customRulesSettings == null)
            {
                throw new ArgumentNullException(nameof(customRulesSettings));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (customRulesSettings.Rules.Count == 0)
            {
                logger.WriteLine(CoreStrings.CFamily_NoCustomRulesSettings);
            }

            var modifiedCustomRules = DisableExcludedRules(customRulesSettings, excludedRuleKeys, logger);

            ActivePartialRuleKeys = CalculateActiveRules(defaultRulesConfig, modifiedCustomRules);
            RulesMetadata         = new Dictionary <string, RuleMetadata>();
            RulesParameters       = new Dictionary <string, IDictionary <string, string> >();
            CalculateEffectiveSettings(defaultRulesConfig, modifiedCustomRules);
        }
예제 #11
0
        private void CalculateEffectiveSettings(ICFamilyRulesConfig defaultRulesConfig, RulesSettings customRulesSettings)
        {
            Debug.Assert(customRulesSettings?.Rules != null && customRulesSettings.Rules.Count != 0);

            foreach (var partialRuleKey in defaultRulesConfig.AllPartialRuleKeys)
            {
                // Not all rules have params, but all should have metadata
                Debug.Assert(defaultRulesConfig.RulesMetadata[partialRuleKey] != null);

                var defaultMetadata = defaultRulesConfig.RulesMetadata[partialRuleKey];
                defaultRulesConfig.RulesParameters.TryGetValue(partialRuleKey, out var defaultParams);

                var fullRuleKey = GetFullRuleKey(defaultRulesConfig.LanguageKey, partialRuleKey);
                customRulesSettings.Rules.TryGetValue(fullRuleKey, out var userRuleConfig);

                RulesMetadata[partialRuleKey] = GetEffectiveMetadata(defaultMetadata, userRuleConfig);

                var effectiveParams = GetEffectiveParameters(defaultParams, userRuleConfig?.Parameters);
                if (effectiveParams != null)
                {
                    RulesParameters[partialRuleKey] = effectiveParams;
                }
            }
        }
예제 #12
0
 protected virtual /* for testing */ ICFamilyRulesConfig CreateConfiguration(string languageKey, ICFamilyRulesConfig sonarWayConfig, RulesSettings settings)
 => effectiveConfigCalculator.GetEffectiveRulesConfig(languageKey, sonarWayConfig, settings);
 public void Add(string languageKey, ICFamilyRulesConfig sourceConfig, UserSettings sourceSettings, ICFamilyRulesConfig effectiveConfig)
 {
     languageToConfigMap[languageKey] = new CacheEntry(sourceConfig, sourceSettings, effectiveConfig);
 }
 public CacheEntry(ICFamilyRulesConfig sourceConfig, UserSettings sourceSettings, ICFamilyRulesConfig effectiveConfig)
 {
     SourceConfig    = sourceConfig;
     SourceSettings  = sourceSettings;
     EffectiveConfig = effectiveConfig;
 }
예제 #15
0
 public DynamicCFamilyRulesConfig(ICFamilyRulesConfig defaultRulesConfig, RulesSettings customRulesSettings, ILogger logger)
     : this(defaultRulesConfig, customRulesSettings, logger, ExcludedRulesKeys)
 {
 }
예제 #16
0
        internal /* for testing */ static Sonarlint.Issue ToSonarLintIssue(Message cfamilyIssue, string sqLanguage, ICFamilyRulesConfig rulesConfiguration)
        {
            // Lines and character positions are 1-based
            Debug.Assert(cfamilyIssue.Line > 0);

            // BUT special case of EndLine=0, Column=0, EndColumn=0 meaning "select the whole line"
            Debug.Assert(cfamilyIssue.EndLine >= 0);
            Debug.Assert(cfamilyIssue.Column > 0 || cfamilyIssue.Column == 0);
            Debug.Assert(cfamilyIssue.EndColumn > 0 || cfamilyIssue.EndLine == 0);

            // Look up default severity and type
            var defaultSeverity = rulesConfiguration.RulesMetadata[cfamilyIssue.RuleKey].DefaultSeverity;
            var defaultType     = rulesConfiguration.RulesMetadata[cfamilyIssue.RuleKey].Type;

            return(new Sonarlint.Issue()
            {
                FilePath = cfamilyIssue.Filename,
                Message = cfamilyIssue.Text,
                RuleKey = sqLanguage + ":" + cfamilyIssue.RuleKey,
                Severity = Convert(defaultSeverity),
                Type = Convert(defaultType),
                StartLine = cfamilyIssue.Line,
                EndLine = cfamilyIssue.EndLine,

                // We don't care about the columns in the special case EndLine=0
                StartLineOffset = cfamilyIssue.EndLine == 0 ? 0 : cfamilyIssue.Column - 1,
                EndLineOffset = cfamilyIssue.EndLine == 0 ? 0 : cfamilyIssue.EndColumn - 1
            });
        }