2014-11-02 10 views
10

Birkaç gün önce TechEd'deydim ve this talk by Kevin Pilch-Bisson (relevent part starts at about 18 minutes)'u gördüm ... Oldukça havalı olduğunu düşündüm, bu yüzden kendimle Roslyn ile oynamaya karar verdim.Roslyn CodeFixProvider kullanarak yönteme erişim düzenleyici ekleyin?

static void Main(string[] args) 
    { 
    } 

Bu ok: -

Ben bir kural "Erişim Değiştirici Beyan Edilmelidir" yapmaya çalışıyorum (StyleCop SA1400) anlamı,

Bu kural ihlal

public static void Main(string[] args) 
    { 
    } 

Açık dahili bir anahtar kelimeye, genel anahtar kelimeye, özel anahtar kelimeye veya pro isabetli olmalıdır. anahtar kelime.

İhlalin algılanması oldukça kolaydı, ancak şimdi bir düzeltme sağlamaya çalışıyorum. Bir şeyler denedim ve her yerde arama yaptım, ancak erişim düzenleyicileri nasıl ekleyeceğimi bulamıyorum.

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken) 
{ 
    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); 
    var token = root.FindToken(span.Start); 

    var methodDeclaration = token.Parent as MethodDeclarationSyntax; 

    //var newModifiers = methodDeclaration.Modifiers.Add(SyntaxFactory.AccessorDeclaration(SyntaxKind.PublicKeyword));   
    //var newModifiers = new SyntaxTokenList() { new SyntaxToken() }; 

    MethodDeclarationSyntax newMethodDeclaration = methodDeclaration.WithModifiers(methodDeclaration.Modifiers); 
    var newRoot = root.ReplaceNode(methodDeclaration, newMethodDeclaration); 
    var newDocument = document.WithSyntaxRoot(newRoot); 

    return new[] { CodeAction.Create("Add Public Keyword", newDocument) }; 
} 

WithModifiers New(), ama SyntaxKind.PublicKeyword yapmak için nasıl bilmiyorum bir SyntaxTokenList ihtiyacı:

Bu defa ne var. Ben de yeni varsayalım veya SyntaxFactory kullanın emin değilim. SyntaxFactory kullanırken Ancak, ben de ... Ben ilgi duyulup duyulmadığını ben DiagnosticAnalyzer dahil olmak üzere tüm şeyi gönderebilir bir SyntaxTokenSyntaxKind.PublicKeyword

ait oluşturmak için gereken hangi yöntemi çözemiyorum

cevap

3

yardımcı

var newModifiers = SyntaxFactory.TokenList(modifiers.Concat(new[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword)})); 
var newMethodDeclaration = methodDeclaration.WithModifiers(newModifiers); 

oldu bu:

Chris Eelmaa önerdi neredeyse ne
var newModifiers = SyntaxFactory.TokenList(SyntaxFactory.Token(accessModifierToken)) 
.AddRange(methodDeclaration.Modifiers); 

Its ama Bu öneri ile geçerli, ancak çirkin olan static public void Main ile bitti.

Genel kullanıma eklenmesi onu listenin sonuna ekler ve bildiğim kadarıyla, erişim değiştiricisinin her zaman ilk olması gerekir.

+1

Kullanılmayan bir yerel "public TokenList" iniz olması dışında bana iyi görünüyor. Tıkladığınızda olduğu gibi önizlemeyi oluşturmak için Func'iniz çağrılacak, ancak bu iyi olmalı –

+0

Tamam teşekkürler :). publicTokenList, genellikle yeniden satıcılar bana bu konuda söyler, ama ben 14'te çalıştığım için bunu yapmamıştım .. –

1

Eh, public static belirten bir değiştiricileri oluşturmak için, bu kullanabilirsiniz:

var modifiers = SyntaxFactory.TokenList(
    new SyntaxToken[] { 
     SyntaxFactory.Token(SyntaxKind.PublicKeyword), 
     SyntaxFactory.Token(SyntaxKind.StaticKeyword) 
    }), 

Ama senin durumunda

, nedenini

var updatedModifiers = methodDeclaration 
       .Modifiers 
       .Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); 

methodDeclaration.WithModifiers(updatedModifiers); 
görmüyorum

işe yaramaz.

+0

İlk öneri işe yaramıyor çünkü açıkçası her zaman statik gerekmiyor, ancak sözdizimini açıklamaya çalışıyorum ... Yine de ikinci öneri gerçekten işe yaramıyor. veya statik publicvoid Ana –

+0

@RonSijm, +1. Cevabınızı temizlerseniz ve sadece ilgili şeyleri koyarsanız (örneğin, GetFixesAsync ve CreateAction'dan kurtulmak) ve bunu kabul ederseniz hiçbir problemim olmaz. Bu güzel bir soru. –

6

Konuşmayı beğendiğinize sevindim! Biz aslında daha kolay listeye öğe eklemek için yapmak sözdizimi modelinde bazı yardımcıları var, yani böyle bir şey yapmak mümkün olmalıdır: Yeni yöntem beyanı almak için

var newMethodDeclaration = methodDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); 

. gibi bir şey

bu genişletilmiş biçimi şöyle olacaktır: Umut bu aslında gerekli Ne

+0

Konuşmadan çok hoşlandım! Async one ile birlikte, teknikte gördüğüm en iyi konuşma hakkında :) - Her neyse, sizin önerileriniz bir tür iş, ama ben 'statik kamusal boşluk Ana' ile sona erer. Çalıştığım gibi görünen kendi çözümümü ekledim. Eğer bir şey garip bir şey yaptım, bu olsa da eğer olabilirdi, bu harika olurdu. Roslyn için yaptığım ilk şey, muhtemelen –

+0

Oh btw'yi geliştirmek için bir sürü şey vardır, neden AnalyzeNode'un sözdizimi şöyledir: public void AnalyzeNode (SyntaxNode düğümü, SemanticModel semanticModel, Eylem addDiagnostic) ve buna değil : 'public Action AnalyzeNode (SyntaxNode node, SemanticModel semanticModel'? Bu biraz garip görünüyor –

+1

Birden fazla tanılamayı rapor edebilirsiniz çünkü Ayrıca, bir geri arama olması bazı tahsisatlardan kaçınmamızı ve sonuçları bildirirken sonuçları akışa geçirmemizi sağlar. eşzamansız bir şekilde –