Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Microsoft.CodeAnalysis;
- using Microsoft.CodeAnalysis.CSharp.Syntax;
- using System.Text;
- namespace FontAliasGenerator {
- // Step 1: Mark this class as an incremental source generator
- [Generator]
- public class FontAliasGenerator : IIncrementalGenerator {
- // Step 2: Initialize the generator and set up an incremental syntax provider pipeline
- public void Initialize(IncrementalGeneratorInitializationContext context) {
- System.Diagnostics.Debug.WriteLine("🚀 FontAliasGenerator is initializing...");
- var syntaxProvider = context.SyntaxProvider
- .CreateSyntaxProvider((node, _) => IsMauiProgram(node), // Step 3: Identify MauiProgram class
- (ctx, _) => ctx.SemanticModel.Compilation) // Step 4: Extract Compilation object
- .Where(comp => comp is not null);
- // Step 5: Register the source output, generating code from extracted compilation data
- context.RegisterSourceOutput(syntaxProvider, GenerateCode);
- }
- // Step 6: Function to determine if a node belongs to MauiProgram.cs
- private bool IsMauiProgram(SyntaxNode node) {
- bool isMaui = node is CompilationUnitSyntax root &&
- root.DescendantNodes().OfType<ClassDeclarationSyntax>()
- .Any(c => c.Identifier.Text == "MauiProgram");
- if(isMaui) {
- System.Diagnostics.Debug.WriteLine("Scanning MauiProgram.cs for fonts...");
- }
- return isMaui;
- }
- // Step 7: Main source generation logic—extract font aliases and add generated code
- private void GenerateCode(SourceProductionContext context, Compilation compilation) {
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(
- "FONT001",
- "Debug",
- "✅ Source Generator is executing!",
- "SourceGenerator",
- DiagnosticSeverity.Info,
- true),
- Location.None));
- var fontAliases = ExtractFontAliases(compilation);
- context.AddSource("FontAliases.g.cs", GenerateFontAliasEnum(fontAliases));
- }
- // Step 8: Extract font alias names from AddFont method calls
- private List<string> ExtractFontAliases(Compilation compilation) {
- var fontAliases = new List<string>();
- // Step 9: Iterate over syntax trees to find MauiProgram.cs
- foreach(var syntaxTree in compilation.SyntaxTrees) {
- var root = syntaxTree.GetRoot();
- foreach(var invocation in root.DescendantNodes().OfType<InvocationExpressionSyntax>()) {
- if(!invocation.Expression.ToString().Contains("AddFont")) {
- continue; // Step 10: Filter only AddFont method calls
- }
- var arguments = invocation.ArgumentList.Arguments;
- if(arguments.Count < 2) {
- continue; // Step 11: Ensure we have both font file and alias
- }
- var semanticModel = compilation.GetSemanticModel(syntaxTree);
- var aliasExpr = arguments[1].Expression;
- var constValue = semanticModel.GetConstantValue(aliasExpr);
- if(constValue.HasValue && constValue.Value is string alias) {
- fontAliases.Add(alias); // Step 12: Extract and store alias
- System.Diagnostics.Debug.WriteLine($"Detected font alias: {alias}"); // Debugging output
- }
- }
- }
- return fontAliases;
- }
- // Step 13: Generate Enum for font aliases
- private string GenerateFontAliasEnum(List<string> fontAliases) {
- var sb = new StringBuilder();
- // Ensure all files in the project automatically use this alias
- sb.AppendLine("global using WindowsPhoneTile.Enums;");
- sb.AppendLine("namespace WindowsPhoneTile.Enums");
- sb.AppendLine("{");
- sb.AppendLine(" public enum FontAliases");
- sb.AppendLine(" {");
- foreach(var alias in fontAliases.Distinct()) {
- var safeName = Sanitize(alias); // Step 14: Clean up alias names for enums
- sb.AppendLine($" {safeName},");
- }
- sb.AppendLine(" }");
- sb.AppendLine("}");
- return sb.ToString();
- }
- // Step 15: Function to sanitize alias names for enum compatibility
- private string Sanitize(string alias) {
- var sanitized = new string([.. alias.Where(char.IsLetterOrDigit)]);
- return string.IsNullOrEmpty(sanitized) ? "_" : char.IsLetter(sanitized[0]) ? sanitized : "_" + sanitized;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement