Piggy back off Roslyn CodeFixProvider を使用してパラメーターをメソッドに追加します。
CodeFixProvider
すべての非同期メソッドが確実に取得できるようにするための作成に取り組んでいますCancellationToken
:
//Before Code Fix:
public async Task Example(){}
//After Code Fix
public async Task Example(CancellationToken token){}
パラメータをメソッドに追加することはできますが、Type.FullName
. System.Threading
代わりに、using ステートメントをクラス ファイルの先頭に追加して、メソッドが完全な名前空間を使用する必要がないようにしたいと考えています。言い換えると:
// What I have thus far:
public class AClass{
public async Task Example(System.Threading.CancellationToken token){}
}
// What I want:
using System.Threading;
public class AClass{
public async Task Example(CancellationToken token){}
}
usingステートメントをに追加するにはどうすればよいDocument
ですか?
私はいくつかの方法を試しましたが、SyntaxTree
参照内の複数のノードを置き換えると継ぎ目が失われます (ツリーは不変であり、変更のたびに再構築されるため)。
以下のコードで部分的に動作させることができましたが、これはプロパティが設定されている場合にのみ機能し、名前空間の後CompilationUnitSyntax.Using
にステートメントを使用する場合はそうではありません。また、これは、ファイルに少なくとも 1 つのステートメントが既に存在することにも依存しています。 using
これを行うより良い方法はありますか?
private async Task<Document> HaveMethodTakeACancellationTokenParameter(
Document document, SyntaxNode syntaxNode, CancellationToken cancellationToken)
{
var syntaxTree =
(await document.GetSyntaxTreeAsync(cancellationToken))
.GetRoot(cancellationToken);
var method = syntaxNode as MethodDeclarationSyntax;
#region Add Parameter
var newParameter =
SyntaxFactory.Parameter(
SyntaxFactory.Identifier("cancellationToken")
)
.WithType(
SyntaxFactory.ParseTypeName(
typeof(CancellationToken).FullName));
var updatedMethod = method.AddParameterListParameters(newParameter);
syntaxTree = syntaxTree.ReplaceNode(method, updatedMethod);
#endregion
#region Add Using Statements
var compilation =
syntaxTree as CompilationUnitSyntax;
var systemThreadingUsingName =
SyntaxFactory.QualifiedName(
SyntaxFactory.IdentifierName("System"),
SyntaxFactory.IdentifierName("Threading"));
if (compilation.Usings.All(u => u.Name.GetText().ToString() != typeof(CancellationToken).Namespace))
{
syntaxTree = syntaxTree.InsertNodesAfter(compilation.Usings.Last(), new[]
{
SyntaxFactory.UsingDirective(
systemThreadingUsingName)
});
}
#endregion
return document.WithSyntaxRoot(syntaxTree);
}