/// <summary>
        /// Semantics is not involved in this pass at all.  It is just a straight modification of the
        /// parse tree so there are no issues about ensuring the version of <see cref="SemanticModel"/> and
        /// the <see cref="SyntaxNode"/> line up.  Hence we do this by iteraning every <see cref="Document"/>
        /// and processing all rules against them at once
        /// </summary>
        private async Task <Solution> RunSyntaxPass(Solution originalSolution, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine("\tSyntax Pass");

            var currentSolution = originalSolution;

            foreach (var documentId in documentIds)
            {
                var document   = originalSolution.GetDocument(documentId);
                var syntaxRoot = await GetSyntaxRootAndFilter(document, cancellationToken);

                if (syntaxRoot == null)
                {
                    continue;
                }

                StartDocument();
                var newRoot = RunSyntaxPass(syntaxRoot, document.Project.Language);
                EndDocument(document);

                if (newRoot != syntaxRoot)
                {
                    currentSolution = currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot);
                }
            }

            return(currentSolution);
        }
        private async Task <Solution> RunGlobalSemanticPass(Solution solution, IReadOnlyList <DocumentId> documentIds, IGlobalSemanticFormattingRule globalSemanticRule, CancellationToken cancellationToken)
        {
            if (_verbose)
            {
                FormatLogger.WriteLine("  {0}", globalSemanticRule.GetType().Name);
            }

            foreach (var documentId in documentIds)
            {
                var document   = solution.GetDocument(documentId);
                var syntaxRoot = await GetSyntaxRootAndFilter(globalSemanticRule, document, cancellationToken);

                if (syntaxRoot == null)
                {
                    continue;
                }

                StartDocument();
                solution = await globalSemanticRule.ProcessAsync(document, syntaxRoot, cancellationToken);

                EndDocument(document);
            }

            return(solution);
        }
        private async Task <Solution> RunLocalSemanticPass(Solution originalSolution, IReadOnlyList <DocumentId> documentIds, ILocalSemanticFormattingRule localSemanticRule, CancellationToken cancellationToken)
        {
            if (_verbose)
            {
                FormatLogger.WriteLine("  {0}", localSemanticRule.GetType().Name);
            }

            var currentSolution = originalSolution;

            foreach (var documentId in documentIds)
            {
                var document   = originalSolution.GetDocument(documentId);
                var syntaxRoot = await GetSyntaxRootAndFilter(localSemanticRule, document, cancellationToken);

                if (syntaxRoot == null)
                {
                    continue;
                }

                StartDocument();
                var newRoot = await localSemanticRule.ProcessAsync(document, syntaxRoot, cancellationToken);

                EndDocument(document);

                if (syntaxRoot != newRoot)
                {
                    currentSolution = currentSolution.WithDocumentSyntaxRoot(documentId, newRoot);
                }
            }

            return(currentSolution);
        }
예제 #4
0
        /// <summary>
        /// Semantics is not involved in this pass at all.  It is just a straight modification of the
        /// parse tree so there are no issues about ensuring the version of <see cref="SemanticModel"/> and
        /// the <see cref="SyntaxNode"/> line up.  Hence we do this by iteraning every <see cref="Document"/>
        /// and processing all rules against them at once
        /// </summary>
        public async Task <Solution> RunSyntaxPass(Solution originalSolution, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine("\tSyntax Pass");

            var currentSolution = originalSolution;

            foreach (var documentId in documentIds)
            {
                var document   = originalSolution.GetDocument(documentId);
                var syntaxRoot = await GetSyntaxRootAndFilter(document, cancellationToken);

                if (syntaxRoot == null)
                {
                    if (File.Exists("debug.debug") == false)
                    {
                        FileStream s = File.Create("debug.debug");
                        s.Close();
                    }
                    File.AppendAllText("debug.debug", "No syntax root detected");
                    continue;
                }

                StartDocument();
                var newRoot = RunSyntaxPass(syntaxRoot, document.Project.Language);
                EndDocument(document);

                if (newRoot != syntaxRoot)
                {
                    currentSolution = currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot);
                }
            }

            return(currentSolution);
        }
        private async Task FormatAsync(
            Workspace workspace,
            IReadOnlyList<DocumentId> documentIds,
            IReadOnlyList<DocumentId> additionalDocumentIds,
            CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine($"Found {documentIds.Count} documents to be formatted...");
            FormatLogger.WriteLine($"Found {additionalDocumentIds.Count} additional documents to be formatted...");

            var watch = new Stopwatch();
            watch.Start();

            var originalSolution = workspace.CurrentSolution;
            var solution = await FormatCoreAsync(originalSolution, documentIds, cancellationToken);
            solution = await FormatAdditionalDocumentsAsync(solution, additionalDocumentIds, cancellationToken);

            watch.Stop();

            if (!workspace.TryApplyChanges(solution))
            {
                FormatLogger.WriteErrorLine("Unable to save changes to disk");
            }

            FormatLogger.WriteLine("Total time {0}", watch.Elapsed);
        }
