From 31ba4e8430f3a8bc9009348d8243485c4fb119ce Mon Sep 17 00:00:00 2001 From: anpete Date: Thu, 13 Feb 2014 17:20:00 -0800 Subject: [PATCH] Use named parameters for format strings --- build/Resources.tt | 131 +++++++++++++++++-------------- build/_k-generate-projects.shade | 15 ++-- 2 files changed, 80 insertions(+), 66 deletions(-) diff --git a/build/Resources.tt b/build/Resources.tt index acd9718401..affd445d8a 100644 --- a/build/Resources.tt +++ b/build/Resources.tt @@ -15,12 +15,10 @@ <#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #> <#@ import namespace="EnvDTE" #> <#@ import namespace="EnvDTE80" #> - <# var hostServiceProvider = (IServiceProvider)Host; var dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE)); var templateProjectItem = dte.Solution.FindProjectItem(Host.TemplateFile); - var projectDirectory = Path.GetDirectoryName(templateProjectItem.ContainingProject.FullName); var ttDirectory = Path.Combine(projectDirectory, "Properties"); var projectName = Path.GetFileName(projectDirectory.TrimEnd('/')); @@ -28,7 +26,7 @@ foreach (var resxFile in Directory.EnumerateFiles(projectDirectory, "*.resx", SearchOption.AllDirectories)) { var fileName = Path.GetFileNameWithoutExtension(resxFile); - var parameterMatcher = new Regex(@"\{(\d)\}"); + var parameterMatcher = new Regex(@"\{([a-z]\w+)\}"); var resourceStrings = new List(); using (var resxReader = new ResXResourceReader(resxFile)) @@ -39,23 +37,27 @@ { var node = (ResXDataNode)entry.Value; var value = (string)node.GetValue((System.ComponentModel.Design.ITypeResolutionService)null); - - var matchedArgs - = parameterMatcher.Matches(value) + + var arguments + = parameterMatcher + .Matches(value) .Cast() - .Select(m => Convert.ToInt32(m.Groups[1].Value)) - .ToArray(); + .Select(m => m.Groups[1].Value) + .Distinct() + .ToList(); - resourceStrings.Add(new ResourceData { - Name = node.Name, - Value = value, - ArgsCount = matchedArgs.Any() ? matchedArgs.Max() + 1 : 0 - }); + resourceStrings.Add( + new ResourceData + { + Name = node.Name, + Value = value, + Arguments = arguments + }); } } + GenerationEnvironment.AppendFormat( @"// - namespace {0} {{ using System.Globalization; @@ -67,75 +69,88 @@ namespace {0} private static readonly ResourceManager _resourceManager = new ResourceManager(""{0}.{1}"", typeof({1}).GetTypeInfo().Assembly); ", projectName, fileName); - foreach (var resourceString in resourceStrings) - { - GenerationEnvironment.AppendLine(); - GenerationEnvironment.AppendFormat(@" /// ").AppendLine(); + + foreach (var resourceString in resourceStrings) + { + GenerationEnvironment.AppendLine(); + GenerationEnvironment.AppendFormat(@" /// ").AppendLine(); foreach (var line in resourceString.Value.Split(new[] { Environment.NewLine }, StringSplitOptions.None)) { GenerationEnvironment.AppendFormat(" /// {0}", line.Replace("<", "<").Replace(">", ">")) .AppendLine(); } - GenerationEnvironment.AppendFormat( + + GenerationEnvironment.AppendFormat( @" /// internal static string {0}{1} {{ -", resourceString.Name, resourceString.ArgsCount > 0 ? resourceString.ParamsArray : string.Empty); - if (resourceString.ArgsCount == 0) - { - GenerationEnvironment.AppendFormat( -@" get {{ return GetString(""{0}""); }}", resourceString.Name); - } - else - { - GenerationEnvironment.AppendFormat( -@" return string.Format(CultureInfo.CurrentCulture, GetString(""{0}""), {1});", resourceString.Name, resourceString.ArgsArray); - } - GenerationEnvironment.AppendLine().Append( -@" }").AppendLine(); - } - GenerationEnvironment.Append(@" - private static string GetString(string name) +", resourceString.Name, resourceString.Arguments.Count > 0 ? resourceString.Parameters : string.Empty); + + if (resourceString.Arguments.Count == 0) { - string value = _resourceManager.GetString(name); + GenerationEnvironment.AppendFormat( +@" get {{ return GetString(""{0}""); }}", resourceString.Name); + } + else + { + GenerationEnvironment.AppendFormat( +@" return string.Format(CultureInfo.CurrentCulture, GetString(""{0}"", {2}), {1});", + resourceString.Name, resourceString.FormatArguments, resourceString.ArgumentNames); + } + + GenerationEnvironment.AppendLine().Append( +@" }").AppendLine(); + } + + GenerationEnvironment.Append(@" + private static string GetString(string name, params string[] argumentNames) + { + var value = _resourceManager.GetString(name); + System.Diagnostics.Debug.Assert(value != null); + + for (var i = 0; i < argumentNames.Length; i++) + { + value = value.Replace(""{"" + argumentNames[i] + ""}"", ""{"" + i + ""}""); + } + return value; } } } "); -#> -<# - string outputPath = Path.Combine(ttDirectory, fileName + ".Designer.cs"); - bool fileExists = File.Exists(outputPath); - File.WriteAllText(outputPath, GenerationEnvironment.ToString()); - GenerationEnvironment.Length = 0; - if (!fileExists) { - - templateProjectItem.ProjectItems.AddFromFile(outputPath); - } + + var outputPath = Path.Combine(ttDirectory, fileName + ".Designer.cs"); + + File.WriteAllText(outputPath, GenerationEnvironment.ToString()); + GenerationEnvironment.Length = 0; + + var resxProjectItem = dte.Solution.FindProjectItem(resxFile); + resxProjectItem.ProjectItems.AddFromFile(outputPath); } #> <#+ - private class ResourceData - { + +private class ResourceData +{ public string Name { get; set; } public string Value { get; set; } - public int ArgsCount { get; set; } + public List Arguments { get; set; } - public string ArgsArray + public string FormatArguments { - get { return GenerateArgs("p"); } + get { return string.Join(", ", Arguments); } } - - public string ParamsArray + + public string ArgumentNames { - get { return "(" + GenerateArgs("object p") + ")"; } + get { return string.Join(", ", Arguments.Select(a => "\"" + a + "\"")); } } - - private string GenerateArgs(string template) + + public string Parameters { - return string.Join(", ", Enumerable.Range(0, ArgsCount).Select(i => template + i)); + get { return "(" + string.Join(", ", Arguments.Select(a => "object " + a)) + ")"; } } - } +} + #> \ No newline at end of file diff --git a/build/_k-generate-projects.shade b/build/_k-generate-projects.shade index 4ec7ac7831..50791c7109 100644 --- a/build/_k-generate-projects.shade +++ b/build/_k-generate-projects.shade @@ -207,9 +207,7 @@ functions // Templates const string csTemplate = @""; const string resxDesignerTemplate = @" - Resources.tt - True - True + {1}.resx "; const string resxTemplate = @" {1}.{2}.resources @@ -220,15 +218,17 @@ functions var resxDesignerFiles = new HashSet(resxFileNames.Select(f => Path.ChangeExtension(f, "Designer.cs")), StringComparer.OrdinalIgnoreCase); - var resxFiles = String.Join(Environment.NewLine, - resxFileNames.Select(p => String.Format(resxTemplate, p, projectName, Path.GetFileNameWithoutExtension(p)))); + var resxFiles + = String.Join(Environment.NewLine, + resxFileNames.Select(p => String.Format(resxTemplate, p, projectName, Path.GetFileNameWithoutExtension(p)))); // Build the list of cs files var csFiles = String.Join(Environment.NewLine, FindFilesOfType(projectDir, "*.cs") - .Select(p => resxDesignerFiles.Contains(p) ? String.Format(resxDesignerTemplate, p) : - String.Format(csTemplate, p))); + .Select(p => resxDesignerFiles.Contains(p) + ? String.Format(resxDesignerTemplate, p, Path.GetFileNameWithoutExtension(p).Replace(".Designer", "")) + : String.Format(csTemplate, p))); bool isSample = Path.GetDirectoryName(projectDir) .TrimEnd(Path.DirectorySeparatorChar) @@ -253,7 +253,6 @@ functions string ttFileTemplate = @" Properties\Resources.tt TextTemplatingFileGenerator - _Resources.cs {0} "; // Link the tt file from packages dir