private static void ProcessFile(string fullName, Statistics stat) { var fileContent = File.ReadAllText(fullName); var fileSyntaxTree = CSharpSyntaxTree.ParseText(fileContent); var root = fileSyntaxTree.GetRoot(); var updatedMethods = new Dictionary<BaseMethodDeclarationSyntax, BaseMethodDeclarationSyntax>(); // Look at classes only: var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>().ToList(); foreach (var classDeclaration in classes) { var classModified = false; var methodAndOperators = classDeclaration.DescendantNodes() .OfType<BaseMethodDeclarationSyntax>() .Where(x => x.Kind() == SyntaxKind.MethodDeclaration || x.Kind() == SyntaxKind.OperatorDeclaration) .ToList(); foreach (var method in methodAndOperators) { var updatedMethod = method; if (RoslynHelper.TransformEmptyMethodToExtern(ref updatedMethod)) { updatedMethods[method] = updatedMethod; switch (method.Kind()) { case SyntaxKind.MethodDeclaration: stat.MethodWasModified(); break; case SyntaxKind.OperatorDeclaration: stat.OperatorWasModified(); break; default: throw new NotSupportedException($"BaseMethod type is not supported: {method.GetType().FullName}"); } stat.MethodWasModified(); classModified = true; } } if (classModified) { stat.ClassWasModified(); } } // Modify the file if there are any changes if (updatedMethods.Count > 0) { root = root.ReplaceNodes(updatedMethods.Keys, (m1, m2) => updatedMethods[m1]); var updatedFileContent = root.ToFullString(); File.WriteAllText(fullName, updatedFileContent); stat.FileWasModified(); } }