public override SyntaxTree CreateSyntaxTree(string filePath, ParseOptions options, Encoding encoding, SyntaxNode root, AnalyzerConfigOptionsResult analyzerConfigOptionsResult) { options ??= GetDefaultParseOptions(); var isUserConfiguredGeneratedCode = GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(analyzerConfigOptionsResult.AnalyzerOptions); return(CSharpSyntaxTree.Create((CSharpSyntaxNode)root, (CSharpParseOptions)options, filePath, encoding, analyzerConfigOptionsResult.TreeOptions, isUserConfiguredGeneratedCode)); }
public override SyntaxTree ParseSyntaxTree(string filePath, ParseOptions options, SourceText text, AnalyzerConfigOptionsResult?analyzerConfigOptionsResult, CancellationToken cancellationToken) { options ??= GetDefaultParseOptions(); var isUserConfiguredGeneratedCode = analyzerConfigOptionsResult.HasValue ? GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(analyzerConfigOptionsResult.Value.AnalyzerOptions) : null; return(SyntaxFactory.ParseSyntaxTree(text, options, filePath, analyzerConfigOptionsResult?.TreeOptions, isUserConfiguredGeneratedCode, cancellationToken: cancellationToken)); }
public Options(AnalyzerConfigOptionsResult?result) { if (result is AnalyzerConfigOptionsResult r) { DiagnosticOptions = r.TreeOptions; IsGenerated = GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(r.AnalyzerOptions); } else { DiagnosticOptions = SyntaxTree.EmptyDiagnosticOptions; IsGenerated = null; } }
private static bool IsGeneratedCode(SyntaxTree syntaxTree, Document document, CancellationToken cancellationToken) { // First check if user has configured "generated_code = true | false" in .editorconfig var analyzerOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree); var isUserConfiguredGeneratedCode = GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(analyzerOptions); if (isUserConfiguredGeneratedCode.HasValue) { return(isUserConfiguredGeneratedCode.Value); } // Otherwise, fallback to generated code heuristic. var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); return(GeneratedCodeUtilities.IsGeneratedCode( syntaxTree, t => syntaxFacts.IsRegularComment(t) || syntaxFacts.IsDocumentationComment(t), cancellationToken)); }
private static SyntaxTree ParseFile( CSharpParseOptions parseOptions, CSharpParseOptions scriptParseOptions, SourceText content, CommandLineSourceFile file, AnalyzerConfigOptionsResult?analyzerConfigOptionsResult) { ImmutableDictionary <string, ReportDiagnostic> diagnosticOptions; bool?isUserConfiguredGeneratedCode; if (analyzerConfigOptionsResult.HasValue) { diagnosticOptions = analyzerConfigOptionsResult.Value.TreeOptions; isUserConfiguredGeneratedCode = GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(analyzerConfigOptionsResult.Value.AnalyzerOptions); } else { diagnosticOptions = null; isUserConfiguredGeneratedCode = null; } var tree = SyntaxFactory.ParseSyntaxTree( content, file.IsScript ? scriptParseOptions : parseOptions, file.Path, diagnosticOptions, isUserConfiguredGeneratedCode); // prepopulate line tables. // we will need line tables anyways and it is better to not wait until we are in emit // where things run sequentially. bool isHiddenDummy; tree.GetMappedLineSpanAndVisibility(default(TextSpan), out isHiddenDummy); return(tree); }
internal static async Task <(int, ImmutableArray <DocumentId>)> DetermineFormattableFilesAsync( Solution solution, string projectPath, FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken) { var totalFileCount = solution.Projects.Sum(project => project.DocumentIds.Count); var projectFileCount = 0; var documentsCoveredByEditorConfig = ImmutableArray.CreateBuilder <DocumentId>(totalFileCount); var documentsNotCoveredByEditorConfig = ImmutableArray.CreateBuilder <DocumentId>(totalFileCount); var addedFilePaths = new HashSet <string>(totalFileCount); foreach (var project in solution.Projects) { if (project?.FilePath is null) { continue; } // If a project is used as a workspace, then ignore other referenced projects. if (!string.IsNullOrEmpty(projectPath) && !project.FilePath.Equals(projectPath, StringComparison.OrdinalIgnoreCase)) { logger.LogDebug(Resources.Skipping_referenced_project_0, project.Name); continue; } // Ignore unsupported project types. if (project.Language != LanguageNames.CSharp && project.Language != LanguageNames.VisualBasic) { logger.LogWarning(Resources.Could_not_format_0_Format_currently_supports_only_CSharp_and_Visual_Basic_projects, project.FilePath); continue; } projectFileCount += project.DocumentIds.Count; foreach (var document in project.Documents) { // If we've already added this document, either via a link or multi-targeted framework, then ignore. if (document?.FilePath is null || addedFilePaths.Contains(document.FilePath)) { continue; } addedFilePaths.Add(document.FilePath); var isFileIncluded = formatOptions.WorkspaceType == WorkspaceType.Folder || (formatOptions.FileMatcher.HasMatches(document.FilePath) && File.Exists(document.FilePath)); if (!isFileIncluded || !document.SupportsSyntaxTree) { continue; } var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree is null) { throw new Exception($"Unable to get a syntax tree for '{document.Name}'"); } if (!formatOptions.IncludeGeneratedFiles && await GeneratedCodeUtilities.IsGeneratedCodeAsync(syntaxTree, cancellationToken).ConfigureAwait(false)) { continue; } // Track files covered by an editorconfig separately from those not covered. var analyzerConfigOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree); if (analyzerConfigOptions != null) { if (formatOptions.IncludeGeneratedFiles || GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(analyzerConfigOptions) != true) { documentsCoveredByEditorConfig.Add(document.Id); } } else { documentsNotCoveredByEditorConfig.Add(document.Id); } } } // Initially we would format all documents in a workspace, even if some files weren't covered by an // .editorconfig and would have defaults applied. This behavior was an early requested change since // users were surprised to have files not specified by the .editorconfig modified. The assumption is // that users without an .editorconfig still wanted formatting (they did run a formatter after all), // so we run on all files with defaults. // If no files are covered by an editorconfig, then return them all. Otherwise only return // files that are covered by an editorconfig. return(documentsCoveredByEditorConfig.Count == 0 ? (projectFileCount, documentsNotCoveredByEditorConfig.ToImmutable()) : (projectFileCount, documentsCoveredByEditorConfig.ToImmutable())); }