From daa230531e787893db5661812f9d683f60a999c3 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sun, 6 Mar 2011 19:13:18 +0000 Subject: [PATCH] Add support for TextTemplatingFileGenerator custom tool. --- .../Project/Configuration/AssemblyInfo.cs | 16 +++ .../Project/Src/ITextTemplatingAppDomain.cs | 12 ++ .../Src/ITextTemplatingAppDomainFactory.cs | 12 ++ .../Src/ITextTemplatingCustomToolContext.cs | 13 +++ .../Src/ITextTemplatingFileGenerator.cs | 12 ++ .../Project/Src/ITextTemplatingHost.cs | 13 +++ .../Project/Src/TextTemplatingAppDomain.cs | 34 ++++++ .../Src/TextTemplatingAppDomainFactory.cs | 15 +++ .../Src/TextTemplatingCustomToolContext.cs | 23 ++++ .../Src/TextTemplatingFileGenerator.cs | 69 +++++++++++ .../TextTemplatingFileGeneratorCustomTool.cs | 38 ++++++ .../Project/Src/TextTemplatingHost.cs | 42 +++++++ .../Project/TextTemplating.addin | 30 +++++ .../Project/TextTemplating.csproj | 84 +++++++++++++ .../Project/lib/Mono.TextTemplating.dll | Bin 0 -> 65536 bytes .../Test/Configuration/AssemblyInfo.cs | 16 +++ .../Helpers/FakeTextTemplatingAppDomain.cs | 20 ++++ .../FakeTextTemplatingAppDomainFactory.cs | 22 ++++ .../FakeTextTemplatingCustomToolContext.cs | 24 ++++ .../FakeTextTemplatingFileGenerator.cs | 24 ++++ .../Test/Helpers/FakeTextTemplatingHost.cs | 30 +++++ .../Test/Helpers/TestableFileProjectItem.cs | 24 ++++ ...leTextTemplatingFileGeneratorCustomTool.cs | 26 +++++ ...tTemplatingFileGeneratorCustomToolTests.cs | 73 ++++++++++++ .../Src/TextTemplatingFileGeneratorTests.cs | 83 +++++++++++++ .../Test/Src/TextTemplatingHostTests.cs | 94 +++++++++++++++ .../Test/TextTemplating.Tests.csproj | 89 ++++++++++++++ .../Misc/TextTemplating/TextTemplating.sln | 110 ++++++++++++++++++ 28 files changed, 1048 insertions(+) create mode 100644 src/AddIns/Misc/TextTemplating/Project/Configuration/AssemblyInfo.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomain.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomainFactory.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingFileGenerator.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomain.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomainFactory.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGeneratorCustomTool.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingHost.cs create mode 100644 src/AddIns/Misc/TextTemplating/Project/TextTemplating.addin create mode 100644 src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj create mode 100644 src/AddIns/Misc/TextTemplating/Project/lib/Mono.TextTemplating.dll create mode 100644 src/AddIns/Misc/TextTemplating/Test/Configuration/AssemblyInfo.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomain.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomainFactory.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingFileGenerator.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/TestableFileProjectItem.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Helpers/TestableTextTemplatingFileGeneratorCustomTool.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorCustomToolTests.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingHostTests.cs create mode 100644 src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj create mode 100644 src/AddIns/Misc/TextTemplating/TextTemplating.sln diff --git a/src/AddIns/Misc/TextTemplating/Project/Configuration/AssemblyInfo.cs b/src/AddIns/Misc/TextTemplating/Project/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..13702edfba --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Configuration/AssemblyInfo.cs @@ -0,0 +1,16 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System.Reflection; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("TextTemplating")] +[assembly: AssemblyDescription("Text Templating (T4) Addin for SharpDevelop")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomain.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomain.cs new file mode 100644 index 0000000000..662c86e088 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomain.cs @@ -0,0 +1,12 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.TextTemplating +{ + public interface ITextTemplatingAppDomain : IDisposable + { + AppDomain AppDomain { get; } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomainFactory.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomainFactory.cs new file mode 100644 index 0000000000..a6fde56036 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingAppDomainFactory.cs @@ -0,0 +1,12 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.TextTemplating +{ + public interface ITextTemplatingAppDomainFactory + { + ITextTemplatingAppDomain CreateTextTemplatingAppDomain(string applicationBase); + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs new file mode 100644 index 0000000000..f7f8c94501 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.TextTemplating +{ + public interface ITextTemplatingCustomToolContext + { + FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName); + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingFileGenerator.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingFileGenerator.cs new file mode 100644 index 0000000000..6b123995ff --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingFileGenerator.cs @@ -0,0 +1,12 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.TextTemplating +{ + public interface ITextTemplatingFileGenerator : IDisposable + { + void ProcessTemplate(); + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs new file mode 100644 index 0000000000..ce47ed5177 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.TextTemplating +{ + public interface ITextTemplatingHost : IDisposable + { + bool ProcessTemplate(string inputFile, string outputFile); + string OutputFile { get; } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomain.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomain.cs new file mode 100644 index 0000000000..cb4da2fb43 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomain.cs @@ -0,0 +1,34 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.Reflection; + +namespace ICSharpCode.TextTemplating +{ + [Serializable] + public class TextTemplatingAppDomain : ITextTemplatingAppDomain + { + AppDomain appDomain; + + public TextTemplatingAppDomain(string applicationBase) + { + AppDomainSetup setupInfo = new AppDomainSetup(); + setupInfo.ApplicationBase = applicationBase; + this.appDomain = AppDomain.CreateDomain("TextTemplatingAppDomain", null, setupInfo); + } + + public AppDomain AppDomain { + get { return this.appDomain; } + } + + public void Dispose() + { + if (this.appDomain != null) { + AppDomain.Unload(this.appDomain); + this.appDomain = null; + } + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomainFactory.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomainFactory.cs new file mode 100644 index 0000000000..b400557915 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingAppDomainFactory.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.TextTemplating +{ + public class TextTemplatingAppDomainFactory : ITextTemplatingAppDomainFactory + { + public ITextTemplatingAppDomain CreateTextTemplatingAppDomain(string applicationBase) + { + return new TextTemplatingAppDomain(applicationBase); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs new file mode 100644 index 0000000000..b483b79751 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs @@ -0,0 +1,23 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.TextTemplating +{ + public class TextTemplatingCustomToolContext : ITextTemplatingCustomToolContext + { + CustomToolContext context; + + public TextTemplatingCustomToolContext(CustomToolContext context) + { + this.context = context; + } + + public FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName) + { + return context.EnsureOutputFileIsInProject(baseItem, outputFileName); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs new file mode 100644 index 0000000000..dde2ec5fa2 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs @@ -0,0 +1,69 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.TextTemplating +{ + public class TextTemplatingFileGenerator : ITextTemplatingFileGenerator + { + ITextTemplatingHost host; + FileProjectItem projectFile; + ITextTemplatingCustomToolContext context; + + public TextTemplatingFileGenerator( + ITextTemplatingHost host, + FileProjectItem projectFile, + ITextTemplatingCustomToolContext context) + { + this.host = host; + this.projectFile = projectFile; + this.context = context; + } + + public void Dispose() + { + host.Dispose(); + } + + public void ProcessTemplate() + { + GenerateOutputFileForTemplate(); + AddOutputFileToProjectIfRequired(); + } + + void GenerateOutputFileForTemplate() + { + string inputFileName = projectFile.FileName; + string outputFileName = GetOutputFileName(inputFileName); + host.ProcessTemplate(inputFileName, outputFileName); + } + + string GetOutputFileName(string inputFileName) + { + return Path.ChangeExtension(inputFileName, ".cs"); + } + + void AddOutputFileToProjectIfRequired() + { + context.EnsureOutputFileIsInProject(projectFile, host.OutputFile); + } + + +// internal static void LogicalSetData (string name, object value, +// System.CodeDom.Compiler.CompilerErrorCollection errors) +// { +// //FIXME: CallContext.LogicalSetData not implemented in Mono +// try { +// System.Runtime.Remoting.Messaging.CallContext.LogicalSetData (name, value); +// } catch (NotImplementedException) { +// errors.Add (new System.CodeDom.Compiler.CompilerError ( +// null, -1, -1, null, +// "Could not set " + name + " - CallContext.LogicalSetData not implemented in this Mono version" +// ) { IsWarning = true }); +// } +// } + } +} \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGeneratorCustomTool.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGeneratorCustomTool.cs new file mode 100644 index 0000000000..f0a0cd7a92 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGeneratorCustomTool.cs @@ -0,0 +1,38 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; +using System.IO; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.TextTemplating +{ + public class TextTemplatingFileGeneratorCustomTool : ICustomTool + { + public void GenerateCode(FileProjectItem item, CustomToolContext context) + { + using (var generator = CreateTextTemplatingFileGenerator(item, context)) { + generator.ProcessTemplate(); + } + } + + protected virtual ITextTemplatingFileGenerator CreateTextTemplatingFileGenerator( + FileProjectItem projectFile, + CustomToolContext context) + { + var appDomainFactory = new TextTemplatingAppDomainFactory(); + string applicationBase = GetAssemblyBaseLocation(); + var host = new TextTemplatingHost(appDomainFactory, applicationBase); + var textTemplatingCustomToolContext = new TextTemplatingCustomToolContext(context); + + return new TextTemplatingFileGenerator(host, projectFile, textTemplatingCustomToolContext); + } + + string GetAssemblyBaseLocation() + { + string location = GetType().Assembly.Location; + return Path.GetDirectoryName(location); + } + } +} \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingHost.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingHost.cs new file mode 100644 index 0000000000..05cf8fd02e --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingHost.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Mono.TextTemplating; + +namespace ICSharpCode.TextTemplating +{ + public class TextTemplatingHost : TemplateGenerator, ITextTemplatingHost + { + ITextTemplatingAppDomainFactory appDomainFactory; + ITextTemplatingAppDomain templatingAppDomain; + string applicationBase; + + public TextTemplatingHost(ITextTemplatingAppDomainFactory appDomainFactory, string applicationBase) + { + this.appDomainFactory = appDomainFactory; + this.applicationBase = applicationBase; + } + + public void Dispose() + { + if (templatingAppDomain != null) { + templatingAppDomain.Dispose(); + templatingAppDomain = null; + } + } + + public override AppDomain ProvideTemplatingAppDomain(string content) + { + if (templatingAppDomain == null) { + CreateAppDomain(); + } + return templatingAppDomain.AppDomain; + } + + void CreateAppDomain() + { + templatingAppDomain = appDomainFactory.CreateTextTemplatingAppDomain(applicationBase); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/TextTemplating.addin b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.addin new file mode 100644 index 0000000000..489c34a8f1 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.addin @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj new file mode 100644 index 0000000000..a0e5eafc90 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj @@ -0,0 +1,84 @@ + + + + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF} + Debug + x86 + Library + ICSharpCode.TextTemplating + TextTemplating + v4.0 + False + False + 4 + false + ..\..\..\..\..\AddIns\Misc\TextTemplating\ + + + x86 + False + Auto + 4194304 + 4096 + + + true + Full + False + True + DEBUG;TRACE + Project + + + false + None + True + False + TRACE + + + + lib\Mono.TextTemplating.dll + + + + 3.5 + + + + + + Configuration\GlobalAssemblyInfo.cs + + + + + + + + + + + + + + + + + Always + + + + + {2748AD25-9C63-4E12-877B-4DCE96FBED54} + ICSharpCode.SharpDevelop + False + + + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} + ICSharpCode.Core + False + + + + \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Project/lib/Mono.TextTemplating.dll b/src/AddIns/Misc/TextTemplating/Project/lib/Mono.TextTemplating.dll new file mode 100644 index 0000000000000000000000000000000000000000..7d4c0825101a2596813ede33a465046716c22683 GIT binary patch literal 65536 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 QC>Cc+c=`W-zik}&Ulp&|YybcN literal 0 HcmV?d00001 diff --git a/src/AddIns/Misc/TextTemplating/Test/Configuration/AssemblyInfo.cs b/src/AddIns/Misc/TextTemplating/Test/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..052d3702c1 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Configuration/AssemblyInfo.cs @@ -0,0 +1,16 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System.Reflection; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("TextTemplating.Tests")] +[assembly: AssemblyDescription("Text Templating (T4) Addin Tests")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomain.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomain.cs new file mode 100644 index 0000000000..ba6c783124 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomain.cs @@ -0,0 +1,20 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class FakeTextTemplatingAppDomain : ITextTemplatingAppDomain + { + public bool IsDisposeCalled; + + public AppDomain AppDomain { get; set; } + + public void Dispose() + { + IsDisposeCalled = true; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomainFactory.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomainFactory.cs new file mode 100644 index 0000000000..297aca7985 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingAppDomainFactory.cs @@ -0,0 +1,22 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class FakeTextTemplatingAppDomainFactory : ITextTemplatingAppDomainFactory + { + public FakeTextTemplatingAppDomain FakeTextTemplatingAppDomain = new FakeTextTemplatingAppDomain(); + public int CreateTextTemplatingAppDomainCallCount; + public string ApplicationBasePassedToCreateTextTemplatingAppDomain; + + public ITextTemplatingAppDomain CreateTextTemplatingAppDomain(string applicationBase) + { + ApplicationBasePassedToCreateTextTemplatingAppDomain = applicationBase; + CreateTextTemplatingAppDomainCallCount++; + return FakeTextTemplatingAppDomain; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs new file mode 100644 index 0000000000..59a26fd62f --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs @@ -0,0 +1,24 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class FakeTextTemplatingCustomToolContext : ITextTemplatingCustomToolContext + { + public FileProjectItem BaseItemPassedToEnsureOutputFileIsInProject; + public string OutputFileNamePassedToEnsureOutputFileIsInProject; + public TestableFileProjectItem EnsureOutputFileIsInProjectReturnValue = new TestableFileProjectItem(@"d:\Projects\MyProject\template.tt"); + + public FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName) + { + BaseItemPassedToEnsureOutputFileIsInProject = baseItem; + OutputFileNamePassedToEnsureOutputFileIsInProject = outputFileName; + + return EnsureOutputFileIsInProjectReturnValue; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingFileGenerator.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingFileGenerator.cs new file mode 100644 index 0000000000..f42fd98597 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingFileGenerator.cs @@ -0,0 +1,24 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class FakeTextTemplatingFileGenerator : ITextTemplatingFileGenerator + { + public bool IsProcessTemplateCalled; + public bool IsDisposeCalledAfterTemplateProcessed; + + public void ProcessTemplate() + { + IsProcessTemplateCalled = true; + } + + public void Dispose() + { + IsDisposeCalledAfterTemplateProcessed = IsProcessTemplateCalled; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs new file mode 100644 index 0000000000..eb76391a25 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs @@ -0,0 +1,30 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class FakeTextTemplatingHost : ITextTemplatingHost + { + public string InputFilePassedToProcessTemplate; + public string OutputFilePassedToProcessTemplate; + public bool ProcessTemplateReturnValue = true; + public bool IsDisposeCalled; + + public bool ProcessTemplate(string inputFile, string outputFile) + { + InputFilePassedToProcessTemplate = inputFile; + OutputFilePassedToProcessTemplate = outputFile; + return ProcessTemplateReturnValue; + } + + public void Dispose() + { + IsDisposeCalled = true; + } + + public string OutputFile { get; set; } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableFileProjectItem.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableFileProjectItem.cs new file mode 100644 index 0000000000..2f5d839e78 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableFileProjectItem.cs @@ -0,0 +1,24 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; + +namespace TextTemplating.Tests.Helpers +{ + public class TestableFileProjectItem : FileProjectItem + { + string fileName; + + public TestableFileProjectItem(string fileName) + : base(null, ItemType.None) + { + this.fileName = fileName; + } + + public override string FileName { + get { return fileName; } + set { fileName = value; } + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableTextTemplatingFileGeneratorCustomTool.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableTextTemplatingFileGeneratorCustomTool.cs new file mode 100644 index 0000000000..9a0eda541e --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/TestableTextTemplatingFileGeneratorCustomTool.cs @@ -0,0 +1,26 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.TextTemplating; + +namespace TextTemplating.Tests.Helpers +{ + public class TestableTextTemplatingFileGeneratorCustomTool : TextTemplatingFileGeneratorCustomTool + { + public FileProjectItem ProjectFilePassedToCreateTextTemplatingFileGenerator; + public CustomToolContext ContextPassedToCreateTextTemplatingFileGenerator; + public FakeTextTemplatingFileGenerator FakeTextTemplatingFileGenerator = new FakeTextTemplatingFileGenerator(); + + protected override ITextTemplatingFileGenerator CreateTextTemplatingFileGenerator( + FileProjectItem projectFile, + CustomToolContext context) + { + ProjectFilePassedToCreateTextTemplatingFileGenerator = projectFile; + ContextPassedToCreateTextTemplatingFileGenerator = context; + + return FakeTextTemplatingFileGenerator; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorCustomToolTests.cs b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorCustomToolTests.cs new file mode 100644 index 0000000000..e0f0555d0a --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorCustomToolTests.cs @@ -0,0 +1,73 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Internal.Templates; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.TextTemplating; +using NUnit.Framework; +using TextTemplating.Tests.Helpers; + +namespace TextTemplating.Tests +{ + [TestFixture] + public class TextTemplatingFileGeneratorCustomToolTests + { + TestableTextTemplatingFileGeneratorCustomTool customTool; + + void CreateCustomTool() + { + customTool = new TestableTextTemplatingFileGeneratorCustomTool(); + } + + IProject CreateProject() + { + return new MSBuildFileProject(@"d:\projects\test.csproj", "test"); + } + + FileProjectItem GenerateCodeWithProjectFile() + { + var file = new TestableFileProjectItem("test.tt"); + customTool.GenerateCode(file, null); + return file; + } + + [Test] + public void GenerateCode_ProjectFilePassed_ProjectFileUsedToCreateTextTemplatingFileGenerator() + { + CreateCustomTool(); + var file = GenerateCodeWithProjectFile(); + + Assert.AreEqual(file, customTool.ProjectFilePassedToCreateTextTemplatingFileGenerator); + } + + [Test] + public void GenerateCode_CustomToolContextPassed_CustomToolContextUsedToCreateTextTemplatingFileGenerator() + { + CreateCustomTool(); + IProject project = CreateProject(); + var context = new CustomToolContext(project); + customTool.GenerateCode(null, context); + + Assert.AreEqual(context, customTool.ContextPassedToCreateTextTemplatingFileGenerator); + } + + [Test] + public void GenerateCode_ProjectFilePassed_TemplateIsProcessed() + { + CreateCustomTool(); + GenerateCodeWithProjectFile(); + + Assert.IsTrue(customTool.FakeTextTemplatingFileGenerator.IsProcessTemplateCalled); + } + + [Test] + public void GenerateCode_ProjectFilePassed_TextTemplatingFileGeneratorIsDisposedAfterTemplateIsProcessed() + { + CreateCustomTool(); + GenerateCodeWithProjectFile(); + + Assert.IsTrue(customTool.FakeTextTemplatingFileGenerator.IsDisposeCalledAfterTemplateProcessed); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs new file mode 100644 index 0000000000..37e7018555 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs @@ -0,0 +1,83 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.TextTemplating; +using NUnit.Framework; +using TextTemplating.Tests.Helpers; + +namespace TextTemplating.Tests +{ + [TestFixture] + public class TextTemplatingFileGeneratorTests + { + TextTemplatingFileGenerator generator; + FakeTextTemplatingHost templatingHost; + FakeTextTemplatingCustomToolContext customToolContext; + + FileProjectItem ProcessTemplate(string fileName) + { + var projectFile = CreateGenerator(fileName); + generator.ProcessTemplate(); + + return projectFile; + } + + FileProjectItem CreateGenerator(string fileName) + { + templatingHost = new FakeTextTemplatingHost(); + var projectFile = new TestableFileProjectItem(fileName); + customToolContext = new FakeTextTemplatingCustomToolContext(); + + generator = new TextTemplatingFileGenerator(templatingHost, projectFile, customToolContext); + + return projectFile; + } + + [Test] + public void ProcessTemplate_TemplateFileInProjectPassed_TemplatingHostProcessesFile() + { + string fileName = @"d:\projects\MyProject\template.tt"; + ProcessTemplate(fileName); + + Assert.AreEqual(fileName, templatingHost.InputFilePassedToProcessTemplate); + } + + [Test] + public void ProcessTemplate_TemplateFileInProjectPassed_OutputFileNamePassedIsInputFileWithFileExtensionChangedToCSharpFileExtension() + { + ProcessTemplate(@"d:\projects\MyProject\template.tt"); + + string expectedOutputFileName = @"d:\projects\MyProject\template.cs"; + Assert.AreEqual(expectedOutputFileName, templatingHost.OutputFilePassedToProcessTemplate); + } + + [Test] + public void Dispose_TemplateHostUsedToCreateFileGenerator_TemplateHostIsDisposed() + { + CreateGenerator(@"d:\template.tt"); + generator.Dispose(); + + Assert.IsTrue(templatingHost.IsDisposeCalled); + } + + [Test] + public void ProcessTemplate_TemplateFileInProjectPassed_TemplateFileInProjectUsedWhenCheckingIfOutputFileExistsInProject() + { + var file = ProcessTemplate(@"d:\template.tt"); + + Assert.AreEqual(file, customToolContext.BaseItemPassedToEnsureOutputFileIsInProject); + } + + [Test] + public void ProcessTemplate_OutputFileNameChangedWhenTemplateProcessed_NewOutputFileNameIsUsedWhenCheckingIfOutputFileExistsInProject() + { + CreateGenerator(@"d:\template.tt"); + templatingHost.OutputFile = @"d:\changed-output.test"; + generator.ProcessTemplate(); + + Assert.AreEqual(@"d:\changed-output.test", customToolContext.OutputFileNamePassedToEnsureOutputFileIsInProject); + } + } +} \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingHostTests.cs b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingHostTests.cs new file mode 100644 index 0000000000..bc66d42de3 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingHostTests.cs @@ -0,0 +1,94 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using ICSharpCode.TextTemplating; +using NUnit.Framework; +using TextTemplating.Tests.Helpers; + +namespace TextTemplating.Tests +{ + [TestFixture] + public class TextTemplatingHostTests + { + TextTemplatingHost host; + FakeTextTemplatingAppDomainFactory textTemplatingAppDomainFactory; + FakeTextTemplatingAppDomain textTemplatingAppDomain; + + void CreateHost() + { + CreateHost(String.Empty); + } + + void CreateHost(string applicationBase) + { + textTemplatingAppDomainFactory = new FakeTextTemplatingAppDomainFactory(); + textTemplatingAppDomain = textTemplatingAppDomainFactory.FakeTextTemplatingAppDomain; + host = new TextTemplatingHost(textTemplatingAppDomainFactory, applicationBase); + } + + [Test] + public void ProvideTemplatingAppDomain_PassedContentName_ReturnsDomainFromTextTemplatingAppDomainFactory() + { + CreateHost(); + AppDomain expectedAppDomain = AppDomain.CreateDomain("TextTemplatingHostTests"); + textTemplatingAppDomain.AppDomain = expectedAppDomain; + + AppDomain actualAppDomain = host.ProvideTemplatingAppDomain("test"); + + Assert.AreEqual(expectedAppDomain, actualAppDomain); + } + + [Test] + public void Dispose_DisposingHostAfterProvideTemplatingAppDomainCalled_DisposesTemplatingAppDomain() + { + CreateHost(); + host.ProvideTemplatingAppDomain("test"); + host.Dispose(); + + Assert.IsTrue(textTemplatingAppDomain.IsDisposeCalled); + } + + [Test] + public void Dispose_DisposingHostWhenProvideTemplatingAppDomainIsNotCalled_DoesNotThrowNullReferenceException() + { + CreateHost(); + Assert.DoesNotThrow(() => host.Dispose()); + } + + [Test] + public void ProvideTemplatingAppDomain_MethodCalledTwice_AppDomainCreatedOnce() + { + CreateHost(); + host.ProvideTemplatingAppDomain("test"); + host.ProvideTemplatingAppDomain("test"); + + Assert.AreEqual(1, textTemplatingAppDomainFactory.CreateTextTemplatingAppDomainCallCount); + } + + [Test] + public void Dispose_DisposeCalledTwiceHostAfterProvideTemplatingAppDomainCalled_DisposesTemplatingAppDomainOnce() + { + CreateHost(); + host.ProvideTemplatingAppDomain("test"); + host.Dispose(); + + textTemplatingAppDomain.IsDisposeCalled = false; + host.Dispose(); + + Assert.IsFalse(textTemplatingAppDomain.IsDisposeCalled); + } + + [Test] + public void ProvideTemplatingAppDomain_PassedContentName_HostApplicationBaseIsUsedAsAppDomainSetupApplicationBase() + { + string applicationBase = @"d:\sharpdevelop\addins\texttemplating"; + CreateHost(applicationBase); + host.ProvideTemplatingAppDomain("test"); + + string actualApplicationBase = textTemplatingAppDomainFactory.ApplicationBasePassedToCreateTextTemplatingAppDomain; + Assert.AreEqual(applicationBase, actualApplicationBase); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj b/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj new file mode 100644 index 0000000000..09a6e946f9 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj @@ -0,0 +1,89 @@ + + + + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6} + Debug + x86 + Library + TextTemplating.Tests + TextTemplating.Tests + v4.0 + Properties + False + False + 4 + false + ..\..\..\..\..\..\bin\UnitTests\ + + + x86 + False + Auto + 4194304 + 4096 + + + true + Full + False + True + DEBUG;TRACE + Project + + + false + None + True + False + TRACE + + + + ..\Project\lib\Mono.TextTemplating.dll + + + ..\..\..\..\Tools\NUnit\nunit.framework.dll + + + + 3.5 + + + + + + Configuration\GlobalAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + {2748AD25-9C63-4E12-877B-4DCE96FBED54} + ICSharpCode.SharpDevelop + + + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} + ICSharpCode.Core + + + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF} + TextTemplating + + + + \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/TextTemplating.sln b/src/AddIns/Misc/TextTemplating/TextTemplating.sln new file mode 100644 index 0000000000..7d3ca24b52 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/TextTemplating.sln @@ -0,0 +1,110 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +# SharpDevelop 4.1.0.7318-alpha +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextTemplating", "Project\TextTemplating.csproj", "{B5D8C3E6-42EC-4D4B-AD05-3644B32563EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDock", "..\..\..\Libraries\AvalonDock\AvalonDock\AvalonDock.csproj", "{87E61430-4243-45F2-B74E-0A4C096CEBF3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Presentation", "..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj", "{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.WinForms", "..\..\..\Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj", "{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "..\..\..\Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextTemplating.Tests", "Test\TextTemplating.Tests.csproj", "{5186325C-DD7F-4246-9BE7-3F384EFBF5A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "..\..\..\Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF}.Debug|x86.Build.0 = Debug|x86 + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF}.Debug|x86.ActiveCfg = Debug|x86 + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF}.Release|x86.Build.0 = Release|x86 + {B5D8C3E6-42EC-4D4B-AD05-3644B32563EF}.Release|x86.ActiveCfg = Release|x86 + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|x86.Build.0 = Debug|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|x86.ActiveCfg = Debug|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|x86.Build.0 = Release|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|x86.ActiveCfg = Release|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|Any CPU.Build.0 = Release|Any CPU + {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.Build.0 = Debug|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.ActiveCfg = Debug|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.Build.0 = Release|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.ActiveCfg = Release|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|x86.Build.0 = Debug|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|x86.ActiveCfg = Debug|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|x86.Build.0 = Release|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|x86.ActiveCfg = Release|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|Any CPU.Build.0 = Release|Any CPU + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.Build.0 = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.ActiveCfg = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.Build.0 = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.Build.0 = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.ActiveCfg = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.Build.0 = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.ActiveCfg = Release|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|x86.Build.0 = Debug|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|x86.ActiveCfg = Debug|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|x86.Build.0 = Release|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|x86.ActiveCfg = Release|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|Any CPU.Build.0 = Release|Any CPU + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|x86.Build.0 = Debug|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|x86.ActiveCfg = Debug|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|x86.Build.0 = Release|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|x86.ActiveCfg = Release|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|Any CPU.Build.0 = Release|Any CPU + {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Debug|x86.Build.0 = Debug|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Debug|x86.ActiveCfg = Debug|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Debug|Any CPU.Build.0 = Debug|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Debug|Any CPU.ActiveCfg = Debug|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Release|x86.Build.0 = Release|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Release|x86.ActiveCfg = Release|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Release|Any CPU.Build.0 = Release|x86 + {5186325C-DD7F-4246-9BE7-3F384EFBF5A6}.Release|Any CPU.ActiveCfg = Release|x86 + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|x86.Build.0 = Debug|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|x86.ActiveCfg = Debug|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|x86.Build.0 = Release|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|x86.ActiveCfg = Release|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|Any CPU.Build.0 = Release|Any CPU + {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|x86.Build.0 = Debug|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|x86.ActiveCfg = Debug|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|x86.Build.0 = Release|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|x86.ActiveCfg = Release|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.Build.0 = Release|Any CPU + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal