示例#1
0
        public IEnumerable <IGeneratedFile> Generate(SimpletOptions options) => new IGeneratedFile[]
        {
            new TextFile(
                $"{options.ProjectName}.csproj",
                $@"<Project Sdk=""Microsoft.NET.Sdk"">

  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>{options.TargetFramework}</TargetFramework>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <Description>{options.Description}</Description>
    <PackageId>{options.ProjectName}</PackageId>
    <Product>{options.ProjectName}</Product>
    <Authors>{options.Author}</Authors>
    <Version>{GetVersion(options.Version)}</Version>
    <DocumentationFile>{options.ProjectName}.xml</DocumentationFile>
    <RootNamespace>{options.ProjectName}</RootNamespace>
    <noWarn>1591,NU5105</noWarn>
    <PackageOutputPath>./</PackageOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <EmbeddedResource Include=""*.txt"" />
  </ItemGroup>
</Project>
"
                )
        };
示例#2
0
        private static IGeneratedFile GeneratePropertyInterfaces(SimpletOptions options, IEnumerable <string> interfaceProperties)
        {
            var content = string.Join(string.Empty, interfaceProperties.Select(propName => $@"
    public interface {propName.ToCsharpInterface()}
    {{
       string {propName} {{ get; set; }}
    }}
"));

            return(new TextFile($"AllInterfaces.cs", $@"namespace {options.ProjectName}
{{{content}}}"));
        }
示例#3
0
        private static IGeneratedFile GenerateModel(SimpletOptions options, TemplateOptions source, string cls, IDictionary <string, string> idents)
        {
            var ifs        = string.Join(", ", idents.Select(m => m.Value.ToCsharpInterface()));
            var properties = string.Join(string.Empty, idents.Select(m => $@"
        /// <summary>Gets or sets the value for replacing '{m.Key}'.</summary>
        public string {m.Value} {{ get; set; }}
"));

            return(new TextFile($"{cls}.cs", $@"namespace {source.Namespace ?? options.ProjectName}
{{
    public class {cls} : {ifs}
    {{{properties}    }}
}}"));
        }
示例#4
0
        public IEnumerable <IGeneratedFile> Generate(SimpletOptions options)
        {
            var cwd = Environment.CurrentDirectory;
            var interfaceProperties = new HashSet <string>();
            var templateId          = 1;
            var allFiles            = Directory.GetFiles(cwd, "*", SearchOption.AllDirectories)
                                      .Select(m => m.Remove(0, cwd.Length + 1))
                                      .ToArray();

            foreach (var source in options.Sources)
            {
                var findPlaceholders = new Regex(source.PlaceholderFormat, RegexOptions.Compiled);
                var glob             = new GlobMatcher(source.IncludePaths, source.ExcludePaths);
                var files            = allFiles.Where(file => glob.IsIncluded(file)).ToArray();
                var commonStart      = files.FindCommonStart();
                var sourceName       = string.Empty;

                var fileMapping = files.ToDictionary(
                    file => file.RemoveCommon(commonStart),
                    file => new TemplateInspector(File.ReadAllText(file))
                    );

                var groups = fileMapping.Keys.Segmentize(source.ParameterType);

                if (source.Sections.Any())
                {
                    var ident = (source.TemplateName ?? $"Template_{templateId++}").ToCsharpIdent();
                    sourceName = $"I{ident}";
                    yield return(GenerateTemplateInterface(options, source, sourceName));
                }

                foreach (var group in groups)
                {
                    var key         = string.IsNullOrEmpty(group.Key) ? "All" : group.Key;
                    var name        = key.ToCsharpIdent();
                    var modelCls    = name + "Model";
                    var templateCls = name + "Template";
                    var result      = GetTemplates(group, fileMapping, findPlaceholders);

                    interfaceProperties.UnionWith(result.Identifiers.Select(m => m.Value));

                    yield return(GenerateModel(options, source, modelCls, result.Identifiers));

                    yield return(GenerateTemplate(options, source, modelCls, templateCls, result.Templates, sourceName));
                }
            }

            yield return(GeneratePropertyInterfaces(options, interfaceProperties));
        }
示例#5
0
        private static IEnumerable <IGeneratedFile> GenerateFiles(string configPath)
        {
            var options         = SimpletOptions.ReadFrom(configPath);
            var dirInfo         = Directory.CreateDirectory(options.TargetDirectory);
            var csGenerator     = new CsGenerator();
            var csFiles         = csGenerator.Generate(options).ToArray();
            var txtGenerator    = new TxtGenerator(csFiles.OfType <IGeneratedClass>());
            var txtFiles        = txtGenerator.Generate(options);
            var csprojGenerator = new CsProjGenerator();
            var csprojFiles     = csprojGenerator.Generate(options);

            foreach (var file in csprojFiles.Concat(txtFiles.Concat(csFiles)))
            {
                yield return(new FullPathFile(dirInfo, file));
            }
        }
示例#6
0
        private static IGeneratedFile GenerateTemplateInterface(SimpletOptions options, TemplateOptions source, string sourceIf)
        {
            var properties = new List <string>();

            foreach (var section in source.Sections)
            {
                properties.Add($@"
        string {section.Title.ToCsharpIdent()} {{ get; }}
");
            }

            var content = string.Join(string.Empty, properties);

            return(new TextFile($"{sourceIf}.cs", $@"namespace {options.ProjectName}
{{
    public interface {sourceIf}
    {{{content}    }}
}}"));
        }
示例#7
0
        public IEnumerable <IGeneratedFile> Generate(SimpletOptions options)
        {
            if (options.Sources.Any(m => m.UseResourceString))
            {
                yield return(new TextFile("_ResourceStringExtensions.cs", $@"
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace {options.ProjectName}
{{
    internal static class _ResourceStringExtensions
    {{
        private static readonly IDictionary<string, string> _cache = new Dictionary<string, string>();

        public static string GetManifestResourceString(this string name)
        {{
            if (!_cache.TryGetValue(name, out var value))
            {{
                var fullName = string.Concat(typeof(_ResourceStringExtensions).Namespace, ""."", name);

                using (var stream = typeof(_ResourceStringExtensions).Assembly.GetManifestResourceStream(fullName))
                {{
                    using (var reader = new StreamReader(stream, Encoding.UTF8))
                    {{
                        value = reader.ReadToEnd();
                    }}
                }}

                _cache[name] = value;
            }}

            return value;
        }}
    }}
}}"));
            }

            foreach (var file in _files)
            {
                yield return(new TextFile(file.Key, file.Value));
            }
        }
示例#8
0
        private static IGeneratedFile GenerateTemplate(SimpletOptions options, TemplateOptions source, string modelCls, string templateCls, Dictionary <string, string> templates, string sourceIf)
        {
            var resources    = new Dictionary <string, string>();
            var hasSections  = source.Sections.Any();
            var type         = source.ParameterType != TemplateParameterType.None ? "type" : "";
            var templateImpl = "return null;";
            var isStatic     = hasSections ? "sealed" : "static";
            var response     = hasSections ? templateCls : "string";
            var headerImpl   = string.Empty;
            var resInterface = string.IsNullOrEmpty(sourceIf) ? "" : $" : {sourceIf}";
            var parameters   = new List <string>
            {
                $"{modelCls} model",
            };

            if (string.IsNullOrEmpty(type))
            {
                templateImpl = $@"return $@""{templates.Values.Single()}"";";
            }
            else if (source.UseResourceString)
            {
                parameters.Add(!string.IsNullOrEmpty(type) ? $"string {type}" : "");
                var cases = templates.Select(m =>
                {
                    var pt      = m.Key.ToCsharpIdent(source.ParameterType);
                    var value   = m.Value;
                    var args    = new List <string>();
                    var matches = _captureVariables.Matches(value);

                    foreach (var match in matches.Reverse())
                    {
                        var group = match.Groups[1];
                        args.Insert(0, group.Value);
                        value = $"{value.Substring(0, group.Index)}{matches.Count - args.Count}{value.Substring(group.Index + group.Length)}";
                    }

                    var name = $"{templateCls}_{pt}.txt";
                    resources.Add(name, value.Replace("\"\"", "\""));
                    return($@"
                case ""{pt}"":
                    return new {templateCls}(string.Format(""{name}"".GetManifestResourceString(), {string.Join(", ", args)}));
");
                });
                templateImpl = $@"switch ({type})
            {{{string.Join(string.Empty, cases)}                    }}
            return null;";
            }
            else
            {
                parameters.Add(!string.IsNullOrEmpty(type) ? $"string {type}" : "");
                var(individual, common) = templates.Optimize();
                var decls = common.Select(m => $@"var {m.Key} = $@""{m.Value}"";");
                var cases = individual.Select(m => $@"
                case ""{m.Key.ToCsharpIdent(source.ParameterType)}"":
                    return new {templateCls}($@""{m.Value}"");
");
                templateImpl = $@"{string.Join(Environment.NewLine, decls)}

            switch ({type})
            {{{string.Join(string.Empty, cases)}                    }}
            return null;";
            }

            var templateParameter = string.Join(", ", parameters);
            var templateArguments = string.Join(", ", parameters.Select(m => m.Split(' ').Last()));
            var result            = $"GetTemplate({templateArguments})";

            var lines = new List <string>
            {
                $@"
        public static {response} Default({templateParameter}) => {result};

        private static {response} GetTemplate({templateParameter})
        {{
            {headerImpl}
            {templateImpl}
        }}
",
            };

            if (!string.IsNullOrEmpty(type))
            {
                var identStrings = new List <string>();

                foreach (var key in templates.Keys)
                {
                    var ident = key.ToCsharpIdent(source.ParameterType);
                    lines.Add($@"
        public static {response} {ident}({parameters.First()}) => {result.Replace(type, $"\"{ident}\"")};
");
                    identStrings.Add($"\"{ident}\"");
                }

                lines.Add($@"
        public static string[] AvailableTypes => new [] {{ {string.Join(", ", identStrings)} }};
");
            }

            if (hasSections)
            {
                lines.Add($@"
        private readonly string _content;

        public {templateCls}(string content) => _content = content;

        private string Cut(string format) => System.Text.RegularExpressions.Regex.Match(_content, format, System.Text.RegularExpressions.RegexOptions.Singleline).Groups[1].Value;
");

                foreach (var section in source.Sections)
                {
                    lines.Add($@"
        public string {section.Title.ToCsharpIdent()} => Cut(""{section.SectionFormat}"");
");
                }

                if (!source.Sections.Any(m => m.Title == "Full"))
                {
                    lines.Add($@"
        public string Full => Cut(""(.*)"");
");
                }
            }

            return(new TextClass($"{templateCls}.cs", $@"namespace {source.Namespace ?? options.ProjectName}
{{
    public {isStatic} class {templateCls}{resInterface}
    {{{string.Join(string.Empty, lines)}    }}
}}", resources));
        }