Skip to content
This repository has been archived by the owner on Oct 18, 2018. It is now read-only.

Commit

Permalink
Modify Resources template to support named and index based formatting
Browse files Browse the repository at this point in the history
parameters
  • Loading branch information
pranavkm committed Feb 26, 2014
1 parent 9cdf630 commit 5dccaab
Showing 1 changed file with 40 additions and 18 deletions.
58 changes: 40 additions & 18 deletions build/Resources.tt
Expand Up @@ -22,11 +22,12 @@
var projectDirectory = Path.GetDirectoryName(templateProjectItem.ContainingProject.FullName);
var ttDirectory = Path.Combine(projectDirectory, "Properties");
var projectName = Path.GetFileName(projectDirectory.TrimEnd('/'));
var namedParameterMatcher = new Regex(@"\{([a-z]\w+)\}", RegexOptions.IgnoreCase);
var numberParameterMatcher = new Regex(@"\{(\d+)\}");

foreach (var resxFile in Directory.EnumerateFiles(projectDirectory, "*.resx", SearchOption.AllDirectories))
{
var fileName = Path.GetFileNameWithoutExtension(resxFile);
var parameterMatcher = new Regex(@"\{([a-z]\w+)\}");
var resourceStrings = new List<ResourceData>();

using (var resxReader = new ResXResourceReader(resxFile))
Expand All @@ -38,20 +39,29 @@
var node = (ResXDataNode)entry.Value;
var value = (string)node.GetValue((System.ComponentModel.Design.ITypeResolutionService)null);

var arguments
= parameterMatcher
.Matches(value)
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.Distinct()
.ToList();
bool usingNamedArgs = true;
var match = namedParameterMatcher.Matches(value);
if (match.Count == 0)

This comment has been minimized.

Copy link
@dougbu

dougbu Feb 26, 2014

Member

Believe match.Count can be >0 when match.Success is false. Probably best to check both.

{
usingNamedArgs = false;
match = numberParameterMatcher.Matches(value);
}

This comment has been minimized.

Copy link
@dougbu

dougbu Feb 26, 2014

Member

Bail out (loudly) if !match.Success at this point.

This comment has been minimized.

Copy link
@pranavkm

pranavkm Feb 26, 2014

Author Contributor

This might be the scenario where you have resources without args. We handle in the generator by generating properties instead of functions. The Linq filtering and selection would work on the empty collection, so we don't have to special case it.

This comment has been minimized.

Copy link
@pranavkm

pranavkm Feb 27, 2014

Author Contributor

Seems like calling Matches always returns a collection and it does not have the Success property on it. According to http://msdn.microsoft.com/en-us/library/e7sf90t3(v=vs.110).aspx, the collection would be empty if it does not match anything, so I think this code works fine as is.


var arguments = match.Cast<Match>()

This comment has been minimized.

Copy link
@dougbu

dougbu Feb 26, 2014

Member

A MatchCollection always contains one or more Match elements. So why is the Cast() needed?

This comment has been minimized.

Copy link
@pranavkm

pranavkm Feb 26, 2014

Author Contributor

It's a non-generic collection. The cast allows us to use Linq on it.

This comment has been minimized.

Copy link
@dougbu

dougbu Feb 26, 2014

Member

Gotcha

.Select(m => m.Groups[1].Value)
.Distinct();
if (!usingNamedArgs)
{
arguments = arguments.OrderBy(Convert.ToInt32);
}

resourceStrings.Add(
new ResourceData
{
Name = node.Name,
Value = value,
Arguments = arguments
Arguments = arguments.ToList(),
UsingNamedArgs = usingNamedArgs
});
}
}
Expand Down Expand Up @@ -94,24 +104,29 @@ namespace {0}
else
{
GenerationEnvironment.AppendFormat(
@" return string.Format(CultureInfo.CurrentCulture, GetString(""{0}"", {2}), {1});",
resourceString.Name, resourceString.FormatArguments, resourceString.ArgumentNames);
@" return string.Format(CultureInfo.CurrentCulture, GetString(""{0}""{1}), {2});",
resourceString.Name,
resourceString.UsingNamedArgs ? ", " + resourceString.FormatArguments : null,
resourceString.ArgumentNames);
}

GenerationEnvironment.AppendLine().Append(
@" }").AppendLine();
}

GenerationEnvironment.Append(@"
private static string GetString(string name, params string[] argumentNames)
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

System.Diagnostics.Debug.Assert(value != null);

for (var i = 0; i < argumentNames.Length; i++)
if (formatterNames != null)
{
value = value.Replace(""{"" + argumentNames[i] + ""}"", ""{"" + i + ""}"");
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace(""{"" + formatterNames[i] + ""}"", ""{"" + i + ""}"");
}
}

return value;
Expand All @@ -136,20 +151,27 @@ private class ResourceData
public string Name { get; set; }
public string Value { get; set; }
public List<string> Arguments { get; set; }

public bool UsingNamedArgs { get; set; }

public string FormatArguments
{
get { return string.Join(", ", Arguments); }
get { return string.Join(", ", Arguments.Select(a => "\"" + a + "\"")); }
}

public string ArgumentNames
{
get { return string.Join(", ", Arguments.Select(a => "\"" + a + "\"")); }
get { return string.Join(", ", Arguments.Select(GetArgName)); }
}

public string Parameters
{
get { return "(" + string.Join(", ", Arguments.Select(a => "object " + a)) + ")"; }
get { return "(" + string.Join(", ", Arguments.Select(a => "object " + GetArgName(a))) + ")"; }
}

public string GetArgName(string name)
{
return UsingNamedArgs ? name : 'p' + name;
}
}

Expand Down

0 comments on commit 5dccaab

Please sign in to comment.