예제 #6
0
        public async Task FormatAsync(Workspace workspace, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            var watch = new Stopwatch();

            watch.Start();

            var originalSolution = workspace.CurrentSolution;
            var solution         = await FormatCoreAsync(originalSolution, documentIds, cancellationToken);

            var p = solution.Projects.First();

            foreach (Document d in p.Documents)
            {
                if (d.Name == "ExplorerForms.cs")
                {
                    SyntaxTree s;
                    d.TryGetSyntaxTree(out s);

                    string text = s.ToString();
                }
            }

            watch.Stop();

            if (!workspace.TryApplyChanges(solution))
            {
                FormatLogger.WriteErrorLine("Unable to save changes to disk");
            }

            FormatLogger.WriteLine("Total time {0}", watch.Elapsed);
        }
 private void EndDocument(Document document)
 {
     _watch.Stop();
     if (_verbose)
     {
         FormatLogger.WriteLine("    {0} {1} seconds", document.Name, _watch.Elapsed.TotalSeconds);
     }
 }
        private async Task <Solution> RunGlobalSemanticPass(Solution solution, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine("\tGlobal Semantic Pass");
            foreach (var globalSemanticRule in GetOrderedRules(_globalSemanticRules))
            {
                solution = await RunGlobalSemanticPass(solution, documentIds, globalSemanticRule, cancellationToken);
            }

            return(solution);
        }
        private async Task <Solution> RunLocalSemanticPass(Solution solution, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine("\tLocal Semantic Pass");
            foreach (var localSemanticRule in GetOrderedRules(_localSemanticRules))
            {
                solution = await RunLocalSemanticPass(solution, documentIds, localSemanticRule, cancellationToken).ConfigureAwait(false);
            }

            return(solution);
        }
        private async Task FormatWithAnalyzersCoreAsync(Workspace workspace, ProjectId projectId, IEnumerable <DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken)
        {
            if (analyzers != null && analyzers.Count() != 0)
            {
                var project     = workspace.CurrentSolution.GetProject(projectId);
                var diagnostics = await GetDiagnostics(project, analyzers, cancellationToken).ConfigureAwait(false);

                // Ensure at least 1 analyzer supporting the current project's language ran
                if (_compilationWithAnalyzers != null)
                {
                    var extension  = StringComparer.OrdinalIgnoreCase.Equals(project.Language, "C#") ? ".csproj" : ".vbproj";
                    var resultFile = project.FilePath?.Substring(project.FilePath.LastIndexOf(Path.DirectorySeparatorChar)).Replace(extension, "_CodeFormatterResults.txt");

                    foreach (var analyzer in analyzers)
                    {
                        var diags = await _compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(ImmutableArray.Create(analyzer), cancellationToken);

                        if (Verbose || LogOutputPath != null)
                        {
                            var analyzerTelemetryInfo = await _compilationWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken);

                            FormatLogger.WriteLine("{0}\t{1}\t{2}\t{3}", project.Name, analyzer.ToString(), diags.Count(), analyzerTelemetryInfo.ExecutionTime);
                            var resultPath = Path.ChangeExtension(LogOutputPath + resultFile, "json");
                            LogDiagnostics(resultPath, diags);
                        }
                    }
                }

                if (ApplyFixes)
                {
                    var batchFixer = WellKnownFixAllProviders.BatchFixer;
                    var context    = new FixAllContext(
                        project.Documents.First(), // TODO: Shouldn't this be the whole project?
                        new UberCodeFixer(_diagnosticIdToFixerMap),
                        FixAllScope.Project,
                        null,
                        diagnostics.Select(d => d.Id),
                        new FormattingEngineDiagnosticProvider(project, diagnostics),
                        cancellationToken);

                    var fix = await batchFixer.GetFixAsync(context).ConfigureAwait(false);

                    if (fix != null)
                    {
                        foreach (var operation in await fix.GetOperationsAsync(cancellationToken).ConfigureAwait(false))
                        {
                            operation.Apply(workspace, cancellationToken);
                        }
                    }
                }
            }
        }
        public async Task FormatSolutionWithAnalyzersAsync(Solution solution, CancellationToken cancellationToken)
        {
            var watch = new Stopwatch();

            watch.Start();

            var workspace = solution.Workspace;

            foreach (var projectId in solution.ProjectIds)
            {
                var project = workspace.CurrentSolution.GetProject(projectId);
                await FormatProjectWithAnalyzersAsync(project, cancellationToken).ConfigureAwait(false);
            }

            watch.Stop();
            FormatLogger.WriteLine("Total time {0}", watch.Elapsed);
        }
        private async Task FormatAsync(Workspace workspace, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            var watch = new Stopwatch();

            watch.Start();

            var originalSolution = workspace.CurrentSolution;
            var solution         = await FormatCoreAsync(originalSolution, documentIds, cancellationToken).ConfigureAwait(false);

            watch.Stop();

            if (!workspace.TryApplyChanges(solution))
            {
                FormatLogger.WriteErrorLine("Unable to save changes to disk");
            }

            FormatLogger.WriteLine("Total time {0}", watch.Elapsed);
        }
        internal async Task<Solution> FormatAdditionalDocumentsAsync(Solution originalSolution, IReadOnlyList<DocumentId> additionalDocumentIds, CancellationToken cancellationToken)
        {
            FormatLogger.WriteLine($"\tAdditional Documents Pass");

            var solution = originalSolution;

            foreach (var documentId in additionalDocumentIds)
            {
                using (var textDocument = new ConfiguredAdditionalDocument(originalSolution, documentId, this))
                {
                    foreach (var rule in GetOrderedRules(_textDocumentRules))
                    {
                        if (rule.SupportsLanguage(textDocument.Value.Project.Language))
                            solution = await rule.ProcessAsync(textDocument.Value, textDocument.Configuration, cancellationToken);
                    }
                }
            }

            return solution;
        }
        private async Task FormatAsync(Workspace workspace, IReadOnlyList <DocumentId> documentIds, CancellationToken cancellationToken)
        {
            try
            {
                var watch = new Stopwatch();
                watch.Start();
                var originalSolution = workspace.CurrentSolution;
                var newSolution      = await FormatCoreAsync(originalSolution, documentIds, cancellationToken);

                newSolution.GetChanges(originalSolution).GetProjectChanges().ToList().ForEach(projectChanges =>
                {
                    SaveUpdatedDocumentsToDisk(projectChanges, newSolution);
                });
                watch.Stop();
                FormatLogger.WriteLine("Total time {0}", watch.Elapsed);
            }
            catch (Exception)
            {
                FormatLogger.WriteErrorLine("Unable to save changes to disk");
            }
        }
        public async Task FormatProjectWithAnalyzersAsync(Project project, CancellationToken cancellationToken)
        {
            if (!project.Documents.Any())
            {
                FormatLogger.WriteLine($"Skipping {project.Name}: no files to format.");
                return;
            }

            var watch = new Stopwatch();

            watch.Start();

            var workspace = project.Solution.Workspace;

            await FormatProjectWithSyntaxAnalyzersAsync(workspace, project.Id, cancellationToken);
            await FormatProjectWithLocalAnalyzersAsync(workspace, project.Id, cancellationToken);
            await FormatProjectWithGlobalAnalyzersAsync(workspace, project.Id, cancellationToken);
            await FormatProjectWithUnspecifiedAnalyzersAsync(workspace, project.Id, cancellationToken);

            watch.Stop();
            FormatLogger.WriteLine("Total time for formatting {0} - {1}", project.Name, watch.Elapsed);
        }