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> " ) };
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}}}")); }
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} }} }}")); }
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)); }
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)); } }
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} }} }}")); }
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)); } }
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)); }