Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0853101

Browse files
committed
Provide analyzer for removing unneeded public partial class Program (#58482)
* Provide analyzer for removing unneeded public partial class Program* Update tests and fix async call* Address feedback* Add test for public partial class with members* Reorganize checks and add tests
1 parenta74dc5a commit0853101

File tree

5 files changed

+405
-28
lines changed

5 files changed

+405
-28
lines changed

‎src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,14 @@ internal static class DiagnosticDescriptors
223223
DiagnosticSeverity.Warning,
224224
isEnabledByDefault:true,
225225
helpLinkUri:"https://aka.ms/aspnet/analyzers");
226+
227+
internalstaticreadonlyDiagnosticDescriptorPublicPartialProgramClassNotRequired=new(
228+
"ASP0027",
229+
newLocalizableResourceString(nameof(Resources.Analyzer_PublicPartialProgramClass_Title),Resources.ResourceManager,typeof(Resources)),
230+
newLocalizableResourceString(nameof(Resources.Analyzer_PublicPartialProgramClass_Message),Resources.ResourceManager,typeof(Resources)),
231+
"Usage",
232+
DiagnosticSeverity.Info,
233+
isEnabledByDefault:true,
234+
helpLinkUri:"https://aka.ms/aspnet/analyzers",
235+
customTags:WellKnownDiagnosticTags.Unnecessary);
226236
}

‎src/Framework/AspNetCoreAnalyzers/src/Analyzers/Resources.resx

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<root>
3-
<!--
4-
Microsoft ResX Schema
5-
3+
<!--
4+
Microsoft ResX Schema
5+
66
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
1111
associated with the data types.
12-
12+
1313
Example:
14-
14+
1515
... ado.net/XML headers & schema ...
1616
<resheader name="resmimetype">text/microsoft-resx</resheader>
1717
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
2626
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
2727
<comment>This is a comment</comment>
2828
</data>
29-
30-
There are any number of "resheader" rows that contain simple
29+
30+
There are any number of "resheader" rows that contain simple
3131
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
3737
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
4141
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
4545
read any of the formats listed below.
46-
46+
4747
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
48+
value : The object must be serialized with
4949
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
5050
: and then encoded with base64 encoding.
51-
51+
5252
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
53+
value : The object must be serialized with
5454
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
5555
: and then encoded with base64 encoding.
5656
5757
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
58+
value : The object must be serialized into a byte array
5959
: using a System.ComponentModel.TypeConverter
6060
: and then encoded with base64 encoding.
6161
-->
@@ -321,4 +321,10 @@
321321
<dataname="Analyzer_OverriddenAuthorizeAttribute_Title"xml:space="preserve">
322322
<value>[Authorize] overridden by [AllowAnonymous] from farther away</value>
323323
</data>
324-
</root>
324+
<dataname="Analyzer_PublicPartialProgramClass_Message"xml:space="preserve">
325+
<value>Using public partial class Program { } to make the generated Program class public is no longer required in ASP.NET Core apps. See https://aka.ms/aspnetcore-warnings/ASP0027 for more details.</value>
326+
</data>
327+
<dataname="Analyzer_PublicPartialProgramClass_Title"xml:space="preserve">
328+
<value>Unnecessary public Program class declaration</value>
329+
</data>
330+
</root>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
usingSystem.Collections.Immutable;
5+
usingSystem.Linq;
6+
usingMicrosoft.CodeAnalysis;
7+
usingMicrosoft.CodeAnalysis.CSharp;
8+
usingMicrosoft.CodeAnalysis.CSharp.Syntax;
9+
usingMicrosoft.CodeAnalysis.Diagnostics;
10+
11+
namespaceMicrosoft.AspNetCore.Analyzers;
12+
13+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
14+
publicsealedclassPublicPartialProgramClassAnalyzer:DiagnosticAnalyzer
15+
{
16+
publicoverrideImmutableArray<DiagnosticDescriptor>SupportedDiagnostics=>ImmutableArray.Create(DiagnosticDescriptors.PublicPartialProgramClassNotRequired);
17+
18+
publicoverridevoidInitialize(AnalysisContextcontext)
19+
{
20+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
21+
context.EnableConcurrentExecution();
22+
context.RegisterSyntaxNodeAction(context=>
23+
{
24+
varsyntaxNode=context.Node;
25+
if(IsPublicPartialClassProgram(syntaxNode))
26+
{
27+
context.ReportDiagnostic(Diagnostic.Create(
28+
DiagnosticDescriptors.PublicPartialProgramClassNotRequired,
29+
syntaxNode.GetLocation()));
30+
}
31+
},SyntaxKind.ClassDeclaration);
32+
}
33+
34+
privatestaticboolIsPublicPartialClassProgram(SyntaxNodesyntaxNode)
35+
{
36+
returnsyntaxNodeisClassDeclarationSyntax{Modifiers:{}modifiers}classDeclaration
37+
&&classDeclaration.ParentisCompilationUnitSyntaxparentNode
38+
&&classDeclarationis{Identifier.ValueText:"Program"}
39+
&&(classDeclaration.Members==null||classDeclaration.Members.Count==0)// Skip non-empty declarations
40+
&&modifiersis{Count:>1}
41+
&&modifiers.Any(SyntaxKind.PublicKeyword)
42+
&&modifiers.Any(SyntaxKind.PartialKeyword)
43+
&&parentNode.DescendantNodes().Count()>1;
44+
}
45+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
usingSystem.Collections.Immutable;
5+
usingSystem.Composition;
6+
usingSystem.Threading.Tasks;
7+
usingMicrosoft.AspNetCore.Analyzers;
8+
usingMicrosoft.CodeAnalysis;
9+
usingMicrosoft.CodeAnalysis.CodeActions;
10+
usingMicrosoft.CodeAnalysis.CodeFixes;
11+
usingMicrosoft.CodeAnalysis.CSharp.Syntax;
12+
usingMicrosoft.CodeAnalysis.Editing;
13+
14+
namespaceMicrosoft.AspNetCore.Fixers;
15+
16+
[ExportCodeFixProvider(LanguageNames.CSharp),Shared]
17+
publicclassPublicPartialProgramClassFixer:CodeFixProvider
18+
{
19+
publicoverrideImmutableArray<string>FixableDiagnosticIds{get;}=[DiagnosticDescriptors.PublicPartialProgramClassNotRequired.Id];
20+
21+
publicsealedoverrideFixAllProviderGetFixAllProvider()=>WellKnownFixAllProviders.BatchFixer;
22+
23+
publicsealedoverrideTaskRegisterCodeFixesAsync(CodeFixContextcontext)
24+
{
25+
foreach(vardiagnosticincontext.Diagnostics)
26+
{
27+
context.RegisterCodeFix(
28+
CodeAction.Create("Remove unnecessary public partial class Program declaration",
29+
async cancellationToken=>
30+
{
31+
vareditor=awaitDocumentEditor.CreateAsync(context.Document,cancellationToken).ConfigureAwait(false);
32+
varroot=awaitcontext.Document.GetSyntaxRootAsync(cancellationToken);
33+
if(rootisnull)
34+
{
35+
returncontext.Document;
36+
}
37+
38+
varclassDeclaration=root.FindNode(diagnostic.Location.SourceSpan)
39+
.FirstAncestorOrSelf<ClassDeclarationSyntax>();
40+
if(classDeclarationisnull)
41+
{
42+
returncontext.Document;
43+
}
44+
editor.RemoveNode(classDeclaration,SyntaxRemoveOptions.KeepExteriorTrivia);
45+
returneditor.GetChangedDocument();
46+
},
47+
equivalenceKey:DiagnosticDescriptors.PublicPartialProgramClassNotRequired.Id),
48+
diagnostic);
49+
}
50+
51+
returnTask.CompletedTask;
52+
}
53+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp