Beispiel #1
0
        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));
            }
        }
Beispiel #2
0
        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}"));
                    }
                }
            }
        }