From 2cb54ae7c090f8810cf55bd8544b1db10c1179f0 Mon Sep 17 00:00:00 2001 From: Marco Fogliatto <2962955+mfogliatto@users.noreply.github.com> Date: Sun, 27 Jul 2025 10:20:30 +0200 Subject: [PATCH 1/4] Update instructions with indentation guidelines --- .github/instructions/copilot-instructions.md | 61 ++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/.github/instructions/copilot-instructions.md b/.github/instructions/copilot-instructions.md index 456312f..ec59923 100644 --- a/.github/instructions/copilot-instructions.md +++ b/.github/instructions/copilot-instructions.md @@ -71,7 +71,28 @@ Please ensure all code follows StyleCop-based conventions as defined in the proj 2. **Ordering Rules**: - Using directives should be placed inside namespaces - System using directives should be listed first -3. **Layout Rules**: All files must end with a newline +3. **Layout Rules**: + - All files must end with a newline + - Use 4 spaces for indentation, not tabs + - Maintain consistent indentation when adding or modifying code blocks +4. **File Organization**: + - Each type (class, interface, struct, enum) should have its own file + - The file name should match the type name exactly + - Nested types can be in the same file as their parent type + +5. **Whitespace Rules**: + - No trailing whitespace at the end of lines (SA1028) + - No empty lines with whitespace characters + - Use a single blank line to separate logical code blocks + - Use a single space after keywords like `if`, `for`, `while`, etc. + - Use a single space before opening braces + +6. **Indentation Guidelines**: + - Always preserve the existing indentation style when modifying code + - Match the surrounding code's indentation level precisely when adding new code + - Ensure that all opening and closing braces maintain proper alignment + - For method parameters and arguments that span multiple lines, align parameters with the first parameter + - Do not mix tabs and spaces for indentation When adding or modifying code, adhere to these style conventions for consistency across the project. @@ -95,9 +116,8 @@ When adding or modifying code, adhere to these style conventions for consistency `result.Should().Be(expectedValue).Because("the discount should apply");` 4. **Test Structure**: - Explicitly separate test phases with comments: -``` - + Explicitly separate test phases with comments and maintain proper indentation: +```csharp // Arrange. var service = Substitute.For(); @@ -108,6 +128,11 @@ var result = sut.Calculate(); result.Should().NotBeNull(); ``` + When adding test methods, ensure that indentation is consistent with existing code: + - Use 4 spaces for indentation levels + - Align closing braces with their corresponding opening statements + - Maintain proper indentation for nested code blocks within test methods + 5. **Framework**: Use **MSTest** attributes: - Annotate test classes with `[TestClass]` @@ -147,12 +172,40 @@ Ensure all required fields in the template are filled out appropriately when cre - MSBuild integration in `ReferenceCopTask.cs` - Roslyn integration in `ReferenceCopAnalyzer.cs` +### Code Generation and Modification Guidelines + +When adding or modifying code in the ReferenceCop project, follow these guidelines: + +1. **Code Addition**: + - Match existing indentation patterns precisely + - Ensure all nested blocks follow the 4-space indentation rule + - Maintain the same brace style as surrounding code + +2. **Code Modification**: + - Preserve the original indentation when replacing or modifying existing code + - When refactoring, ensure that the modified code follows the same indentation patterns + - Do not change indentation of surrounding, unchanged code + +3. **Line Wrapping**: + - For method signatures that span multiple lines, indent continuation lines with 4 spaces + - For parameter lists, align parameters with the first parameter + - For chained method calls, use consistent indentation for each line + +4. **XML Documentation**: + - Ensure XML doc comments maintain consistent indentation with the code they document + - Indent XML doc elements consistently within the comment block + ## Instructions for the AI Agent - Write clean, idiomatic C# code. - Follow the coding standards and style described in the sections above. - Add XML documentation for all public methods. - Write MSTest tests for all new code. +- Pay careful attention to code indentation: + - Maintain 4-space indentation throughout the codebase + - Align braces correctly according to the existing code style + - Ensure that code additions match the surrounding indentation exactly + - When generating code, verify that indentation remains consistent with existing patterns - If you need clarification, request it in the `[ASSISTANT NOTE]` section below. ## Reference From ab9d359d7a0e92a668e0b2226183e2161698d1e8 Mon Sep 17 00:00:00 2001 From: Marco Fogliatto <2962955+mfogliatto@users.noreply.github.com> Date: Sat, 2 Aug 2025 06:49:26 +0200 Subject: [PATCH 2/4] Introduce NoWarn support --- .../MSBuildProjectMetadataProviderTests.cs | 42 ++++++++- .../ReferenceCopTaskTests.cs | 19 ++-- .../Providers/IProjectMetadataProvider.cs | 2 +- .../MSBuildProjectMetadataProvider.cs | 17 +++- .../Providers/ProjectReferenceInfo.cs | 31 +++++++ src/ReferenceCop.MSBuild/ReferenceCopTask.cs | 10 +- .../ReferenceCopAnalyzer.cs | 8 +- .../AssemblyNameViolationDetectorTests.cs | 83 ++++++++++++++--- ...emblyNameViolationDetectorTests.cs.updated | 0 .../ProjectPathViolationDetectorTests.cs | 86 ++++++++++++++++- ...ojectPathViolationDetectorTests.cs.updated | 0 .../ProjectTagViolationDetectorTests.cs | 92 +++++++++++++++++-- ...rojectTagViolationDetectorTests.cs.updated | 0 .../AssemblyNameViolationDetector.cs | 11 ++- .../Detectors/IViolationDetector.cs | 2 +- .../Detectors/ProjectPathViolationDetector.cs | 14 ++- .../Detectors/ProjectTagViolationDetector.cs | 14 ++- .../Detectors/ReferenceEvaluationContext.cs | 30 ++++++ .../ReferenceEvaluationContextFactory.cs | 32 +++++++ 19 files changed, 441 insertions(+), 52 deletions(-) create mode 100644 src/ReferenceCop.MSBuild/Providers/ProjectReferenceInfo.cs create mode 100644 src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs.updated create mode 100644 src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs.updated create mode 100644 src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs.updated create mode 100644 src/ReferenceCop/Detectors/ReferenceEvaluationContext.cs create mode 100644 src/ReferenceCop/Detectors/ReferenceEvaluationContextFactory.cs diff --git a/src/ReferenceCop.MSBuild.Tests/Providers/MSBuildProjectMetadataProviderTests.cs b/src/ReferenceCop.MSBuild.Tests/Providers/MSBuildProjectMetadataProviderTests.cs index 2c13743..3ae6438 100644 --- a/src/ReferenceCop.MSBuild.Tests/Providers/MSBuildProjectMetadataProviderTests.cs +++ b/src/ReferenceCop.MSBuild.Tests/Providers/MSBuildProjectMetadataProviderTests.cs @@ -1,6 +1,7 @@ namespace ReferenceCop.MSBuild.Tests { using System.IO; + using System.Linq; using FluentAssertions; using Microsoft.Build.Evaluation; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -24,6 +25,30 @@ public void Setup() ProjectCollection.GlobalProjectCollection.UnloadAllProjects(); } + [TestMethod] + public void GetProjectReferences_WhenReferenceHasNoWarn_ReturnsNoWarnValue() + { + // Arrange. + string tempProjectPath = this.CreateTempProjectFileWithReferenceNoWarn(); + + try + { + // Act. + var references = this.provider.GetProjectReferences(tempProjectPath).ToList(); + + // Assert. + references.Should().ContainSingle(); + var reference = references.Single(); + reference.Path.Should().Be("TestReferenceWithNoWarn.csproj"); + reference.NoWarn.Should().ContainSingle().Which.Should().Be("RC0001;RC0002"); + } + finally + { + // Cleanup + File.Delete(tempProjectPath); + } + } + [TestMethod] public void GetProjectReferences_WhenProjectHasOneReference_ReturnsSingleReference() { @@ -36,7 +61,7 @@ public void GetProjectReferences_WhenProjectHasOneReference_ReturnsSingleReferen var references = this.provider.GetProjectReferences(tempProjectPath); // Assert. - references.Should().NotBeNull().And.ContainSingle(r => r == TestReference); + references.Should().NotBeNull().And.ContainSingle(r => r.Path == TestReference); } finally { @@ -113,6 +138,21 @@ private string CreateTempProjectFileWithProperty() net6.0 <{TestPropertyName}>{TestPropertyValue} +"; + File.WriteAllText(tempFile, projectContent); + return tempFile; + } + + private string CreateTempProjectFileWithReferenceNoWarn() + { + string tempFile = Path.GetTempFileName() + ".csproj"; + string projectContent = @" + + net6.0 + + + + "; File.WriteAllText(tempFile, projectContent); return tempFile; diff --git a/src/ReferenceCop.MSBuild.Tests/ReferenceCopTaskTests.cs b/src/ReferenceCop.MSBuild.Tests/ReferenceCopTaskTests.cs index 9ede591..7ab4c36 100644 --- a/src/ReferenceCop.MSBuild.Tests/ReferenceCopTaskTests.cs +++ b/src/ReferenceCop.MSBuild.Tests/ReferenceCopTaskTests.cs @@ -1,6 +1,7 @@ namespace ReferenceCop.MSBuild.Tests { using System.Collections.Generic; + using System.Linq; using FluentAssertions; using Microsoft.Build.Framework; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -27,13 +28,13 @@ public void Execute_WhenViolationHasWarningSeverity_ReturnsTrue() // Setup the fake IProjectMetadataProvider fakeProjectReferencesProvider.GetProjectReferences(Arg.Any()) - .Returns(new List { "ReferenceProject.csproj" }); + .Returns(new List { new ProjectReferenceInfo("ReferenceProject.csproj") }); fakeProjectReferencesProvider.GetPropertyValue(Arg.Any(), Arg.Any()) .Returns("C:\\path\\to\\repo"); - tagViolationDetector.GetViolationsFrom(Arg.Any>()) + tagViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List { warningViolation }); - pathViolationDetector.GetViolationsFrom(Arg.Any>()) + pathViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List()); fakeConfigLoader.Load().Returns(new ReferenceCopConfig()); @@ -71,16 +72,16 @@ public void Execute_WhenViolationHasErrorSeverity_ReturnsFalse() // Setup the fake IProjectReferencesProvider fakeProjectReferencesProvider.GetProjectReferences(Arg.Any()) - .Returns(new List { "ReferenceProject.csproj" }); + .Returns(new List { new ProjectReferenceInfo("ReferenceProject.csproj") }); fakeProjectReferencesProvider.GetPropertyValue(Arg.Any(), Arg.Any()) .Returns("C:\\path\\to\\repo"); var rule = new ReferenceCopConfig.AssemblyName { Severity = ReferenceCopConfig.Rule.ViolationSeverity.Error }; var errorViolation = new Violation(rule, "TestReference"); - tagViolationDetector.GetViolationsFrom(Arg.Any>()) + tagViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List { errorViolation }); - pathViolationDetector.GetViolationsFrom(Arg.Any>()) + pathViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List()); fakeConfigLoader.Load().Returns(new ReferenceCopConfig()); @@ -118,7 +119,7 @@ public void Execute_WhenHasBothErrorAndWarningSeverities_ReturnsFalse() // Setup the fake IProjectReferencesProvider fakeProjectReferencesProvider.GetProjectReferences(Arg.Any()) - .Returns(new List { "ReferenceProject.csproj" }); + .Returns(new List { new ProjectReferenceInfo("ReferenceProject.csproj") }); fakeProjectReferencesProvider.GetPropertyValue(Arg.Any(), Arg.Any()) .Returns("C:\\path\\to\\repo"); @@ -127,9 +128,9 @@ public void Execute_WhenHasBothErrorAndWarningSeverities_ReturnsFalse() var errorViolation = new Violation(errorRule, "TestErrorReference"); var warningViolation = new Violation(warningRule, "TestWarningReference"); - tagViolationDetector.GetViolationsFrom(Arg.Any>()) + tagViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List { errorViolation }); - pathViolationDetector.GetViolationsFrom(Arg.Any>()) + pathViolationDetector.GetViolationsFrom(Arg.Any>>()) .Returns(new List { warningViolation }); fakeConfigLoader.Load().Returns(new ReferenceCopConfig()); diff --git a/src/ReferenceCop.MSBuild/Providers/IProjectMetadataProvider.cs b/src/ReferenceCop.MSBuild/Providers/IProjectMetadataProvider.cs index fe22633..89c3118 100644 --- a/src/ReferenceCop.MSBuild/Providers/IProjectMetadataProvider.cs +++ b/src/ReferenceCop.MSBuild/Providers/IProjectMetadataProvider.cs @@ -12,7 +12,7 @@ public interface IProjectMetadataProvider /// /// The path to the project file. /// The collection of project references. - IEnumerable GetProjectReferences(string projectFilePath); + IEnumerable GetProjectReferences(string projectFilePath); /// /// Gets a resolved property value from a project file. diff --git a/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs b/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs index c341a2d..6710d5c 100644 --- a/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs +++ b/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs @@ -10,13 +10,14 @@ namespace ReferenceCop.MSBuild public class MSBuildProjectMetadataProvider : IProjectMetadataProvider { private const string ProjectReferenceNode = "ProjectReference"; + private const string NoWarnMetadata = "NoWarn"; /// /// Gets the project references from a project file. /// /// The path to the project file. /// The collection of project references. - public IEnumerable GetProjectReferences(string projectFilePath) + public IEnumerable GetProjectReferences(string projectFilePath) { var projectCollection = new ProjectCollection(); var project = projectCollection.LoadProject(projectFilePath); @@ -24,8 +25,18 @@ public IEnumerable GetProjectReferences(string projectFilePath) // Get all ProjectReference items. These are the direct project references. var projectReferences = project.GetItems(ProjectReferenceNode); - // Extract the Include attribute, which contains the path to the referenced project. - return projectReferences.Select(pr => pr.EvaluatedInclude); + // Extract the Include attribute and NoWarn metadata for each reference + foreach (var pr in projectReferences) + { + string referencePath = pr.EvaluatedInclude; + string noWarnValue = pr.GetMetadataValue(NoWarnMetadata); + + IEnumerable noWarnCodes = string.IsNullOrEmpty(noWarnValue) + ? new List() + : noWarnValue.Split(',').Select(code => code.Trim()); + + yield return new ProjectReferenceInfo(referencePath, noWarnCodes); + } } /// diff --git a/src/ReferenceCop.MSBuild/Providers/ProjectReferenceInfo.cs b/src/ReferenceCop.MSBuild/Providers/ProjectReferenceInfo.cs new file mode 100644 index 0000000..deddd18 --- /dev/null +++ b/src/ReferenceCop.MSBuild/Providers/ProjectReferenceInfo.cs @@ -0,0 +1,31 @@ +namespace ReferenceCop.MSBuild +{ + using System.Collections.Generic; + + /// + /// Contains information about a project reference, including the path and NoWarn values. + /// + public class ProjectReferenceInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The path to the referenced project. + /// The NoWarn values for this reference. + public ProjectReferenceInfo(string path, IEnumerable noWarn = null) + { + this.Path = path; + this.NoWarn = noWarn ?? new List(); + } + + /// + /// Gets the path to the referenced project. + /// + public string Path { get; } + + /// + /// Gets the NoWarn values for this reference. + /// + public IEnumerable NoWarn { get; } + } +} diff --git a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs index 3cd48ca..c07e28e 100644 --- a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs +++ b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs @@ -1,7 +1,9 @@ namespace ReferenceCop.MSBuild { using System; + using System.Collections.Generic; using System.Diagnostics; + using System.Linq; using Microsoft.Build.Framework; public class ReferenceCopTask : ITask @@ -70,10 +72,14 @@ public bool Execute() var configFilePath = ConfigFilePathsParser.Parse(this.ConfigFilePaths); var configLoader = this.configLoaderFactory(configFilePath); var config = configLoader.Load(); + var projectReferences = this.projectReferencesProvider.GetProjectReferences(this.ProjectFile.ItemSpec); + var evaluationContexts = projectReferences + .Select(_ => ReferenceEvaluationContextFactory.Create(_.Path, _.NoWarn)) + .ToList(); var projectTagViolationDetector = this.tagViolationDetectorFactory(config, this.ProjectFile.ItemSpec); - foreach (var violation in projectTagViolationDetector.GetViolationsFrom(projectReferences)) + foreach (var violation in projectTagViolationDetector.GetViolationsFrom(evaluationContexts)) { if (violation.Rule.Severity == ReferenceCopConfig.Rule.ViolationSeverity.Error) { @@ -86,7 +92,7 @@ public bool Execute() var repositoryRoot = this.projectReferencesProvider.GetPropertyValue( this.ProjectFile.ItemSpec, ReferenceCopRepositoryRootProperty); var projectPathViolationDetector = this.pathViolationDetectorFactory(config, this.ProjectFile.ItemSpec, repositoryRoot); - foreach (var violation in projectPathViolationDetector.GetViolationsFrom(projectReferences)) + foreach (var violation in projectPathViolationDetector.GetViolationsFrom(evaluationContexts)) { if (violation.Rule.Severity == ReferenceCopConfig.Rule.ViolationSeverity.Error) { diff --git a/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs b/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs index fa324a8..fdf2dca 100644 --- a/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs +++ b/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; using System.Diagnostics; + using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; @@ -52,7 +53,12 @@ private static void LaunchDebuggerIfRequested(CompilationAnalysisContext compila private void AnalyzeCompilation(CompilationAnalysisContext compilationAnalysisContext) { var compilation = compilationAnalysisContext.Compilation; - foreach (var violation in this.detector.GetViolationsFrom(compilation.ReferencedAssemblyNames)) + + var evaluationContexts = compilation.ReferencedAssemblyNames + .Select(assemblyRef => ReferenceEvaluationContextFactory.Create(assemblyRef)) + .ToList(); + + foreach (var violation in this.detector.GetViolationsFrom(evaluationContexts)) { compilationAnalysisContext.ReportDiagnostic(DiagnosticFactory.CreateFor(violation)); } diff --git a/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs b/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs index 432df28..b6dca52 100644 --- a/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs +++ b/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs @@ -20,7 +20,10 @@ public void GetViolationsFrom_WhenNoRules_ReturnsEmpty() var detector = new AssemblyNameViolationDetector(Substitute.For>(), config); // Act. - var result = detector.GetViolationsFrom(new List { new AssemblyIdentity("System.Xml.Linq") }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Xml.Linq")), + }); // Assert. result.Should().BeEmpty(); @@ -39,9 +42,9 @@ public void GetViolationsFrom_WhenMatchingRule_ReturnsViolation() var detector = new AssemblyNameViolationDetector(comparer, config); var references = new[] { - new AssemblyIdentity(detectableValue), - new AssemblyIdentity("System.Xml.Serialization"), - new AssemblyIdentity("System.Xml.Linq"), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity(detectableValue)), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Xml.Serialization")), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Xml.Linq")), }; // Act @@ -65,9 +68,9 @@ public void GetViolationsFrom_WhenMatchingRuleUsesPatternMatch_ReturnsViolations var detector = new AssemblyNameViolationDetector(new PatternMatchComparer(), config); var references = new[] { - new AssemblyIdentity(detectableValue1), - new AssemblyIdentity(detectableValue2), - new AssemblyIdentity("System.Text"), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity(detectableValue1)), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity(detectableValue2)), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Text")), }; // Act @@ -85,8 +88,8 @@ public void GetViolationsFrom_WhenNoMatchingRules_ReturnsEmpty() var detector = new AssemblyNameViolationDetector(Substitute.For>(), config); var references = new[] { - new AssemblyIdentity("System.Xml.Serialization"), - new AssemblyIdentity("System.Xml.Linq"), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Xml.Serialization")), + ReferenceEvaluationContextFactory.Create(new AssemblyIdentity("System.Xml.Linq")), }; // Act @@ -106,12 +109,68 @@ public void GetViolationsFrom_WhenNoReferences_ReturnsEmpty() var detector = new AssemblyNameViolationDetector(Substitute.For>(), config); // Act - var diagnostics = detector.GetViolationsFrom(Array.Empty()); + var diagnostics = detector.GetViolationsFrom(Array.Empty>()); // Assert diagnostics.Should().BeEmpty(); } + [TestMethod] + public void GetViolationsFrom_WhenWarningSuppressed_SkipsViolation() + { + // Arrange. + const string detectableValue = "System.Xml"; + var config = new ReferenceCopConfigBuilder() + .WithAssemblyNameRule(detectableValue) + .Build(); + var comparer = Substitute.For>(); + comparer.Equals(detectableValue, detectableValue).Returns(true); + var detector = new AssemblyNameViolationDetector(comparer, config); + var references = new[] + { + // Create with warning suppressed + new ReferenceEvaluationContext(new AssemblyIdentity(detectableValue), isWarningSuppressed: true), + }; + + // Act + var diagnostics = detector.GetViolationsFrom(references); + + // Assert + diagnostics.Should().BeEmpty("because the violation was suppressed"); + } + + [TestMethod] + public void GetViolationsFrom_WhenMultipleReferencesWithSomeSuppressed_ReturnsSomeViolations() + { + // Arrange. + const string partialMatch = "System.Xml"; + var detectablePattern = $"{partialMatch}.*"; + var detectableValue1 = $"{partialMatch}.Serialization"; + var detectableValue2 = $"{partialMatch}.Linq"; + var config = new ReferenceCopConfigBuilder() + .WithAssemblyNameRule(detectablePattern) + .Build(); + var detector = new AssemblyNameViolationDetector(new PatternMatchComparer(), config); + var references = new[] + { + // Regular reference with no suppression + new ReferenceEvaluationContext(new AssemblyIdentity(detectableValue1), isWarningSuppressed: false), + + // Suppressed reference + new ReferenceEvaluationContext(new AssemblyIdentity(detectableValue2), isWarningSuppressed: true), + + // Non-matching reference + new ReferenceEvaluationContext(new AssemblyIdentity("System.Text"), isWarningSuppressed: false), + }; + + // Act + var diagnostics = detector.GetViolationsFrom(references); + + // Assert + diagnostics.Should().ContainSingle() + .Which.ReferenceName.Should().Be(detectableValue1); + } + [TestMethod] public void GetViolationsFrom_WhenNullReference_ThrowsInvalidOperationException() { @@ -120,9 +179,9 @@ public void GetViolationsFrom_WhenNullReference_ThrowsInvalidOperationException( .WithAssemblyNameRule("somePattern") .Build(); var detector = new AssemblyNameViolationDetector(Substitute.For>(), config); - var references = new AssemblyIdentity[] + var references = new ReferenceEvaluationContext[] { - null, + ReferenceEvaluationContextFactory.Create(null), }; // Act diff --git a/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs.updated b/src/ReferenceCop.Tests/Detectors/AssemblyNameViolationDetectorTests.cs.updated new file mode 100644 index 0000000..e69de29 diff --git a/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs b/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs index afc60c4..0e14394 100644 --- a/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs +++ b/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs @@ -22,7 +22,10 @@ public void GetViolationsFrom_WhenNoRules_ReturnsEmpty() // Arrange. var config = new ReferenceCopConfig(); var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, Substitute.For()); - var references = new List { this.projectOneFilePath }; + var references = new List> + { + ReferenceEvaluationContextFactory.Create(this.projectOneFilePath), + }; // Act. var result = detector.GetViolationsFrom(references); @@ -39,7 +42,7 @@ public void GetViolationsFrom_WhenNoReferences_ReturnsEmpty() var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, Substitute.For()); // Act. - var result = detector.GetViolationsFrom(Enumerable.Empty()); + var result = detector.GetViolationsFrom(Enumerable.Empty>()); // Assert. result.Should().BeEmpty(); @@ -59,7 +62,10 @@ public void GetViolationsFrom_WhenNoMatchingRules_ReturnsEmpty() var projectPathProvider = Substitute.For(); projectPathProvider.GetRelativePath(this.projectOneFilePath).Returns(ProjectOneDir); var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, projectPathProvider); - var references = new List { this.projectTwoFilePath }; + var references = new List> + { + ReferenceEvaluationContextFactory.Create(this.projectTwoFilePath), + }; // Act. var result = detector.GetViolationsFrom(references); @@ -83,7 +89,10 @@ public void GetViolationsFrom_WhenMatchingRule_ReturnsViolations() projectPathProvider.GetRelativePath(this.projectOneFilePath).Returns(ProjectOneDir); projectPathProvider.GetRelativePath(this.projectTwoFilePath).Returns(ProjectTwoDir); var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, projectPathProvider); - var references = new List { this.projectTwoFilePath }; + var references = new List> + { + ReferenceEvaluationContextFactory.Create(this.projectTwoFilePath), + }; // Act. var result = detector.GetViolationsFrom(references); @@ -110,7 +119,11 @@ public void GetViolationsFrom_WhenMultipleMatchingReferences_ReturnsViolations() projectPathProvider.GetRelativePath(this.projectTwoFilePath).Returns(ProjectTwoDir); projectPathProvider.GetRelativePath(this.projectThreeFilePath).Returns(ProjectThreeDir); var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, projectPathProvider); - var references = new List { this.projectTwoFilePath, this.projectThreeFilePath }; + var references = new List> + { + ReferenceEvaluationContextFactory.Create(this.projectTwoFilePath), + ReferenceEvaluationContextFactory.Create(this.projectThreeFilePath), + }; // Act. var result = detector.GetViolationsFrom(references); @@ -120,5 +133,68 @@ public void GetViolationsFrom_WhenMultipleMatchingReferences_ReturnsViolations() result.Should().Contain(v => v.ReferenceName == this.projectTwoFilePath); result.Should().Contain(v => v.ReferenceName == this.projectThreeFilePath); } + + [TestMethod] + public void GetViolationsFrom_WhenWarningSuppressed_SkipsViolation() + { + // Arrange. + var config = new ReferenceCopConfig + { + Rules = new List + { + new ReferenceCopConfig.ProjectPath { FromPath = ProjectOneDir, ToPath = ProjectTwoDir }, + }, + }; + var projectPathProvider = Substitute.For(); + projectPathProvider.GetRelativePath(this.projectOneFilePath).Returns(ProjectOneDir); + projectPathProvider.GetRelativePath(this.projectTwoFilePath).Returns(ProjectTwoDir); + var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, projectPathProvider); + var references = new List> + { + // Create with warning suppressed + new ReferenceEvaluationContext(this.projectTwoFilePath, isWarningSuppressed: true), + }; + + // Act. + var result = detector.GetViolationsFrom(references); + + // Assert. + result.Should().BeEmpty("because the violation was suppressed"); + } + + [TestMethod] + public void GetViolationsFrom_WhenMultipleReferencesWithSomeSuppressed_ReturnsSomeViolations() + { + // Arrange. + var config = new ReferenceCopConfig + { + Rules = new List + { + new ReferenceCopConfig.ProjectPath { FromPath = ProjectOneDir, ToPath = ProjectTwoDir }, + new ReferenceCopConfig.ProjectPath { FromPath = ProjectOneDir, ToPath = ProjectThreeDir }, + }, + }; + var projectPathProvider = Substitute.For(); + projectPathProvider.GetRelativePath(this.projectOneFilePath).Returns(ProjectOneDir); + projectPathProvider.GetRelativePath(this.projectTwoFilePath).Returns(ProjectTwoDir); + projectPathProvider.GetRelativePath(this.projectThreeFilePath).Returns(ProjectThreeDir); + var detector = new ProjectPathViolationDetector(config, this.projectOneFilePath, projectPathProvider); + var references = new List> + { + // Regular reference with no suppression + new ReferenceEvaluationContext(this.projectTwoFilePath, isWarningSuppressed: false), + + // Suppressed reference + new ReferenceEvaluationContext(this.projectThreeFilePath, isWarningSuppressed: true), + }; + + // Act. + var result = detector.GetViolationsFrom(references); + + // Assert. + result.Should().ContainSingle(); + result.Should().Contain(v => v.ReferenceName == this.projectTwoFilePath); + result.Should().NotContain(v => v.ReferenceName == this.projectThreeFilePath); + } } } diff --git a/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs.updated b/src/ReferenceCop.Tests/Detectors/ProjectPathViolationDetectorTests.cs.updated new file mode 100644 index 0000000..e69de29 diff --git a/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs b/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs index e630957..03997c4 100644 --- a/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs +++ b/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs @@ -25,7 +25,10 @@ public void GetViolationsFrom_WhenNoRules_ReturnsEmpty() var detector = new ProjectTagViolationDetector(config, SourceFilePath, Substitute.For()); // Act. - var result = detector.GetViolationsFrom(new List { ReferenceFilePath1 }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + }); // Assert. result.Should().BeEmpty(); @@ -42,7 +45,7 @@ public void GetViolationsFrom_WhenNoReferences_ReturnsEmpty() var detector = new ProjectTagViolationDetector(config, SourceFilePath, Substitute.For()); // Act. - var result = detector.GetViolationsFrom(Enumerable.Empty()); + var result = detector.GetViolationsFrom(Enumerable.Empty>()); // Assert. result.Should().BeEmpty(); @@ -66,7 +69,10 @@ public void GetViolationsFrom_WhenNoMatchingRules_ReturnsEmpty() var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); // Act. - var result = detector.GetViolationsFrom(new List { ReferenceFilePath1 }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + }); // Assert. result.Should().BeEmpty(); @@ -89,7 +95,10 @@ public void GetViolationsFrom_WhenMatchingRule_ReturnsViolation() var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); // Act. - var result = detector.GetViolationsFrom(new List { ReferenceFilePath1 }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + }); // Assert. result.Should().ContainSingle() @@ -115,7 +124,11 @@ public void GetViolationsFrom_WhenMultipleMatchingReferences_ReturnsViolations() var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); // Act. - var result = detector.GetViolationsFrom(new List { ReferenceFilePath1, ReferenceFilePath2 }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + ReferenceEvaluationContextFactory.Create(ReferenceFilePath2), + }); // Assert. result.Should().HaveCount(2); @@ -137,12 +150,74 @@ public void GetViolationsFrom_WhenUnknownProjectTag_ReturnsEmpty() var detector = new ProjectTagViolationDetector(config, "nonexistent.csproj", tagProvider); // Act. - var result = detector.GetViolationsFrom(new List { ReferenceFilePath1 }); + var result = detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + }); // Assert. result.Should().BeEmpty(); } + [TestMethod] + public void GetViolationsFrom_WhenWarningSuppressed_SkipsViolation() + { + // Arrange. + var config = new ReferenceCopConfig + { + Rules = new List + { + new ReferenceCopConfig.ProjectTag { FromProjectTag = ProjectTag1, ToProjectTag = ProjectTag2 }, + }, + }; + var tagProvider = Substitute.For(); + tagProvider.GetProjectTag(SourceFilePath).Returns(ProjectTag1); + tagProvider.GetProjectTag(ReferenceFilePath1).Returns(ProjectTag2); + var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); + + // Act. + var result = detector.GetViolationsFrom(new List> + { + // Create with warning suppressed + new ReferenceEvaluationContext(ReferenceFilePath1, isWarningSuppressed: true), + }); + + // Assert. + result.Should().BeEmpty("because the violation was suppressed"); + } + + [TestMethod] + public void GetViolationsFrom_WhenMultipleReferencesWithSomeSuppressed_ReturnsSomeViolations() + { + // Arrange. + var config = new ReferenceCopConfig + { + Rules = new List + { + new ReferenceCopConfig.ProjectTag { FromProjectTag = ProjectTag1, ToProjectTag = ProjectTag2 }, + }, + }; + var tagProvider = Substitute.For(); + tagProvider.GetProjectTag(SourceFilePath).Returns(ProjectTag1); + tagProvider.GetProjectTag(ReferenceFilePath1).Returns(ProjectTag2); + tagProvider.GetProjectTag(ReferenceFilePath2).Returns(ProjectTag2); + var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); + + // Act. + var result = detector.GetViolationsFrom(new List> + { + // Regular reference with no suppression + new ReferenceEvaluationContext(ReferenceFilePath1, isWarningSuppressed: false), + + // Suppressed reference + new ReferenceEvaluationContext(ReferenceFilePath2, isWarningSuppressed: true), + }); + + // Assert. + result.Should().ContainSingle() + .Which.ReferenceName.Should().Be(ReferenceFilePath1); + } + [TestMethod] public void GetViolationsFrom_WhenTagProviderThrows_ReThrowsException() { @@ -156,7 +231,10 @@ public void GetViolationsFrom_WhenTagProviderThrows_ReThrowsException() var detector = new ProjectTagViolationDetector(config, SourceFilePath, tagProvider); // Act. - Action act = () => detector.GetViolationsFrom(new List { ReferenceFilePath1 }).ToList(); + Action act = () => detector.GetViolationsFrom(new List> + { + ReferenceEvaluationContextFactory.Create(ReferenceFilePath1), + }).ToList(); // Assert. act.Should().Throw(); diff --git a/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs.updated b/src/ReferenceCop.Tests/Detectors/ProjectTagViolationDetectorTests.cs.updated new file mode 100644 index 0000000..e69de29 diff --git a/src/ReferenceCop/Detectors/AssemblyNameViolationDetector.cs b/src/ReferenceCop/Detectors/AssemblyNameViolationDetector.cs index 6ada1a5..0643eb2 100644 --- a/src/ReferenceCop/Detectors/AssemblyNameViolationDetector.cs +++ b/src/ReferenceCop/Detectors/AssemblyNameViolationDetector.cs @@ -17,12 +17,13 @@ public AssemblyNameViolationDetector(IEqualityComparer referenceNameComp this.referenceNameComparer = referenceNameComparer; } - public IEnumerable GetViolationsFrom(IEnumerable references) + public IEnumerable GetViolationsFrom(IEnumerable> references) { foreach (var rule in this.rules) { - foreach (var reference in references) + foreach (var referenceContext in references) { + var reference = referenceContext.Reference; if (string.IsNullOrEmpty(reference?.Name)) { throw new InvalidOperationException("Reference name cannot be null or empty."); @@ -30,6 +31,12 @@ public IEnumerable GetViolationsFrom(IEnumerable re if (this.referenceNameComparer.Equals(rule.Key, reference.Name)) { + // Check if this warning should be suppressed + if (referenceContext.IsWarningSuppressed) + { + continue; + } + yield return new Violation(rule.Value, reference.Name); } } diff --git a/src/ReferenceCop/Detectors/IViolationDetector.cs b/src/ReferenceCop/Detectors/IViolationDetector.cs index 904948b..81fb561 100644 --- a/src/ReferenceCop/Detectors/IViolationDetector.cs +++ b/src/ReferenceCop/Detectors/IViolationDetector.cs @@ -4,6 +4,6 @@ public interface IViolationDetector { - IEnumerable GetViolationsFrom(IEnumerable references); + IEnumerable GetViolationsFrom(IEnumerable> references); } } diff --git a/src/ReferenceCop/Detectors/ProjectPathViolationDetector.cs b/src/ReferenceCop/Detectors/ProjectPathViolationDetector.cs index 614e31d..588ebe2 100644 --- a/src/ReferenceCop/Detectors/ProjectPathViolationDetector.cs +++ b/src/ReferenceCop/Detectors/ProjectPathViolationDetector.cs @@ -17,7 +17,7 @@ public ProjectPathViolationDetector(ReferenceCopConfig config, string projectFil this.projectPathProvider = projectPathProvider; } - public IEnumerable GetViolationsFrom(IEnumerable references) + public IEnumerable GetViolationsFrom(IEnumerable> references) { var fromProjectPath = this.projectPathProvider.GetRelativePath(this.projectFilePath); @@ -25,13 +25,19 @@ public IEnumerable GetViolationsFrom(IEnumerable references) { if (fromProjectPath.StartsWith(rule.FromPath)) { - foreach (var reference in references) + foreach (var referenceContext in references) { - var toProjectPath = this.projectPathProvider.GetRelativePath(reference); + var toProjectPath = this.projectPathProvider.GetRelativePath(referenceContext.Reference); if (toProjectPath.StartsWith(rule.ToPath)) { - yield return new Violation(rule, reference); + // Check if this warning should be suppressed + if (referenceContext.IsWarningSuppressed) + { + continue; + } + + yield return new Violation(rule, referenceContext.Reference); } } } diff --git a/src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs b/src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs index e107373..8863b7c 100644 --- a/src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs +++ b/src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs @@ -17,7 +17,7 @@ public ProjectTagViolationDetector(ReferenceCopConfig config, string projectFile this.projectTagProvider = projectTagProvider; } - public IEnumerable GetViolationsFrom(IEnumerable references) + public IEnumerable GetViolationsFrom(IEnumerable> references) { var fromProjectTag = this.projectTagProvider.GetProjectTag(this.projectFilePath); @@ -25,13 +25,19 @@ public IEnumerable GetViolationsFrom(IEnumerable references) { if (fromProjectTag == rule.FromProjectTag) { - foreach (var reference in references) + foreach (var referenceContext in references) { - var toProjectTag = this.projectTagProvider.GetProjectTag(reference); + var toProjectTag = this.projectTagProvider.GetProjectTag(referenceContext.Reference); if (toProjectTag == rule.ToProjectTag) { - yield return new Violation(rule, reference); + // Check if this warning should be suppressed + if (referenceContext.IsWarningSuppressed) + { + continue; + } + + yield return new Violation(rule, referenceContext.Reference); } } } diff --git a/src/ReferenceCop/Detectors/ReferenceEvaluationContext.cs b/src/ReferenceCop/Detectors/ReferenceEvaluationContext.cs new file mode 100644 index 0000000..b0dc708 --- /dev/null +++ b/src/ReferenceCop/Detectors/ReferenceEvaluationContext.cs @@ -0,0 +1,30 @@ +namespace ReferenceCop +{ + /// + /// Represents a context for evaluating references, including warning suppression information. + /// + /// The type of assembly identity. + public class ReferenceEvaluationContext + { + /// + /// Initializes a new instance of the class. + /// + /// The reference assembly identity. + /// Indicates whether warnings are suppressed for this reference. + public ReferenceEvaluationContext(TAssemblyIdentity reference, bool isWarningSuppressed = false) + { + this.Reference = reference; + this.IsWarningSuppressed = isWarningSuppressed; + } + + /// + /// Gets the reference assembly identity. + /// + public TAssemblyIdentity Reference { get; } + + /// + /// Gets a value indicating whether warnings are suppressed for this reference. + /// + public bool IsWarningSuppressed { get; } + } +} diff --git a/src/ReferenceCop/Detectors/ReferenceEvaluationContextFactory.cs b/src/ReferenceCop/Detectors/ReferenceEvaluationContextFactory.cs new file mode 100644 index 0000000..644bc53 --- /dev/null +++ b/src/ReferenceCop/Detectors/ReferenceEvaluationContextFactory.cs @@ -0,0 +1,32 @@ +namespace ReferenceCop +{ + using System.Collections.Generic; + using System.Linq; + + /// + /// Factory for creating ReferenceEvaluationContext instances. + /// + public static class ReferenceEvaluationContextFactory + { + /// + /// Creates a ReferenceEvaluationContext for the given reference. + /// + /// The type of assembly identity. + /// The reference. + /// The NoWarn codes associated with this reference. + /// A new ReferenceEvaluationContext instance. + public static ReferenceEvaluationContext Create( + TAssemblyIdentity reference, + IEnumerable noWarnCodes = null) + { + // Determine if ReferenceCop warnings are suppressed for this reference + var isWarningSuppressed = false; + if (noWarnCodes != null) + { + isWarningSuppressed = noWarnCodes.Contains(Violation.ViolationSeverityWarningCode); + } + + return new ReferenceEvaluationContext(reference, isWarningSuppressed); + } + } +} From a408f86ce5bf04affdded49e06f0489070585e7a Mon Sep 17 00:00:00 2001 From: Marco Fogliatto <2962955+mfogliatto@users.noreply.github.com> Date: Sat, 2 Aug 2025 06:55:51 +0200 Subject: [PATCH 3/4] Rename local vars for clarity --- src/ReferenceCop.MSBuild/ReferenceCopTask.cs | 12 ++++++------ src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs index c07e28e..836d16a 100644 --- a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs +++ b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs @@ -13,8 +13,8 @@ public class ReferenceCopTask : ITask private readonly IProjectMetadataProvider projectReferencesProvider; private readonly Func configLoaderFactory; - private readonly Func> tagViolationDetectorFactory; - private readonly Func> pathViolationDetectorFactory; + private readonly Func> projectTagViolationDetectorFactory; + private readonly Func> projectPathViolationDetectorFactory; /// /// Initializes a new instance of the class. @@ -43,10 +43,10 @@ public ReferenceCopTask( this.configLoaderFactory = (configFilePaths) => configLoader ?? new XmlConfigurationLoader(configFilePaths); - this.tagViolationDetectorFactory = (config, projectPath) => + this.projectTagViolationDetectorFactory = (config, projectPath) => tagViolationDetector ?? new ProjectTagViolationDetector(config, projectPath, new ProjectTagProvider()); - this.pathViolationDetectorFactory = (config, projectPath, repositoryRoot) => + this.projectPathViolationDetectorFactory = (config, projectPath, repositoryRoot) => pathViolationDetector ?? new ProjectPathViolationDetector(config, projectPath, new ProjectPathProvider(repositoryRoot)); } @@ -78,7 +78,7 @@ public bool Execute() .Select(_ => ReferenceEvaluationContextFactory.Create(_.Path, _.NoWarn)) .ToList(); - var projectTagViolationDetector = this.tagViolationDetectorFactory(config, this.ProjectFile.ItemSpec); + var projectTagViolationDetector = this.projectTagViolationDetectorFactory(config, this.ProjectFile.ItemSpec); foreach (var violation in projectTagViolationDetector.GetViolationsFrom(evaluationContexts)) { if (violation.Rule.Severity == ReferenceCopConfig.Rule.ViolationSeverity.Error) @@ -91,7 +91,7 @@ public bool Execute() var repositoryRoot = this.projectReferencesProvider.GetPropertyValue( this.ProjectFile.ItemSpec, ReferenceCopRepositoryRootProperty); - var projectPathViolationDetector = this.pathViolationDetectorFactory(config, this.ProjectFile.ItemSpec, repositoryRoot); + var projectPathViolationDetector = this.projectPathViolationDetectorFactory(config, this.ProjectFile.ItemSpec, repositoryRoot); foreach (var violation in projectPathViolationDetector.GetViolationsFrom(evaluationContexts)) { if (violation.Rule.Severity == ReferenceCopConfig.Rule.ViolationSeverity.Error) diff --git a/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs b/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs index fdf2dca..ba093d5 100644 --- a/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs +++ b/src/ReferenceCop.Roslyn/ReferenceCopAnalyzer.cs @@ -13,7 +13,7 @@ public class ReferenceCopAnalyzer : DiagnosticAnalyzer private const string LaunchDebuggerKey = "build_property.LaunchDebugger"; private const string RoslynDebuggerTriggerValue = "Roslyn"; - private IViolationDetector detector; + private IViolationDetector assemblyNameViolationDetector; public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create( DiagnosticDescriptors.GeneralError, @@ -30,7 +30,7 @@ public override void Initialize(AnalysisContext context) { var configLoader = new XmlConfigurationLoader(compilationAnalysisContext); var config = configLoader.Load(); - this.detector = new AssemblyNameViolationDetector(new PatternMatchComparer(), config); + this.assemblyNameViolationDetector = new AssemblyNameViolationDetector(new PatternMatchComparer(), config); this.AnalyzeCompilation(compilationAnalysisContext); } catch (Exception ex) @@ -58,7 +58,7 @@ private void AnalyzeCompilation(CompilationAnalysisContext compilationAnalysisCo .Select(assemblyRef => ReferenceEvaluationContextFactory.Create(assemblyRef)) .ToList(); - foreach (var violation in this.detector.GetViolationsFrom(evaluationContexts)) + foreach (var violation in this.assemblyNameViolationDetector.GetViolationsFrom(evaluationContexts)) { compilationAnalysisContext.ReportDiagnostic(DiagnosticFactory.CreateFor(violation)); } From df15958cb3808ecce7ec9c19b6a2504eb0167c35 Mon Sep 17 00:00:00 2001 From: Marco Fogliatto <2962955+mfogliatto@users.noreply.github.com> Date: Tue, 5 Aug 2025 06:46:06 +0200 Subject: [PATCH 4/4] Remove old template file --- src/.github/PULL_REQUEST_TEMPLATE.md | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/.github/PULL_REQUEST_TEMPLATE.md diff --git a/src/.github/PULL_REQUEST_TEMPLATE.md b/src/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 41bef00..0000000 --- a/src/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,23 +0,0 @@ -## Description -This PR includes the following changes from the last 3 commits: - -- Autoincrease version for publishing package to local feed. (src/ReferenceCop.Package/ReferenceCop.Package.csproj) -- Fix ReferenceCop.Package not importing targets file when testing with local feed. (src/Directory.Build.props, src/ReferenceCop.Package/ReferenceCop.Package.csproj) -- Update dotnet sdk version. (global.json) - -## Type of change -- [x] Enhancement (e.g. new feature, functional improvement, etc.) -- [x] Bug fix -- [x] Chore (e.g. refactoring, documentation, etc.) - -## Related Issue -[Link to the related issue, if applicable] - -## How Has This Been Tested? -[Describe the tests you ran to verify your changes] - -## Screenshots (if applicable) -[Add screenshots to help explain your changes] - -## Additional context -[Add any other context about the PR here]