Наследование: CSharpSyntaxRewriter
Пример #1
0
        static void Main(string[] args)
        {

            if (args.Length != 3)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("{0} <IntelliSenseDirectory> <SourceDirectory> <SolutionFilePath>", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine("Press ENTER to exit;");
                Console.ReadLine();
                return;
            }

            ParseIntelliSense p = new ParseIntelliSense(args[0]);

            //Check parameters
            if (!Directory.Exists(p.IntelliSenseDirectory))
            {
                Console.WriteLine($"Directory not found: {p.IntelliSenseDirectory}");
                Console.WriteLine("Press ENTER to exit;");
                Console.ReadLine();
                return;
            }
            if (!Directory.Exists(args[1]))
            {
                Console.WriteLine($"Directory not found: {args[1]}");
                Console.WriteLine("Press ENTER to exit;");
                Console.ReadLine();
                return;
            }
            if (!File.Exists(args[2]))
            {
                Console.WriteLine($"Solution file not found: {args[2]}");
                Console.WriteLine("Press ENTER to exit;");
                Console.ReadLine();
                return;
            }
            p.ParseIntelliSenseFiles();

            var workspace = MSBuildWorkspace.Create();

            var solution = workspace.OpenSolutionAsync(args[2]).Result;

            var projects = solution.Projects.ToList();

            var metadataReferences = projects.Where(proj => !proj.Name.Contains("test")) // Filter out test projects I guess?
                                             .SelectMany(proj => proj.MetadataReferences)
                                             .Distinct(); // Does it matter if they're distinct or not?

            Project project = null;

            var projectsMatchingDir = projects.Where(proj => proj.FilePath.Contains(args[1])).ToList();
            if (projects.Count > 1)
            {
                // Picking the first one is fine because this pattern emerged in the following case:
                //
                // System.LibraryWeCareAbout
                // System.LibraryWeCareAbout.Other
                //
                // In this case, we just use the first.  We can always run the tool again on the second one if it's necessary.
                project = projects.FirstOrDefault(proj => proj.FilePath.Contains(args[1]));
            }
            else if (projectsMatchingDir.Count == 0)
            {
                var path = GetPathToProject(args[1]);
                project = workspace.OpenProjectAsync(path).Result;
            }
            else
            {
                project = projectsMatchingDir.First();
            }

            foreach (var document in project.Documents)
            {
                SourceText text;
                try
                {
                    using (var stream = File.OpenRead(document.FilePath))
                    {
                        text = SourceText.From(stream);
                    }
                }
                catch (DirectoryNotFoundException)
                {
                    continue;
                }
                catch (FileNotFoundException)
                {
                    continue;
                }

                SyntaxTree initialTree = (SyntaxTree)CSharpSyntaxTree.ParseText(text);

                var compilation = CSharpCompilation.Create(
                    "test", syntaxTrees: new[] { initialTree }, references: metadataReferences);

                var rewriter = new Rewriter(compilation.GetSemanticModel(initialTree), p.MembersDictionary);
                
                var treeWithFormattedTrivia = rewriter.Visit(initialTree.GetRoot()).SyntaxTree;

                var options = SetOptions(workspace.Options);

                var simplifiedTree = Simplifier.ReduceAsync(document.WithSyntaxRoot(treeWithFormattedTrivia.GetRoot()), options).Result
                                    .GetSyntaxTreeAsync().Result;

                var simplifiedTriviaLookup = GetSimplifiedCommentLookup(simplifiedTree, metadataReferences);

                var rw = new MoveCommentsRewriter(compilation.GetSemanticModel(initialTree), simplifiedTree.GetRoot(), simplifiedTriviaLookup);

                var finalTree = rw.Visit(initialTree.GetRoot()).SyntaxTree;

                if (initialTree != finalTree)
                {
                    // Need to call format here because comments are inserted at the 0th column when rewriting the syntax tree.
                    var formattedRootNode = Formatter.Format(finalTree.GetRoot(), workspace, options);

                    Console.WriteLine($"Saving file: {document.FilePath}");
                    SourceText newText = formattedRootNode.GetText();
                    using (var writer = new StreamWriter(document.FilePath, append: false, encoding: text.Encoding))
                    {
                        newText.Write(writer);
                    }
                }
            }

            Console.WriteLine("Press ENTER to exit;");
            Console.ReadLine();
        }