public void GenerateFromEnums(GeneratorExecutionContext context, SyntaxReceiverClass receiver) { var compilation = context.Compilation; var fieldSymbols = new List <IFieldSymbol>(); foreach (var enums in receiver.CandidateEnums) { var model = compilation.GetSemanticModel(enums.SyntaxTree); var classWithMethods = model.GetDeclaredSymbol(enums); var type = model.GetTypeInfo(enums); //enums.Members; //enums.Identifier.Text; //Debugger.Launch(); var att = classWithMethods.GetAttributes() .FirstOrDefault(it => it.AttributeClass.Name == autoEnums); if (att == null) { continue; } //verify for null var template = att.NamedArguments.FirstOrDefault(it => it.Key == "template") .Value .Value ?.ToString(); if (string.IsNullOrEmpty(template)) { context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Warning, $"enum {classWithMethods.Name} do not have a template for {nameof(AutoEnumAttribute)}. At least put [AutoMethods(template = TemplateMethod.None)]")); continue; } var templateId = (EnumMethod)long.Parse(template); string templateCustom = ""; if (att.NamedArguments.Any(it => it.Key == "CustomTemplateFileName")) { templateCustom = att.NamedArguments.First(it => it.Key == "CustomTemplateFileName") .Value .Value .ToString() ; } string post = ""; switch (templateId) { case EnumMethod.None: context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Info, $"class {classWithMethods.Name} has no template ")); continue; case EnumMethod.CustomTemplateFile: var file = context.AdditionalFiles.FirstOrDefault(it => it.Path.EndsWith(templateCustom)); if (file == null) { context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Error, $"cannot find {templateCustom} for {classWithMethods.Name} . Did you put in AdditionalFiles in csproj ?")); continue; } post = file.GetText().ToString(); break; default: using (var stream = executing.GetManifestResourceStream($"AOPMethodsGenerator.templates.{templateId}.txt")) { using (var reader = new StreamReader(stream)) post = reader.ReadToEnd(); } break; } var members = enums.Members; var ed = new EnumDefinition(enums.Members.Count); ed.Original = enums; ed.Version = ThisAssembly.Info.Version; ed.Name = enums.Identifier.Text; ed.FullName = ed.Name; ed.NamespaceName = "EnumGenerator"; if (!string.IsNullOrWhiteSpace(classWithMethods.ContainingNamespace.Name)) { ed.FullName = classWithMethods.ContainingNamespace.Name + "." + ed.Name; ed.NamespaceName = classWithMethods.ContainingNamespace.Name; } long lastValue = 0; for (int i = 0; i < members.Count; i++) { var m = members[i]; if (m.EqualsValue != null) { lastValue = long.Parse(m.EqualsValue.Value.GetText().ToString()); } ed.Values[i] = new KeyValuePair <string, long>(m.Identifier.Text, lastValue); lastValue++; } // Debugger.Launch(); string typeEnum = "int"; var bs = enums.BaseList; if (bs != null) { typeEnum = bs.Types.FirstOrDefault().GetText().ToString(); } ed.Type = typeEnum; var templateScriban = Scriban.Template.Parse(post); var output = templateScriban.Render(ed, member => member.Name); //Debugger.Launch(); context.AddSource($"{ed.FullName}.autogenerate.cs", SourceText.From(output, Encoding.UTF8)); } }
public void GeneratePublicMethods(GeneratorExecutionContext context, SyntaxReceiverClass receiver) { if ((receiver.CandidatesClasses?.Count ?? 0) == 0) { return; } var compilation = context.Compilation; var fieldSymbols = new List <IFieldSymbol>(); foreach (var classDec in receiver.CandidatesClasses) { var model = compilation.GetSemanticModel(classDec.SyntaxTree); var attrArray = classDec.AttributeLists; var classWithMethods = model.GetDeclaredSymbol(classDec); var attAll = classWithMethods.GetAttributes() .Where(it => it.AttributeClass.Name == autoMethods).ToArray(); if (attAll.Length == 0) { continue; } for (int i = 0; i < attAll.Length; i++) { var att = attAll[i]; //verify for null var template = att.NamedArguments.FirstOrDefault(it => it.Key == "template") .Value .Value ?.ToString(); if (string.IsNullOrEmpty(template)) { context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Warning, $"class {classWithMethods.Name} do not have a template for {nameof(AutoMethodsAttribute)}. At least put [AutoMethods(template = TemplateMethod.None)]")); continue; } var templateId = (TemplateMethod)long.Parse(template); var suffix = att.NamedArguments.FirstOrDefault(it => it.Key == "MethodSuffix") .Value .Value ?.ToString(); ; var prefix = att.NamedArguments.FirstOrDefault(it => it.Key == "MethodPrefix") .Value .Value ?.ToString(); ; string[] excludeFields = null; try { excludeFields = att.NamedArguments.FirstOrDefault(it => it.Key == "ExcludeFields") .Value .Values .Select(it => it.Value?.ToString()) .ToArray() ; } catch (Exception) { //it is not mandatory to define ExcludeFields //do nothing, } string templateCustom = ""; if (att.NamedArguments.Any(it => it.Key == "CustomTemplateFileName")) { templateCustom = att.NamedArguments.First(it => it.Key == "CustomTemplateFileName") .Value .Value .ToString() ; } context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Info, $"starting class {classWithMethods.Name} with template {templateId}")); string post = ""; try { string nameTemplate = templateId.ToString(); switch (templateId) { case TemplateMethod.None: context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Info, $"class {classWithMethods.Name} has no template ")); continue; case TemplateMethod.CustomTemplateFile: var file = context.AdditionalFiles.FirstOrDefault(it => it.Path.EndsWith(templateCustom)); if (file == null) { context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Error, $"cannot find {templateCustom} for {classWithMethods.Name} . Did you put in AdditionalFiles in csproj ?")); continue; } nameTemplate = Path.GetFileNameWithoutExtension(file.Path); post = file.GetText().ToString(); break; default: using (var stream = executing.GetManifestResourceStream($"AOPMethodsGenerator.templates.{templateId}.txt")) { using (var reader = new StreamReader(stream)) post = reader.ReadToEnd(); } break; } string classSource = ProcessClass(classWithMethods, prefix, suffix, post); if (string.IsNullOrWhiteSpace(classSource)) { continue; } context.AddSource($"{classWithMethods.Name}_{nameTemplate}_{i}.autogenerate.cs", SourceText.From(classSource, Encoding.UTF8)); } catch (Exception ex) { context.ReportDiagnostic(DoDiagnostic(DiagnosticSeverity.Error, $"{classWithMethods.Name} error {ex.Message}")); } } } }