Skip to content

Commit 014c5ae

Browse files
authored
Merge pull request #6 from PandaTechAM/development
fixing small thing
2 parents cfcb848 + 12f6080 commit 014c5ae

File tree

4 files changed

+53
-86
lines changed

4 files changed

+53
-86
lines changed

src/Analyzers/Analyzers.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<PackageId>Pandatech.Analyzers</PackageId>
1919
<PackageIcon>pandatech.png</PackageIcon>
2020
<PackageReadmeFile>Readme.md</PackageReadmeFile>
21-
<Version>1.4.2</Version>
21+
<Version>1.4.3</Version>
2222
<Authors>Pandatech</Authors>
2323
<Description>Pandatech Roslyn analyzers enforcing company coding rules.</Description>
2424
<PackageLicenseExpression>MIT</PackageLicenseExpression>

src/Analyzers/Async/AsyncMethodConventionsCodeFixProvider.cs

Lines changed: 50 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ private static async Task<Solution> RenameCancellationTokenForInterfaceAndImplem
989989
IMethodSymbol interfaceMethod,
990990
CancellationToken cancellationToken)
991991
{
992-
// 1. Find CT parameter ordinal on the interface
992+
// 1. Find CT parameter index on the interface
993993
var ctIndex = -1;
994994
for (var i = 0; i < interfaceMethod.Parameters.Length; i++)
995995
{
@@ -1006,9 +1006,14 @@ private static async Task<Solution> RenameCancellationTokenForInterfaceAndImplem
10061006
return solution;
10071007
}
10081008

1009-
// 2. Collect interface + implementing methods
1010-
var allMethods = ImmutableArray.CreateBuilder<IMethodSymbol>();
1011-
allMethods.Add(interfaceMethod);
1009+
// 2. Collect documentation IDs for the interface method and all implementations
1010+
var methodIds = new List<string>();
1011+
1012+
var interfaceId = interfaceMethod.GetDocumentationCommentId();
1013+
if (!string.IsNullOrEmpty(interfaceId))
1014+
{
1015+
methodIds.Add(interfaceId!);
1016+
}
10121017

10131018
var impls = await SymbolFinder.FindImplementationsAsync(
10141019
interfaceMethod,
@@ -1019,92 +1024,73 @@ private static async Task<Solution> RenameCancellationTokenForInterfaceAndImplem
10191024

10201025
foreach (var impl in impls.OfType<IMethodSymbol>())
10211026
{
1022-
if (impl.DeclaringSyntaxReferences.Length > 0)
1027+
if (impl.DeclaringSyntaxReferences.Length == 0)
10231028
{
1024-
allMethods.Add(impl);
1029+
continue; // skip metadata-only
10251030
}
1026-
}
10271031

1028-
// 3. Group by document
1029-
var methodsByDocument = new Dictionary<DocumentId, ImmutableArray<MethodDeclarationSyntax>.Builder>();
1032+
var id = impl.GetDocumentationCommentId();
1033+
if (!string.IsNullOrEmpty(id))
1034+
{
1035+
methodIds.Add(id!);
1036+
}
1037+
}
10301038

1031-
foreach (var method in allMethods)
1039+
// 3. Resolve each method symbol in the current solution and rename its CT param
1040+
foreach (var methodId in methodIds)
10321041
{
1033-
foreach (var syntaxRef in method.DeclaringSyntaxReferences)
1042+
IMethodSymbol? methodSymbol = null;
1043+
1044+
foreach (var project in solution.Projects)
10341045
{
1035-
var syntax = await syntaxRef.GetSyntaxAsync(cancellationToken)
1036-
.ConfigureAwait(false);
1037-
if (syntax is not MethodDeclarationSyntax methodDecl)
1046+
var compilation = await project.GetCompilationAsync(cancellationToken)
1047+
.ConfigureAwait(false);
1048+
if (compilation is null)
10381049
{
10391050
continue;
10401051
}
10411052

1042-
var doc = solution.GetDocument(methodDecl.SyntaxTree);
1043-
if (doc is null)
1044-
{
1045-
continue;
1046-
}
1053+
var symbol = DocumentationCommentId.GetFirstSymbolForDeclarationId(methodId, compilation)
1054+
as IMethodSymbol;
10471055

1048-
var docId = doc.Id;
1049-
if (!methodsByDocument.TryGetValue(docId, out var list))
1056+
if (symbol is null)
10501057
{
1051-
list = ImmutableArray.CreateBuilder<MethodDeclarationSyntax>();
1052-
methodsByDocument[docId] = list;
1058+
continue;
10531059
}
10541060

1055-
list.Add(methodDecl);
1061+
methodSymbol = symbol;
1062+
break;
10561063
}
1057-
}
1058-
1059-
// 4. Rewrite name in each method declaration at the same ordinal
1060-
foreach (var kvp in methodsByDocument)
1061-
{
1062-
var docId = kvp.Key;
1063-
var methodDecls = kvp.Value.ToImmutable();
10641064

1065-
var document = solution.GetDocument(docId);
1066-
if (document is null)
1065+
if (methodSymbol is null)
10671066
{
10681067
continue;
10691068
}
10701069

1071-
var root = await document.GetSyntaxRootAsync(cancellationToken)
1072-
.ConfigureAwait(false);
1073-
if (root is null)
1070+
if (ctIndex >= methodSymbol.Parameters.Length)
10741071
{
1072+
// Signature drifted – be conservative.
10751073
continue;
10761074
}
10771075

1078-
var newRoot = root.ReplaceNodes(
1079-
methodDecls,
1080-
(original, _) =>
1081-
{
1082-
var parameters = original.ParameterList.Parameters;
1083-
if (ctIndex < 0 || ctIndex >= parameters.Count)
1084-
{
1085-
// Signature drifted; be conservative.
1086-
return original;
1087-
}
1088-
1089-
var ctParamSyntax = parameters[ctIndex];
1090-
1091-
// If it's already 'ct', no change needed.
1092-
if (ctParamSyntax.Identifier.Text == "ct")
1093-
{
1094-
return original;
1095-
}
1096-
1097-
var newCtParamSyntax = ctParamSyntax.WithIdentifier(
1098-
SyntaxFactory.Identifier("ct")
1099-
.WithTriviaFrom(ctParamSyntax.Identifier));
1100-
1101-
var newParameters = parameters.Replace(ctParamSyntax, newCtParamSyntax);
1076+
var p = methodSymbol.Parameters[ctIndex];
1077+
if (!IsCancellationToken(p.Type))
1078+
{
1079+
continue;
1080+
}
11021081

1103-
return original.WithParameterList(
1104-
original.ParameterList.WithParameters(newParameters));
1105-
});
1082+
if (string.Equals(p.Name, "ct", StringComparison.Ordinal))
1083+
{
1084+
continue;
1085+
}
11061086

1107-
solution = solution.WithDocumentSyntaxRoot(docId, newRoot);
1087+
solution = await Renamer.RenameSymbolAsync(
1088+
solution,
1089+
p,
1090+
new SymbolRenameOptions(),
1091+
"ct",
1092+
cancellationToken)
1093+
.ConfigureAwait(false);
11081094
}
11091095

11101096
return solution;

test/Analyzers.Sample/Async/Examples1.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public Task<Order> GetOrderByCodeAsync(CancellationToken token, string code)
4343

4444
public Task<Order> GetSomethingAsync(CancellationToken ct = default, params string[] args)
4545
{
46+
ct.ThrowIfCancellationRequested();
4647
throw new System.NotImplementedException();
4748
}
4849

test/Analyzers.Tests/AsyncMethodConventionsAnalyzerTests.cs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -113,27 +113,7 @@ public class Service : IService
113113

114114
await VerifyCS.VerifyAnalyzerAsync(code);
115115
}
116-
117-
[Fact]
118-
public async Task Ct_name_rule_applies_on_contract_implementation()
119-
{
120-
const string code = """
121-
using System.Threading;
122-
using System.Threading.Tasks;
123-
124-
public interface IService
125-
{
126-
Task GetValueAsync(CancellationToken ct);
127-
}
128-
129-
public class Service : IService
130-
{
131-
public Task {|PT0003:GetValueAsync|}(CancellationToken token) => Task.CompletedTask;
132-
}
133-
""";
134-
135-
await VerifyCS.VerifyAnalyzerAsync(code);
136-
}
116+
137117

138118
[Fact]
139119
public async Task Ct_before_params_is_considered_last_non_params()

0 commit comments

Comments
 (0)