public IEnumerable <RuleSetDeclaration> GetProjectRuleSetsDeclarations(Project project) { /* This method walks through all of the available configurations (e.g. Debug, Release, Foo) and * attempts to fetch the values of a couple of properties from the project (CodeAnalysisRuleSet * and CodeAnalysisRuleSetDirectories). The collected data is put into a data object * and returned to the caller. The collected data includes the DTE Property object itself, which * is used later to update the ruleset value. * * TODO: consider refactoring. The code seems over-complicated: it finds the "ruleset" * property for all configurations, then backtracks to find the configuration, then looks * for the corresponding "ruleset directories" property. * Note: we are now fetching the "ruleset directories" property from the MSBuild project, * rather than through the DTE (the previous version of this code that used the DTE fails * for C# and VB projects that use the new project system). */ if (project == null) { throw new ArgumentNullException(nameof(project)); } bool found = false; var projectSystem = this.serviceProvider.GetService <IProjectSystemHelper>(); var ruleSetProperties = VsShellUtils.GetProjectProperties(project, Constants.CodeAnalysisRuleSetPropertyKey); Debug.Assert(ruleSetProperties != null); Debug.Assert(ruleSetProperties.All(p => p != null), "Not expecting nulls in the list of properties"); foreach (Property ruleSetProperty in ruleSetProperties) { found = true; string activationContext = TryGetPropertyConfiguration(ruleSetProperty)?.ConfigurationName ?? string.Empty; string ruleSetDirectoriesValue = projectSystem.GetProjectProperty(project, Constants.CodeAnalysisRuleSetDirectoriesPropertyKey, activationContext); string[] ruleSetDirectories = ruleSetDirectoriesValue?.Split(new[] { RuleSetDirectoriesValueSpliter }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0]; string ruleSetValue = ruleSetProperty.Value as string; yield return(new RuleSetDeclaration(project, ruleSetProperty, ruleSetValue, activationContext, ruleSetDirectories)); } if (!found) { logger.WriteLine(Strings.CouldNotFindCodeAnalysisRuleSetPropertyOnProject, project.UniqueName); } }