-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
33 changed files
with
412 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
<Project> | ||
<PropertyGroup> | ||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageVersion Include="coverlet.collector" Version="6.0.2" /> | ||
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.1.1" /> | ||
<PackageVersion Include="DotNet.ReproducibleBuilds.Isolated" Version="1.1.1" /> | ||
<PackageVersion Include="EcoCode" Version="1.0.1-beta7" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.MSTest" Version="1.1.1" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.MSTest" Version="1.1.1" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" /> | ||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> | ||
<PackageVersion Include="Microsoft.VSSDK.BuildTools" Version="17.9.3174" /> | ||
<PackageVersion Include="MSTest.TestAdapter" Version="3.2.2" /> | ||
<PackageVersion Include="MSTest.TestFramework" Version="3.2.2" /> | ||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageVersion Include="coverlet.collector" Version="6.0.2" /> | ||
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.1.1" /> | ||
<PackageVersion Include="DotNet.ReproducibleBuilds.Isolated" Version="1.1.1" /> | ||
<PackageVersion Include="EcoCode" Version="1.0.1" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.MSTest" Version="1.1.1" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.MSTest" Version="1.1.1" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" /> | ||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" /> | ||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> | ||
<PackageVersion Include="Microsoft.VSSDK.BuildTools" Version="17.9.3174" /> | ||
<PackageVersion Include="MSTest.TestAdapter" Version="3.2.2" /> | ||
<PackageVersion Include="MSTest.TestFramework" Version="3.2.2" /> | ||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
src/EcoCode.Analyzers/Analyzers/EC81_SpecifyStructLayoutAnalyzer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
namespace EcoCode.Analyzers; | ||
|
||
/// <summary>Analyzer for specify struct layout.</summary> | ||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
public sealed class SpecifyStructLayoutAnalyzer : DiagnosticAnalyzer | ||
{ | ||
private static readonly ImmutableArray<SymbolKind> SymbolKinds = [SymbolKind.NamedType]; | ||
|
||
/// <summary>The diagnostic descriptor.</summary> | ||
public static DiagnosticDescriptor Descriptor { get; } = new( | ||
Rule.Ids.EC81_UseStructLayout, | ||
title: "Use struct layout", | ||
messageFormat: "Use struct layout", | ||
Rule.Categories.Performance, | ||
DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true, | ||
description: string.Empty, | ||
helpLinkUri: Rule.GetHelpUri(Rule.Ids.EC81_UseStructLayout)); | ||
|
||
/// <inheritdoc/> | ||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Descriptor]; | ||
|
||
/// <inheritdoc/> | ||
public override void Initialize(AnalysisContext context) | ||
{ | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.EnableConcurrentExecution(); | ||
context.RegisterSymbolAction(static context => Analyze(context), SymbolKinds); | ||
} | ||
|
||
private static void Analyze(SymbolAnalysisContext context) | ||
{ | ||
if (context.Symbol is not INamedTypeSymbol symbol || !symbol.IsValueType || symbol.EnumUnderlyingType is not null) | ||
return; | ||
|
||
var structLayoutAttributeType = context.Compilation.GetBestTypeByMetadataName("System.Runtime.InteropServices.StructLayoutAttribute"); | ||
if (structLayoutAttributeType is null) return; | ||
|
||
foreach (var attr in symbol.GetAttributes()) | ||
{ | ||
if (SymbolEqualityComparer.Default.Equals(structLayoutAttributeType, attr.AttributeClass)) | ||
return; | ||
} | ||
|
||
int memberCount = 0; | ||
foreach (var member in symbol.GetMembers()) | ||
{ | ||
if (member is not IFieldSymbol fieldSymbol || fieldSymbol.IsConst || fieldSymbol.IsStatic) | ||
continue; | ||
|
||
if (fieldSymbol.Type.IsReferenceType) return; // A struct containing a reference type is always in auto layout | ||
memberCount++; | ||
} | ||
|
||
if (memberCount < 2) return; | ||
foreach (var location in symbol.Locations) | ||
context.ReportDiagnostic(Diagnostic.Create(Descriptor, location)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/EcoCode.CodeFixes/CodeFixes/EC81_SpecifyStructLayoutCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Editing; | ||
using Microsoft.CodeAnalysis.Simplification; | ||
using System.Threading; | ||
|
||
namespace EcoCode.CodeFixes; | ||
|
||
/// <summary>The code fix provider for use struct layout.</summary> | ||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(SpecifyStructLayoutCodeFixProvider)), Shared] | ||
public sealed class SpecifyStructLayoutCodeFixProvider : CodeFixProvider | ||
{ | ||
/// <inheritdoc/> | ||
public override ImmutableArray<string> FixableDiagnosticIds => [SpecifyStructLayoutAnalyzer.Descriptor.Id]; | ||
|
||
/// <inheritdoc/> | ||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; | ||
|
||
/// <inheritdoc/> | ||
public override async Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); | ||
var node = root?.FindNode(context.Span, getInnermostNodeForTie: true); | ||
if (node is not TypeDeclarationSyntax nodeToFix) return; | ||
|
||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
"Add Auto StructLayout attribute", | ||
ct => Refactor(context.Document, nodeToFix, LayoutKind.Auto, ct), | ||
equivalenceKey: "Add Auto StructLayout attribute"), | ||
context.Diagnostics); | ||
|
||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
"Add Sequential StructLayout attribute", | ||
ct => Refactor(context.Document, nodeToFix, LayoutKind.Sequential, ct), | ||
equivalenceKey: "Add Sequential StructLayout attribute"), | ||
context.Diagnostics); | ||
} | ||
|
||
private static async Task<Document> Refactor(Document document, SyntaxNode nodeToFix, LayoutKind layoutKind, CancellationToken cancellationToken) | ||
{ | ||
var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); | ||
|
||
var structLayoutAttributeType = editor.SemanticModel.Compilation.GetBestTypeByMetadataName("System.Runtime.InteropServices.StructLayoutAttribute"); | ||
if (structLayoutAttributeType is null) return document; | ||
|
||
var layoutKindType = editor.SemanticModel.Compilation.GetBestTypeByMetadataName("System.Runtime.InteropServices.LayoutKind"); | ||
if (layoutKindType is null) return document; | ||
|
||
editor.AddAttribute(nodeToFix, editor.Generator.Attribute( | ||
editor.Generator.TypeExpression(structLayoutAttributeType).WithAdditionalAnnotations(Simplifier.AddImportsAnnotation), | ||
[ | ||
editor.Generator.AttributeArgument(editor.Generator.MemberAccessExpression( | ||
editor.Generator.TypeExpression(layoutKindType).WithAdditionalAnnotations(Simplifier.AddImportsAnnotation), | ||
layoutKind.ToString())), | ||
])); | ||
return editor.GetChangedDocument(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
global using EcoCode.Analyzers; | ||
global using EcoCode.Shared; | ||
global using Microsoft.CodeAnalysis; | ||
global using Microsoft.CodeAnalysis.CodeFixes; | ||
global using System.Collections.Immutable; | ||
global using System.Composition; | ||
global using System.Runtime.InteropServices; | ||
global using System.Threading.Tasks; | ||
global using System.Threading.Tasks; |
Oops, something went wrong.