public IDocumentOptionsProvider?TryCreate(Workspace workspace) { if (EditorConfigDocumentOptionsProviderFactory.ShouldUseNativeEditorConfigSupport(workspace)) { // If the native support exists, then we'll simply disable this one return(null); } ICodingConventionsManager codingConventionsManager; if (workspace.Kind == WorkspaceKind.RemoteWorkspace) { // If it's the remote workspace, it's our own implementation of the file watcher which is already doesn't have // UI thread dependencies. codingConventionsManager = _codingConventionsManager; } else { // The default file watcher implementation inside Visual Studio accientally depends on the UI thread // (sometimes!) when trying to add a watch to a file. This can cause us to deadlock, since our assumption is // consumption of a coding convention can be done freely without having to use a JTF-friendly wait. // So we'll wrap the standard file watcher with one that defers the file watches until later. var deferredFileWatcher = new DeferredFileWatcher(_fileWatcher, _asynchronousOperationListenerProvider); codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(deferredFileWatcher); } return(new LegacyEditorConfigDocumentOptionsProvider(workspace, codingConventionsManager, _asynchronousOperationListenerProvider)); }
internal EditorConfigDocumentOptionsProvider(Workspace workspace) { _codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); workspace.DocumentOpened += Workspace_DocumentOpened; workspace.DocumentClosed += Workspace_DocumentClosed; }
internal void InitializeWorker(AnalysisContext context) { var workspace = new AdhocWorkspace(); var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); context.RegisterSyntaxTreeAction(c => AnalyzeSyntaxTree(c, workspace, codingConventionsManager)); }
internal EditorConfigDocumentOptionsProvider(Workspace workspace) { _codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); _errorLogger = workspace.Services.GetService <IErrorLoggerService>(); workspace.DocumentOpened += Workspace_DocumentOpened; workspace.DocumentClosed += Workspace_DocumentClosed; }
public static async Task <int> FormatWorkspaceAsync(ILogger logger, string solutionOrProjectPath, bool isSolution, CancellationToken cancellationToken) { logger.LogInformation(string.Format(Resources.Formatting_code_files_in_workspace_0, solutionOrProjectPath)); logger.LogTrace(Resources.Loading_workspace); var exitCode = 1; var workspaceStopwatch = Stopwatch.StartNew(); var properties = new Dictionary <string, string>(StringComparer.Ordinal) { // This property ensures that XAML files will be compiled in the current AppDomain // rather than a separate one. Any tasks isolated in AppDomains or tasks that create // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, }; var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); using (var workspace = MSBuildWorkspace.Create(properties)) { workspace.WorkspaceFailed += (s, e) => { if (e.Diagnostic.Kind != WorkspaceDiagnosticKind.Failure) { logger.LogError(e.Diagnostic.Message); logger.LogError(Resources.Unable_to_load_workspace); } }; var projectPath = string.Empty; if (isSolution) { await workspace.OpenSolutionAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); } else { await workspace.OpenProjectAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); projectPath = solutionOrProjectPath; } logger.LogTrace(Resources.Workspace_loaded_in_0_ms, workspaceStopwatch.ElapsedMilliseconds); workspaceStopwatch.Restart(); exitCode = await FormatFilesInSolutionAsync(logger, workspace.CurrentSolution, projectPath, codingConventionsManager, cancellationToken).ConfigureAwait(false); logger.LogDebug(Resources.Format_complete_in_0_ms, workspaceStopwatch.ElapsedMilliseconds); } logger.LogInformation(Resources.Format_complete); return(exitCode); }
private async Task <OptionSet> GetOptionsAsync(Document document, CancellationToken cancellationToken) { OptionSet options = CompilerAnalyzerConfigOptions.Empty; // The in-IDE workspace supports .editorconfig without special handling. However, the AdhocWorkspace used // in testing requires manual handling of .editorconfig. if (File.Exists(document.FilePath ?? document.Name)) { var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); var codingConventionContext = await codingConventionsManager.GetConventionContextAsync(document.FilePath ?? document.Name, cancellationToken).ConfigureAwait(false); options = ApplyFormattingOptions(options, codingConventionContext); } return(options); }
public static async Task <OptionSet> WithEditorConfigOptions(this OptionSet optionSet, string path, ILoggerFactory loggerFactory) { if (!Path.IsPathRooted(path)) { path = Directory.GetCurrentDirectory(); } var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); var optionsApplier = new EditorConfigOptionsApplier(loggerFactory); var context = await codingConventionsManager.GetConventionContextAsync(path, CancellationToken.None); if (context != null && context.CurrentConventions != null) { return(optionsApplier.ApplyConventions(optionSet, context.CurrentConventions, LanguageNames.CSharp)); } return(optionSet); }
public static async Task <WorkspaceFormatResult> FormatWorkspaceAsync(ILogger logger, string solutionOrProjectPath, bool isSolution, bool logAllWorkspaceWarnings, bool saveFormattedFiles, string[] filesToFormat, CancellationToken cancellationToken) { logger.LogInformation(string.Format(Resources.Formatting_code_files_in_workspace_0, solutionOrProjectPath)); logger.LogTrace(Resources.Loading_workspace); var loggedWarningCount = 0; var formatResult = new WorkspaceFormatResult() { ExitCode = 1 }; var workspaceStopwatch = Stopwatch.StartNew(); var properties = new Dictionary <string, string>(StringComparer.Ordinal) { // This property ensures that XAML files will be compiled in the current AppDomain // rather than a separate one. Any tasks isolated in AppDomains or tasks that create // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, // This flag is used at restore time to avoid imports from packages changing the inputs to restore, // without this it is possible to get different results between the first and second restore. { "ExcludeRestorePackageImports", bool.TrueString }, }; var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); using (var workspace = MSBuildWorkspace.Create(properties)) { workspace.WorkspaceFailed += LogWorkspaceWarnings; var projectPath = string.Empty; if (isSolution) { await workspace.OpenSolutionAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); } else { try { await workspace.OpenProjectAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); projectPath = solutionOrProjectPath; } catch (InvalidOperationException) { logger.LogError(Resources.Could_not_format_0_Format_currently_supports_only_CSharp_and_Visual_Basic_projects, solutionOrProjectPath); return(formatResult); } } logger.LogTrace(Resources.Workspace_loaded_in_0_ms, workspaceStopwatch.ElapsedMilliseconds); workspaceStopwatch.Restart(); (formatResult.ExitCode, formatResult.FileCount, formatResult.FilesFormatted) = await FormatFilesInWorkspaceAsync(logger, workspace, projectPath, codingConventionsManager, saveFormattedFiles, filesToFormat, cancellationToken).ConfigureAwait(false); logger.LogDebug(Resources.Formatted_0_of_1_files_in_2_ms, formatResult.FilesFormatted, formatResult.FileCount, workspaceStopwatch.ElapsedMilliseconds); } logger.LogInformation(Resources.Format_complete); return(formatResult); void LogWorkspaceWarnings(object sender, WorkspaceDiagnosticEventArgs args) { if (args.Diagnostic.Kind == WorkspaceDiagnosticKind.Failure) { return; } logger.LogWarning(args.Diagnostic.Message); if (!logAllWorkspaceWarnings) { loggedWarningCount++; if (loggedWarningCount == MaxLoggedWorkspaceWarnings) { logger.LogWarning(Resources.Maximum_number_of_workspace_warnings_to_log_has_been_reached_Set_the_verbosity_option_to_the_diagnostic_level_to_see_all_warnings); ((MSBuildWorkspace)sender).WorkspaceFailed -= LogWorkspaceWarnings; } } } }
public static async Task <int> FormatWorkspaceAsync(ILogger logger, string solutionOrProjectPath, bool isSolution, bool logAllWorkspaceWarnings, bool saveFormattedFiles, CancellationToken cancellationToken) { logger.LogInformation(string.Format(Resources.Formatting_code_files_in_workspace_0, solutionOrProjectPath)); logger.LogTrace(Resources.Loading_workspace); var loggedWarningCount = 0; var exitCode = 1; var workspaceStopwatch = Stopwatch.StartNew(); var properties = new Dictionary <string, string>(StringComparer.Ordinal) { // This property ensures that XAML files will be compiled in the current AppDomain // rather than a separate one. Any tasks isolated in AppDomains or tasks that create // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, }; var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); using (var workspace = MSBuildWorkspace.Create(properties)) { workspace.WorkspaceFailed += LogWorkspaceWarnings; var projectPath = string.Empty; if (isSolution) { await workspace.OpenSolutionAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); } else { await workspace.OpenProjectAsync(solutionOrProjectPath, cancellationToken : cancellationToken).ConfigureAwait(false); projectPath = solutionOrProjectPath; } logger.LogTrace(Resources.Workspace_loaded_in_0_ms, workspaceStopwatch.ElapsedMilliseconds); workspaceStopwatch.Restart(); int fileCount; int filesFormatted; (exitCode, fileCount, filesFormatted) = await FormatFilesInWorkspaceAsync(logger, workspace, projectPath, codingConventionsManager, saveFormattedFiles, cancellationToken).ConfigureAwait(false); logger.LogDebug(Resources.Formatted_0_of_1_files_in_2_ms, filesFormatted, fileCount, workspaceStopwatch.ElapsedMilliseconds); } logger.LogInformation(Resources.Format_complete); return(exitCode); void LogWorkspaceWarnings(object sender, WorkspaceDiagnosticEventArgs args) { if (args.Diagnostic.Kind == WorkspaceDiagnosticKind.Failure) { return; } logger.LogWarning(args.Diagnostic.Message); if (!logAllWorkspaceWarnings) { loggedWarningCount++; if (loggedWarningCount == MaxLoggedWorkspaceWarnings) { logger.LogWarning(Resources.Maximum_number_of_workspace_warnings_to_log_has_been_reached_Set_the_verbosity_option_to_the_diagnostic_level_to_see_all_warnings); ((MSBuildWorkspace)sender).WorkspaceFailed -= LogWorkspaceWarnings; } } } }
protected override void InitializeWorker(AnalysisContext context) { var codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager(); context.RegisterSyntaxTreeAction(c => AnalyzeSyntaxTree(c, codingConventionsManager)); }