diff options
author | Matt Ward <matt.ward@xamarin.com> | 2015-11-24 15:38:24 +0300 |
---|---|---|
committer | Matt Ward <matt.ward@xamarin.com> | 2015-11-24 15:38:24 +0300 |
commit | da9087ce789f4ec0560333a6d5f791beef43aa3d (patch) | |
tree | 5282812a6e2f5de23015c038768679863f8f30da /main/src/addins/TextTemplating | |
parent | 880068a2f17793aa3d21caeecd6138c84a0246df (diff) | |
parent | 174f1335283a16918b1cfcac1a5f5594122d3464 (diff) |
Merge branch 'master' into roslyn
Conflicts:
version-checks
Diffstat (limited to 'main/src/addins/TextTemplating')
3 files changed, 135 insertions, 3 deletions
diff --git a/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/GenerateIndentedClassCodeTests.cs b/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/GenerateIndentedClassCodeTests.cs new file mode 100644 index 0000000000..0810e2e783 --- /dev/null +++ b/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/GenerateIndentedClassCodeTests.cs @@ -0,0 +1,108 @@ +// +// GenerateIndentedClassCodeTests.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2015 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using NUnit.Framework; +using System.IO; + +namespace Mono.TextTemplating.Tests +{ + [TestFixture] + public class GenerateIndentedClassCodeTests + { + [Test] + public void FieldAndPropertyGenerated () + { + var provider = CodeDomProvider.CreateProvider ("C#"); + var field = CreateBoolField (); + var property = CreateBoolProperty (); + + string output = TemplatingEngine.GenerateIndentedClassCode (provider, field, property); + output = FixOutput (output); + string expectedOutput = FixOutput (MethodAndFieldGeneratedOutput); + + Assert.AreEqual (expectedOutput, output); + } + + static CodeTypeMember CreateVoidMethod () + { + var meth = new CodeMemberMethod { Name = "MyMethod" }; + meth.ReturnType = new CodeTypeReference (typeof(void)); + return meth; + } + + static CodeTypeMember CreateBoolField () + { + var type = new CodeTypeReference (typeof(bool)); + return new CodeMemberField { Name = "myField", Type = type }; + } + + static CodeTypeMember CreateBoolProperty () + { + var type = new CodeTypeReference (typeof(bool)); + var prop = new CodeMemberProperty { Name = "MyProperty", Type = type }; + prop.GetStatements.Add ( + new CodeMethodReturnStatement ( + new CodePrimitiveExpression (true) + ) + ); + return prop; + } + + /// <summary> + /// Remove empty lines which are not generated on Mono. + /// </summary> + static string FixOutput (string output, string newLine = "\n") + { + using (var writer = new StringWriter ()) { + using (var reader = new StringReader (output)) { + + string line; + while ((line = reader.ReadLine ()) != null) { + if (!String.IsNullOrWhiteSpace (line)) { + writer.Write (line); + writer.Write (newLine); + } + } + } + return writer.ToString (); + } + } + + public static string MethodAndFieldGeneratedOutput = +@" + private bool myField; + + private bool MyProperty { + get { + return true; + } + } +"; + } +} diff --git a/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj b/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj index 3b67d5045d..fec16c1aac 100644 --- a/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj +++ b/main/src/addins/TextTemplating/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj @@ -41,6 +41,7 @@ <Compile Include="GenerationTests.cs" /> <Compile Include="TemplatingEngineHelper.cs" /> <Compile Include="TemplateEnginePreprocessTemplateTests.cs" /> + <Compile Include="GenerateIndentedClassCodeTests.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Mono.TextTemplating\Mono.TextTemplating.csproj"> diff --git a/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 8a312101d2..9425f6dae8 100644 --- a/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -1091,7 +1091,7 @@ namespace Mono.TextTemplating } var cgType = typeof (CodeGenerator); - var cgInit = cgType.GetMethod ("InitOutput", BindingFlags.NonPublic | BindingFlags.Instance); + var initializeCodeGenerator = GetInitializeCodeGeneratorAction (cgType); var cgFieldGen = cgType.GetMethod ("GenerateField", BindingFlags.NonPublic | BindingFlags.Instance); var cgPropGen = cgType.GetMethod ("GenerateProperty", BindingFlags.NonPublic | BindingFlags.Instance); @@ -1103,19 +1103,42 @@ namespace Mono.TextTemplating foreach (CodeTypeMember member in members) { var f = member as CodeMemberField; if (f != null) { - cgInit.Invoke (generator, new object[] { sw, options }); + initializeCodeGenerator (generator, sw, options); cgFieldGen.Invoke (generator, new object[] { f }); continue; } var p = member as CodeMemberProperty; if (p != null) { - cgInit.Invoke (generator, new object[] { sw, options }); + initializeCodeGenerator (generator, sw, options); cgPropGen.Invoke (generator, new object[] { p, dummy }); continue; } } } + static Action<CodeGenerator, StringWriter, CodeGeneratorOptions> GetInitializeCodeGeneratorAction (Type cgType) + { + var cgInit = cgType.GetMethod ("InitOutput", BindingFlags.NonPublic | BindingFlags.Instance); + if (cgInit != null) { + return new Action<CodeGenerator, StringWriter, CodeGeneratorOptions> ((generator, sw, options) => { + cgInit.Invoke (generator, new object[] { sw, options }); + }); + } + + var cgOptions = cgType.GetField ("options", BindingFlags.NonPublic | BindingFlags.Instance); + var cgOutput = cgType.GetField ("output", BindingFlags.NonPublic | BindingFlags.Instance); + + if (cgOptions != null && cgOutput != null) { + return new Action<CodeGenerator, StringWriter, CodeGeneratorOptions> ((generator, sw, options) => { + var output = new IndentedTextWriter (sw); + cgOptions.SetValue (generator, options); + cgOutput.SetValue (generator, output); + }); + } + + throw new InvalidOperationException ("Unable to initialize CodeGenerator."); + } + public static string GenerateIndentedClassCode (CodeDomProvider provider, params CodeTypeMember[] members) { return GenerateIndentedClassCode (provider, (IEnumerable<CodeTypeMember>)members); |