Implemented support for having the resource files in separate class libraries

This commit is contained in:
Christian Resma Helle
2013-02-01 00:21:46 +01:00
parent f3f862624b
commit a75c9d1632
6 changed files with 126 additions and 7 deletions
@@ -32,4 +32,4 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.*")] [assembly: AssemblyVersion("1.0.3.*")]
@@ -3,6 +3,7 @@ using System.CodeDom;
using System.CodeDom.Compiler; using System.CodeDom.Compiler;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Reflection;
using System.Text; using System.Text;
using Microsoft.CSharp; using Microsoft.CSharp;
@@ -51,11 +52,66 @@ namespace ChristianHelle.DeveloperTools.CodeGenerators.Resw.CustomTool
const string resourceLoaderType = "ResourceLoader"; const string resourceLoaderType = "ResourceLoader";
var resourceLoaderField = new CodeMemberField(resourceLoaderType, "resourceLoader") var resourceLoaderField = new CodeMemberField(resourceLoaderType, "resourceLoader")
{ {
Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final, Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final
InitExpression = new CodeObjectCreateExpression(resourceLoaderType, new CodePrimitiveExpression(className))
}; };
targetClass.Members.Add(resourceLoaderField); targetClass.Members.Add(resourceLoaderField);
var constructor = new CodeTypeConstructor();
var executingAssemblyVar = new CodeVariableDeclarationStatement(typeof(string), "executingAssemblyName");
var executingAssemblyInit = new CodeAssignStatement(
new CodeVariableReferenceExpression("executingAssemblyName"),
new CodeSnippetExpression("Windows.UI.Xaml.Application.Current.GetType().AssemblyQualifiedName"));
var executingAssemblySplit = new CodeVariableDeclarationStatement(typeof(string[]), "executingAssemblySplit");
var executingAssemblyInit2 = new CodeAssignStatement(
new CodeVariableReferenceExpression("executingAssemblySplit"),
new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("executingAssemblyName"), "Split", new CodePrimitiveExpression(',')));
var executingAssemblyInit3 = new CodeAssignStatement(
new CodeVariableReferenceExpression("executingAssemblyName"),
new CodeArrayIndexerExpression(new CodeVariableReferenceExpression("executingAssemblySplit"), new CodePrimitiveExpression(1)));
var currentAssemblyVar = new CodeVariableDeclarationStatement(typeof(string), "currentAssemblyName");
var currentAssemblyInit = new CodeAssignStatement(
new CodeVariableReferenceExpression("currentAssemblyName"),
new CodePropertyReferenceExpression(new CodeTypeOfExpression(className), "AssemblyQualifiedName"));
var currentAssemblySplit = new CodeVariableDeclarationStatement(typeof(string[]), "currentAssemblySplit");
var currentAssemblyInit2 = new CodeAssignStatement(
new CodeVariableReferenceExpression("currentAssemblySplit"),
new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("currentAssemblyName"), "Split", new CodePrimitiveExpression(',')));
var currentAssemblyInit3 = new CodeAssignStatement(
new CodeVariableReferenceExpression("currentAssemblyName"),
new CodeArrayIndexerExpression(new CodeVariableReferenceExpression("currentAssemblySplit"), new CodePrimitiveExpression(1)));
var createResourceLoader = new CodeConditionStatement(
new CodeSnippetExpression("executingAssemblyName.Equals(currentAssemblyName)"),
new CodeStatement[] // true
{
new CodeAssignStatement(
new CodeFieldReferenceExpression(null, "resourceLoader"),
new CodeObjectCreateExpression(new CodeTypeReference("ResourceLoader")))
},
new CodeStatement[] // false
{
new CodeAssignStatement(
new CodeFieldReferenceExpression(null, "resourceLoader"),
new CodeObjectCreateExpression(new CodeTypeReference("ResourceLoader"),
new CodeSnippetExpression("currentAssemblyName + \"/Resources\"")))
});
constructor.Statements.Add(executingAssemblyVar);
constructor.Statements.Add(executingAssemblyInit);
constructor.Statements.Add(executingAssemblySplit);
constructor.Statements.Add(executingAssemblyInit2);
constructor.Statements.Add(executingAssemblyInit3);
constructor.Statements.Add(currentAssemblyVar);
constructor.Statements.Add(currentAssemblyInit);
constructor.Statements.Add(currentAssemblySplit);
constructor.Statements.Add(currentAssemblyInit2);
constructor.Statements.Add(currentAssemblyInit3);
constructor.Statements.Add(createResourceLoader);
targetClass.Members.Add(constructor);
var resources = ResourceParser.Parse(); var resources = ResourceParser.Parse();
foreach (var item in resources) foreach (var item in resources)
{ {
@@ -32,4 +32,4 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.*")] [assembly: AssemblyVersion("1.0.3.*")]
@@ -6,7 +6,7 @@ namespace ChristianHelle.DeveloperTools.CodeGenerators.Resw.CustomTool.Tests
{ {
[TestClass] [TestClass]
[DeploymentItem("Resources/Resources.resw")] [DeploymentItem("Resources/Resources.resw")]
public class CodeGeneratorTests public class CSharpCodeGeneratorTests
{ {
private string reswFileContents; private string reswFileContents;
private const string FilePath = "Resources.resw"; private const string FilePath = "Resources.resw";
@@ -55,7 +55,7 @@ namespace ChristianHelle.DeveloperTools.CodeGenerators.Resw.CustomTool.Tests
[TestMethod] [TestMethod]
public void ResourceLoaderInitializedWithClassName() public void ResourceLoaderInitializedWithClassName()
{ {
Assert.IsTrue(actual.Contains("new ResourceLoader(\"Resources\");")); Assert.IsTrue(actual.Contains("new ResourceLoader(currentAssemblyName + \"/Resources\");"));
} }
} }
} }
@@ -57,10 +57,11 @@
<ItemGroup> <ItemGroup>
<Compile Include="ClassNameExtractorTests.cs" /> <Compile Include="ClassNameExtractorTests.cs" />
<Compile Include="CodeGeneratorFactoryTests.cs" /> <Compile Include="CodeGeneratorFactoryTests.cs" />
<Compile Include="CodeGeneratorTests.cs" /> <Compile Include="CSharpCodeGeneratorTests.cs" />
<Compile Include="ResourceParserErrorHandlingTests.cs" /> <Compile Include="ResourceParserErrorHandlingTests.cs" />
<Compile Include="ResourceParserTests.cs" /> <Compile Include="ResourceParserTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VisualBasicCodeGeneratorTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Resources\Resources.resw"> <Content Include="Resources\Resources.resw">
@@ -0,0 +1,62 @@
using System.IO;
using System.Linq;
using Microsoft.VisualBasic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ChristianHelle.DeveloperTools.CodeGenerators.Resw.CustomTool.Tests
{
[TestClass]
[DeploymentItem("Resources/Resources.resw")]
public class VisualBasicCodeGeneratorTests
{
private const string FilePath = "Resources.resw";
private string actual;
private string reswFileContents;
private ICodeGenerator target;
[TestInitialize]
public void Initialize()
{
reswFileContents = File.ReadAllText(FilePath);
target = new CodeGeneratorFactory().Create(FilePath.Replace(".resw", string.Empty), "TestApp", reswFileContents, new VBCodeProvider());
actual = target.GenerateCode();
}
[TestMethod]
public void GenerateCodeDoesNotReturnNull()
{
Assert.IsNotNull(actual);
}
[TestMethod]
public void GeneratedCodeContainsPropertiesDefinedInResources()
{
var resourceItems = target.ResourceParser.Parse();
foreach (var item in resourceItems.Where(item => !item.Name.Contains(".")))
Assert.IsTrue(actual.Contains("Public Shared ReadOnly Property " + item.Name + "() As String"));
}
[TestMethod]
public void GeneratedCodePropertiesContainsCommentsSimilarToValuesDefinedInResources()
{
var resourceItems = target.ResourceParser.Parse();
foreach (var item in resourceItems.Where(item => !item.Name.Contains(".")))
Assert.IsTrue(actual.Contains("Localized resource similar to \"" + item.Value + "\""));
}
[TestMethod]
public void ClassNameEqualsFileNameWithoutExtension()
{
Assert.IsTrue(actual.Contains("Class Resources"));
}
[TestMethod]
public void ResourceLoaderInitializedWithClassName()
{
Assert.IsTrue(actual.Contains("New ResourceLoader(currentAssemblyName + \"/Resources\")"));
}
}
}