Working on VSDiagnostics, I implemented a tool that adds the default access modifiers to C# code.  An example use would be starting with this:static class Foo { }And ending with this:internal static class Foo { }This is the analyzer:public override void Initialize(AnalysisContext context){    context.RegisterSyntaxNodeAction(AnalyzeSymbol,        SyntaxKind.ClassDeclaration,        SyntaxKind.ConstructorDeclaration,        SyntaxKind.DelegateDeclaration,        SyntaxKind.EnumDeclaration,        SyntaxKind.EventDeclaration,        SyntaxKind.EventFieldDeclaration,        SyntaxKind.FieldDeclaration,        SyntaxKind.IndexerDeclaration,        SyntaxKind.InterfaceDeclaration,        SyntaxKind.MethodDeclaration,        SyntaxKind.PropertyDeclaration,        SyntaxKind.StructDeclaration);}private void AnalyzeSymbol(SyntaxNodeAnalysisContext context){    if (context.Node is ClassDeclarationSyntax)    {        var declarationExpression = (ClassDeclarationSyntax) context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is StructDeclarationSyntax)    {        var declarationExpression = (StructDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is EnumDeclarationSyntax)    {        var declarationExpression = (EnumDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is DelegateDeclarationSyntax)    {        var declarationExpression = (DelegateDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is InterfaceDeclarationSyntax)    {        var declarationExpression = (InterfaceDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is FieldDeclarationSyntax)    {        var declarationExpression = (FieldDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                private));        }    }    if (context.Node is PropertyDeclarationSyntax)    {        var declarationExpression = (PropertyDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is MethodDeclarationSyntax)    {        var declarationExpression = (MethodDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is ConstructorDeclarationSyntax)    {        var declarationExpression = (ConstructorDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind()) || m.Kind() == SyntaxKind.StaticKeyword))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is EventFieldDeclarationSyntax)    {        var declarationExpression = (EventFieldDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                private));        }    }    if (context.Node is EventDeclarationSyntax)    {        var declarationExpression = (EventDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }    if (context.Node is IndexerDeclarationSyntax)    {        var declarationExpression = (IndexerDeclarationSyntax)context.Node;        if (!declarationExpression.Modifiers.Any(m => _accessModifierKinds.Contains(m.Kind())))        {            var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationExpression).DeclaredAccessibility;            context.ReportDiagnostic(Diagnostic.Create(Rule, declarationExpression.GetLocation(),                accessibility.ToString().ToLower()));        }    }}private readonly SyntaxKind[] _accessModifierKinds ={    SyntaxKind.PublicKeyword,    SyntaxKind.ProtectedKeyword,    SyntaxKind.InternalKeyword,    SyntaxKind.PrivateKeyword};I cannot get the current access modifier for EventFieldDeclarations and FieldDeclarations because the type containing the access modifier is a child of this type.This is the code fix:public override async Task RegisterCodeFixesAsync(CodeFixContext context){    var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);    var diagnostic = context.Diagnostics.First();    var diagnosticSpan = diagnostic.Location.SourceSpan;    var statement = root.FindNode(diagnosticSpan);    var semanticModel = context.Document.GetSemanticModelAsync().Result;    var symbol = semanticModel.GetDeclaredSymbol(statement);    var accessibility = symbol?.DeclaredAccessibility ?? Accessibility.Private;    context.RegisterCodeFix(CodeAction.Create(VSDiagnosticsResources.ExplicitAccessModifiersCodeFixTitle, x => AddModifier(context.Document, root, statement, accessibility), nameof(ExplicitAccessModifiersAnalyzer)), diagnostic);}private Task<Solution> AddModifier(Document document, SyntaxNode root, SyntaxNode statement, Accessibility accessibility){    SyntaxNode newStatement = null;    var accessModifierTokens = SyntaxFactory.TokenList(AccessModifiers(accessibility));    if (statement is ClassDeclarationSyntax)    {        var classExpression = (ClassDeclarationSyntax) statement;        var newClass = classExpression.WithModifiers(classExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newClass);    }    if (statement is StructDeclarationSyntax)    {        var structExpression = (StructDeclarationSyntax)statement;        var newStruct = structExpression.WithModifiers(structExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newStruct);    }    if (statement is EnumDeclarationSyntax)    {        var enumExpression = (EnumDeclarationSyntax)statement;        var newEnum = enumExpression.WithModifiers(enumExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newEnum);    }    if (statement is DelegateDeclarationSyntax)    {        var delegateExpression = (DelegateDeclarationSyntax)statement;        var newDelegate = delegateExpression.WithModifiers(delegateExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newDelegate);    }    if (statement is InterfaceDeclarationSyntax)    {        var interfaceExpression = (InterfaceDeclarationSyntax)statement;        var newInterface = interfaceExpression.WithModifiers(interfaceExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newInterface);    }    if (statement is FieldDeclarationSyntax)    {        var fieldExpression = (FieldDeclarationSyntax)statement;        var newStruct = fieldExpression.WithModifiers(fieldExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newStruct);    }    if (statement is PropertyDeclarationSyntax)    {        var propertyExpression = (PropertyDeclarationSyntax)statement;        var newProperty = propertyExpression.WithModifiers(propertyExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newProperty);    }    if (statement is MethodDeclarationSyntax)    {        var methodExpression = (MethodDeclarationSyntax)statement;        var newMethod = methodExpression.WithModifiers(methodExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newMethod);    }    if (statement is ConstructorDeclarationSyntax)    {        var constructorExpression = (ConstructorDeclarationSyntax)statement;        var newConstructor = constructorExpression.WithModifiers(constructorExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newConstructor);    }    if (statement is EventFieldDeclarationSyntax)    {        var eventFieldExpression = (EventFieldDeclarationSyntax)statement;        var newEventField = eventFieldExpression.WithModifiers(eventFieldExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newEventField);    }    if (statement is EventDeclarationSyntax)    {        var eventExpression = (EventDeclarationSyntax)statement;        var newEvent = eventExpression.WithModifiers(eventExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newEvent);    }    if (statement is IndexerDeclarationSyntax)    {        var indexerExpression = (IndexerDeclarationSyntax)statement;        var newIndexer = indexerExpression.WithModifiers(indexerExpression.Modifiers.AddRange(accessModifierTokens));        newStatement = statement.ReplaceNode(statement, newIndexer);    }    var newRoot = newStatement == null ? root : root.ReplaceNode(statement, newStatement);    return Task.FromResult(document.WithSyntaxRoot(newRoot).Project.Solution);}private SyntaxToken[] AccessModifiers(Accessibility accessibility){    switch (accessibility)    {        case Accessibility.Private:            return new[] { SyntaxFactory.Token(SyntaxKind.PrivateKeyword) };        case Accessibility.ProtectedAndInternal:            return new[] { SyntaxFactory.Token(SyntaxKind.ProtectedKeyword), SyntaxFactory.Token(SyntaxKind.InternalKeyword) };        case Accessibility.Protected:            return new[] { SyntaxFactory.Token(SyntaxKind.ProtectedKeyword) };        case Accessibility.Internal:            return new[] { SyntaxFactory.Token(SyntaxKind.InternalKeyword) };        case Accessibility.Public:            return new[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword) };    }    return null;    // this cannot be reached}And here is a subset of the 68 unit tests:[TestMethod]public void ExplicitAccessModifiers_ClassDeclaration_InvokesWarning(){    var original = @namespace ConsoleApplication1{    class MyClass    {    }};    var result = @namespace ConsoleApplication1{    internal class MyClass    {    }};    VerifyDiagnostic(original, string.Format(ExplicitAccessModifiersAnalyzer.Rule.MessageFormat.ToString(), internal));    VerifyFix(original, result);}[TestMethod]public void ExplicitAccessModifiers_ClassDeclaration_ContainsNonAccessModifier_InvokesWarning(){    var original = @namespace ConsoleApplication1{    static class MyClass    {    }};    var result = @namespace ConsoleApplication1{    static internal class MyClass    {    }};    VerifyDiagnostic(original, string.Format(ExplicitAccessModifiersAnalyzer.Rule.MessageFormat.ToString(), internal));    VerifyFix(original, result);}[TestMethod]public void ExplicitAccessModifiers_ClassDeclaration_ContainsAccessModifier_DoesNotInvokeWarning(){    var original = @namespace ConsoleApplication1{    public class MyClass    {    }};    VerifyDiagnostic(original);}[TestMethod]public void ExplicitAccessModifiers_ClassDeclaration_OnlyChangesAccessModifiers_InvokesWarning(){    var original = @using System;namespace ConsoleApplication1{    [Obsolete]    class MyClass    {        public void Method() { }    }};    var result = @using System;namespace ConsoleApplication1{    [Obsolete]    internal class MyClass    {        public void Method() { }    }};    VerifyDiagnostic(original, string.Format(ExplicitAccessModifiersAnalyzer.Rule.MessageFormat.ToString(), internal));    VerifyFix(original, result);}I appreciate any and all feedback.
Tool to Add Access Modifiers to Code
c#;meta programming;roslyn
private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) This method is quite large and could at least be improved for readability and performance. Right now you are checking for each expected type although if a previous check had been successful. It would better return early.That beeing said let us see what the different DeclarationSyntax's have in common.  By checking the rosaly source we see the following inheritance tree  ClassDeclarationSyntax -> TypeDeclarationSyntax  -> BaseTypeDeclarationSyntaxStructDeclarationSyntax -> TypeDeclarationSyntax -> BaseTypeDeclarationSyntaxEnumDeclarationSyntax -> BaseTypeDeclarationSyntaxInterfaceDeclarationSyntax -> TypeDeclarationSyntax -> BaseTypeDeclarationSyntax DelegateDeclarationSyntax -> MemberDeclarationSyntax EventFieldDeclarationSyntax -> BaseFieldDeclarationSyntaxFieldDeclarationSyntax -> BaseFieldDeclarationSyntax PropertyDeclarationSyntax -> BasePropertyDeclarationSyntaxEventDeclarationSyntax -> BasePropertyDeclarationSyntaxIndexerDeclarationSyntax -> BasePropertyDeclarationSyntax MethodDeclarationSyntax -> BaseMethodDeclarationSyntaxConstructorDeclarationSyntax -> BaseMethodDeclarationSyntax and expect for DelegateDeclarationSyntax -> MemberDeclarationSyntax  each of these base classes share a SyntaxTokenList Modifiers property. If we then add a class AnalyzeResult like so  private class AnalyzeResult{    public Location NodeLocion { get; private set; }    public string Accessibility { get; private set; }    public AnalyzeResult(Location location, string accessibility)    {        NodeLocion = location;        Accessibility = accessibility;    }}We can add methods for processing the separate base classes in a bool TryGetValue(SyntaxNodeAnalysisContext, out AnalyzeResult) fashion.  By adding generic methods for processing the extending classes in the same fashion like so  private bool TryAnalyzeBaseType<T>(SyntaxNodeAnalysisContext context, out AnalyzeResult value) where T : BaseTypeDeclarationSyntax{    value = null;    var declaration = context.Node as T;    if (declaration == null) { return false; }    var accessibility = context.SemanticModel.GetDeclaredSymbol(declaration).DeclaredAccessibility.ToString().ToLower();    value = new AnalyzeResult(declaration.GetLocation(), accessibility);    return true;}which are called from here  private bool TryAnalyzeBaseTypeSymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as BaseTypeDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    if (TryAnalyzeBaseType<ClassDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseType<StructDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseType<EnumDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseType<InterfaceDeclarationSyntax>(context, out result))    {        return true;    }    return false;}private bool IsContainedInDeclaredModifiers(SyntaxTokenList modifiers){    return modifiers.Any(m => _accessModifierKinds.Contains(m.Kind()));}We have a clear chain of execution for each class which extends BaseTypeDeclarationSyntax.  For completeness all these TryX..() and their generic methods  private bool IsContainedInDeclaredModifiers(SyntaxTokenList modifiers){    return modifiers.Any(m => _accessModifierKinds.Contains(m.Kind()));}private bool TryAnalyzeBaseTypeSymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as BaseTypeDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    if (TryAnalyzeBaseTypeSymbol<ClassDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseTypeSymbol<StructDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseTypeSymbol<EnumDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseTypeSymbol<InterfaceDeclarationSyntax>(context, out result))    {        return true;    }    return false;}private bool TryAnalyzeBaseTypeSymbol<T>(SyntaxNodeAnalysisContext context, out AnalyzeResult value) where T : BaseTypeDeclarationSyntax{    value = null;    var declaration = context.Node as T;    if (declaration == null) { return false; }    var accessibility = context.SemanticModel.GetDeclaredSymbol(declaration).DeclaredAccessibility.ToString().ToLower();    value = new AnalyzeResult(declaration.GetLocation(), accessibility);    return true;}private bool TryAnalyzeBasePropertySymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as BasePropertyDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    if (TryAnalyzeBasePropertySymbol<PropertyDeclarationSyntax>(context,out result))    {        return true;    }    if (TryAnalyzeBasePropertySymbol<EventDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBasePropertySymbol<IndexerDeclarationSyntax>(context, out result))    {        return true;    }    return false;}private bool TryAnalyzeBasePropertySymbol<T>(SyntaxNodeAnalysisContext context, out AnalyzeResult value) where T : BasePropertyDeclarationSyntax{    value = null;    var declaration = context.Node as T;    if (declaration == null) { return false; }    var accessibility = context.SemanticModel.GetDeclaredSymbol(declaration).DeclaredAccessibility.ToString().ToLower();    value = new AnalyzeResult(declaration.GetLocation(), accessibility);    return true;}private bool TryAnalyzeBaseMethodSymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as BaseMethodDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    if (TryAnalyzeBaseMethodSymbol<MethodDeclarationSyntax>(context, out result))    {        return true;    }    if (TryAnalyzeBaseMethodSymbol<ConstructorDeclarationSyntax>(context, out result))    {        return true;    }    return false;}private bool TryAnalyzeBaseMethodSymbol<T>(SyntaxNodeAnalysisContext context, out AnalyzeResult value) where T : BaseMethodDeclarationSyntax{    value = null;    var declaration = context.Node as T;    if (declaration == null) { return false; }    var accessibility = context.SemanticModel.GetDeclaredSymbol(declaration).DeclaredAccessibility.ToString().ToLower();    value = new AnalyzeResult(declaration.GetLocation(), accessibility);    return true;}private bool TryAnalyzeDelegateSymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as DelegateDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    var accessibility = context.SemanticModel.GetDeclaredSymbol(declarationSyntax).DeclaredAccessibility.ToString().ToLower();    result = new AnalyzeResult(declarationSyntax.GetLocation(), accessibility);    return true;}private bool TryAnalyzeBaseFieldSymbol(SyntaxNodeAnalysisContext context, out AnalyzeResult result){    result = null;    var declarationSyntax = context.Node as BaseFieldDeclarationSyntax;    if (declarationSyntax == null)    {        return false;    }    if (IsContainedInDeclaredModifiers(declarationSyntax.Modifiers))    {        return true;    }    result = new AnalyzeResult(declarationSyntax.GetLocation(), private);    return true;}  then we will change the former AnalyzeSymbol() method like so  private void AnalyzeSymbol(SyntaxNodeAnalysisContext context){    AnalyzeResult result;    if (TryAnalyzeBaseTypeSymbol(context, out result))    {        if (result == null) { return; }    }    else if (TryAnalyzeBaseFieldSymbol(context, out result))    {        if (result == null) { return; }    } else if(TryAnalyzeBasePropertySymbol(context,out result))    {        if (result == null) { return; }    } else if (TryAnalyzeBaseMethodSymbol(context,out result))    {        if (result == null) { return; }    } else if(TryAnalyzeDelegateSymbol(context,out result))    {        if (result == null) { return; }    }    else    {        return;    }    context.ReportDiagnostic(Diagnostic.Create(Rule, result.NodeLocion,                result.Accessibility));}