| File: Utilities\GeneratedCodeUtilities.cs | Web Access |
| Project: src\sdk\src\Dotnet.Format\dotnet-format\dotnet-format.csproj (dotnet-format) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis.Diagnostics; namespace Microsoft.CodeAnalysis.Tools.Utilities { internal static class GeneratedCodeUtilities { private static readonly string[] s_autoGeneratedStrings = new[] { "<autogenerated", "<auto-generated" }; private static readonly Func<SyntaxTrivia, bool> s_isCSharpCommentTrivia = (syntaxTrivia) => syntaxTrivia.IsKind(CSharp.SyntaxKind.SingleLineCommentTrivia) || syntaxTrivia.IsKind(CSharp.SyntaxKind.MultiLineCommentTrivia) || syntaxTrivia.IsKind(CSharp.SyntaxKind.SingleLineDocumentationCommentTrivia) || syntaxTrivia.IsKind(CSharp.SyntaxKind.MultiLineDocumentationCommentTrivia); private static readonly Func<SyntaxTrivia, bool> s_isVisualBasicCommentTrivia = (syntaxTrivia) => syntaxTrivia.IsKind(VisualBasic.SyntaxKind.CommentTrivia) || syntaxTrivia.IsKind(VisualBasic.SyntaxKind.DocumentationCommentTrivia); internal static async Task<bool> IsGeneratedCodeAsync(SyntaxTree syntaxTree, CancellationToken cancellationToken) { if (IsGeneratedCodeFileName(syntaxTree.FilePath)) { return true; } var isCommentTrivia = syntaxTree.Options.Language == LanguageNames.CSharp ? s_isCSharpCommentTrivia : s_isVisualBasicCommentTrivia; var syntaxRoot = await syntaxTree.GetRootAsync(cancellationToken); return BeginsWithAutoGeneratedComment(syntaxRoot, isCommentTrivia); } private static bool IsGeneratedCodeFileName(string? filePath) { if (!string.IsNullOrEmpty(filePath)) { var fileName = Path.GetFileName(filePath); if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase)) { return true; } var extension = Path.GetExtension(fileName); if (!string.IsNullOrEmpty(extension)) { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); if (fileNameWithoutExtension.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) || fileNameWithoutExtension.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) || fileNameWithoutExtension.EndsWith(".g", StringComparison.OrdinalIgnoreCase) || fileNameWithoutExtension.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase)) { return true; } } } return false; } private static bool BeginsWithAutoGeneratedComment(SyntaxNode syntaxRoot, Func<SyntaxTrivia, bool> isComment) { if (syntaxRoot.HasLeadingTrivia) { var leadingTrivia = syntaxRoot.GetLeadingTrivia(); foreach (var trivia in leadingTrivia) { if (!isComment(trivia)) { continue; } var text = trivia.ToString(); // Check to see if the text of the comment contains an auto generated comment. foreach (var autoGenerated in s_autoGeneratedStrings) { if (text.Contains(autoGenerated)) { return true; } } } } return false; } internal static bool? GetIsGeneratedCodeFromOptions(AnalyzerConfigOptions options) { // Check for explicit user configuration for generated code. // generated_code = true | false if (options.TryGetValue("generated_code", out var optionValue) && bool.TryParse(optionValue, out var boolValue)) { return boolValue; } // Either no explicit user configuration or we don't recognize the option value. return null; } } }