Skip to content

Commit

Permalink
NET-908 ONLY raise on VS version >= 17.9
Browse files Browse the repository at this point in the history
Co-authored-by: Andrei Epure <[email protected]>
  • Loading branch information
2 people authored and sonartech committed Jan 7, 2025
1 parent 56e87ce commit deef83e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
8 changes: 7 additions & 1 deletion analyzers/src/SonarAnalyzer.CFG/Common/RoslynVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ public static bool IsRoslynCfgSupported(int minimalVersion = MinimalSupportedMaj
!IsVersionLessThan(minimalVersion);

public static bool IsVersionLessThan(int minimalVersion = MinimalSupportedMajorVersion) =>
typeof(SemanticModel).Assembly.GetName().Version.Major < minimalVersion;
CurrentVersion().Major < minimalVersion;

public static bool IsVersionLessThan(Version version) =>
CurrentVersion() < version;

private static Version CurrentVersion() =>
typeof(SemanticModel).Assembly.GetName().Version;
}
17 changes: 16 additions & 1 deletion analyzers/src/SonarAnalyzer.Core/Helpers/IssueReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* along with this program; if not, see https://sonarsource.com/license/ssal/
*/

using SonarAnalyzer.CFG.Common;

namespace SonarAnalyzer.Helpers;

public static class IssueReporter
Expand All @@ -30,6 +32,10 @@ public static class IssueReporter
"S1481",
"S1871");

// Minimum supported version for Razor IDE is Visual Studio 17.9/Roslyn 4.9.2
// https://learn.microsoft.com/en-us/visualstudio/extensibility/roslyn-version-support?view=vs-2022
private static Version minimumDesignTimeRoslynVersion = new("4.9.2");

public static void ReportIssueCore(
Compilation compilation,
Func<DiagnosticDescriptor, bool> hasMatchingScope,
Expand Down Expand Up @@ -88,13 +94,22 @@ public static void ReportIssueCore(
}
}

internal static void SetMinimumDesignTimeRoslynVersion(Version version) =>
minimumDesignTimeRoslynVersion = version;

internal static Version GetMinimumDesignTimeRoslynVersion() =>
minimumDesignTimeRoslynVersion;

private static bool ShouldRaiseOnRazorFile(ref Diagnostic diagnostic)
{
// On design time, we only raise on generated .ide.g.cs files if the diagnostic has a mapped location.
if (GeneratedCodeRecognizer.IsDesignTimeRazorGeneratedFile(diagnostic.Location.SourceTree))
{
return diagnostic.Location.GetMappedLineSpan().HasMappedPath
&& !ExcludedFromDesignTimeRuleIds.Contains(diagnostic.Id);
&& !ExcludedFromDesignTimeRuleIds.Contains(diagnostic.Id)
// We only want to raise on design time generated files if the Visual studio version is >= 17.9 which we infer from the Roslyn version
// https://learn.microsoft.com/en-us/visualstudio/extensibility/roslyn-version-support?view=vs-2022
&& !RoslynVersion.IsVersionLessThan(minimumDesignTimeRoslynVersion);
}
// On build time, if the diagnostic has a mapped location, we do the mapping ourselves and raise there.
else if (GeneratedCodeRecognizer.IsBuildTimeRazorGeneratedFile(diagnostic.Location.SourceTree))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace SonarAnalyzer.Core.Test.Common;
[TestClass]
public class IssueReporterTest
{
private readonly Version defaultVersion = new Version("4.9.2");
private readonly DummyDiagnosticReporter reporter = new();

[DataTestMethod]
Expand Down Expand Up @@ -60,16 +61,65 @@ public void ReportIssueCore_DesignTimeDiagnostic_HasMappedPath_False()
reporter.LastDiagnostic.Should().BeNull();
}

private Diagnostic ReportDiagnostic(string filePath, bool hasMappedPath, string diagnosticId = "id")
[TestMethod]
public void ReportIssueCore_DesignTimeDiagnostic_RoslynVersion_1000_0_0()
{
ReportDiagnostic(@"C:\SonarSource\SomeFile.razor.-6NXeWT5Akt4vxdz.ide.g.cs", hasMappedPath: true, roslynVersion: new Version(1000, 0, 0));
reporter.Counter.Should().Be(0);
reporter.LastDiagnostic.Should().BeNull();
}

[TestMethod]
public void ReportIssueCore_DesignTimeDiagnostic_RoslynVersion_Greater_Than_Current()
{
Version current = new(typeof(SemanticModel).Assembly.GetName().Version.ToString());
Version greaterThanCurrent = new(current.Major, current.Minor, current.Build + 1);

ReportDiagnostic(@"C:\SonarSource\SomeFile.razor.-6NXeWT5Akt4vxdz.ide.g.cs", hasMappedPath: true, roslynVersion: greaterThanCurrent);
reporter.Counter.Should().Be(0);
reporter.LastDiagnostic.Should().BeNull();
}

[TestMethod]
public void ReportIssueCore_DesignTimeDiagnostic_RoslynVersion_Less_Than_Current()
{
var lessthanCurrent = LessThanCurrent();

var diagnostic = ReportDiagnostic(@"C:\SonarSource\SomeFile.razor.-6NXeWT5Akt4vxdz.ide.g.cs", hasMappedPath: true, roslynVersion: lessthanCurrent);
reporter.Counter.Should().Be(1);
reporter.LastDiagnostic.Should().Be(diagnostic);

static Version LessThanCurrent()
{
var roslynVersion = new Version(typeof(SemanticModel).Assembly.GetName().Version.ToString());
return roslynVersion.Build switch
{
> 0 => new Version(roslynVersion.Major, roslynVersion.Minor, roslynVersion.Build - 1),
_ when roslynVersion.Minor > 0 => new Version(roslynVersion.Major, roslynVersion.Minor - 1),
_ => new Version(roslynVersion.Major - 1, 99, 99),
};
}
}

[TestMethod]
public void ReportIssueCore_MinimumRoslyVersion_Is_4_9_2() =>
Assert.AreEqual(defaultVersion, IssueReporter.GetMinimumDesignTimeRoslynVersion());

private Diagnostic ReportDiagnostic(string filePath, bool hasMappedPath, string diagnosticId = "id", Version roslynVersion = null)
{
roslynVersion ??= defaultVersion;
var tree = GetTree(filePath);
var diagnostic = GetDiagnostic(diagnosticId, tree, hasMappedPath);

IssueReporter.SetMinimumDesignTimeRoslynVersion(roslynVersion);

IssueReporter.ReportIssueCore(
x => true,
x => new DummyReportingContext(reporter, x, tree),
diagnostic);

IssueReporter.SetMinimumDesignTimeRoslynVersion(defaultVersion);

return diagnostic;
}

Expand Down

0 comments on commit deef83e

Please sign in to comment.