Advertisement
EdGr87

Untitled

Jun 9th, 2025
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.87 KB | None | 0 0
  1. using Microsoft.CodeAnalysis;
  2. using Microsoft.CodeAnalysis.CSharp.Syntax;
  3.  
  4. using System.Text;
  5.  
  6. namespace FontAliasGenerator {
  7.  
  8.     // Step 1: Mark this class as an incremental source generator
  9.     [Generator]
  10.     public class FontAliasGenerator : IIncrementalGenerator {
  11.         // Step 2: Initialize the generator and set up an incremental syntax provider pipeline
  12.         public void Initialize(IncrementalGeneratorInitializationContext context) {
  13.             System.Diagnostics.Debug.WriteLine("🚀 FontAliasGenerator is initializing...");
  14.  
  15.             var syntaxProvider = context.SyntaxProvider
  16.                     .CreateSyntaxProvider((node, _) => IsMauiProgram(node), // Step 3: Identify MauiProgram class
  17.                         (ctx, _) => ctx.SemanticModel.Compilation) // Step 4: Extract Compilation object
  18.                     .Where(comp => comp is not null);
  19.  
  20.             // Step 5: Register the source output, generating code from extracted compilation data
  21.             context.RegisterSourceOutput(syntaxProvider, GenerateCode);
  22.         }
  23.  
  24.         // Step 6: Function to determine if a node belongs to MauiProgram.cs
  25.         private bool IsMauiProgram(SyntaxNode node) {
  26.             bool isMaui = node is CompilationUnitSyntax root &&
  27.                 root.DescendantNodes().OfType<ClassDeclarationSyntax>()
  28.                     .Any(c => c.Identifier.Text == "MauiProgram");
  29.  
  30.             if(isMaui) {
  31.                 System.Diagnostics.Debug.WriteLine("Scanning MauiProgram.cs for fonts...");
  32.             }
  33.  
  34.             return isMaui;
  35.         }
  36.  
  37.         // Step 7: Main source generation logic—extract font aliases and add generated code
  38.         private void GenerateCode(SourceProductionContext context, Compilation compilation) {
  39.  
  40.             context.ReportDiagnostic(Diagnostic.Create(
  41.       new DiagnosticDescriptor(
  42.           "FONT001",
  43.           "Debug",
  44.           "✅ Source Generator is executing!",
  45.           "SourceGenerator",
  46.           DiagnosticSeverity.Info,
  47.           true),
  48.       Location.None));
  49.  
  50.  
  51.  
  52.  
  53.  
  54.             var fontAliases = ExtractFontAliases(compilation);
  55.             context.AddSource("FontAliases.g.cs", GenerateFontAliasEnum(fontAliases));
  56.         }
  57.  
  58.         // Step 8: Extract font alias names from AddFont method calls
  59.         private List<string> ExtractFontAliases(Compilation compilation) {
  60.             var fontAliases = new List<string>();
  61.  
  62.             // Step 9: Iterate over syntax trees to find MauiProgram.cs
  63.             foreach(var syntaxTree in compilation.SyntaxTrees) {
  64.                 var root = syntaxTree.GetRoot();
  65.  
  66.                 foreach(var invocation in root.DescendantNodes().OfType<InvocationExpressionSyntax>()) {
  67.                     if(!invocation.Expression.ToString().Contains("AddFont")) {
  68.                         continue; // Step 10: Filter only AddFont method calls
  69.                     }
  70.  
  71.                     var arguments = invocation.ArgumentList.Arguments;
  72.                     if(arguments.Count < 2) {
  73.                         continue; // Step 11: Ensure we have both font file and alias
  74.                     }
  75.  
  76.                     var semanticModel = compilation.GetSemanticModel(syntaxTree);
  77.                     var aliasExpr = arguments[1].Expression;
  78.                     var constValue = semanticModel.GetConstantValue(aliasExpr);
  79.  
  80.                     if(constValue.HasValue && constValue.Value is string alias) {
  81.                         fontAliases.Add(alias); // Step 12: Extract and store alias
  82.                         System.Diagnostics.Debug.WriteLine($"Detected font alias: {alias}"); // Debugging output
  83.                     }
  84.                 }
  85.             }
  86.  
  87.             return fontAliases;
  88.         }
  89.  
  90.         // Step 13: Generate Enum for font aliases
  91.         private string GenerateFontAliasEnum(List<string> fontAliases) {
  92.             var sb = new StringBuilder();
  93.  
  94.             // Ensure all files in the project automatically use this alias
  95.             sb.AppendLine("global using WindowsPhoneTile.Enums;");
  96.  
  97.             sb.AppendLine("namespace WindowsPhoneTile.Enums");
  98.             sb.AppendLine("{");
  99.             sb.AppendLine("    public enum FontAliases");
  100.             sb.AppendLine("    {");
  101.  
  102.             foreach(var alias in fontAliases.Distinct()) {
  103.                 var safeName = Sanitize(alias); // Step 14: Clean up alias names for enums
  104.                 sb.AppendLine($"        {safeName},");
  105.             }
  106.  
  107.             sb.AppendLine("    }");
  108.             sb.AppendLine("}");
  109.             return sb.ToString();
  110.         }
  111.  
  112.         // Step 15: Function to sanitize alias names for enum compatibility
  113.         private string Sanitize(string alias) {
  114.             var sanitized = new string([.. alias.Where(char.IsLetterOrDigit)]);
  115.             return string.IsNullOrEmpty(sanitized) ? "_" : char.IsLetter(sanitized[0]) ? sanitized : "_" + sanitized;
  116.         }
  117.     }
  118. }
  119.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement