From f921bef863ecce6c817a6452715243f7fa59b1b0 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Tue, 28 Jul 2020 11:40:49 -0600 Subject: [PATCH 01/58] renamed the namespace Microsoft.VisualStudio to Mono.VisualStudio so this can build in a vsix solution --- Mono.TextTemplating.Tests/DummyHost.cs | 2 +- Mono.TextTemplating.Tests/GenerationTests.cs | 10 +++---- .../TemplateEnginePreprocessTemplateTests.cs | 2 +- .../TextTemplatingSessionTests.cs | 4 +-- .../Mono.TextTemplating/CompiledTemplate.cs | 2 +- .../Mono.TextTemplating/ParsedTemplate.cs | 2 +- .../Mono.TextTemplating/TemplateGenerator.cs | 2 +- .../Mono.TextTemplating/TemplateSettings.cs | 2 +- .../Mono.TextTemplating/TemplatingEngine.cs | 2 +- .../DirectiveProcessor.cs | 2 +- .../DirectiveProcessorException.cs | 2 +- .../EncodingHelper.cs | 3 +-- .../Engine.cs | 2 +- .../Interfaces.cs | 26 ++++++++++++++++++- .../ParameterDirectiveProcessor.cs | 2 +- .../RequiresProvidesDirectiveProcessor.cs | 2 +- .../TextTemplatingSession.cs | 2 +- .../TextTransformation.cs | 2 +- .../ToStringHelper.cs | 2 +- dotnet-t4/TextTransform.cs | 4 +-- dotnet-t4/ToolTemplateGenerator.cs | 2 +- dotnet-t4/ToolTemplateSession.cs | 4 +-- 22 files changed, 53 insertions(+), 30 deletions(-) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/DirectiveProcessor.cs (98%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/DirectiveProcessorException.cs (97%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/EncodingHelper.cs (94%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/Engine.cs (97%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/Interfaces.cs (86%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/ParameterDirectiveProcessor.cs (99%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/RequiresProvidesDirectiveProcessor.cs (99%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/TextTemplatingSession.cs (98%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/TextTransformation.cs (99%) rename Mono.TextTemplating/{Microsoft.VisualStudio.TextTemplating => Mono.VisualStudio.TextTemplating}/ToStringHelper.cs (98%) diff --git a/Mono.TextTemplating.Tests/DummyHost.cs b/Mono.TextTemplating.Tests/DummyHost.cs index 86da60f..82796e5 100644 --- a/Mono.TextTemplating.Tests/DummyHost.cs +++ b/Mono.TextTemplating.Tests/DummyHost.cs @@ -27,7 +27,7 @@ using System; using System.Collections.Generic; using System.CodeDom.Compiler; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; namespace Mono.TextTemplating.Tests { diff --git a/Mono.TextTemplating.Tests/GenerationTests.cs b/Mono.TextTemplating.Tests/GenerationTests.cs index fb5038a..99c8eb6 100644 --- a/Mono.TextTemplating.Tests/GenerationTests.cs +++ b/Mono.TextTemplating.Tests/GenerationTests.cs @@ -28,7 +28,7 @@ using System.Collections.Generic; using System.IO; using NUnit.Framework; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using System.Linq; using System.CodeDom.Compiler; @@ -121,7 +121,7 @@ public void DefaultLanguage () void Generate (string input, string expectedOutput, string newline) { var host = new DummyHost (); - string nameSpaceName = "Microsoft.VisualStudio.TextTemplating4f504ca0"; + string nameSpaceName = "Mono.VisualStudio.TextTemplating4f504ca0"; string code = GenerateCode (host, input, nameSpaceName, newline); Assert.AreEqual (0, host.Errors.Count); @@ -168,10 +168,10 @@ string GenerateCode (ITextTemplatingEngineHost host, string content, string name public static string OutputSample1 = @" -namespace Microsoft.VisualStudio.TextTemplating4f504ca0 { +namespace Mono.VisualStudio.TextTemplating4f504ca0 { - public partial class GeneratedTextTransformation : global::Microsoft.VisualStudio.TextTemplating.TextTransformation { + public partial class GeneratedTextTransformation : global::Mono.VisualStudio.TextTemplating.TextTransformation { #line 9 """" @@ -205,7 +205,7 @@ public override string TransformText() { #line hidden #line 7 """" - this.Write(global::Microsoft.VisualStudio.TextTemplating.ToStringHelper.ToStringWithCulture( bar )); + this.Write(global::Mono.VisualStudio.TextTemplating.ToStringHelper.ToStringWithCulture( bar )); #line default #line hidden diff --git a/Mono.TextTemplating.Tests/TemplateEnginePreprocessTemplateTests.cs b/Mono.TextTemplating.Tests/TemplateEnginePreprocessTemplateTests.cs index 86b170d..fef001d 100644 --- a/Mono.TextTemplating.Tests/TemplateEnginePreprocessTemplateTests.cs +++ b/Mono.TextTemplating.Tests/TemplateEnginePreprocessTemplateTests.cs @@ -29,7 +29,7 @@ using System.Collections.Generic; using System.IO; using NUnit.Framework; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; namespace Mono.TextTemplating.Tests { diff --git a/Mono.TextTemplating.Tests/TextTemplatingSessionTests.cs b/Mono.TextTemplating.Tests/TextTemplatingSessionTests.cs index 1c7c5a8..405e953 100644 --- a/Mono.TextTemplating.Tests/TextTemplatingSessionTests.cs +++ b/Mono.TextTemplating.Tests/TextTemplatingSessionTests.cs @@ -1,4 +1,4 @@ -// +// // TextTemplatingSessionTests.cs // // Author: @@ -26,7 +26,7 @@ using System; using System.Reflection; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using NUnit.Framework; namespace Mono.TextTemplating.Tests diff --git a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs index 3760f9f..c180041 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs @@ -26,7 +26,7 @@ using System; using System.Reflection; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using System.CodeDom.Compiler; using System.Globalization; using System.Collections.Generic; diff --git a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs index 8248385..b5f841d 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs @@ -28,7 +28,7 @@ using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; namespace Mono.TextTemplating { diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs index 7ead97e..582dcdf 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs @@ -30,7 +30,7 @@ using System.IO; using System.Reflection; using System.Text; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; namespace Mono.TextTemplating { diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index cd3f318..27ccab4 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -27,7 +27,7 @@ using System; using System.Text; using System.Collections.Generic; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using System.IO; namespace Mono.TextTemplating diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 781b4c7..65a7313 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -34,7 +34,7 @@ using System.Text; using System.Threading; using Microsoft.CSharp; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; #if FEATURE_ROSLYN using Mono.TextTemplating.CodeCompilation; #endif diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs similarity index 98% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessor.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs index aae9e09..14afe5c 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs @@ -29,7 +29,7 @@ using System.CodeDom.Compiler; using System.CodeDom; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { public abstract class DirectiveProcessor : IDirectiveProcessor { diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessorException.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessorException.cs similarity index 97% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessorException.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessorException.cs index ffc08cd..90cdd84 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/DirectiveProcessorException.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessorException.cs @@ -27,7 +27,7 @@ using System; using System.Runtime.Serialization; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { [Serializable] diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/EncodingHelper.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs similarity index 94% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/EncodingHelper.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs index 89a6a46..cc7270f 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/EncodingHelper.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs @@ -27,9 +27,8 @@ using System; using System.Text; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { - [Obsolete("Not implemented")] public static class EncodingHelper { public static Encoding GetEncoding (string filePath) diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs similarity index 97% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs index fd78b49..faaa564 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs @@ -27,7 +27,7 @@ using System; using Mono.TextTemplating; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { [Obsolete ("Use Mono.TextTemplating.TemplatingEngine directly")] public class Engine : ITextTemplatingEngine diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs similarity index 86% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Interfaces.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index d2eb60e..2dd5540 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -31,8 +31,9 @@ using System.Collections.Generic; using System.Runtime.Serialization; using System.Text; +using Mono.TextTemplating; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { public interface IRecognizeHostSpecific { @@ -48,6 +49,29 @@ string PreprocessTemplate (string content, ITextTemplatingEngineHost host, strin string classNamespace, out string language, out string [] references); } + public interface ITextTemplatingComponents + { + ITextTemplatingEngineHost Host { get; } + + TemplatingEngine Engine { get; } + + string InputFile { get; } + + ITextTemplatingCallback Callback { get; set; } + + object Hierarchy { get; set; } + } + + public interface ITextTemplatingCallback + { + bool Errors { get; set; } + string Extension { get; } + void ErrorCallback (bool warning, string message, int line, int column); + void SetFileExtension (string extension); + void SetOutputEncoding (Encoding encoding, bool fromOutputDirective); + Encoding OutputEncoding { get; } + } + public interface ITextTemplatingEngineHost { object GetHostOption (string optionName); diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs similarity index 99% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs index 9810385..afa280f 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs @@ -30,7 +30,7 @@ using System.IO; using Mono.TextTemplating; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { public sealed class ParameterDirectiveProcessor : DirectiveProcessor, IRecognizeHostSpecific { diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs similarity index 99% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs index 3b577d1..2a63eae 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/RequiresProvidesDirectiveProcessor.cs @@ -29,7 +29,7 @@ using System.CodeDom.Compiler; using System.Text; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTemplatingSession.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs similarity index 98% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTemplatingSession.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs index 94426cb..423fa73 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTemplatingSession.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs @@ -28,7 +28,7 @@ using System.Collections; using System.Runtime.Serialization; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { [Serializable] public sealed class TextTemplatingSession : Dictionary, ITextTemplatingSession, ISerializable diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTransformation.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs similarity index 99% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTransformation.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs index 119a98a..b1e2596 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/TextTransformation.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs @@ -29,7 +29,7 @@ using System.Collections.Generic; using System.Text; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { public abstract class TextTransformation : IDisposable { diff --git a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ToStringHelper.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ToStringHelper.cs similarity index 98% rename from Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ToStringHelper.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ToStringHelper.cs index ab9a0bf..2e4e832 100644 --- a/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/ToStringHelper.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ToStringHelper.cs @@ -27,7 +27,7 @@ using System; using System.Reflection; -namespace Microsoft.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating { public static class ToStringHelper { diff --git a/dotnet-t4/TextTransform.cs b/dotnet-t4/TextTransform.cs index 55e2ca7..89a9dab 100644 --- a/dotnet-t4/TextTransform.cs +++ b/dotnet-t4/TextTransform.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) 2009 Novell, Inc. (http://www.novell.com) // Copyright (c) Microsoft Corp. (https://www.microsoft.com) // @@ -27,7 +27,7 @@ using System.Linq; using System.Reflection; using System.Text; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using Mono.Options; namespace Mono.TextTemplating diff --git a/dotnet-t4/ToolTemplateGenerator.cs b/dotnet-t4/ToolTemplateGenerator.cs index b077e2d..bdecf47 100644 --- a/dotnet-t4/ToolTemplateGenerator.cs +++ b/dotnet-t4/ToolTemplateGenerator.cs @@ -21,7 +21,7 @@ using System.CodeDom.Compiler; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; namespace Mono.TextTemplating { diff --git a/dotnet-t4/ToolTemplateSession.cs b/dotnet-t4/ToolTemplateSession.cs index 8f00a03..0e38de5 100644 --- a/dotnet-t4/ToolTemplateSession.cs +++ b/dotnet-t4/ToolTemplateSession.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft Corp (https://www.microsoft.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -20,7 +20,7 @@ // THE SOFTWARE. using System; -using Microsoft.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; From 042ae23a0e878563cb6d0ce5838aa568f5e2e4ae Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Tue, 28 Jul 2020 19:17:11 -0600 Subject: [PATCH 02/58] no message --- Mono.TextTemplating.sln | 23 ++- .../Mono.TextTemplating.csproj | 6 + .../Mono.TextTemplating/TemplateSettings.cs | 13 ++ .../Mono.TextTemplating/TemplatingEngine.cs | 2 +- .../Engine.cs | 5 +- .../Interfaces.cs | 40 +++- .../TextTemplatingSession.cs | 27 ++- dotnet-t4-vsix-library/Resources.Designer.cs | 153 +++++++++++++++ dotnet-t4-vsix-library/Resources.resx | 150 +++++++++++++++ .../TextDebugTemplateEngine.cs | 131 +++++++++++++ .../TextTemplatingCallback.cs | 57 ++++++ .../TransformationRunFactory.cs | 26 +++ .../TransformationRunner.cs | 174 ++++++++++++++++++ .../dotnet-t4-vsix-library.csproj | 33 ++++ dotnet-t4/ToolTemplateGenerator.cs | 2 +- dotnet-t4/ToolTemplateSession.cs | 4 +- 16 files changed, 825 insertions(+), 21 deletions(-) create mode 100644 dotnet-t4-vsix-library/Resources.Designer.cs create mode 100644 dotnet-t4-vsix-library/Resources.resx create mode 100644 dotnet-t4-vsix-library/TextDebugTemplateEngine.cs create mode 100644 dotnet-t4-vsix-library/TextTemplatingCallback.cs create mode 100644 dotnet-t4-vsix-library/TransformationRunFactory.cs create mode 100644 dotnet-t4-vsix-library/TransformationRunner.cs create mode 100644 dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj diff --git a/Mono.TextTemplating.sln b/Mono.TextTemplating.sln index d6a1007..12e0fe3 100644 --- a/Mono.TextTemplating.sln +++ b/Mono.TextTemplating.sln @@ -1,11 +1,12 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.TextTemplating", "Mono.TextTemplating\Mono.TextTemplating.csproj", "{A2364D6A-00EF-417C-80A6-815726C70032}" +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.TextTemplating", "Mono.TextTemplating\Mono.TextTemplating.csproj", "{A2364D6A-00EF-417C-80A6-815726C70032}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.TextTemplating.Tests", "Mono.TextTemplating.Tests\Mono.TextTemplating.Tests.csproj", "{CB590106-8331-4CBE-8131-B154E7BF79E1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.TextTemplating.Tests", "Mono.TextTemplating.Tests\Mono.TextTemplating.Tests.csproj", "{CB590106-8331-4CBE-8131-B154E7BF79E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextTransform", "TextTransform\TextTransform.csproj", "{D1D35409-C814-47F6-B038-B9B5BF0FE490}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextTransform", "TextTransform\TextTransform.csproj", "{D1D35409-C814-47F6-B038-B9B5BF0FE490}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EEE624A1-0ED3-4D57-96B4-5D1B22E72697}" ProjectSection(SolutionItems) = preProject @@ -13,11 +14,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Directory.Build.props = Directory.Build.props EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-t4", "dotnet-t4\dotnet-t4.csproj", "{6AA924D8-7119-4593-9B56-11D17AC3578E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-t4", "dotnet-t4\dotnet-t4.csproj", "{6AA924D8-7119-4593-9B56-11D17AC3578E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-t4-project-tool", "dotnet-t4-project-tool\dotnet-t4-project-tool.csproj", "{114B7AEF-61DA-453A-9A84-6DDEA13460B7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-t4-project-tool", "dotnet-t4-project-tool\dotnet-t4-project-tool.csproj", "{114B7AEF-61DA-453A-9A84-6DDEA13460B7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.TextTemplating.Roslyn", "Mono.TextTemplating.Roslyn\Mono.TextTemplating.Roslyn.csproj", "{8DB780A9-27C1-44B4-860F-50C4419FD349}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.TextTemplating.Roslyn", "Mono.TextTemplating.Roslyn\Mono.TextTemplating.Roslyn.csproj", "{8DB780A9-27C1-44B4-860F-50C4419FD349}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-t4-vsix-library", "dotnet-t4-vsix-library\dotnet-t4-vsix-library.csproj", "{6B494E73-4201-4FA8-848D-2970C27299D0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -49,6 +52,10 @@ Global {8DB780A9-27C1-44B4-860F-50C4419FD349}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DB780A9-27C1-44B4-860F-50C4419FD349}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DB780A9-27C1-44B4-860F-50C4419FD349}.Release|Any CPU.Build.0 = Release|Any CPU + {6B494E73-4201-4FA8-848D-2970C27299D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B494E73-4201-4FA8-848D-2970C27299D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B494E73-4201-4FA8-848D-2970C27299D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B494E73-4201-4FA8-848D-2970C27299D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Mono.TextTemplating/Mono.TextTemplating.csproj b/Mono.TextTemplating/Mono.TextTemplating.csproj index 5034720..6b7e9ea 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.csproj +++ b/Mono.TextTemplating/Mono.TextTemplating.csproj @@ -31,4 +31,10 @@ This package allows embedding the T4 engine in an application. + + + + 4.3.0 + + \ No newline at end of file diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index 27ccab4..f75191a 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using Mono.VisualStudio.TextTemplating; using System.IO; +using System.Reflection; namespace Mono.TextTemplating { @@ -65,6 +66,18 @@ public TemplateSettings () public bool NoLinePragmas { get; set; } public bool InternalVisibility { get; set; } public Type HostType { get; set; } + + public void ApplyTo (ITextTemplatingSession session) + { + foreach(PropertyInfo property in GetType().GetProperties()) { + if (!property.PropertyType.IsSerializable) { + continue; + } + + session[property.Name] = property.GetValue (this); + } + } + public string GetFullName () => string.IsNullOrEmpty (Namespace) ? Name : Namespace + "." + Name; } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 65a7313..10d725f 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -311,7 +311,7 @@ static CompilerResults CompileCode (IEnumerable references, TemplateSett } #endif - static string [] ProcessReferences (ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings) + protected static string[] ProcessReferences (ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings) { var resolved = new Dictionary (); diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs index faaa564..02f7e8c 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs @@ -30,7 +30,8 @@ namespace Mono.VisualStudio.TextTemplating { [Obsolete ("Use Mono.TextTemplating.TemplatingEngine directly")] - public class Engine : ITextTemplatingEngine + public class Engine + : ITextTemplatingEngine { TemplatingEngine engine = new TemplatingEngine (); @@ -44,7 +45,7 @@ public string PreprocessTemplate (string content, ITextTemplatingEngineHost host { return engine.PreprocessTemplate (content, host, className, classNamespace, out language, out references); } - + public const string CacheAssembliesOptionString = "CacheAssemblies"; } } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 2dd5540..cb85d95 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -29,6 +29,10 @@ using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; +using System.Reflection; +#if NETSTANDARD +using System.Runtime.Loader; +#endif using System.Runtime.Serialization; using System.Text; using Mono.TextTemplating; @@ -41,7 +45,30 @@ public interface IRecognizeHostSpecific bool RequiresProcessingRunIsHostSpecific { get; } } - [Obsolete("Use Mono.TextTemplating.TemplatingEngine directly")] + public interface IDebugTransformationRun + { + string PerformTransformation (); + + CompilerErrorCollection Errors { get; } + } + + public interface IDebugTransformationRunFactory + { +#if FEATURE_APPDOMAINS + IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); +#elif NETSTANDARD + IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, Func resolver); +#endif + + string RunTransformation (IDebugTransformationRun transformationRun); + } + + public interface IDebugTextTemplatingEngine + : ITextTemplatingEngine + { + IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory); + } + public interface ITextTemplatingEngine { string ProcessTemplate (string content, ITextTemplatingEngineHost host); @@ -53,7 +80,7 @@ public interface ITextTemplatingComponents { ITextTemplatingEngineHost Host { get; } - TemplatingEngine Engine { get; } + ITextTemplatingEngine Engine { get; } string InputFile { get; } @@ -69,6 +96,8 @@ public interface ITextTemplatingCallback void ErrorCallback (bool warning, string message, int line, int column); void SetFileExtension (string extension); void SetOutputEncoding (Encoding encoding, bool fromOutputDirective); + ITextTemplatingCallback DeepCopy (); + Encoding OutputEncoding { get; } } @@ -99,9 +128,14 @@ public interface ITextTemplatingSession : IEnumerable, ISerializable { Guid Id { get; } + bool Debug { get; set; } + string TemplateFile { get; set; } + ITextTemplatingSessionHost UserTransformationSession { get; set; } + Stack IncludeStack { get; } } - public interface ITextTemplatingSessionHost + public interface ITextTemplatingSessionHost + : ISerializable { ITextTemplatingSession CreateSession (); ITextTemplatingSession Session { get; set; } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs index 423fa73..5c2cbe9 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs @@ -40,18 +40,38 @@ public TextTemplatingSession () : this (Guid.NewGuid ()) TextTemplatingSession (SerializationInfo info, StreamingContext context) : base (info, context) { - Id = (Guid)info.GetValue ("Id", typeof (Guid)); } public TextTemplatingSession (Guid id) { this.Id = id; + this.IncludeStack = new Stack (); } public Guid Id { - get; private set; + get => (Guid)this[nameof (Id)]; + set => this[nameof (Id)] = value; } - + + public bool Debug { + get => (bool)this[nameof (Debug)]; + set => this[nameof (Debug)] = value; + } + + public string TemplateFile { + get => (string)this[nameof (TemplateFile)]; + set => this[nameof (TemplateFile)] = value; + } + public ITextTemplatingSessionHost UserTransformationSession { + get => (ITextTemplatingSessionHost)this[nameof (UserTransformationSession)]; + set => this[nameof (UserTransformationSession)] = value; + } + + public Stack IncludeStack { + get => (Stack)this[nameof (IncludeStack)]; + set => this[nameof (IncludeStack)] = value; + } + public override int GetHashCode () { return Id.GetHashCode (); @@ -76,7 +96,6 @@ public bool Equals (ITextTemplatingSession other) void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) { base.GetObjectData (info, context); - info.AddValue ("Id", Id); } } } diff --git a/dotnet-t4-vsix-library/Resources.Designer.cs b/dotnet-t4-vsix-library/Resources.Designer.cs new file mode 100644 index 0000000..65fe00f --- /dev/null +++ b/dotnet-t4-vsix-library/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Mono.VisualStudio.TextTemplating { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mono.VisualStudio.TextTemplating.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Assembly "{0}" Load Error: . + /// + internal static string AssemblyLoadError { + get { + return ResourceManager.GetString("AssemblyLoadError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error initializing the transformation object.. + /// + internal static string ErrorInitializingTransformationObject { + get { + return ResourceManager.GetString("ErrorInitializingTransformationObject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to // Error Generating Output. + /// + internal static string ErrorOutput { + get { + return ResourceManager.GetString("ErrorOutput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exception: {0}. + /// + internal static string Exception { + get { + return ResourceManager.GetString("Exception", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error Instanciating Object: . + /// + internal static string ExceptionInstantiatingTransformationObject { + get { + return ResourceManager.GetString("ExceptionInstantiatingTransformationObject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exception Processing Template: {0}. + /// + internal static string ExceptionProcessingTemplate { + get { + return ResourceManager.GetString("ExceptionProcessingTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exception setting host property on: {0}. + /// + internal static string ExceptionSettingHost { + get { + return ResourceManager.GetString("ExceptionSettingHost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exception setting session on: {0}. + /// + internal static string ExceptionSettingSession { + get { + return ResourceManager.GetString("ExceptionSettingSession", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Host Property Not Found On: {0}. + /// + internal static string HostPropertyNotFound { + get { + return ResourceManager.GetString("HostPropertyNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Something bad happened while prepping transformation.. + /// + internal static string SessionHostMarshalError { + get { + return ResourceManager.GetString("SessionHostMarshalError", resourceCulture); + } + } + } +} diff --git a/dotnet-t4-vsix-library/Resources.resx b/dotnet-t4-vsix-library/Resources.resx new file mode 100644 index 0000000..c0683c3 --- /dev/null +++ b/dotnet-t4-vsix-library/Resources.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Assembly "{0}" Load Error: + + + Error initializing the transformation object. + + + // Error Generating Output + + + Exception: {0} + + + Error Instanciating Object: + + + Exception Processing Template: {0} + + + Exception setting host property on: {0} + + + Exception setting session on: {0} + + + Host Property Not Found On: {0} + + + Something bad happened while prepping transformation. + + \ No newline at end of file diff --git a/dotnet-t4-vsix-library/TextDebugTemplateEngine.cs b/dotnet-t4-vsix-library/TextDebugTemplateEngine.cs new file mode 100644 index 0000000..31d8733 --- /dev/null +++ b/dotnet-t4-vsix-library/TextDebugTemplateEngine.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Mono.VisualStudio.TextTemplating +{ + using System.Globalization; + using System.IO; + using System.Reflection; + using System.Runtime.Loader; + using System.Runtime.Serialization; + using System.Threading; + using Microsoft.Extensions.DependencyModel; + using Microsoft.Extensions.DependencyModel.Resolution; + using Mono.TextTemplating; + + public class TextDebugTemplateEngine + : TemplatingEngine + , IDebugTextTemplatingEngine + { + public IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory) + { + if (content == null) { + throw new ArgumentNullException (nameof(content)); + } + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + if (runFactory == null) { + throw new ArgumentNullException (nameof (runFactory)); + } + + ITextTemplatingSession session = new TextTemplatingSession (); + ParsedTemplate pt = ParsedTemplate.FromText (content, host); + + InitializeSessionWithHostData (host, session); + + IDebugTransformationRun run = null; + try { + if (pt.Errors.HasErrors) { + return null; + } + TemplateSettings settings = GetSettings (host, pt); + + settings.Debug = true; + + settings.ApplyTo (session); + + run = CompileAndPrepareRun (pt, host, session, runFactory, settings); + } catch(Exception ex) { + if (IsCriticalException(ex)) { + throw; + } + pt.LogError (string.Format(CultureInfo.CurrentCulture, Resources.ExceptionProcessingTemplate, ex), new Location (session.TemplateFile, -1, -1)); + } + finally { + session.IncludeStack.Clear (); + host.LogErrors (pt.Errors); + } + + return run; + } + + void InitializeSessionWithHostData (ITextTemplatingEngineHost host, ITextTemplatingSession session) + { + try { + session.TemplateFile = host.TemplateFile; + } catch(NotImplementedException) { + session.TemplateFile = string.Empty; + } + + session.IncludeStack.Push (session.TemplateFile); + + if (host is ITextTemplatingSessionHost sessionHost) { + session.UserTransformationSession = sessionHost; + } + } + + IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, ITextTemplatingEngineHost host, ITextTemplatingSession session, IDebugTransformationRunFactory runFactory, TemplateSettings settings) + { + TransformationRunner runner = null; + bool success = false; + + try { + try { + if (runFactory.CreateTransformationRun (typeof (TransformationRunner), template, null) is TransformationRunner theRunner) { + runner = theRunner; + } + } + catch (Exception ex) { + if (IsCriticalException (ex)) { + throw; + } + } + if (runner != null && !runner.Errors.HasErrors) { + string[] assemblies = ProcessReferences (host, template, settings); + if (!template.Errors.HasErrors) { + runner.PreLoadAssemblies (assemblies); + + try { + success = runner.PrepareTransformation (session, template, settings.HostSpecific ? host : null); + } + catch (SerializationException) { + template.LogError (Resources.SessionHostMarshalError, new Location (session.TemplateFile, -1, -1)); + throw; + } + } + } + } + catch(Exception ex) { + if (IsCriticalException (ex)) { + throw; + } + template.LogError (ex.ToString (), new Location (session.TemplateFile, -1, -1)); + } + finally { + if (runner != null) { + template.Errors.AddRange (runner.Errors); + runner.ClearErrors (); + } + } + + return success ? runner : null; + } + + public static bool IsCriticalException(Exception e) + { + return ((e is StackOverflowException) || ((e is OutOfMemoryException) || ((e is ThreadAbortException) || ((e.InnerException != null) && IsCriticalException (e.InnerException))))); + } + } +} diff --git a/dotnet-t4-vsix-library/TextTemplatingCallback.cs b/dotnet-t4-vsix-library/TextTemplatingCallback.cs new file mode 100644 index 0000000..52e10fd --- /dev/null +++ b/dotnet-t4-vsix-library/TextTemplatingCallback.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Mono.VisualStudio.TextTemplating +{ + public class TextTemplatingCallback + : ITextTemplatingCallback + { + bool isFromOutputDirective; + + public bool Errors { get; set; } + + public string Extension { get; private set; } = null; + + public Encoding OutputEncoding { get; private set; } = Encoding.UTF8; + + public void ErrorCallback (bool warning, string message, int line, int column) + { + Errors = true; + } + + public void SetFileExtension (string extension) + { + Extension = extension ?? throw new ArgumentNullException (nameof (extension)); + } + + public void SetOutputEncoding (Encoding encoding, bool fromOutputDirective) + { + if (!isFromOutputDirective) { + if (fromOutputDirective) { + isFromOutputDirective = true; + OutputEncoding = encoding ?? throw new ArgumentNullException (nameof (encoding)); + } else { + if ((OutputEncoding != null) && !ReferenceEquals (encoding, OutputEncoding)) { + OutputEncoding = Encoding.UTF8; + } + OutputEncoding = encoding; + } + } + } + + public ITextTemplatingCallback DeepCopy () + { + TextTemplatingCallback callback = (TextTemplatingCallback)base.MemberwiseClone (); + + if (Extension != null) { + callback.Extension = (string)Extension.Clone (); + } + if (OutputEncoding != null) { + callback.OutputEncoding = (Encoding)OutputEncoding.Clone (); + } + + return callback; + } + } +} diff --git a/dotnet-t4-vsix-library/TransformationRunFactory.cs b/dotnet-t4-vsix-library/TransformationRunFactory.cs new file mode 100644 index 0000000..ec7c1d9 --- /dev/null +++ b/dotnet-t4-vsix-library/TransformationRunFactory.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Mono.VisualStudio.TextTemplating +{ + public abstract class TransformationRunFactory : +#if FEATURE_APPDOMAINS + MarshalByRefObject, +#endif + IDebugTransformationRunFactory + { + public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; + public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); + + public abstract IDebugTransformationRun CreateTransformationRun (Type t, string content, ResolveEventHandler resolver); + + public abstract string RunTransformation (IDebugTransformationRun transformationRun); +#if FEATURE_APPDOMAINS + public override object InitializeLifetimeService () + { + return null; + } +#endif + } +} diff --git a/dotnet-t4-vsix-library/TransformationRunner.cs b/dotnet-t4-vsix-library/TransformationRunner.cs new file mode 100644 index 0000000..112e378 --- /dev/null +++ b/dotnet-t4-vsix-library/TransformationRunner.cs @@ -0,0 +1,174 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using Mono.TextTemplating; + +namespace Mono.VisualStudio.TextTemplating +{ + public class TransformationRunner : +#if FEATURE_APPDOMAINS + MarshalByRefObject, +#endif + IDebugTransformationRun + { + private Assembly assembly; + private TemplateSettings settings; + private ITextTemplatingSession session; + private ITextTemplatingEngineHost host; + private static Regex linePattern; + + + public CompilerErrorCollection Errors { get; private set; } + + public string PerformTransformation () + { + string errorOutput = Resources.ErrorOutput; + + if (assembly == null) { + LogError (Resources.ErrorInitializingTransformationObject, false); + + return errorOutput; + } + + object result = null; + + try { + result = CreateTextTransformation (settings, host, assembly, session); + + throw new NotImplementedException (); + } + finally { + if (result is IDisposable disposable) { + disposable.Dispose (); + } + assembly = null; + host = null; + } + + return errorOutput; + } + + PropertyInfo GetDerivedProperty (Type transformType, string propertyName) + { + while(transformType != typeof(object) && transformType != null) { + PropertyInfo property = transformType.GetProperty (propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + if (property != null) { + return property; + } + transformType = transformType.BaseType; + } + return null; + } + + protected virtual object CreateTextTransformation(TemplateSettings settings, ITextTemplatingEngineHost host, Assembly assembly, ITextTemplatingSession session) { + object result = null; + object success = null; + try { + Type type; + + result = assembly.CreateInstance (settings.GetFullName ()); + + if (result != null) { + type = result.GetType (); + + if (settings.HostPropertyOnBase) { + try { + PropertyInfo property = type.GetProperty ("Host"); + + if (property != null) { + property?.SetValue (result, host, null); + } + else { + LogError (string.Format(CultureInfo.CurrentCulture, Resources.HostPropertyNotFound, settings.HostType.Name), false); + } + } + catch(Exception hostException) { + if (TextDebugTemplateEngine.IsCriticalException(hostException)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingHost, settings.GetFullName ()), false); + } + } + + try { + PropertyInfo property = GetDerivedProperty (type, nameof (TextTransformation.Session)); + + property?.SetValue (result, session, null); + } + catch(Exception sessionException) { + if (TextDebugTemplateEngine.IsCriticalException (sessionException)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingSession, settings.GetFullName ()), false); + } + success = result; + + } else { + LogError (Resources.ExceptionInstantiatingTransformationObject, false); + } + } + catch(Exception instantiatingException) { + if (TextDebugTemplateEngine.IsCriticalException (instantiatingException)) { + throw; + } + LogError (Resources.ExceptionInstantiatingTransformationObject + string.Format(CultureInfo.CurrentCulture, Resources.Exception, instantiatingException), false); + success = null; + } + return success; + } + + internal bool PrepareTransformation (ITextTemplatingSession session, ParsedTemplate template, ITextTemplatingEngineHost host) + { + throw new NotImplementedException (); + } + + internal void PreLoadAssemblies (string[] assemblies) + { + throw new NotImplementedException (); + } + + protected Assembly AttemptAssemblyLoad(string assemblyName) + { + try { + return Assembly.LoadFrom (assemblyName); + } + catch(Exception ex) { + LogError (string.Format (CultureInfo.CurrentCulture, Resources.AssemblyLoadError, assemblyName) + string.Format (CultureInfo.CurrentCulture, Resources.Exception, ex), false); + return null; + } + } + + public void ClearErrors() + { + Errors.Clear (); + } + + protected void LogError(string message, bool isWarning) + { + CompilerError error = new CompilerError () { + ErrorText = message, + IsWarning = isWarning + }; + + Errors.Add (error); + } + + protected void LogError(string message, bool isWarning, string filename, int line, int column) + { + CompilerError error = new CompilerError () { + ErrorText = message, + IsWarning = isWarning, + FileName = filename, + Line = line, + Column = column + }; + + Errors.Add (error); + } + } +} diff --git a/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj b/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj new file mode 100644 index 0000000..fc88232 --- /dev/null +++ b/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj @@ -0,0 +1,33 @@ + + + + netstandard2.0 + Mono.VisualStudio.TextTemplating + Mono.VisualStudio.TextTemplating + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/dotnet-t4/ToolTemplateGenerator.cs b/dotnet-t4/ToolTemplateGenerator.cs index bdecf47..548466f 100644 --- a/dotnet-t4/ToolTemplateGenerator.cs +++ b/dotnet-t4/ToolTemplateGenerator.cs @@ -32,7 +32,7 @@ public ToolTemplateGenerator () Refs.Add (typeof (CompilerErrorCollection).Assembly.Location); } - protected override ITextTemplatingSession CreateSession () => new ToolTemplateSession (this); + protected override ITextTemplatingSession CreateSession () => new TextTemplatingSession (this); public string PreprocessTemplate ( ParsedTemplate pt, diff --git a/dotnet-t4/ToolTemplateSession.cs b/dotnet-t4/ToolTemplateSession.cs index 0e38de5..0a20924 100644 --- a/dotnet-t4/ToolTemplateSession.cs +++ b/dotnet-t4/ToolTemplateSession.cs @@ -27,12 +27,12 @@ namespace Mono.TextTemplating { - class ToolTemplateSession : ITextTemplatingSession + class TextTemplatingSession : ITextTemplatingSession { readonly Dictionary session = new Dictionary (); readonly ToolTemplateGenerator toolTemplateGenerator; - public ToolTemplateSession (ToolTemplateGenerator toolTemplateGenerator) + public TextTemplatingSession (ToolTemplateGenerator toolTemplateGenerator) { this.toolTemplateGenerator = toolTemplateGenerator; } From 479530cf110169fba1598b91ca746a1be526167e Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Tue, 28 Jul 2020 19:26:05 -0600 Subject: [PATCH 03/58] no message --- .../Mono.TextTemplating/TemplateGenerator.cs | 6 ++++++ .../Mono.TextTemplating/TemplateSettings.cs | 2 +- .../TransformationRunFactory.cs | 5 ++++- dotnet-t4/ToolTemplateSession.cs | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs index 582dcdf..4c24063 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Text; using Mono.VisualStudio.TextTemplating; +using System.Runtime.Serialization; namespace Mono.TextTemplating { @@ -508,5 +509,10 @@ public virtual IEnumerable GetAdditionalDirectiveProcessors { yield break; } + + public void GetObjectData (SerializationInfo info, StreamingContext context) + { + throw new NotImplementedException (); + } } } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index f75191a..fbf9d00 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -74,7 +74,7 @@ public void ApplyTo (ITextTemplatingSession session) continue; } - session[property.Name] = property.GetValue (this); + session[property.Name] = property.GetValue (this, null); } } diff --git a/dotnet-t4-vsix-library/TransformationRunFactory.cs b/dotnet-t4-vsix-library/TransformationRunFactory.cs index ec7c1d9..4082a44 100644 --- a/dotnet-t4-vsix-library/TransformationRunFactory.cs +++ b/dotnet-t4-vsix-library/TransformationRunFactory.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Loader; using System.Text; +using Mono.TextTemplating; namespace Mono.VisualStudio.TextTemplating { @@ -13,7 +16,7 @@ public abstract class TransformationRunFactory : public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); - public abstract IDebugTransformationRun CreateTransformationRun (Type t, string content, ResolveEventHandler resolver); + public abstract IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, Func resolver); public abstract string RunTransformation (IDebugTransformationRun transformationRun); #if FEATURE_APPDOMAINS diff --git a/dotnet-t4/ToolTemplateSession.cs b/dotnet-t4/ToolTemplateSession.cs index 0a20924..588171d 100644 --- a/dotnet-t4/ToolTemplateSession.cs +++ b/dotnet-t4/ToolTemplateSession.cs @@ -47,6 +47,26 @@ public object this [string key] { public ICollection Values => session.Values; public int Count => session.Count; public bool IsReadOnly => false; + + public bool Debug { + get => (bool)this[nameof (Debug)]; + set => this[nameof (Debug)] = value; + } + + public string TemplateFile { + get => (string)this[nameof (TemplateFile)]; + set => this[nameof (TemplateFile)] = value; + } + public ITextTemplatingSessionHost UserTransformationSession { + get => (ITextTemplatingSessionHost)this[nameof (UserTransformationSession)]; + set => this[nameof (UserTransformationSession)] = value; + } + + public Stack IncludeStack { + get => (Stack)this[nameof (IncludeStack)]; + set => this[nameof (IncludeStack)] = value; + } + public void Add (string key, object value) => session.Add (key, value); public void Add (KeyValuePair item) => session.Add (item.Key, item.Value); public void Clear () => session.Clear (); From 41ff2dbb1f5a8a7252ae9c6ea58d5afe9af795be Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Tue, 28 Jul 2020 23:40:20 -0600 Subject: [PATCH 04/58] more work on the vsix implementation --- .../Mono.TextTemplating/CompiledTemplate.cs | 19 ++- .../Mono.TextTemplating/StringUtil.cs | 30 ++++ .../Mono.TextTemplating/TemplateSettings.cs | 7 + .../CompiledTemplateCache.cs | 37 +++++ .../CompiledTemplateRecord.cs | 20 +++ .../Interfaces.cs | 9 +- .../SupportedLangaugeEnum.cs | 12 ++ .../TextTemplatingSession.cs | 25 +++ ...teEngine.cs => DebugTextTemplateEngine.cs} | 16 +- .../TransformationRunFactory.cs | 2 +- .../TransformationRunner.cs | 142 +++++++++++++++--- dotnet-t4/ToolTemplateSession.cs | 27 ++++ 12 files changed, 309 insertions(+), 37 deletions(-) create mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateCache.cs create mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateRecord.cs create mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs rename dotnet-t4-vsix-library/{TextDebugTemplateEngine.cs => DebugTextTemplateEngine.cs} (87%) diff --git a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs index c180041..156246c 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs @@ -54,12 +54,19 @@ public CompiledTemplate (ITextTemplatingEngineHost host, CompilerResults results Load (results, fullName); } + /// + /// Get the compiled assembly + /// + public Assembly Assembly { get; private set; } + void Load (CompilerResults results, string fullName) { //results.CompiledAssembly doesn't work on .NET core, it throws a cryptic internal error //use Assembly.LoadFile instead - var assembly = System.Reflection.Assembly.LoadFile (results.PathToAssembly); - Type transformType = assembly.GetType (fullName); + //for debugging we need the assembly + Assembly = System.Reflection.Assembly.LoadFile (results.PathToAssembly); + + Type transformType = Assembly.GetType (fullName); //MS Templating Engine does not look on the type itself, //it checks only that required methods are exists in the compiled type textTransformation = Activator.CreateInstance (transformType); @@ -82,7 +89,13 @@ void Load (CompilerResults results, string fullName) } } - public string Process () + + public string Process() + { + return Process (textTransformation); + } + + public string Process (object textTransformation) { var ttType = textTransformation.GetType (); diff --git a/Mono.TextTemplating/Mono.TextTemplating/StringUtil.cs b/Mono.TextTemplating/Mono.TextTemplating/StringUtil.cs index bfcadb5..b98c412 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/StringUtil.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/StringUtil.cs @@ -1,4 +1,6 @@ using System; +using System.ComponentModel; +using System.Reflection; namespace Mono.TextTemplating { @@ -14,5 +16,33 @@ public static Boolean IsNullOrWhiteSpace (String value) return true; } + + public static TType GetValue(this PropertyInfo property, object @object, object[] index) + { + if (property.GetValue(@object, index) is TType success) { + return success; + } + return default; + } + + + public static bool TryParse (this string value, out TEnum @enum) + where TEnum: struct + { +#if NET35 + if (Enum.Parse (typeof (TEnum), value) is TEnum success) { + @enum = success; + + return true; + } + + @enum = default; + + return false; +#else + return Enum.TryParse (value, out @enum); +#endif + } + } } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index fbf9d00..db5af78 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -72,10 +72,17 @@ public void ApplyTo (ITextTemplatingSession session) foreach(PropertyInfo property in GetType().GetProperties()) { if (!property.PropertyType.IsSerializable) { continue; + } else if (property.Name.Equals(nameof(Language), StringComparison.OrdinalIgnoreCase)) { + if (property.GetValue(this, null).TryParse(out SupportedLangaugeEnum supported)) { + session.SupportedLangauge = supported; + } + continue; } session[property.Name] = property.GetValue (this, null); } + + session.ClassFullName = GetFullName (); } public string GetFullName () => string.IsNullOrEmpty (Namespace) ? Name : Namespace + "." + Name; diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateCache.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateCache.cs new file mode 100644 index 0000000..ad97284 --- /dev/null +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateCache.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Mono.TextTemplating; + +namespace Mono.VisualStudio.TextTemplating +{ + public static class CompiledTemplateCache + { + public static Dictionary compiledTemplates = new Dictionary (0x23); + public static DateTime lastUse; + + public static CompiledTemplate Find(string fullClassName) + { + CompiledTemplate compiledTemplate = null; + Dictionary compiledTemplates = CompiledTemplateCache.compiledTemplates; + lock (compiledTemplates) { + lastUse = DateTime.Now; + if (CompiledTemplateCache.compiledTemplates.TryGetValue(fullClassName, out CompiledTemplateRecord record)) { + compiledTemplate = record.CompiledTemplate; + record.LastUse = lastUse; + } + } + return compiledTemplate; + } + + public static void Insert (string classFullName, CompiledTemplate compiledTemplate) + { + Dictionary assemblies = CompiledTemplateCache.compiledTemplates; + lock (assemblies) { + CompiledTemplateCache.compiledTemplates[classFullName] = new CompiledTemplateRecord (compiledTemplate); + lastUse = DateTime.Now; + } + } + } +} diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateRecord.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateRecord.cs new file mode 100644 index 0000000..e117012 --- /dev/null +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/CompiledTemplateRecord.cs @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using Mono.TextTemplating; + +namespace Mono.VisualStudio.TextTemplating +{ + public class CompiledTemplateRecord + { + readonly CompiledTemplate compiledTemplate; + + public CompiledTemplate CompiledTemplate => compiledTemplate; + public DateTime LastUse { get; set; } + + public CompiledTemplateRecord(CompiledTemplate compiledTemplate) + { + this.compiledTemplate = compiledTemplate; + LastUse = DateTime.Now; + } + } +} diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index cb85d95..98140b8 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -54,11 +54,7 @@ public interface IDebugTransformationRun public interface IDebugTransformationRunFactory { -#if FEATURE_APPDOMAINS IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); -#elif NETSTANDARD - IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, Func resolver); -#endif string RunTransformation (IDebugTransformationRun transformationRun); } @@ -129,9 +125,14 @@ public interface ITextTemplatingSession : { Guid Id { get; } bool Debug { get; set; } + bool CachedTemplates { get; set; } string TemplateFile { get; set; } ITextTemplatingSessionHost UserTransformationSession { get; set; } Stack IncludeStack { get; } + List Assemblies { get; } + string ClassFullName { get; set; } + string CompilerOptions { get; set; } + SupportedLangaugeEnum SupportedLangauge { get; set; } } public interface ITextTemplatingSessionHost diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs new file mode 100644 index 0000000..618778c --- /dev/null +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; + +namespace Mono.VisualStudio.TextTemplating +{ + public enum SupportedLangaugeEnum + { + [Description ("C#")] + CSharp, + [Description ("VB")] + VB + } +} diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs index 5c2cbe9..5555155 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs @@ -46,6 +46,7 @@ public TextTemplatingSession (Guid id) { this.Id = id; this.IncludeStack = new Stack (); + this.Assemblies = new List (); } public Guid Id { @@ -58,6 +59,11 @@ public bool Debug { set => this[nameof (Debug)] = value; } + public bool CachedTemplates { + get => (bool)this[nameof (CachedTemplates)]; + set => this[nameof (CachedTemplates)] = value; + } + public string TemplateFile { get => (string)this[nameof (TemplateFile)]; set => this[nameof (TemplateFile)] = value; @@ -72,6 +78,25 @@ public Stack IncludeStack { set => this[nameof (IncludeStack)] = value; } + public List Assemblies { + get => (List)this[nameof (Assemblies)]; + set => this[nameof (Assemblies)] = value; + } + public string ClassFullName { + get => (string)this[nameof (ClassFullName)]; + set => this[nameof (ClassFullName)] = value; + } + + public SupportedLangaugeEnum SupportedLangauge { + get => (SupportedLangaugeEnum)this[nameof (SupportedLangauge)]; + set => this[nameof (SupportedLangauge)] = value; + } + + public string CompilerOptions { + get => (string)this[nameof (CompilerOptions)]; + set => this[nameof (CompilerOptions)] = value; + } + public override int GetHashCode () { return Id.GetHashCode (); diff --git a/dotnet-t4-vsix-library/TextDebugTemplateEngine.cs b/dotnet-t4-vsix-library/DebugTextTemplateEngine.cs similarity index 87% rename from dotnet-t4-vsix-library/TextDebugTemplateEngine.cs rename to dotnet-t4-vsix-library/DebugTextTemplateEngine.cs index 31d8733..0fd60b1 100644 --- a/dotnet-t4-vsix-library/TextDebugTemplateEngine.cs +++ b/dotnet-t4-vsix-library/DebugTextTemplateEngine.cs @@ -14,7 +14,7 @@ namespace Mono.VisualStudio.TextTemplating using Microsoft.Extensions.DependencyModel.Resolution; using Mono.TextTemplating; - public class TextDebugTemplateEngine + public class DebugTextTemplateEngine : TemplatingEngine , IDebugTextTemplatingEngine { @@ -44,9 +44,7 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe settings.Debug = true; - settings.ApplyTo (session); - - run = CompileAndPrepareRun (pt, host, session, runFactory, settings); + run = CompileAndPrepareRun (pt, content, host, session, runFactory, settings); } catch(Exception ex) { if (IsCriticalException(ex)) { throw; @@ -76,7 +74,7 @@ void InitializeSessionWithHostData (ITextTemplatingEngineHost host, ITextTemplat } } - IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, ITextTemplatingEngineHost host, ITextTemplatingSession session, IDebugTransformationRunFactory runFactory, TemplateSettings settings) + IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string content, ITextTemplatingEngineHost host, ITextTemplatingSession session, IDebugTransformationRunFactory runFactory, TemplateSettings settings) { TransformationRunner runner = null; bool success = false; @@ -93,12 +91,14 @@ IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, ITextTemp } } if (runner != null && !runner.Errors.HasErrors) { - string[] assemblies = ProcessReferences (host, template, settings); + ProcessReferences (host, template, settings); if (!template.Errors.HasErrors) { - runner.PreLoadAssemblies (assemblies); + runner.PreLoadAssemblies (settings.Assemblies); + + settings.ApplyTo (session); try { - success = runner.PrepareTransformation (session, template, settings.HostSpecific ? host : null); + success = runner.PrepareTransformation (session, template, content, settings.HostSpecific ? host : null, settings); } catch (SerializationException) { template.LogError (Resources.SessionHostMarshalError, new Location (session.TemplateFile, -1, -1)); diff --git a/dotnet-t4-vsix-library/TransformationRunFactory.cs b/dotnet-t4-vsix-library/TransformationRunFactory.cs index 4082a44..22e9b6d 100644 --- a/dotnet-t4-vsix-library/TransformationRunFactory.cs +++ b/dotnet-t4-vsix-library/TransformationRunFactory.cs @@ -16,7 +16,7 @@ public abstract class TransformationRunFactory : public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); - public abstract IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, Func resolver); + public abstract IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); public abstract string RunTransformation (IDebugTransformationRun transformationRun); #if FEATURE_APPDOMAINS diff --git a/dotnet-t4-vsix-library/TransformationRunner.cs b/dotnet-t4-vsix-library/TransformationRunner.cs index 112e378..3ad9684 100644 --- a/dotnet-t4-vsix-library/TransformationRunner.cs +++ b/dotnet-t4-vsix-library/TransformationRunner.cs @@ -3,9 +3,8 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; using Mono.TextTemplating; namespace Mono.VisualStudio.TextTemplating @@ -16,12 +15,12 @@ public class TransformationRunner : #endif IDebugTransformationRun { - private Assembly assembly; - private TemplateSettings settings; - private ITextTemplatingSession session; - private ITextTemplatingEngineHost host; - private static Regex linePattern; - + static HashSet shadowCopyPaths = null; + static object shadowCopySync = new object (); + CompiledTemplate compiledTemplate; + TemplateSettings settings; + ITextTemplatingSession session; + ITextTemplatingEngineHost host; public CompilerErrorCollection Errors { get; private set; } @@ -29,24 +28,31 @@ public string PerformTransformation () { string errorOutput = Resources.ErrorOutput; - if (assembly == null) { + if (compiledTemplate == null) { LogError (Resources.ErrorInitializingTransformationObject, false); return errorOutput; } - object result = null; + object transform = null; try { - result = CreateTextTransformation (settings, host, assembly, session); + transform = CreateTextTransformation (settings, host, compiledTemplate.Assembly, session); - throw new NotImplementedException (); + return compiledTemplate.Process (transform); + } + catch (Exception ex) { + if (DebugTextTemplateEngine.IsCriticalException(ex)) { + throw; + } + LogError (ex.ToString (), false); } finally { - if (result is IDisposable disposable) { + if (transform is IDisposable disposable) { disposable.Dispose (); } - assembly = null; + compiledTemplate?.Dispose (); + compiledTemplate = null; host = null; } @@ -88,7 +94,7 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe } } catch(Exception hostException) { - if (TextDebugTemplateEngine.IsCriticalException(hostException)) { + if (DebugTextTemplateEngine.IsCriticalException(hostException)) { throw; } LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingHost, settings.GetFullName ()), false); @@ -101,7 +107,7 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe property?.SetValue (result, session, null); } catch(Exception sessionException) { - if (TextDebugTemplateEngine.IsCriticalException (sessionException)) { + if (DebugTextTemplateEngine.IsCriticalException (sessionException)) { throw; } LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingSession, settings.GetFullName ()), false); @@ -113,7 +119,7 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe } } catch(Exception instantiatingException) { - if (TextDebugTemplateEngine.IsCriticalException (instantiatingException)) { + if (DebugTextTemplateEngine.IsCriticalException (instantiatingException)) { throw; } LogError (Resources.ExceptionInstantiatingTransformationObject + string.Format(CultureInfo.CurrentCulture, Resources.Exception, instantiatingException), false); @@ -122,14 +128,108 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe return success; } - internal bool PrepareTransformation (ITextTemplatingSession session, ParsedTemplate template, ITextTemplatingEngineHost host) + internal bool PrepareTransformation (ITextTemplatingSession session, ParsedTemplate template, string content, ITextTemplatingEngineHost host, TemplateSettings settings) + { + this.session = session ?? throw new ArgumentNullException (nameof (session)); + this.host = host ?? throw new ArgumentNullException (nameof (host)); + this.settings = settings ?? throw new ArgumentNullException (nameof (settings)); + + try { + this.settings.Assemblies.Add (base.GetType ().Assembly.Location); + this.settings.Assemblies.Add (typeof (ITextTemplatingEngineHost).Assembly.Location); + this.compiledTemplate = LocateAssembly (session, template, content); + } + catch(Exception ex) { + if (DebugTextTemplateEngine.IsCriticalException (ex)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, Resources.Exception, ex), false); + } + return this.compiledTemplate != null; + } + + CompiledTemplate LocateAssembly (ITextTemplatingSession session, ParsedTemplate template, string content) + { + CompiledTemplate compiledTemplate = null; + + if (session.CachedTemplates) { + compiledTemplate = CompiledTemplateCache.Find (session.ClassFullName); + } + if (compiledTemplate == null) { + compiledTemplate = Compile (template, content); + if (session.CachedTemplates && compiledTemplate != null) { + CompiledTemplateCache.Insert (session.ClassFullName, compiledTemplate); + } + } + return compiledTemplate; + } + + CompiledTemplate Compile (ParsedTemplate template, string content) + { + CompiledTemplate compiledTemplate = null; + + if (host is ITextTemplatingComponents Component && + Component.Engine is DebugTextTemplateEngine engine) { + compiledTemplate = engine.CompileTemplate (template, content, host, settings); + } + + return compiledTemplate; + } + + internal void PreLoadAssemblies (IEnumerable assemblies) { - throw new NotImplementedException (); + try { + //TODO:: investigate preloading assemblies with the AssemblyLoadContext + }catch(Exception ex) { + if (DebugTextTemplateEngine.IsCriticalException (ex)) { + throw; + } + } } - internal void PreLoadAssemblies (string[] assemblies) + [Obsolete] + void LoadExplicitAssemblyReferences (IEnumerable references) { - throw new NotImplementedException (); + references = (from referenceAssembly in references + where !string.IsNullOrEmpty (referenceAssembly) && File.Exists (referenceAssembly) + select referenceAssembly).ToList (); + + List source = new List (); + + if (AppDomain.CurrentDomain.ShadowCopyFiles) { + foreach(string reference in references) { + string referenceDir = Path.GetDirectoryName (reference); + if (string.IsNullOrEmpty (referenceDir)) { + string currentDir = Directory.GetCurrentDirectory (); + if (File.Exists(Path.Combine(currentDir, reference))) { + referenceDir = currentDir; + } + } + source.Add (referenceDir); + } + EnsureShadowCopyPaths (source.Distinct (StringComparer.OrdinalIgnoreCase)); + } + } + + [Obsolete] + void EnsureShadowCopyPaths (IEnumerable paths) + { + if (AppDomain.CurrentDomain.ShadowCopyFiles) { + string path = string.Empty; + object shadowCopySync = TransformationRunner.shadowCopySync; + lock (shadowCopySync) { + if (shadowCopyPaths == null) { + shadowCopyPaths = new HashSet (StringComparer.OrdinalIgnoreCase); + } + foreach (string str2 in paths) { + if (!shadowCopyPaths.Contains (str2)) { + shadowCopyPaths.Add (str2); + } + } + path = string.Join (";", shadowCopyPaths.ToArray ()); + } + AppDomain.CurrentDomain.SetShadowCopyPath (path); + } } protected Assembly AttemptAssemblyLoad(string assemblyName) diff --git a/dotnet-t4/ToolTemplateSession.cs b/dotnet-t4/ToolTemplateSession.cs index 588171d..019687f 100644 --- a/dotnet-t4/ToolTemplateSession.cs +++ b/dotnet-t4/ToolTemplateSession.cs @@ -35,6 +35,8 @@ class TextTemplatingSession : ITextTemplatingSession public TextTemplatingSession (ToolTemplateGenerator toolTemplateGenerator) { this.toolTemplateGenerator = toolTemplateGenerator; + this.IncludeStack = new Stack (); + this.Assemblies = new List (); } public object this [string key] { @@ -53,6 +55,11 @@ public bool Debug { set => this[nameof (Debug)] = value; } + public bool CachedTemplates { + get => (bool)this[nameof (CachedTemplates)]; + set => this[nameof (CachedTemplates)] = value; + } + public string TemplateFile { get => (string)this[nameof (TemplateFile)]; set => this[nameof (TemplateFile)] = value; @@ -67,6 +74,26 @@ public Stack IncludeStack { set => this[nameof (IncludeStack)] = value; } + public List Assemblies { + get => (List)this[nameof (Assemblies)]; + set => this[nameof (Assemblies)] = value; + } + + public string ClassFullName { + get => (string)this[nameof (ClassFullName)]; + set => this[nameof (ClassFullName)] = value; + } + + public SupportedLangaugeEnum SupportedLangauge { + get => (SupportedLangaugeEnum)this[nameof (SupportedLangauge)]; + set => this[nameof (SupportedLangauge)] = value; + } + + public string CompilerOptions { + get => (string)this[nameof (CompilerOptions)]; + set => this[nameof (CompilerOptions)] = value; + } + public void Add (string key, object value) => session.Add (key, value); public void Add (KeyValuePair item) => session.Add (item.Key, item.Value); public void Clear () => session.Clear (); From d992902de627839219cc706b0ac4fbbd567c9a31 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 12:13:39 -0600 Subject: [PATCH 05/58] merged teh vsix changes into the mono.texttemplating project. I am unsure how to unit test the interfaces and intended functionality without hooking it into Visual Studio and finishing the run factory. all existing unit tests pass. --- Mono.TextTemplating.sln | 6 - .../Mono.TextTemplating.csproj | 15 + .../DebugTextTemplateEngine.cs | 72 +++-- .../Mono.TextTemplating/TemplateSettings.cs | 19 +- .../Mono.TextTemplating/TemplatingEngine.cs | 2 +- .../DebugTemplateEventArgs.cs | 10 + .../TextTemplatingCallback.cs | 3 +- .../TransformationRunFactory.cs | 17 +- .../TransformationRunner.cs | 230 +++++++++++++++ .../Interfaces.cs | 26 +- .../TextTemplatingSession.cs | 45 --- .../VsTemplatingErrorResources.Designer.cs | 19 +- .../VsTemplatingErrorResources.resx | 5 +- .../TransformationRunner.cs | 274 ------------------ .../dotnet-t4-vsix-library.csproj | 15 - dotnet-t4/ToolTemplateSession.cs | 49 +--- 16 files changed, 340 insertions(+), 467 deletions(-) rename {dotnet-t4-vsix-library => Mono.TextTemplating/Mono.TextTemplating}/DebugTextTemplateEngine.cs (55%) create mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs rename {dotnet-t4-vsix-library => Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost}/TextTemplatingCallback.cs (94%) rename {dotnet-t4-vsix-library => Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost}/TransformationRunFactory.cs (60%) create mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs rename dotnet-t4-vsix-library/Resources.Designer.cs => Mono.TextTemplating/VsTemplatingErrorResources.Designer.cs (89%) rename dotnet-t4-vsix-library/Resources.resx => Mono.TextTemplating/VsTemplatingErrorResources.resx (97%) delete mode 100644 dotnet-t4-vsix-library/TransformationRunner.cs diff --git a/Mono.TextTemplating.sln b/Mono.TextTemplating.sln index 12e0fe3..847a0df 100644 --- a/Mono.TextTemplating.sln +++ b/Mono.TextTemplating.sln @@ -20,8 +20,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-t4-project-tool", "d EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.TextTemplating.Roslyn", "Mono.TextTemplating.Roslyn\Mono.TextTemplating.Roslyn.csproj", "{8DB780A9-27C1-44B4-860F-50C4419FD349}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-t4-vsix-library", "dotnet-t4-vsix-library\dotnet-t4-vsix-library.csproj", "{6B494E73-4201-4FA8-848D-2970C27299D0}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -52,10 +50,6 @@ Global {8DB780A9-27C1-44B4-860F-50C4419FD349}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DB780A9-27C1-44B4-860F-50C4419FD349}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DB780A9-27C1-44B4-860F-50C4419FD349}.Release|Any CPU.Build.0 = Release|Any CPU - {6B494E73-4201-4FA8-848D-2970C27299D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B494E73-4201-4FA8-848D-2970C27299D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B494E73-4201-4FA8-848D-2970C27299D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B494E73-4201-4FA8-848D-2970C27299D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Mono.TextTemplating/Mono.TextTemplating.csproj b/Mono.TextTemplating/Mono.TextTemplating.csproj index 6b7e9ea..3ad5fc3 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.csproj +++ b/Mono.TextTemplating/Mono.TextTemplating.csproj @@ -37,4 +37,19 @@ This package allows embedding the T4 engine in an application. 4.3.0 + + + + VsTemplatingErrorResources.resx + True + True + + + + + + VsTemplatingErrorResources.Designer.cs + ResXFileCodeGenerator + + \ No newline at end of file diff --git a/dotnet-t4-vsix-library/DebugTextTemplateEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs similarity index 55% rename from dotnet-t4-vsix-library/DebugTextTemplateEngine.cs rename to Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs index 0fd60b1..e45e9af 100644 --- a/dotnet-t4-vsix-library/DebugTextTemplateEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs @@ -1,22 +1,17 @@ using System; -using System.Collections.Generic; -using System.Text; +using Mono.VisualStudio.TextTemplating; +using Mono.VisualStudio.TextTemplating.VHost; -namespace Mono.VisualStudio.TextTemplating +namespace Mono.TextTemplating { using System.Globalization; using System.IO; using System.Reflection; - using System.Runtime.Loader; using System.Runtime.Serialization; using System.Threading; - using Microsoft.Extensions.DependencyModel; - using Microsoft.Extensions.DependencyModel.Resolution; - using Mono.TextTemplating; - public class DebugTextTemplateEngine - : TemplatingEngine - , IDebugTextTemplatingEngine + public partial class TemplatingEngine + : IDebugTextTemplatingEngine { public IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory) { @@ -30,12 +25,16 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe throw new ArgumentNullException (nameof (runFactory)); } - ITextTemplatingSession session = new TextTemplatingSession (); - ParsedTemplate pt = ParsedTemplate.FromText (content, host); + if (host is ITextTemplatingSessionHost sessionHost) { + if (sessionHost.Session == null) { + sessionHost.Session = sessionHost.CreateSession (); + } + } - InitializeSessionWithHostData (host, session); + ParsedTemplate pt = ParsedTemplate.FromText (content, host); IDebugTransformationRun run = null; + try { if (pt.Errors.HasErrors) { return null; @@ -44,44 +43,45 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe settings.Debug = true; - run = CompileAndPrepareRun (pt, content, host, session, runFactory, settings); + run = CompileAndPrepareRun (pt, content, host, runFactory, settings); } catch(Exception ex) { if (IsCriticalException(ex)) { throw; } - pt.LogError (string.Format(CultureInfo.CurrentCulture, Resources.ExceptionProcessingTemplate, ex), new Location (session.TemplateFile, -1, -1)); + pt.LogError (string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.ExceptionProcessingTemplate, ex), new Location (host.TemplateFile, -1, -1)); } finally { - session.IncludeStack.Clear (); host.LogErrors (pt.Errors); } return run; } - void InitializeSessionWithHostData (ITextTemplatingEngineHost host, ITextTemplatingSession session) + protected virtual IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory, TemplateSettings settings) { - try { - session.TemplateFile = host.TemplateFile; - } catch(NotImplementedException) { - session.TemplateFile = string.Empty; - } + TransformationRunner runner = null; + bool success = false; - session.IncludeStack.Push (session.TemplateFile); + Assembly ResolveReferencedAssemblies (object sender, ResolveEventArgs args) + { + AssemblyName asmName = new AssemblyName (args.Name); + foreach (var asmFile in settings.Assemblies) { + if (asmName.Name == Path.GetFileNameWithoutExtension (asmFile)) + return Assembly.LoadFrom (asmFile); + } - if (host is ITextTemplatingSessionHost sessionHost) { - session.UserTransformationSession = sessionHost; - } - } + var path = host.ResolveAssemblyReference (asmName.Name); - IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string content, ITextTemplatingEngineHost host, ITextTemplatingSession session, IDebugTransformationRunFactory runFactory, TemplateSettings settings) - { - TransformationRunner runner = null; - bool success = false; + if (File.Exists (path)) { + return Assembly.LoadFrom (path); + } + + return null; + } try { try { - if (runFactory.CreateTransformationRun (typeof (TransformationRunner), template, null) is TransformationRunner theRunner) { + if (runFactory.CreateTransformationRun (typeof (TransformationRunner), template, new ResolveEventHandler(ResolveReferencedAssemblies)) is TransformationRunner theRunner) { runner = theRunner; } } @@ -95,13 +95,11 @@ IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string co if (!template.Errors.HasErrors) { runner.PreLoadAssemblies (settings.Assemblies); - settings.ApplyTo (session); - try { - success = runner.PrepareTransformation (session, template, content, settings.HostSpecific ? host : null, settings); + success = runner.PrepareTransformation (template, content, settings.HostSpecific ? host : null, settings); } catch (SerializationException) { - template.LogError (Resources.SessionHostMarshalError, new Location (session.TemplateFile, -1, -1)); + template.LogError (VsTemplatingErrorResources.SessionHostMarshalError, new Location (host.TemplateFile, -1, -1)); throw; } } @@ -111,7 +109,7 @@ IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string co if (IsCriticalException (ex)) { throw; } - template.LogError (ex.ToString (), new Location (session.TemplateFile, -1, -1)); + template.LogError (ex.ToString (), new Location (host.TemplateFile, -1, -1)); } finally { if (runner != null) { diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index db5af78..64f0bad 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -46,6 +46,7 @@ public TemplateSettings () public bool HostSpecific { get; set; } public bool HostPropertyOnBase { get; set; } public bool Debug { get; set; } + public bool CachedTemplates { get; set; } public TextWriter Log { get; set; } public string Inherits { get; set; } public string Name { get; set; } @@ -67,24 +68,6 @@ public TemplateSettings () public bool InternalVisibility { get; set; } public Type HostType { get; set; } - public void ApplyTo (ITextTemplatingSession session) - { - foreach(PropertyInfo property in GetType().GetProperties()) { - if (!property.PropertyType.IsSerializable) { - continue; - } else if (property.Name.Equals(nameof(Language), StringComparison.OrdinalIgnoreCase)) { - if (property.GetValue(this, null).TryParse(out SupportedLangaugeEnum supported)) { - session.SupportedLangauge = supported; - } - continue; - } - - session[property.Name] = property.GetValue (this, null); - } - - session.ClassFullName = GetFullName (); - } - public string GetFullName () => string.IsNullOrEmpty (Namespace) ? Name : Namespace + "." + Name; } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 10d725f..f7f30f0 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -41,7 +41,7 @@ namespace Mono.TextTemplating { - public class TemplatingEngine : + public partial class TemplatingEngine : #if FEATURE_APPDOMAINS MarshalByRefObject, #endif diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs new file mode 100644 index 0000000..abbe5a7 --- /dev/null +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs @@ -0,0 +1,10 @@ +using System; + +namespace Mono.VisualStudio.TextTemplating.VHost +{ + public class DebugTemplateEventArgs : EventArgs + { + public string TemplateOutput { get; set; } + public bool Succeeded { get; set; } + } +} diff --git a/dotnet-t4-vsix-library/TextTemplatingCallback.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs similarity index 94% rename from dotnet-t4-vsix-library/TextTemplatingCallback.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs index 52e10fd..ae2f652 100644 --- a/dotnet-t4-vsix-library/TextTemplatingCallback.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs @@ -1,8 +1,7 @@ using System; -using System.Collections.Generic; using System.Text; -namespace Mono.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating.VHost { public class TextTemplatingCallback : ITextTemplatingCallback diff --git a/dotnet-t4-vsix-library/TransformationRunFactory.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs similarity index 60% rename from dotnet-t4-vsix-library/TransformationRunFactory.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs index 22e9b6d..e988b9c 100644 --- a/dotnet-t4-vsix-library/TransformationRunFactory.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs @@ -1,11 +1,7 @@ using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Loader; -using System.Text; using Mono.TextTemplating; -namespace Mono.VisualStudio.TextTemplating +namespace Mono.VisualStudio.TextTemplating.VHost { public abstract class TransformationRunFactory : #if FEATURE_APPDOMAINS @@ -15,7 +11,16 @@ public abstract class TransformationRunFactory : { public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); - + /// + /// Create the transformation runner + /// + /// + /// + /// + /// + /// + /// abstracted, just because I am uncertain on how this would run on multiple platforms. Also visual studio classes may be required to pull of correctly. + /// public abstract IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); public abstract string RunTransformation (IDebugTransformationRun transformationRun); diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs new file mode 100644 index 0000000..24c1607 --- /dev/null +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs @@ -0,0 +1,230 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using Mono.TextTemplating; + +namespace Mono.VisualStudio.TextTemplating.VHost +{ + public class TransformationRunner : +#if FEATURE_APPDOMAINS + MarshalByRefObject, +#endif + IDebugTransformationRun + { + CompiledTemplate compiledTemplate; + TemplateSettings settings; + ITextTemplatingEngineHost host; + + public CompilerErrorCollection Errors { get; private set; } + + public virtual string PerformTransformation () + { + string errorOutput = VsTemplatingErrorResources.ErrorOutput; + + if (compiledTemplate == null) { + LogError (VsTemplatingErrorResources.ErrorInitializingTransformationObject, false); + + return errorOutput; + } + + object transform = null; + + try { + transform = CreateTextTransformation (settings, host, compiledTemplate.Assembly); + + return compiledTemplate.Process (transform); + } + catch (Exception ex) { + if (TemplatingEngine.IsCriticalException(ex)) { + throw; + } + LogError (ex.ToString (), false); + } + finally { + if (transform is IDisposable disposable) { + disposable.Dispose (); + } + compiledTemplate?.Dispose (); + compiledTemplate = null; + host = null; + } + + return errorOutput; + } + + PropertyInfo GetDerivedProperty (Type transformType, string propertyName) + { + while(transformType != typeof(object) && transformType != null) { + PropertyInfo property = transformType.GetProperty (propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + if (property != null) { + return property; + } + transformType = transformType.BaseType; + } + return null; + } + + protected virtual object CreateTextTransformation(TemplateSettings settings, ITextTemplatingEngineHost host, Assembly assembly) { + object success = null; + try { + Type type; + + var result = assembly.CreateInstance (settings.GetFullName ()); + + if (result != null) { + type = result.GetType (); + + if (settings.HostPropertyOnBase) { + try { + PropertyInfo property = type.GetProperty ("Host"); + + if (property != null) { + property?.SetValue (result, host, null); + } + else { + LogError (string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.HostPropertyNotFound, settings.HostType.Name), false); + } + } + catch(Exception hostException) { + if (TemplatingEngine.IsCriticalException(hostException)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, VsTemplatingErrorResources.ExceptionSettingHost, settings.GetFullName ()), false); + } + } + + try { + if (host is ITextTemplatingSessionHost sessionHost && + sessionHost.Session != null) { + PropertyInfo property = GetDerivedProperty (type, nameof (TextTransformation.Session)); + + property?.SetValue (result, sessionHost.Session, null); + } + else { + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.SessionHostSessionNotInitialized, settings.GetFullName())); + } + } + catch (Exception sessionException) { + if (TemplatingEngine.IsCriticalException (sessionException)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, VsTemplatingErrorResources.ExceptionSettingSession, sessionException), false); + } + success = result; + + } else { + LogError (VsTemplatingErrorResources.ExceptionInstantiatingTransformationObject, false); + } + } + catch(Exception instantiatingException) { + if (TemplatingEngine.IsCriticalException (instantiatingException)) { + throw; + } + LogError (VsTemplatingErrorResources.ExceptionInstantiatingTransformationObject + string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.Exception, instantiatingException), false); + success = null; + } + return success; + } + + public virtual bool PrepareTransformation (ParsedTemplate template, string content, ITextTemplatingEngineHost host, TemplateSettings settings) + { + this.host = host ?? throw new ArgumentNullException (nameof (host)); + this.settings = settings ?? throw new ArgumentNullException (nameof (settings)); + + try { + this.settings.Assemblies.Add (base.GetType ().Assembly.Location); + this.settings.Assemblies.Add (typeof (ITextTemplatingEngineHost).Assembly.Location); + this.compiledTemplate = LocateAssembly (template, content); + } + catch(Exception ex) { + if (TemplatingEngine.IsCriticalException (ex)) { + throw; + } + LogError (string.Format (CultureInfo.CurrentCulture, VsTemplatingErrorResources.Exception, ex), false); + } + return this.compiledTemplate != null; + } + + CompiledTemplate LocateAssembly (ParsedTemplate template, string content) + { + CompiledTemplate compiledTemplate = null; + + if (settings.CachedTemplates) { + compiledTemplate = CompiledTemplateCache.Find (settings.GetFullName ()); + } + if (compiledTemplate == null) { + compiledTemplate = Compile (template, content); + if (settings.CachedTemplates && compiledTemplate != null) { + CompiledTemplateCache.Insert (settings.GetFullName (), compiledTemplate); + } + } + return compiledTemplate; + } + + CompiledTemplate Compile (ParsedTemplate template, string content) + { + CompiledTemplate compiledTemplate = null; + + if (host is ITextTemplatingComponents Component && + Component.Engine is TemplatingEngine engine) { + compiledTemplate = engine.CompileTemplate (template, content, host, settings); + // do we want to dispose the appdomain resolver in compiled template in favor of the transformation runner? + //compiledTemplate?.Dispose (); + } + + return compiledTemplate; + } + + public virtual void PreLoadAssemblies (IEnumerable assemblies) + { + try { + //TODO:: investigate preloading assemblies with the AssemblyLoadContext + }catch(Exception ex) { + if (TemplatingEngine.IsCriticalException (ex)) { + throw; + } + } + } + + protected Assembly AttemptAssemblyLoad(AssemblyName assembly) + { + try { + return Assembly.LoadFrom (assembly.CodeBase); + } + catch(Exception ex) { + LogError (string.Format (CultureInfo.CurrentCulture, VsTemplatingErrorResources.AssemblyLoadError, assembly.Name, ex), false); + return null; + } + } + + public void ClearErrors() + { + Errors.Clear (); + } + + protected void LogError(string message, bool isWarning) + { + CompilerError error = new CompilerError () { + ErrorText = message, + IsWarning = isWarning + }; + + Errors.Add (error); + } + + protected void LogError(string message, bool isWarning, string filename, int line, int column) + { + CompilerError error = new CompilerError () { + ErrorText = message, + IsWarning = isWarning, + FileName = filename, + Line = line, + Column = column + }; + + Errors.Add (error); + } + } +} diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 98140b8..65d0b74 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -39,12 +39,29 @@ namespace Mono.VisualStudio.TextTemplating { + using VHost; + public interface IRecognizeHostSpecific { void SetProcessingRunIsHostSpecific (bool hostSpecific); bool RequiresProcessingRunIsHostSpecific { get; } } + public interface IDebugTextTemplating + : ITextTemplating + { + event EventHandler DebugCompleted; + void DebugTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy); + } + + public interface ITextTemplating + { + void BeginErrorSession (); + bool EndErrorSession (); + string PreprocessTemplate (string inputFile, string content, ITextTemplatingCallback callback, string className, string classNamespace, out string[] references); + string ProcessTemplate (string inputFile, string content, ITextTemplatingCallback callback = null, object hierarchy = null); + } + public interface IDebugTransformationRun { string PerformTransformation (); @@ -124,15 +141,6 @@ public interface ITextTemplatingSession : IEnumerable, ISerializable { Guid Id { get; } - bool Debug { get; set; } - bool CachedTemplates { get; set; } - string TemplateFile { get; set; } - ITextTemplatingSessionHost UserTransformationSession { get; set; } - Stack IncludeStack { get; } - List Assemblies { get; } - string ClassFullName { get; set; } - string CompilerOptions { get; set; } - SupportedLangaugeEnum SupportedLangauge { get; set; } } public interface ITextTemplatingSessionHost diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs index 5555155..8f95c10 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTemplatingSession.cs @@ -45,8 +45,6 @@ public TextTemplatingSession () : this (Guid.NewGuid ()) public TextTemplatingSession (Guid id) { this.Id = id; - this.IncludeStack = new Stack (); - this.Assemblies = new List (); } public Guid Id { @@ -54,49 +52,6 @@ public Guid Id { set => this[nameof (Id)] = value; } - public bool Debug { - get => (bool)this[nameof (Debug)]; - set => this[nameof (Debug)] = value; - } - - public bool CachedTemplates { - get => (bool)this[nameof (CachedTemplates)]; - set => this[nameof (CachedTemplates)] = value; - } - - public string TemplateFile { - get => (string)this[nameof (TemplateFile)]; - set => this[nameof (TemplateFile)] = value; - } - public ITextTemplatingSessionHost UserTransformationSession { - get => (ITextTemplatingSessionHost)this[nameof (UserTransformationSession)]; - set => this[nameof (UserTransformationSession)] = value; - } - - public Stack IncludeStack { - get => (Stack)this[nameof (IncludeStack)]; - set => this[nameof (IncludeStack)] = value; - } - - public List Assemblies { - get => (List)this[nameof (Assemblies)]; - set => this[nameof (Assemblies)] = value; - } - public string ClassFullName { - get => (string)this[nameof (ClassFullName)]; - set => this[nameof (ClassFullName)] = value; - } - - public SupportedLangaugeEnum SupportedLangauge { - get => (SupportedLangaugeEnum)this[nameof (SupportedLangauge)]; - set => this[nameof (SupportedLangauge)] = value; - } - - public string CompilerOptions { - get => (string)this[nameof (CompilerOptions)]; - set => this[nameof (CompilerOptions)] = value; - } - public override int GetHashCode () { return Id.GetHashCode (); diff --git a/dotnet-t4-vsix-library/Resources.Designer.cs b/Mono.TextTemplating/VsTemplatingErrorResources.Designer.cs similarity index 89% rename from dotnet-t4-vsix-library/Resources.Designer.cs rename to Mono.TextTemplating/VsTemplatingErrorResources.Designer.cs index 65fe00f..a9a5c0b 100644 --- a/dotnet-t4-vsix-library/Resources.Designer.cs +++ b/Mono.TextTemplating/VsTemplatingErrorResources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Mono.VisualStudio.TextTemplating { +namespace Mono.TextTemplating { using System; @@ -22,14 +22,14 @@ namespace Mono.VisualStudio.TextTemplating { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { + internal class VsTemplatingErrorResources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { + internal VsTemplatingErrorResources() { } /// @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mono.VisualStudio.TextTemplating.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mono.TextTemplating.VsTemplatingErrorResources", typeof(VsTemplatingErrorResources).Assembly); resourceMan = temp; } return resourceMan; @@ -61,7 +61,7 @@ internal Resources() { } /// - /// Looks up a localized string similar to Assembly "{0}" Load Error: . + /// Looks up a localized string similar to Assembly "{0}" Load Error: {1}. /// internal static string AssemblyLoadError { get { @@ -149,5 +149,14 @@ internal static string SessionHostMarshalError { return ResourceManager.GetString("SessionHostMarshalError", resourceCulture); } } + + /// + /// Looks up a localized string similar to Session host session is not initialized for {0}.. + /// + internal static string SessionHostSessionNotInitialized { + get { + return ResourceManager.GetString("SessionHostSessionNotInitialized", resourceCulture); + } + } } } diff --git a/dotnet-t4-vsix-library/Resources.resx b/Mono.TextTemplating/VsTemplatingErrorResources.resx similarity index 97% rename from dotnet-t4-vsix-library/Resources.resx rename to Mono.TextTemplating/VsTemplatingErrorResources.resx index c0683c3..65f4ea5 100644 --- a/dotnet-t4-vsix-library/Resources.resx +++ b/Mono.TextTemplating/VsTemplatingErrorResources.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Assembly "{0}" Load Error: + Assembly "{0}" Load Error: {1} Error initializing the transformation object. @@ -147,4 +147,7 @@ Something bad happened while prepping transformation. + + Session host session is not initialized for {0}. + \ No newline at end of file diff --git a/dotnet-t4-vsix-library/TransformationRunner.cs b/dotnet-t4-vsix-library/TransformationRunner.cs deleted file mode 100644 index 3ad9684..0000000 --- a/dotnet-t4-vsix-library/TransformationRunner.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using Mono.TextTemplating; - -namespace Mono.VisualStudio.TextTemplating -{ - public class TransformationRunner : -#if FEATURE_APPDOMAINS - MarshalByRefObject, -#endif - IDebugTransformationRun - { - static HashSet shadowCopyPaths = null; - static object shadowCopySync = new object (); - CompiledTemplate compiledTemplate; - TemplateSettings settings; - ITextTemplatingSession session; - ITextTemplatingEngineHost host; - - public CompilerErrorCollection Errors { get; private set; } - - public string PerformTransformation () - { - string errorOutput = Resources.ErrorOutput; - - if (compiledTemplate == null) { - LogError (Resources.ErrorInitializingTransformationObject, false); - - return errorOutput; - } - - object transform = null; - - try { - transform = CreateTextTransformation (settings, host, compiledTemplate.Assembly, session); - - return compiledTemplate.Process (transform); - } - catch (Exception ex) { - if (DebugTextTemplateEngine.IsCriticalException(ex)) { - throw; - } - LogError (ex.ToString (), false); - } - finally { - if (transform is IDisposable disposable) { - disposable.Dispose (); - } - compiledTemplate?.Dispose (); - compiledTemplate = null; - host = null; - } - - return errorOutput; - } - - PropertyInfo GetDerivedProperty (Type transformType, string propertyName) - { - while(transformType != typeof(object) && transformType != null) { - PropertyInfo property = transformType.GetProperty (propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); - if (property != null) { - return property; - } - transformType = transformType.BaseType; - } - return null; - } - - protected virtual object CreateTextTransformation(TemplateSettings settings, ITextTemplatingEngineHost host, Assembly assembly, ITextTemplatingSession session) { - object result = null; - object success = null; - try { - Type type; - - result = assembly.CreateInstance (settings.GetFullName ()); - - if (result != null) { - type = result.GetType (); - - if (settings.HostPropertyOnBase) { - try { - PropertyInfo property = type.GetProperty ("Host"); - - if (property != null) { - property?.SetValue (result, host, null); - } - else { - LogError (string.Format(CultureInfo.CurrentCulture, Resources.HostPropertyNotFound, settings.HostType.Name), false); - } - } - catch(Exception hostException) { - if (DebugTextTemplateEngine.IsCriticalException(hostException)) { - throw; - } - LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingHost, settings.GetFullName ()), false); - } - } - - try { - PropertyInfo property = GetDerivedProperty (type, nameof (TextTransformation.Session)); - - property?.SetValue (result, session, null); - } - catch(Exception sessionException) { - if (DebugTextTemplateEngine.IsCriticalException (sessionException)) { - throw; - } - LogError (string.Format (CultureInfo.CurrentCulture, Resources.ExceptionSettingSession, settings.GetFullName ()), false); - } - success = result; - - } else { - LogError (Resources.ExceptionInstantiatingTransformationObject, false); - } - } - catch(Exception instantiatingException) { - if (DebugTextTemplateEngine.IsCriticalException (instantiatingException)) { - throw; - } - LogError (Resources.ExceptionInstantiatingTransformationObject + string.Format(CultureInfo.CurrentCulture, Resources.Exception, instantiatingException), false); - success = null; - } - return success; - } - - internal bool PrepareTransformation (ITextTemplatingSession session, ParsedTemplate template, string content, ITextTemplatingEngineHost host, TemplateSettings settings) - { - this.session = session ?? throw new ArgumentNullException (nameof (session)); - this.host = host ?? throw new ArgumentNullException (nameof (host)); - this.settings = settings ?? throw new ArgumentNullException (nameof (settings)); - - try { - this.settings.Assemblies.Add (base.GetType ().Assembly.Location); - this.settings.Assemblies.Add (typeof (ITextTemplatingEngineHost).Assembly.Location); - this.compiledTemplate = LocateAssembly (session, template, content); - } - catch(Exception ex) { - if (DebugTextTemplateEngine.IsCriticalException (ex)) { - throw; - } - LogError (string.Format (CultureInfo.CurrentCulture, Resources.Exception, ex), false); - } - return this.compiledTemplate != null; - } - - CompiledTemplate LocateAssembly (ITextTemplatingSession session, ParsedTemplate template, string content) - { - CompiledTemplate compiledTemplate = null; - - if (session.CachedTemplates) { - compiledTemplate = CompiledTemplateCache.Find (session.ClassFullName); - } - if (compiledTemplate == null) { - compiledTemplate = Compile (template, content); - if (session.CachedTemplates && compiledTemplate != null) { - CompiledTemplateCache.Insert (session.ClassFullName, compiledTemplate); - } - } - return compiledTemplate; - } - - CompiledTemplate Compile (ParsedTemplate template, string content) - { - CompiledTemplate compiledTemplate = null; - - if (host is ITextTemplatingComponents Component && - Component.Engine is DebugTextTemplateEngine engine) { - compiledTemplate = engine.CompileTemplate (template, content, host, settings); - } - - return compiledTemplate; - } - - internal void PreLoadAssemblies (IEnumerable assemblies) - { - try { - //TODO:: investigate preloading assemblies with the AssemblyLoadContext - }catch(Exception ex) { - if (DebugTextTemplateEngine.IsCriticalException (ex)) { - throw; - } - } - } - - [Obsolete] - void LoadExplicitAssemblyReferences (IEnumerable references) - { - references = (from referenceAssembly in references - where !string.IsNullOrEmpty (referenceAssembly) && File.Exists (referenceAssembly) - select referenceAssembly).ToList (); - - List source = new List (); - - if (AppDomain.CurrentDomain.ShadowCopyFiles) { - foreach(string reference in references) { - string referenceDir = Path.GetDirectoryName (reference); - if (string.IsNullOrEmpty (referenceDir)) { - string currentDir = Directory.GetCurrentDirectory (); - if (File.Exists(Path.Combine(currentDir, reference))) { - referenceDir = currentDir; - } - } - source.Add (referenceDir); - } - EnsureShadowCopyPaths (source.Distinct (StringComparer.OrdinalIgnoreCase)); - } - } - - [Obsolete] - void EnsureShadowCopyPaths (IEnumerable paths) - { - if (AppDomain.CurrentDomain.ShadowCopyFiles) { - string path = string.Empty; - object shadowCopySync = TransformationRunner.shadowCopySync; - lock (shadowCopySync) { - if (shadowCopyPaths == null) { - shadowCopyPaths = new HashSet (StringComparer.OrdinalIgnoreCase); - } - foreach (string str2 in paths) { - if (!shadowCopyPaths.Contains (str2)) { - shadowCopyPaths.Add (str2); - } - } - path = string.Join (";", shadowCopyPaths.ToArray ()); - } - AppDomain.CurrentDomain.SetShadowCopyPath (path); - } - } - - protected Assembly AttemptAssemblyLoad(string assemblyName) - { - try { - return Assembly.LoadFrom (assemblyName); - } - catch(Exception ex) { - LogError (string.Format (CultureInfo.CurrentCulture, Resources.AssemblyLoadError, assemblyName) + string.Format (CultureInfo.CurrentCulture, Resources.Exception, ex), false); - return null; - } - } - - public void ClearErrors() - { - Errors.Clear (); - } - - protected void LogError(string message, bool isWarning) - { - CompilerError error = new CompilerError () { - ErrorText = message, - IsWarning = isWarning - }; - - Errors.Add (error); - } - - protected void LogError(string message, bool isWarning, string filename, int line, int column) - { - CompilerError error = new CompilerError () { - ErrorText = message, - IsWarning = isWarning, - FileName = filename, - Line = line, - Column = column - }; - - Errors.Add (error); - } - } -} diff --git a/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj b/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj index fc88232..1c970de 100644 --- a/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj +++ b/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj @@ -15,19 +15,4 @@ - - - True - True - Resources.resx - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - diff --git a/dotnet-t4/ToolTemplateSession.cs b/dotnet-t4/ToolTemplateSession.cs index 019687f..592c51e 100644 --- a/dotnet-t4/ToolTemplateSession.cs +++ b/dotnet-t4/ToolTemplateSession.cs @@ -35,8 +35,6 @@ class TextTemplatingSession : ITextTemplatingSession public TextTemplatingSession (ToolTemplateGenerator toolTemplateGenerator) { this.toolTemplateGenerator = toolTemplateGenerator; - this.IncludeStack = new Stack (); - this.Assemblies = new List (); } public object this [string key] { @@ -48,52 +46,7 @@ public object this [string key] { public ICollection Keys => session.Keys; public ICollection Values => session.Values; public int Count => session.Count; - public bool IsReadOnly => false; - - public bool Debug { - get => (bool)this[nameof (Debug)]; - set => this[nameof (Debug)] = value; - } - - public bool CachedTemplates { - get => (bool)this[nameof (CachedTemplates)]; - set => this[nameof (CachedTemplates)] = value; - } - - public string TemplateFile { - get => (string)this[nameof (TemplateFile)]; - set => this[nameof (TemplateFile)] = value; - } - public ITextTemplatingSessionHost UserTransformationSession { - get => (ITextTemplatingSessionHost)this[nameof (UserTransformationSession)]; - set => this[nameof (UserTransformationSession)] = value; - } - - public Stack IncludeStack { - get => (Stack)this[nameof (IncludeStack)]; - set => this[nameof (IncludeStack)] = value; - } - - public List Assemblies { - get => (List)this[nameof (Assemblies)]; - set => this[nameof (Assemblies)] = value; - } - - public string ClassFullName { - get => (string)this[nameof (ClassFullName)]; - set => this[nameof (ClassFullName)] = value; - } - - public SupportedLangaugeEnum SupportedLangauge { - get => (SupportedLangaugeEnum)this[nameof (SupportedLangauge)]; - set => this[nameof (SupportedLangauge)] = value; - } - - public string CompilerOptions { - get => (string)this[nameof (CompilerOptions)]; - set => this[nameof (CompilerOptions)] = value; - } - + public bool IsReadOnly => false; public void Add (string key, object value) => session.Add (key, value); public void Add (KeyValuePair item) => session.Add (item.Key, item.Value); public void Clear () => session.Clear (); From 7fcffc6ef6d0bc0a3995d462abc2ab44ec83bd98 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 12:34:04 -0600 Subject: [PATCH 06/58] removed the vsix library project file --- .../dotnet-t4-vsix-library.csproj | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj diff --git a/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj b/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj deleted file mode 100644 index 1c970de..0000000 --- a/dotnet-t4-vsix-library/dotnet-t4-vsix-library.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - netstandard2.0 - Mono.VisualStudio.TextTemplating - Mono.VisualStudio.TextTemplating - - - - - - - - - - - - From c83c292a01226166c8e0c4009386d62abeb83d8c Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 12:35:26 -0600 Subject: [PATCH 07/58] removed another file - yagni --- .../SupportedLangaugeEnum.cs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs deleted file mode 100644 index 618778c..0000000 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/SupportedLangaugeEnum.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel; - -namespace Mono.VisualStudio.TextTemplating -{ - public enum SupportedLangaugeEnum - { - [Description ("C#")] - CSharp, - [Description ("VB")] - VB - } -} From a493fb4d45015c017e10ca3275b200351162d3b7 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 13:03:29 -0600 Subject: [PATCH 08/58] mispelled a namespace --- .../Mono.TextTemplating/DebugTextTemplateEngine.cs | 2 +- .../DebugTemplateEventArgs.cs | 2 +- .../TextTemplatingCallback.cs | 2 +- .../TransformationRunFactory.cs | 2 +- .../TransformationRunner.cs | 2 +- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename Mono.TextTemplating/{Mono.VisualStudio.TextTemplating.VHost => Mono.VisualStudio.TextTemplating.VSHost}/DebugTemplateEventArgs.cs (75%) rename Mono.TextTemplating/{Mono.VisualStudio.TextTemplating.VHost => Mono.VisualStudio.TextTemplating.VSHost}/TextTemplatingCallback.cs (96%) rename Mono.TextTemplating/{Mono.VisualStudio.TextTemplating.VHost => Mono.VisualStudio.TextTemplating.VSHost}/TransformationRunFactory.cs (95%) rename Mono.TextTemplating/{Mono.VisualStudio.TextTemplating.VHost => Mono.VisualStudio.TextTemplating.VSHost}/TransformationRunner.cs (99%) diff --git a/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs index e45e9af..ad152a6 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs @@ -1,6 +1,6 @@ using System; using Mono.VisualStudio.TextTemplating; -using Mono.VisualStudio.TextTemplating.VHost; +using Mono.VisualStudio.TextTemplating.VSHost; namespace Mono.TextTemplating { diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs similarity index 75% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs index abbe5a7..e0c2d3e 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/DebugTemplateEventArgs.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs @@ -1,6 +1,6 @@ using System; -namespace Mono.VisualStudio.TextTemplating.VHost +namespace Mono.VisualStudio.TextTemplating.VSHost { public class DebugTemplateEventArgs : EventArgs { diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs similarity index 96% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs index ae2f652..639395d 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TextTemplatingCallback.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Mono.VisualStudio.TextTemplating.VHost +namespace Mono.VisualStudio.TextTemplating.VSHost { public class TextTemplatingCallback : ITextTemplatingCallback diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs similarity index 95% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs index e988b9c..54dbc5f 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunFactory.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs @@ -1,7 +1,7 @@ using System; using Mono.TextTemplating; -namespace Mono.VisualStudio.TextTemplating.VHost +namespace Mono.VisualStudio.TextTemplating.VSHost { public abstract class TransformationRunFactory : #if FEATURE_APPDOMAINS diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs similarity index 99% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs index 24c1607..b7c2956 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VHost/TransformationRunner.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs @@ -5,7 +5,7 @@ using System.Reflection; using Mono.TextTemplating; -namespace Mono.VisualStudio.TextTemplating.VHost +namespace Mono.VisualStudio.TextTemplating.VSHost { public class TransformationRunner : #if FEATURE_APPDOMAINS diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 65d0b74..9313c8c 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -39,7 +39,7 @@ namespace Mono.VisualStudio.TextTemplating { - using VHost; + using Mono.VisualStudio.TextTemplating.VSHost; public interface IRecognizeHostSpecific { From 9ad0858055656d8af2f7a6cdd1dcdeb2fa2f8327 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 13:59:49 -0600 Subject: [PATCH 09/58] update to ensure that the service that is built works with what has been implemented so far --- .../TransformationRunner.cs | 2 +- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs index b7c2956..0eefa30 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs @@ -168,7 +168,7 @@ CompiledTemplate Compile (ParsedTemplate template, string content) CompiledTemplate compiledTemplate = null; if (host is ITextTemplatingComponents Component && - Component.Engine is TemplatingEngine engine) { + Component.Engine is IDebugTextTemplatingEngine engine) { compiledTemplate = engine.CompileTemplate (template, content, host, settings); // do we want to dispose the appdomain resolver in compiled template in favor of the transformation runner? //compiledTemplate?.Dispose (); diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 9313c8c..6dd9eee 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -47,6 +47,16 @@ public interface IRecognizeHostSpecific bool RequiresProcessingRunIsHostSpecific { get; } } + public interface ITextTemplatingService + : ITextTemplatingEngineHost + , ITextTemplatingSessionHost + , ITextTemplatingComponents + , IDebugTextTemplating + , ITextTemplating + { + new IDebugTextTemplatingEngine Engine { get; } + } + public interface IDebugTextTemplating : ITextTemplating { @@ -80,6 +90,8 @@ public interface IDebugTextTemplatingEngine : ITextTemplatingEngine { IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory); + + CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); } public interface ITextTemplatingEngine @@ -95,7 +107,7 @@ public interface ITextTemplatingComponents ITextTemplatingEngine Engine { get; } - string InputFile { get; } + string InputFile { get; set; } ITextTemplatingCallback Callback { get; set; } From e7e7a3b32e6d00c5399d86e91055d5c0bfda3363 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 29 Jul 2020 21:32:23 -0600 Subject: [PATCH 10/58] re-initialize the error callback --- .../TextTemplatingCallback.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs index 639395d..2a69a91 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TextTemplatingCallback.cs @@ -14,6 +14,14 @@ public class TextTemplatingCallback public Encoding OutputEncoding { get; private set; } = Encoding.UTF8; + public void Initialize() + { + Errors = false; + Extension = null; + OutputEncoding = Encoding.UTF8; + isFromOutputDirective = false; + } + public void ErrorCallback (bool warning, string message, int line, int column) { Errors = true; From 4aebef7c09219edba4eee8d3132a309d9400ba62 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 10:07:58 -0600 Subject: [PATCH 11/58] moved the Engine class back into the microsoft namespace with the obsolete set to throw a compiler error. --- .../Engine.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename Mono.TextTemplating/{Mono.VisualStudio.TextTemplating => Microsoft.VisualStudio.TextTemplating}/Engine.cs (92%) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs b/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs similarity index 92% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs rename to Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs index 02f7e8c..6af95ff 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Engine.cs +++ b/Mono.TextTemplating/Microsoft.VisualStudio.TextTemplating/Engine.cs @@ -26,10 +26,11 @@ using System; using Mono.TextTemplating; +using Mono.VisualStudio.TextTemplating; -namespace Mono.VisualStudio.TextTemplating +namespace Microsoft.VisualStudio.TextTemplating { - [Obsolete ("Use Mono.TextTemplating.TemplatingEngine directly")] + [Obsolete ("Use Mono.TextTemplating.TemplatingEngine directly", true)] public class Engine : ITextTemplatingEngine { From 3a8356eaf47ccaa241a267e24f89672bc25c1c4e Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 16:22:53 -0600 Subject: [PATCH 12/58] rename InputFile to TemplateFile --- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 6dd9eee..507885d 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -107,7 +107,7 @@ public interface ITextTemplatingComponents ITextTemplatingEngine Engine { get; } - string InputFile { get; set; } + string TemplateFile { get; set; } ITextTemplatingCallback Callback { get; set; } From 4e3bc72826b9734ac2063dbcd171b4ace408de43 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 17:52:47 -0600 Subject: [PATCH 13/58] update get settings to request from the host as well if not in the template --- .../Mono.TextTemplating/TemplateSettings.cs | 2 +- .../Mono.TextTemplating/TemplatingEngine.cs | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index 64f0bad..d686577 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -63,7 +63,7 @@ public TemplateSettings () public Dictionary DirectiveProcessors { get; private set; } public bool IncludePreprocessingHelpers { get; set; } public bool IsPreprocessed { get; set; } - public bool RelativeLinePragmas { get; set; } + public bool UseRelativeLinePragmas { get; set; } public bool NoLinePragmas { get; set; } public bool InternalVisibility { get; set; } public Type HostType { get; set; } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index f7f30f0..8d18c74 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -337,7 +337,7 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars { var settings = new TemplateSettings (); - bool relativeLinePragmas = host.GetHostOption ("UseRelativeLinePragmas") as bool? ?? false; + bool relativeLinePragmas = host.GetHostOption (nameof (TemplateSettings.UseRelativeLinePragmas)) as bool? ?? false; foreach (Directive dt in pt.Directives) { switch (dt.Name.ToLowerInvariant ()) { @@ -368,15 +368,15 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars settings.HostSpecific = string.Compare (val, "true", StringComparison.OrdinalIgnoreCase) == 0; } } - val = dt.Extract ("CompilerOptions"); + val = dt.Extract (nameof (TemplateSettings.CompilerOptions)) ?? host.GetHostOption(nameof(TemplateSettings.CompilerOptions))?.ToString().ToLower(); if (val != null) { settings.CompilerOptions = val; } - val = dt.Extract ("relativeLinePragmas"); + val = dt.Extract ("relativeLinePragmas") ?? host.GetHostOption (nameof (TemplateSettings.UseRelativeLinePragmas))?.ToString().ToLower(); if (val != null) { relativeLinePragmas = string.Compare (val, "true", StringComparison.OrdinalIgnoreCase) == 0; } - val = dt.Extract ("linePragmas"); + val = dt.Extract ("linePragmas") ?? host.GetHostOption (nameof (TemplateSettings.NoLinePragmas))?.ToString ().ToLower (); if (val != null) { settings.NoLinePragmas = string.Compare (val, "false", StringComparison.OrdinalIgnoreCase) == 0; } @@ -483,7 +483,9 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars return settings; } - settings.RelativeLinePragmas = relativeLinePragmas; + settings.UseRelativeLinePragmas = relativeLinePragmas; + + settings.CachedTemplates = (bool?)host.GetHostOption (nameof (TemplateSettings.CachedTemplates)) ?? false; return settings; } @@ -652,7 +654,7 @@ public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost hos CodeLinePragma location = null; if (!settings.NoLinePragmas) { var f = seg.StartLocation.FileName ?? host.TemplateFile; - if (settings.RelativeLinePragmas) + if (settings.UseRelativeLinePragmas) f = FileUtil.AbsoluteToRelativePath (baseDirectory, f).Replace ('\\', '/'); location = new CodeLinePragma (f, seg.StartLocation.Line); } From b5266bd7a6fdcd44c18a76d58c0b1f39407ea949 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 18:40:34 -0600 Subject: [PATCH 14/58] no message --- .../TransformationRunner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs index 0eefa30..ac712b4 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs @@ -76,7 +76,7 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe if (result != null) { type = result.GetType (); - if (settings.HostPropertyOnBase) { + if (settings.HostPropertyOnBase || settings.HostSpecific) { try { PropertyInfo property = type.GetProperty ("Host"); From 929b52f82b7b11c97118c8f42106192370ccba34 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 19:00:21 -0600 Subject: [PATCH 15/58] added a means by which a text writer for the log can be set. --- .../Mono.TextTemplating/TemplatingEngine.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 8d18c74..1ccc23e 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -485,7 +485,13 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars settings.UseRelativeLinePragmas = relativeLinePragmas; - settings.CachedTemplates = (bool?)host.GetHostOption (nameof (TemplateSettings.CachedTemplates)) ?? false; + if (host.GetHostOption (nameof (TemplateSettings.CachedTemplates)) is bool cachedTemplates) { + settings.CachedTemplates = cachedTemplates; + } + + if (host.GetHostOption (nameof (TemplateSettings.Log)) is TextWriter output) { + settings.Log = output; + } return settings; } From c289524d43f76025437f1f063bbb595a0e6d4547 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 21:22:10 -0600 Subject: [PATCH 16/58] added a cancelation token to the template settings --- .../CscCodeCompiler.cs | 9 +++++---- .../Mono.TextTemplating/TemplateSettings.cs | 4 ++++ .../Mono.TextTemplating/TemplatingEngine.cs | 13 +++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index 52c1b2f..fee3a7b 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -115,15 +115,16 @@ public override async Task CompileFile (CodeCompilerArgument UseShellExecute = false }; - if (log != null) { - log.WriteLine ($"{psi.FileName} {psi.Arguments}"); - } - if (runtime.Kind == RuntimeKind.NetCore) { psi.Arguments = $"\"{psi.FileName}\" {psi.Arguments}"; psi.FileName = Path.GetFullPath (Path.Combine (runtime.RuntimeDir, "..", "..", "..", "dotnet")); } + if (log != null) + { + log.WriteLine($"{psi.FileName} {psi.Arguments}"); + } + var stdout = new StringWriter (); var stderr = new StringWriter (); diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index d686577..b7a42ca 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -30,6 +30,7 @@ using Mono.VisualStudio.TextTemplating; using System.IO; using System.Reflection; +using System.Threading; namespace Mono.TextTemplating { @@ -47,6 +48,9 @@ public TemplateSettings () public bool HostPropertyOnBase { get; set; } public bool Debug { get; set; } public bool CachedTemplates { get; set; } +#if !NET35 + public CancellationToken CancellationToken { get; set; } +#endif public TextWriter Log { get; set; } public string Inherits { get; set; } public string Name { get; set; } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 1ccc23e..17d7235 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -259,7 +259,7 @@ CompilerResults CompileCode (IEnumerable references, TemplateSettings se args.OutputPath = Path.Combine (tempFolder, settings.Name + ".dll"); args.TempDirectory = tempFolder; - var result = compiler.CompileFile (args, settings.Log, CancellationToken.None).Result; + var result = compiler.CompileFile (args, settings.Log, settings.CancellationToken).Result; var r = new CompilerResults (new TempFileCollection ()); r.TempFiles.AddFile (sourceFilename, false); @@ -491,7 +491,16 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars if (host.GetHostOption (nameof (TemplateSettings.Log)) is TextWriter output) { settings.Log = output; - } + } + +#if !NET35 + if (host.GetHostOption (nameof (TemplateSettings.CancellationToken)) is CancellationToken cancellationToken) { + settings.CancellationToken = cancellationToken; + } + else { + settings.CancellationToken = CancellationToken.None; + } +#endif return settings; } From be0d39492eb4f916758a897b60d8633e25a0e818 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 22:16:25 -0600 Subject: [PATCH 17/58] if canceled do not await process that was never started --- .../Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index fee3a7b..e49d5a6 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -136,7 +136,11 @@ public override async Task CompileFile (CodeCompilerArgument var process = ProcessUtils.StartProcess (psi, outWriter, errWriter, token); - var result = await process; + int result = -1; + + if (!token.IsCancellationRequested) { + result = await process; + } var outputList = new List (); var errors = new List (); From 78b28543e9cc83c019bc317d39f84c4dea48fe59 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 22:34:25 -0600 Subject: [PATCH 18/58] update process to be asynchronous on writing messages out --- .../ProcessUtils.cs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index b285b76..41c0fcc 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -71,17 +71,21 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.EnableRaisingEvents = true; if (psi.RedirectStandardOutput) { bool stdOutInitialized = false; - p.OutputDataReceived += (sender, e) => { + p.OutputDataReceived += async (sender, e) => { try { if (e.Data == null) { outputDone = true; if (exitDone && errorDone) - tcs.TrySetResult (p.ExitCode); + { + tcs.TrySetResult(p.ExitCode); + } return; } if (stdOutInitialized) - stdout.WriteLine (); + { + await stdout.WriteLineAsync(); + } stdout.Write (e.Data); stdOutInitialized = true; } catch (Exception ex) { @@ -95,17 +99,20 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (psi.RedirectStandardError) { bool stdErrInitialized = false; - p.ErrorDataReceived += (sender, e) => { + p.ErrorDataReceived += async (sender, e) => { try { if (e.Data == null) { errorDone = true; if (exitDone && outputDone) - tcs.TrySetResult (p.ExitCode); + { + tcs.TrySetResult(p.ExitCode); + } return; } - if (stdErrInitialized) - stderr.WriteLine (); + if (stdErrInitialized) { + await stderr.WriteLineAsync(); + } stderr.Write (e.Data); stdErrInitialized = true; } catch (Exception ex) { @@ -120,7 +127,9 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.Exited += (sender, e) => { exitDone = true; if (errorDone && outputDone) - tcs.TrySetResult (p.ExitCode); + { + tcs.TrySetResult(p.ExitCode); + } }; return tcs.Task; From a72403c49fd5651b1c644bc29c1f6b9039768b7c Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 22:42:15 -0600 Subject: [PATCH 19/58] more code that was not written correctly for asynchronous work --- .../CscCodeCompiler.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index e49d5a6..b57ed26 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -200,6 +200,18 @@ public override void Write (string value) a.Write (value); b.Write (value); } + + public override async Task WriteAsync(string value) + { + await a.WriteAsync(value); + await b.WriteAsync(value); + } + + public override async Task WriteLineAsync() + { + await a.WriteLineAsync(); + await b.WriteLineAsync(); + } } } } From ba6bd93d79501f7c66187df8ab7516f36147267d Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 22:46:16 -0600 Subject: [PATCH 20/58] few more --- .../Mono.TextTemplating.CodeCompilation/ProcessUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 41c0fcc..2f87b98 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -86,7 +86,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T { await stdout.WriteLineAsync(); } - stdout.Write (e.Data); + await stdout.WriteLineAsync(e.Data); stdOutInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); @@ -113,7 +113,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdErrInitialized) { await stderr.WriteLineAsync(); } - stderr.Write (e.Data); + await stderr.WriteLineAsync(e.Data); stdErrInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); From 3344933d15b3f80908db5ddf459130b50b631c5e Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 22:59:15 -0600 Subject: [PATCH 21/58] update references --- .../Mono.TextTemplating.Roslyn.csproj | 6 +++++- Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj | 7 +++++-- Mono.TextTemplating/Mono.TextTemplating.csproj | 6 +++++- TextTransform/TextTransform.csproj | 4 ++++ dotnet-t4-project-tool/dotnet-t4-project-tool.csproj | 5 +++++ dotnet-t4/dotnet-t4.csproj | 4 ++++ 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj b/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj index 40f813a..613c1e9 100644 --- a/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj +++ b/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj @@ -32,10 +32,14 @@ To enable the in-process C# compiler, use the TemplatingEngine.UseInProcessCompi - + + + + + diff --git a/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj b/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj index 7a0d11b..4114384 100644 --- a/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj +++ b/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj @@ -8,8 +8,11 @@ - + - + + + + diff --git a/Mono.TextTemplating/Mono.TextTemplating.csproj b/Mono.TextTemplating/Mono.TextTemplating.csproj index 3ad5fc3..c05a127 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.csproj +++ b/Mono.TextTemplating/Mono.TextTemplating.csproj @@ -29,7 +29,7 @@ This package allows embedding the T4 engine in an application. - + @@ -52,4 +52,8 @@ This package allows embedding the T4 engine in an application. ResXFileCodeGenerator + + + + \ No newline at end of file diff --git a/TextTransform/TextTransform.csproj b/TextTransform/TextTransform.csproj index 71232d6..2b5f518 100644 --- a/TextTransform/TextTransform.csproj +++ b/TextTransform/TextTransform.csproj @@ -24,4 +24,8 @@ + + + + \ No newline at end of file diff --git a/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj b/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj index 10e2cff..3f2b3ff 100644 --- a/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj +++ b/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj @@ -31,4 +31,9 @@ This package can be installed into a project using `DotNetCliToolReference`. + + + + + diff --git a/dotnet-t4/dotnet-t4.csproj b/dotnet-t4/dotnet-t4.csproj index 51d83ee..0a637d4 100644 --- a/dotnet-t4/dotnet-t4.csproj +++ b/dotnet-t4/dotnet-t4.csproj @@ -39,4 +39,8 @@ This package can be installed as a dotnet global or local tool. + + + + From e3c922772e1ab3a4d840211741b7f7a82ffde710 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 23:30:04 -0600 Subject: [PATCH 22/58] no message --- .../Mono.TextTemplating.Roslyn.csproj | 4 ++++ .../Mono.TextTemplating.Tests.csproj | 4 ++++ Mono.TextTemplating/Mono.TextTemplating.csproj | 15 ++++++++++++--- TextTransform/TextTransform.csproj | 4 ++++ .../dotnet-t4-project-tool.csproj | 8 ++++---- dotnet-t4/dotnet-t4.csproj | 8 ++++---- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj b/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj index 613c1e9..892551f 100644 --- a/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj +++ b/Mono.TextTemplating.Roslyn/Mono.TextTemplating.Roslyn.csproj @@ -27,6 +27,10 @@ To enable the in-process C# compiler, use the TemplatingEngine.UseInProcessCompi + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj b/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj index 4114384..7998921 100644 --- a/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj +++ b/Mono.TextTemplating.Tests/Mono.TextTemplating.Tests.csproj @@ -8,6 +8,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Mono.TextTemplating/Mono.TextTemplating.csproj b/Mono.TextTemplating/Mono.TextTemplating.csproj index c05a127..5401e2f 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.csproj +++ b/Mono.TextTemplating/Mono.TextTemplating.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net45;net35 true @@ -25,6 +25,10 @@ This package allows embedding the T4 engine in an application. + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -33,6 +37,9 @@ This package allows embedding the T4 engine in an application. + + 4.3.0 + 4.3.0 @@ -53,7 +60,9 @@ This package allows embedding the T4 engine in an application. - - + + + 4.3.0 + \ No newline at end of file diff --git a/TextTransform/TextTransform.csproj b/TextTransform/TextTransform.csproj index 2b5f518..599c599 100644 --- a/TextTransform/TextTransform.csproj +++ b/TextTransform/TextTransform.csproj @@ -16,6 +16,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj b/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj index 3f2b3ff..2c7c9ee 100644 --- a/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj +++ b/dotnet-t4-project-tool/dotnet-t4-project-tool.csproj @@ -22,6 +22,10 @@ This package can be installed into a project using `DotNetCliToolReference`. + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -32,8 +36,4 @@ This package can be installed into a project using `DotNetCliToolReference`. - - - - diff --git a/dotnet-t4/dotnet-t4.csproj b/dotnet-t4/dotnet-t4.csproj index 0a637d4..0425930 100644 --- a/dotnet-t4/dotnet-t4.csproj +++ b/dotnet-t4/dotnet-t4.csproj @@ -24,6 +24,10 @@ This package can be installed as a dotnet global or local tool. + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -39,8 +43,4 @@ This package can be installed as a dotnet global or local tool. - - - - From 0ddbca475fcd4f66af871d56a39c19a7c5e77426 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Thu, 30 Jul 2020 23:57:41 -0600 Subject: [PATCH 23/58] trying to get this process to yield to the main thread --- .../CscCodeCompiler.cs | 78 ++++++++++--------- .../ProcessUtils.cs | 38 ++++----- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index b57ed26..df6b725 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -125,54 +125,60 @@ public override async Task CompileFile (CodeCompilerArgument log.WriteLine($"{psi.FileName} {psi.Arguments}"); } - var stdout = new StringWriter (); - var stderr = new StringWriter (); + using (var stdout = new StringWriter ()) + using (var stderr = new StringWriter ()) + using (TextWriter outWriter = log != null ? new SplitOutputWriter (log, (TextWriter)stderr) : (TextWriter)stderr) + using (TextWriter errWriter = log != null ? new SplitOutputWriter (log, (TextWriter)stderr) : (TextWriter)stderr) { - TextWriter outWriter = stderr, errWriter = stderr; - if (log != null) { - outWriter = new SplitOutputWriter (log, outWriter); - errWriter = new SplitOutputWriter (log, errWriter); - } + //TextWriter + // outWriter = stderr, + // errWriter = stderr; - var process = ProcessUtils.StartProcess (psi, outWriter, errWriter, token); + //if (log != null) { + // outWriter = new SplitOutputWriter (log, outWriter); + // errWriter = new SplitOutputWriter (log, errWriter); + //} - int result = -1; + var process = ProcessUtils.StartProcess (psi, outWriter, errWriter, token); - if (!token.IsCancellationRequested) { - result = await process; - } + int result = -1; - var outputList = new List (); - var errors = new List (); + if (!token.IsCancellationRequested) { + result = await process.ConfigureAwait (false); + } - void ConsumeOutput (string s) - { - using (var sw = new StringReader (s)) { - string line; - while ((line = sw.ReadLine ()) != null) { - outputList.Add (line); - var err = MSBuildErrorParser.TryParseLine (line); - if (err != null) { - errors.Add (err); + var outputList = new List (); + var errors = new List (); + + void ConsumeOutput (string s) + { + using (var sw = new StringReader (s)) { + string line; + while ((line = sw.ReadLine ()) != null) { + outputList.Add (line); + var err = MSBuildErrorParser.TryParseLine (line); + if (err != null) { + errors.Add (err); + } } } } - } - ConsumeOutput (stdout.ToString ()); - ConsumeOutput (stderr.ToString ()); + ConsumeOutput (stdout.ToString ()); + ConsumeOutput (stderr.ToString ()); - if (log != null) { - log.WriteLine ($"{psi.FileName} {psi.Arguments}"); - } + if (log != null) { + log.WriteLine ($"{psi.FileName} {psi.Arguments}"); + } - return new CodeCompilerResult { - Success = result == 0, - Errors = errors, - ExitCode = result, - Output = outputList, - ResponseFile = rspPath - }; + return new CodeCompilerResult { + Success = result == 0, + Errors = errors, + ExitCode = result, + Output = outputList, + ResponseFile = rspPath + }; + } } //we know that ProcessUtils.StartProcess only uses WriteLine and Write(string) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 2f87b98..7e1ae65 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -57,9 +57,11 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (!p.HasExited) { p.Kill (); } - } catch (InvalidOperationException ex) { - if (ex.Message.IndexOf ("already exited", StringComparison.Ordinal) < 0) + } + catch (InvalidOperationException ex) { + if (ex.Message.IndexOf ("already exited", StringComparison.Ordinal) < 0) { throw; + } } }); } @@ -75,20 +77,19 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T try { if (e.Data == null) { outputDone = true; - if (exitDone && errorDone) - { - tcs.TrySetResult(p.ExitCode); + if (exitDone && errorDone) { + tcs.TrySetResult (p.ExitCode); } return; } - if (stdOutInitialized) - { - await stdout.WriteLineAsync(); + if (stdOutInitialized) { + await stdout.WriteLineAsync ().ConfigureAwait (false); } - await stdout.WriteLineAsync(e.Data); + await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); stdOutInitialized = true; - } catch (Exception ex) { + } + catch (Exception ex) { tcs.TrySetException (ex); } }; @@ -103,19 +104,19 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T try { if (e.Data == null) { errorDone = true; - if (exitDone && outputDone) - { - tcs.TrySetResult(p.ExitCode); + if (exitDone && outputDone) { + tcs.TrySetResult (p.ExitCode); } return; } if (stdErrInitialized) { - await stderr.WriteLineAsync(); + await stderr.WriteLineAsync ().ConfigureAwait (false); } - await stderr.WriteLineAsync(e.Data); + await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); stdErrInitialized = true; - } catch (Exception ex) { + } + catch (Exception ex) { tcs.TrySetException (ex); } }; @@ -126,9 +127,8 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.Exited += (sender, e) => { exitDone = true; - if (errorDone && outputDone) - { - tcs.TrySetResult(p.ExitCode); + if (errorDone && outputDone) { + tcs.TrySetResult (p.ExitCode); } }; From 30aaed7caecb883bbdbcc1d7d49882574943eb74 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 00:09:44 -0600 Subject: [PATCH 24/58] no message --- .../Mono.TextTemplating.CodeCompilation/ProcessUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 7e1ae65..c7cabca 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -86,7 +86,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdOutInitialized) { await stdout.WriteLineAsync ().ConfigureAwait (false); } - await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); + await stdout.WriteAsync (e.Data).ConfigureAwait (false); stdOutInitialized = true; } catch (Exception ex) { @@ -113,7 +113,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdErrInitialized) { await stderr.WriteLineAsync ().ConfigureAwait (false); } - await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); + await stderr.WriteAsync (e.Data).ConfigureAwait (false); stdErrInitialized = true; } catch (Exception ex) { From fc496a8668a8de7ad0383d2a68cbf40a66016943 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 00:26:10 -0600 Subject: [PATCH 25/58] try writing lines again --- .../CscCodeCompiler.cs | 8 ++++---- .../Mono.TextTemplating.CodeCompilation/ProcessUtils.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index df6b725..a56dd28 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -209,14 +209,14 @@ public override void Write (string value) public override async Task WriteAsync(string value) { - await a.WriteAsync(value); - await b.WriteAsync(value); + await a.WriteAsync(value).ConfigureAwait(false); + await b.WriteAsync(value).ConfigureAwait (false); } public override async Task WriteLineAsync() { - await a.WriteLineAsync(); - await b.WriteLineAsync(); + await a.WriteLineAsync().ConfigureAwait (false); + await b.WriteLineAsync().ConfigureAwait (false); } } } diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index c7cabca..7e1ae65 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -86,7 +86,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdOutInitialized) { await stdout.WriteLineAsync ().ConfigureAwait (false); } - await stdout.WriteAsync (e.Data).ConfigureAwait (false); + await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); stdOutInitialized = true; } catch (Exception ex) { @@ -113,7 +113,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdErrInitialized) { await stderr.WriteLineAsync ().ConfigureAwait (false); } - await stderr.WriteAsync (e.Data).ConfigureAwait (false); + await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); stdErrInitialized = true; } catch (Exception ex) { From 1692d0ff22287bdeacd6c53d5189213975d013a6 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 00:36:32 -0600 Subject: [PATCH 26/58] yagni --- .../ProcessUtils.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 7e1ae65..c00eab0 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -72,7 +72,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.EnableRaisingEvents = true; if (psi.RedirectStandardOutput) { - bool stdOutInitialized = false; + //bool stdOutInitialized = false; p.OutputDataReceived += async (sender, e) => { try { if (e.Data == null) { @@ -83,11 +83,11 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T return; } - if (stdOutInitialized) { - await stdout.WriteLineAsync ().ConfigureAwait (false); - } + //if (stdOutInitialized) { + // await stdout.WriteLineAsync ().ConfigureAwait (false); + //} await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); - stdOutInitialized = true; + //stdOutInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); @@ -99,7 +99,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T } if (psi.RedirectStandardError) { - bool stdErrInitialized = false; + //bool stdErrInitialized = false; p.ErrorDataReceived += async (sender, e) => { try { if (e.Data == null) { @@ -110,11 +110,11 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T return; } - if (stdErrInitialized) { - await stderr.WriteLineAsync ().ConfigureAwait (false); - } + //if (stdErrInitialized) { + // await stderr.WriteLineAsync ().ConfigureAwait (false); + //} await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); - stdErrInitialized = true; + //stdErrInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); From 580d4538f17207fa088a74896f795d27dde1154e Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 00:46:25 -0600 Subject: [PATCH 27/58] 3rd time is a charm --- .../Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index a56dd28..c81c548 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -218,6 +218,12 @@ public override async Task WriteLineAsync() await a.WriteLineAsync().ConfigureAwait (false); await b.WriteLineAsync().ConfigureAwait (false); } + + public override async Task WriteLineAsync (string value) + { + await a.WriteLineAsync (value).ConfigureAwait (false); + await b.WriteLineAsync (value).ConfigureAwait (false); + } } } } From ea8e698eee149ae6838c6508cc630873f0fa6857 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 00:52:53 -0600 Subject: [PATCH 28/58] no message --- .../ProcessUtils.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index c00eab0..7e1ae65 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -72,7 +72,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.EnableRaisingEvents = true; if (psi.RedirectStandardOutput) { - //bool stdOutInitialized = false; + bool stdOutInitialized = false; p.OutputDataReceived += async (sender, e) => { try { if (e.Data == null) { @@ -83,11 +83,11 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T return; } - //if (stdOutInitialized) { - // await stdout.WriteLineAsync ().ConfigureAwait (false); - //} + if (stdOutInitialized) { + await stdout.WriteLineAsync ().ConfigureAwait (false); + } await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); - //stdOutInitialized = true; + stdOutInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); @@ -99,7 +99,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T } if (psi.RedirectStandardError) { - //bool stdErrInitialized = false; + bool stdErrInitialized = false; p.ErrorDataReceived += async (sender, e) => { try { if (e.Data == null) { @@ -110,11 +110,11 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T return; } - //if (stdErrInitialized) { - // await stderr.WriteLineAsync ().ConfigureAwait (false); - //} + if (stdErrInitialized) { + await stderr.WriteLineAsync ().ConfigureAwait (false); + } await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); - //stdErrInitialized = true; + stdErrInitialized = true; } catch (Exception ex) { tcs.TrySetException (ex); From f25822937ed80ee07d17cc5943f162ef4fe0547c Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 10:30:47 -0600 Subject: [PATCH 29/58] testing the logging to string builder async --- .../CscCodeCompiler.cs | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index c81c548..4ecf7c3 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -32,6 +32,7 @@ using System.Threading.Tasks; using System.Linq; using System.Text; +using System.Globalization; namespace Mono.TextTemplating.CodeCompilation { @@ -125,19 +126,10 @@ public override async Task CompileFile (CodeCompilerArgument log.WriteLine($"{psi.FileName} {psi.Arguments}"); } - using (var stdout = new StringWriter ()) - using (var stderr = new StringWriter ()) - using (TextWriter outWriter = log != null ? new SplitOutputWriter (log, (TextWriter)stderr) : (TextWriter)stderr) - using (TextWriter errWriter = log != null ? new SplitOutputWriter (log, (TextWriter)stderr) : (TextWriter)stderr) { - - //TextWriter - // outWriter = stderr, - // errWriter = stderr; - - //if (log != null) { - // outWriter = new SplitOutputWriter (log, outWriter); - // errWriter = new SplitOutputWriter (log, errWriter); - //} + using (var stdout = new StringWriter (new StringBuilder(), CultureInfo.CurrentCulture)) + using (var stderr = new StringWriter (new StringBuilder (), CultureInfo.CurrentCulture)) + using (TextWriter outWriter = log != null ? new SplitOutputWriter (log, stderr) : (TextWriter)stderr) + using (TextWriter errWriter = log != null ? new SplitOutputWriter (log, stderr) : (TextWriter)stderr) { var process = ProcessUtils.StartProcess (psi, outWriter, errWriter, token); @@ -184,45 +176,60 @@ void ConsumeOutput (string s) //we know that ProcessUtils.StartProcess only uses WriteLine and Write(string) class SplitOutputWriter : TextWriter { - readonly TextWriter a; - readonly TextWriter b; + readonly TextWriter logWriter; + readonly TextWriter errorWriter; public SplitOutputWriter (TextWriter a, TextWriter b) { - this.a = a; - this.b = b; + this.logWriter = a; + this.errorWriter = b; } public override Encoding Encoding => Encoding.UTF8; public override void WriteLine () { - a.WriteLine (); - b.WriteLine (); + logWriter.WriteLine (); + errorWriter.WriteLine (); + } + + public override void WriteLine (string value) + { + logWriter.WriteLine (value); + errorWriter.WriteLine (value); } public override void Write (string value) { - a.Write (value); - b.Write (value); + logWriter.Write (value); + errorWriter.Write (value); } public override async Task WriteAsync(string value) { - await a.WriteAsync(value).ConfigureAwait(false); - await b.WriteAsync(value).ConfigureAwait (false); + await logWriter.WriteAsync(value).ConfigureAwait(false); + + if (errorWriter is StringWriter sw) { + await sw.WriteAsync (value).ConfigureAwait (false); + } } public override async Task WriteLineAsync() { - await a.WriteLineAsync().ConfigureAwait (false); - await b.WriteLineAsync().ConfigureAwait (false); + await logWriter.WriteLineAsync().ConfigureAwait (false); + + if (errorWriter is StringWriter sw) { + await sw.WriteLineAsync ().ConfigureAwait (false); + } } public override async Task WriteLineAsync (string value) { - await a.WriteLineAsync (value).ConfigureAwait (false); - await b.WriteLineAsync (value).ConfigureAwait (false); + await logWriter.WriteLineAsync (value).ConfigureAwait (false); + + if (errorWriter is StringWriter sw) { + await sw.WriteLineAsync (value).ConfigureAwait (false); + } } } } From 00115283e35d580230099b48d05a53a0ca76131d Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 11:41:22 -0600 Subject: [PATCH 30/58] roll back to before, the log writer for VS will convert Write synchrounous call to asynchronous. --- .../CscCodeCompiler.cs | 27 ------------------- .../ProcessUtils.cs | 12 ++++----- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index 4ecf7c3..16bb226 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -204,33 +204,6 @@ public override void Write (string value) logWriter.Write (value); errorWriter.Write (value); } - - public override async Task WriteAsync(string value) - { - await logWriter.WriteAsync(value).ConfigureAwait(false); - - if (errorWriter is StringWriter sw) { - await sw.WriteAsync (value).ConfigureAwait (false); - } - } - - public override async Task WriteLineAsync() - { - await logWriter.WriteLineAsync().ConfigureAwait (false); - - if (errorWriter is StringWriter sw) { - await sw.WriteLineAsync ().ConfigureAwait (false); - } - } - - public override async Task WriteLineAsync (string value) - { - await logWriter.WriteLineAsync (value).ConfigureAwait (false); - - if (errorWriter is StringWriter sw) { - await sw.WriteLineAsync (value).ConfigureAwait (false); - } - } } } } diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 7e1ae65..1a36b7e 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -73,7 +73,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T p.EnableRaisingEvents = true; if (psi.RedirectStandardOutput) { bool stdOutInitialized = false; - p.OutputDataReceived += async (sender, e) => { + p.OutputDataReceived += (sender, e) => { try { if (e.Data == null) { outputDone = true; @@ -84,9 +84,9 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T } if (stdOutInitialized) { - await stdout.WriteLineAsync ().ConfigureAwait (false); + stdout.WriteLine (); } - await stdout.WriteLineAsync (e.Data).ConfigureAwait (false); + stdout.WriteLine (e.Data); stdOutInitialized = true; } catch (Exception ex) { @@ -100,7 +100,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (psi.RedirectStandardError) { bool stdErrInitialized = false; - p.ErrorDataReceived += async (sender, e) => { + p.ErrorDataReceived += (sender, e) => { try { if (e.Data == null) { errorDone = true; @@ -111,9 +111,9 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T } if (stdErrInitialized) { - await stderr.WriteLineAsync ().ConfigureAwait (false); + stderr.WriteLine (); } - await stderr.WriteLineAsync (e.Data).ConfigureAwait (false); + stderr.WriteLine (e.Data); stdErrInitialized = true; } catch (Exception ex) { From 53fa35429a70919b91b484dc3233873982908825 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 11:50:43 -0600 Subject: [PATCH 31/58] clean up around extra line --- .../Mono.TextTemplating.CodeCompilation/ProcessUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs index 1a36b7e..00ad60e 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/ProcessUtils.cs @@ -86,7 +86,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdOutInitialized) { stdout.WriteLine (); } - stdout.WriteLine (e.Data); + stdout.Write (e.Data); stdOutInitialized = true; } catch (Exception ex) { @@ -113,7 +113,7 @@ public static Task StartProcess (ProcessStartInfo psi, TextWriter stdout, T if (stdErrInitialized) { stderr.WriteLine (); } - stderr.WriteLine (e.Data); + stderr.Write (e.Data); stdErrInitialized = true; } catch (Exception ex) { From 09ec3885b1e186d159c7d34cb2451fdc79ea0075 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 12:19:31 -0600 Subject: [PATCH 32/58] added a delimeter for the error logging --- .../Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index 16bb226..be566c2 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -124,6 +124,7 @@ public override async Task CompileFile (CodeCompilerArgument if (log != null) { log.WriteLine($"{psi.FileName} {psi.Arguments}"); + log.WriteLine ("-------------------------------------------------------------------------------"); } using (var stdout = new StringWriter (new StringBuilder(), CultureInfo.CurrentCulture)) @@ -160,6 +161,7 @@ void ConsumeOutput (string s) ConsumeOutput (stderr.ToString ()); if (log != null) { + log.WriteLine ("-------------------------------------------------------------------------------"); log.WriteLine ($"{psi.FileName} {psi.Arguments}"); } From 87026b24338ed5a93b4d6a595f19a26651c46cc8 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 12:23:47 -0600 Subject: [PATCH 33/58] no message --- .../Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs index be566c2..f2809c4 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CscCodeCompiler.cs @@ -161,7 +161,8 @@ void ConsumeOutput (string s) ConsumeOutput (stderr.ToString ()); if (log != null) { - log.WriteLine ("-------------------------------------------------------------------------------"); + log.WriteLine (); + log.WriteLine (); log.WriteLine ($"{psi.FileName} {psi.Arguments}"); } From 92960e0b0a586eb6a3894942f4a3650c5d5c9950 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 14:01:38 -0600 Subject: [PATCH 34/58] added the ability to configure the runtime for any template runner that understands netstandard 2.0 and 4.5 --- .../RuntimeInfo.cs | 53 ++++++++++--------- .../Mono.TextTemplating/TemplateSettings.cs | 4 ++ .../Mono.TextTemplating/TemplatingEngine.cs | 12 +++-- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs index d64b5d6..b9615ec 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs @@ -30,8 +30,9 @@ namespace Mono.TextTemplating.CodeCompilation { - enum RuntimeKind + public enum RuntimeKind { + Default = 0, NetCore, NetFramework, Mono @@ -49,18 +50,18 @@ class RuntimeInfo public string CscPath { get; private set; } public bool IsValid => Error == null; - public static RuntimeInfo GetRuntime () + public static RuntimeInfo GetRuntime (RuntimeKind kind = RuntimeKind.Default) { var monoFx = GetMonoRuntime (); - if (monoFx.IsValid) { + if (monoFx.IsValid && (monoFx.Kind == kind || kind == RuntimeKind.Default)) { return monoFx; } var netFx = GetNetFrameworkRuntime (); - if (netFx.IsValid) { + if (netFx.IsValid && (netFx.Kind == kind || kind == RuntimeKind.Default)) { return netFx; } var coreFx = GetDotNetCoreRuntime (); - if (coreFx.IsValid) { + if (coreFx.IsValid && (coreFx.Kind == kind || kind == RuntimeKind.Default)) { return coreFx; } return FromError (RuntimeKind.Mono, "Could not find any valid runtime" ); @@ -97,6 +98,27 @@ public static RuntimeInfo GetNetFrameworkRuntime () }; } + public static RuntimeInfo GetDotNetCoreRuntime () + { + var dotnetRoot = FindDotNetRoot (); + if (dotnetRoot == null) { + return FromError (RuntimeKind.NetCore, "Could not find .NET Core installation"); + } + + string MakeCscPath (string d) => Path.Combine (d, "Roslyn", "bincore", "csc.dll"); + var sdkDir = FindHighestVersionedDirectory (Path.Combine (dotnetRoot, "sdk"), d => File.Exists (MakeCscPath (d))); + if (sdkDir == null) { + return FromError (RuntimeKind.NetCore, "Could not find csc.dll in any .NET Core SDK"); + } + + var runtimeDir = FindHighestVersionedDirectory (Path.Combine (dotnetRoot, "shared", "Microsoft.NETCore.App"), d => File.Exists (Path.Combine (d, "System.Runtime.dll"))); + if (runtimeDir == null) { + return FromError (RuntimeKind.NetCore, "Could not find System.Runtime.dll in any .NET shared runtime"); + } + + return new RuntimeInfo (RuntimeKind.NetCore) { RuntimeDir = runtimeDir, CscPath = MakeCscPath (sdkDir) }; + } + static string FindDotNetRoot () { string dotnetRoot; @@ -144,25 +166,6 @@ static string FindHighestVersionedDirectory (string parentFolder, Func Path.Combine (d, "Roslyn", "bincore", "csc.dll"); - var sdkDir = FindHighestVersionedDirectory (Path.Combine (dotnetRoot, "sdk"), d => File.Exists (MakeCscPath (d))); - if (sdkDir == null) { - return FromError (RuntimeKind.NetCore, "Could not find csc.dll in any .NET Core SDK" ); - } - - var runtimeDir = FindHighestVersionedDirectory (Path.Combine (dotnetRoot, "shared", "Microsoft.NETCore.App"), d => File.Exists (Path.Combine (d, "System.Runtime.dll"))); - if (runtimeDir == null) { - return FromError (RuntimeKind.NetCore, "Could not find System.Runtime.dll in any .NET shared runtime" ); - } - - return new RuntimeInfo (RuntimeKind.NetCore) { RuntimeDir = runtimeDir, CscPath = MakeCscPath (sdkDir) }; - } + } } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs index b7a42ca..7aa9f3f 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs @@ -31,6 +31,9 @@ using System.IO; using System.Reflection; using System.Threading; +#if !NET35 +using Mono.TextTemplating.CodeCompilation; +#endif namespace Mono.TextTemplating { @@ -50,6 +53,7 @@ public TemplateSettings () public bool CachedTemplates { get; set; } #if !NET35 public CancellationToken CancellationToken { get; set; } + public RuntimeKind RuntimeKind { get; set; } #endif public TextWriter Log { get; set; } public string Inherits { get; set; } diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 17d7235..d7e6473 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -60,10 +60,10 @@ internal void SetCompilerFunc (Func cr createCompilerFunc = createCompiler; } - CodeCompilation.CodeCompiler GetOrCreateCompiler () + CodeCompilation.CodeCompiler GetOrCreateCompiler (RuntimeKind kind = RuntimeKind.Default) { if (cachedCompiler == null) { - var runtime = RuntimeInfo.GetRuntime (); + var runtime = RuntimeInfo.GetRuntime (kind); if (runtime.Error != null) { throw new Exception (runtime.Error); } @@ -238,7 +238,7 @@ CompilerResults CompileCode (IEnumerable references, TemplateSettings se } // this may throw, so do it before writing source files - var compiler = GetOrCreateCompiler (); + var compiler = GetOrCreateCompiler (settings.RuntimeKind); var tempFolder = Path.GetTempFileName (); File.Delete (tempFolder); @@ -500,8 +500,14 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars else { settings.CancellationToken = CancellationToken.None; } + + if ((host.GetHostOption (nameof (TemplateSettings.RuntimeKind)) ?? RuntimeKind.Default) is RuntimeKind runtimeKind) { + settings.RuntimeKind = runtimeKind; + } #endif + + return settings; } From 5d5c176a31297ed939105a8a53a1f52f010d6b27 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 18:21:02 -0600 Subject: [PATCH 35/58] System.Private.CoreLib is a bad image --- .../Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs index 5e3145f..c662375 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs @@ -47,7 +47,7 @@ IEnumerable GetImplicitReferences () yield return "System.Runtime.dll"; //because we're referencing the impl not the ref asms, we end up //having to ref internals - yield return "System.Private.CoreLib.dll"; + //yield return "System.Private.CoreLib.dll"; } } From 9d422352d5c5b0c11d8e2277b4e7fb467ec043b7 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 18:32:22 -0600 Subject: [PATCH 36/58] Revert "System.Private.CoreLib is a bad image" This reverts commit 5d5c176a31297ed939105a8a53a1f52f010d6b27. --- .../Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs index c662375..5e3145f 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs @@ -47,7 +47,7 @@ IEnumerable GetImplicitReferences () yield return "System.Runtime.dll"; //because we're referencing the impl not the ref asms, we end up //having to ref internals - //yield return "System.Private.CoreLib.dll"; + yield return "System.Private.CoreLib.dll"; } } From 2a4b59931785e0653ccb228773354d40903476b1 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 21:19:09 -0600 Subject: [PATCH 37/58] best effort to detect encoding --- .../EncodingHelper.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs index cc7270f..8d771e7 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/EncodingHelper.cs @@ -26,6 +26,7 @@ using System; using System.Text; +using System.IO; namespace Mono.VisualStudio.TextTemplating { @@ -33,7 +34,19 @@ public static class EncodingHelper { public static Encoding GetEncoding (string filePath) { - throw new NotImplementedException (); + var bom = new byte[4]; + using (FileStream stream = File.OpenRead (filePath)) { + stream.Read (bom, 0, bom.Length); + } + + if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) { return Encoding.UTF7; } + if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) { return Encoding.UTF8; } + if (bom[0] == 0xff && bom[1] == 0xfe && bom[2] == 0 && bom[3] == 0) { return Encoding.UTF32; } //UTF-32LE + if (bom[0] == 0xff && bom[1] == 0xfe) { return Encoding.Unicode; } //UTF-16LE + if (bom[0] == 0xfe && bom[1] == 0xff) { return Encoding.BigEndianUnicode; } //UTF-16BE + if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) { return new UTF32Encoding (true, true); } //UTF-32BE + + return null; } } } From b8a7f47112ffbfa19fc401d513732e591cb3fa8d Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 22:21:02 -0600 Subject: [PATCH 38/58] renamed the debug interfaces to process interfaces, the new approach app domain is the process. --- .../DebugTextTemplateEngine.cs | 44 +++++++++----- ...entArgs.cs => ProcessTemplateEventArgs.cs} | 2 +- .../TransformationRunFactory.cs | 8 +-- .../TransformationRunner.cs | 58 ++++++++++++------- .../Interfaces.cs | 22 +++---- 5 files changed, 83 insertions(+), 51 deletions(-) rename Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/{DebugTemplateEventArgs.cs => ProcessTemplateEventArgs.cs} (75%) diff --git a/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs index ad152a6..235b68b 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/DebugTextTemplateEngine.cs @@ -11,9 +11,9 @@ namespace Mono.TextTemplating using System.Threading; public partial class TemplatingEngine - : IDebugTextTemplatingEngine + : IProcessTextTemplatingEngine { - public IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory) + public IProcessTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false) { if (content == null) { throw new ArgumentNullException (nameof(content)); @@ -33,7 +33,7 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe ParsedTemplate pt = ParsedTemplate.FromText (content, host); - IDebugTransformationRun run = null; + IProcessTransformationRun run = null; try { if (pt.Errors.HasErrors) { @@ -41,7 +41,7 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe } TemplateSettings settings = GetSettings (host, pt); - settings.Debug = true; + settings.Debug = debugging; run = CompileAndPrepareRun (pt, content, host, runFactory, settings); } catch(Exception ex) { @@ -57,11 +57,27 @@ public IDebugTransformationRun PrepareTransformationRun (string content, ITextTe return run; } - protected virtual IDebugTransformationRun CompileAndPrepareRun (ParsedTemplate template, string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory, TemplateSettings settings) + protected virtual IProcessTransformationRun CompileAndPrepareRun (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, TemplateSettings settings) { TransformationRunner runner = null; bool success = false; + if (pt == null) { + throw new ArgumentNullException (nameof (pt)); + } + + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + + if (runFactory == null) { + throw new ArgumentNullException (nameof (runFactory)); + } + + if (settings == null) { + throw new ArgumentNullException (nameof (settings)); + } + Assembly ResolveReferencedAssemblies (object sender, ResolveEventArgs args) { AssemblyName asmName = new AssemblyName (args.Name); @@ -81,7 +97,7 @@ Assembly ResolveReferencedAssemblies (object sender, ResolveEventArgs args) try { try { - if (runFactory.CreateTransformationRun (typeof (TransformationRunner), template, new ResolveEventHandler(ResolveReferencedAssemblies)) is TransformationRunner theRunner) { + if (runFactory.CreateTransformationRun (typeof (TransformationRunner), pt, new ResolveEventHandler(ResolveReferencedAssemblies)) is TransformationRunner theRunner) { runner = theRunner; } } @@ -91,15 +107,15 @@ Assembly ResolveReferencedAssemblies (object sender, ResolveEventArgs args) } } if (runner != null && !runner.Errors.HasErrors) { - ProcessReferences (host, template, settings); - if (!template.Errors.HasErrors) { - runner.PreLoadAssemblies (settings.Assemblies); - + ProcessReferences (host, pt, settings); + if (!pt.Errors.HasErrors) { + //with app domains dissappearing we may not be able to pre load anything + //runner.PreLoadAssemblies (settings.Assemblies); try { - success = runner.PrepareTransformation (template, content, settings.HostSpecific ? host : null, settings); + success = runner.PrepareTransformation (pt, content, settings.HostSpecific ? host : null, settings); } catch (SerializationException) { - template.LogError (VsTemplatingErrorResources.SessionHostMarshalError, new Location (host.TemplateFile, -1, -1)); + pt.LogError (VsTemplatingErrorResources.SessionHostMarshalError, new Location (host.TemplateFile, -1, -1)); throw; } } @@ -109,11 +125,11 @@ Assembly ResolveReferencedAssemblies (object sender, ResolveEventArgs args) if (IsCriticalException (ex)) { throw; } - template.LogError (ex.ToString (), new Location (host.TemplateFile, -1, -1)); + pt.LogError (ex.ToString (), new Location (host.TemplateFile, -1, -1)); } finally { if (runner != null) { - template.Errors.AddRange (runner.Errors); + pt.Errors.AddRange (runner.Errors); runner.ClearErrors (); } } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/ProcessTemplateEventArgs.cs similarity index 75% rename from Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs rename to Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/ProcessTemplateEventArgs.cs index e0c2d3e..0406257 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/DebugTemplateEventArgs.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/ProcessTemplateEventArgs.cs @@ -2,7 +2,7 @@ namespace Mono.VisualStudio.TextTemplating.VSHost { - public class DebugTemplateEventArgs : EventArgs + public class ProcessTemplateEventArgs : EventArgs { public string TemplateOutput { get; set; } public bool Succeeded { get; set; } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs index 54dbc5f..7237563 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs @@ -7,7 +7,7 @@ public abstract class TransformationRunFactory : #if FEATURE_APPDOMAINS MarshalByRefObject, #endif - IDebugTransformationRunFactory + IProcessTransformationRunFactory { public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); @@ -15,15 +15,15 @@ public abstract class TransformationRunFactory : /// Create the transformation runner /// /// - /// + /// /// /// /// /// abstracted, just because I am uncertain on how this would run on multiple platforms. Also visual studio classes may be required to pull of correctly. /// - public abstract IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); + public abstract IProcessTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate pt, ResolveEventHandler resolver); - public abstract string RunTransformation (IDebugTransformationRun transformationRun); + public abstract string RunTransformation (IProcessTransformationRun transformationRun); #if FEATURE_APPDOMAINS public override object InitializeLifetimeService () { diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs index ac712b4..18b7b53 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs @@ -11,7 +11,7 @@ public class TransformationRunner : #if FEATURE_APPDOMAINS MarshalByRefObject, #endif - IDebugTransformationRun + IProcessTransformationRun { CompiledTemplate compiledTemplate; TemplateSettings settings; @@ -54,7 +54,7 @@ public virtual string PerformTransformation () return errorOutput; } - PropertyInfo GetDerivedProperty (Type transformType, string propertyName) + static PropertyInfo GetDerivedProperty (Type transformType, string propertyName) { while(transformType != typeof(object) && transformType != null) { PropertyInfo property = transformType.GetProperty (propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); @@ -68,6 +68,19 @@ PropertyInfo GetDerivedProperty (Type transformType, string propertyName) protected virtual object CreateTextTransformation(TemplateSettings settings, ITextTemplatingEngineHost host, Assembly assembly) { object success = null; + + if (settings == null) { + throw new ArgumentNullException (nameof (settings)); + } + + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + + if (assembly == null) { + throw new ArgumentNullException (nameof (assembly)); + } + try { Type type; @@ -128,7 +141,7 @@ protected virtual object CreateTextTransformation(TemplateSettings settings, ITe return success; } - public virtual bool PrepareTransformation (ParsedTemplate template, string content, ITextTemplatingEngineHost host, TemplateSettings settings) + public virtual bool PrepareTransformation (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings) { this.host = host ?? throw new ArgumentNullException (nameof (host)); this.settings = settings ?? throw new ArgumentNullException (nameof (settings)); @@ -136,7 +149,7 @@ public virtual bool PrepareTransformation (ParsedTemplate template, string conte try { this.settings.Assemblies.Add (base.GetType ().Assembly.Location); this.settings.Assemblies.Add (typeof (ITextTemplatingEngineHost).Assembly.Location); - this.compiledTemplate = LocateAssembly (template, content); + this.compiledTemplate = LocateAssembly (pt, content); } catch(Exception ex) { if (TemplatingEngine.IsCriticalException (ex)) { @@ -147,7 +160,7 @@ public virtual bool PrepareTransformation (ParsedTemplate template, string conte return this.compiledTemplate != null; } - CompiledTemplate LocateAssembly (ParsedTemplate template, string content) + CompiledTemplate LocateAssembly (ParsedTemplate pt, string content) { CompiledTemplate compiledTemplate = null; @@ -155,7 +168,7 @@ CompiledTemplate LocateAssembly (ParsedTemplate template, string content) compiledTemplate = CompiledTemplateCache.Find (settings.GetFullName ()); } if (compiledTemplate == null) { - compiledTemplate = Compile (template, content); + compiledTemplate = Compile (pt, content); if (settings.CachedTemplates && compiledTemplate != null) { CompiledTemplateCache.Insert (settings.GetFullName (), compiledTemplate); } @@ -163,30 +176,33 @@ CompiledTemplate LocateAssembly (ParsedTemplate template, string content) return compiledTemplate; } - CompiledTemplate Compile (ParsedTemplate template, string content) + CompiledTemplate Compile (ParsedTemplate pt, string content) { CompiledTemplate compiledTemplate = null; if (host is ITextTemplatingComponents Component && - Component.Engine is IDebugTextTemplatingEngine engine) { - compiledTemplate = engine.CompileTemplate (template, content, host, settings); - // do we want to dispose the appdomain resolver in compiled template in favor of the transformation runner? - //compiledTemplate?.Dispose (); + Component.Engine is IProcessTextTemplatingEngine engine) { + compiledTemplate = engine.CompileTemplate (pt, content, host, settings); + + if (settings.CachedTemplates) { + // we will resolve loading of assemblies through the run factory for cached templates + compiledTemplate?.Dispose (); + } } return compiledTemplate; } - public virtual void PreLoadAssemblies (IEnumerable assemblies) - { - try { - //TODO:: investigate preloading assemblies with the AssemblyLoadContext - }catch(Exception ex) { - if (TemplatingEngine.IsCriticalException (ex)) { - throw; - } - } - } + //public virtual void PreLoadAssemblies (IEnumerable assemblies) + //{ + // try { + // //TODO:: investigate preloading assemblies with the AssemblyLoadContext + // }catch(Exception ex) { + // if (TemplatingEngine.IsCriticalException (ex)) { + // throw; + // } + // } + //} protected Assembly AttemptAssemblyLoad(AssemblyName assembly) { diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 507885d..5362df1 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -51,17 +51,17 @@ public interface ITextTemplatingService : ITextTemplatingEngineHost , ITextTemplatingSessionHost , ITextTemplatingComponents - , IDebugTextTemplating + , IProcessTextTemplating , ITextTemplating { - new IDebugTextTemplatingEngine Engine { get; } + new IProcessTextTemplatingEngine Engine { get; } } - public interface IDebugTextTemplating + public interface IProcessTextTemplating : ITextTemplating { - event EventHandler DebugCompleted; - void DebugTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy); + event EventHandler TransformProcessCompleted; + void ProcessTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); } public interface ITextTemplating @@ -72,24 +72,24 @@ public interface ITextTemplating string ProcessTemplate (string inputFile, string content, ITextTemplatingCallback callback = null, object hierarchy = null); } - public interface IDebugTransformationRun + public interface IProcessTransformationRun { string PerformTransformation (); CompilerErrorCollection Errors { get; } } - public interface IDebugTransformationRunFactory + public interface IProcessTransformationRunFactory { - IDebugTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate template, ResolveEventHandler resolver); + IProcessTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate pt, ResolveEventHandler resolver); - string RunTransformation (IDebugTransformationRun transformationRun); + string RunTransformation (IProcessTransformationRun transformationRun); } - public interface IDebugTextTemplatingEngine + public interface IProcessTextTemplatingEngine : ITextTemplatingEngine { - IDebugTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IDebugTransformationRunFactory runFactory); + IProcessTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false); CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); } From 9c8e762ec7887490972ba1101b12880a82ea2658 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Fri, 31 Jul 2020 22:31:13 -0600 Subject: [PATCH 39/58] will work on makeing the process work asynchronously with visual studio --- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 5362df1..176df71 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -29,9 +29,8 @@ using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; -using System.Reflection; -#if NETSTANDARD -using System.Runtime.Loader; +#if NET45 || NETSTANDARD +using System.Threading.Tasks; #endif using System.Runtime.Serialization; using System.Text; @@ -61,7 +60,11 @@ public interface IProcessTextTemplating : ITextTemplating { event EventHandler TransformProcessCompleted; - void ProcessTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); +#if NETSTANDARD || NET45 + Task ProcessTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); +#elif NET35 + void ProcessTemplate (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); +#endif } public interface ITextTemplating From 24315768ae54a76a96bc115cb58f4ee621b63887 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 10:56:32 -0600 Subject: [PATCH 40/58] temp directory was not being cleaned up and was spamming folder creation --- Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index d7e6473..81882f5 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -283,7 +283,9 @@ CompilerResults CompileCode (IEnumerable references, TemplateSettings se } if (!args.Debug) { - r.TempFiles.Delete (); + if (r.TempFiles is IDisposable disposable) { + disposable.Dispose (); + } } return r; From 203095d1f88e38855d41d0dab350d187433e692a Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 11:22:30 -0600 Subject: [PATCH 41/58] address code cop warnings --- .../Mono.TextTemplating/TemplatingEngine.cs | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 81882f5..7bb2cc9 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -315,6 +315,16 @@ static CompilerResults CompileCode (IEnumerable references, TemplateSett protected static string[] ProcessReferences (ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings) { + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + if (pt == null) { + throw new ArgumentNullException (nameof (pt)); + } + if (settings == null) { + throw new ArgumentNullException (nameof (settings)); + } + var resolved = new Dictionary (); foreach (string assem in settings.Assemblies.Union (host.StandardAssemblyReferences)) { @@ -337,12 +347,21 @@ protected static string[] ProcessReferences (ITextTemplatingEngineHost host, Par public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, ParsedTemplate pt) { + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + if (pt == null) { + throw new ArgumentNullException (nameof (pt)); + } + var settings = new TemplateSettings (); bool relativeLinePragmas = host.GetHostOption (nameof (TemplateSettings.UseRelativeLinePragmas)) as bool? ?? false; foreach (Directive dt in pt.Directives) { +#pragma warning disable CA1308 // Normalize strings to uppercase switch (dt.Name.ToLowerInvariant ()) { +#pragma warning restore CA1308 // Normalize strings to uppercase case "template": string val = dt.Extract ("language"); if (val != null) @@ -522,6 +541,10 @@ public static string IndentSnippetText (CodeDomProvider provider, string text, s public static string IndentSnippetText (string text, string indent) { + if (text == null) { + throw new ArgumentNullException (nameof (text)); + } + var builder = new StringBuilder (text.Length); builder.Append (indent); int lastNewline = 0; @@ -563,11 +586,13 @@ static void AddDirective (TemplateSettings settings, ITextTemplatingEngineHost h processor = (IDirectiveProcessor)Activator.CreateInstance (processorType); break; } - if (!processor.IsDirectiveSupported (directive.Name)) - throw new InvalidOperationException ("Directive processor '" + processorName + "' does not support directive '" + directive.Name + "'"); - - settings.DirectiveProcessors [processorName] = processor; } + + if (!processor.IsDirectiveSupported (directive.Name)) + throw new InvalidOperationException ("Directive processor '" + processorName + "' does not support directive '" + directive.Name + "'"); + + settings.DirectiveProcessors[processorName] = processor; + settings.CustomDirectives.Add (new CustomDirective (processorName, directive)); } @@ -617,6 +642,18 @@ static void ProcessDirectives (string content, ParsedTemplate pt, TemplateSettin public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost host, string content, ParsedTemplate pt, TemplateSettings settings) { + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + + if (pt == null) { + throw new ArgumentNullException (nameof (pt)); + } + + if (settings == null) { + throw new ArgumentNullException (nameof (settings)); + } + ProcessDirectives (content, pt, settings); string baseDirectory = Path.GetDirectoryName (host.TemplateFile); @@ -648,7 +685,7 @@ public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost hos //prep the transform method var transformMeth = new CodeMemberMethod { Name = "TransformText", - ReturnType = new CodeTypeReference (typeof (String)), + ReturnType = new CodeTypeReference (typeof (string)), Attributes = MemberAttributes.Public, }; if (!settings.IncludePreprocessingHelpers) @@ -863,6 +900,10 @@ static void GenerateInitializationMethod (CodeTypeDeclaration type, TemplateSett static void GenerateProcessingHelpers (CodeTypeDeclaration type, TemplateSettings settings) { + if (settings == null) { + throw new ArgumentNullException (nameof (settings)); + } + var thisRef = new CodeThisReferenceExpression (); var sbTypeRef = TypeRef (); @@ -1256,9 +1297,18 @@ static CodeMemberField PrivateField (CodeTypeReference typeRef, string name) /// public static void GenerateCodeFromMembers (CodeDomProvider provider, CodeGeneratorOptions options, StringWriter sw, IEnumerable members) { + if (provider == null) { + throw new ArgumentNullException (nameof (provider)); + } + + if (members == null) { + throw new ArgumentNullException (nameof (members)); + } + if (!useMonoHack) { - foreach (CodeTypeMember member in members) + foreach (CodeTypeMember member in members) { provider.GenerateCodeFromMember (member, sw, options); + } return; } From 9db4f27eb16a8730aec571a71bec87f7c158faef Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 11:27:04 -0600 Subject: [PATCH 42/58] no message --- .../Mono.TextTemplating/TemplatingEngine.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 7bb2cc9..022e5fc 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -576,16 +576,20 @@ public static string IndentSnippetText (string text, string indent) static void AddDirective (TemplateSettings settings, ITextTemplatingEngineHost host, string processorName, Directive directive) { - if (!settings.DirectiveProcessors.TryGetValue (processorName, out IDirectiveProcessor processor)) { - switch (processorName) { - case "ParameterDirectiveProcessor": - processor = new ParameterDirectiveProcessor (); - break; - default: - Type processorType = host.ResolveDirectiveProcessor (processorName); - processor = (IDirectiveProcessor)Activator.CreateInstance (processorType); - break; - } + if (settings.DirectiveProcessors.ContainsKey(processorName)) { + return; + } + + IDirectiveProcessor processor; + + switch (processorName) { + case "ParameterDirectiveProcessor": + processor = new ParameterDirectiveProcessor (); + break; + default: + Type processorType = host.ResolveDirectiveProcessor (processorName); + processor = (IDirectiveProcessor)Activator.CreateInstance (processorType); + break; } if (!processor.IsDirectiveSupported (directive.Name)) From 0803d38e021555be5fae8ad4951e61bef701b062 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 11:28:29 -0600 Subject: [PATCH 43/58] no message --- Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 022e5fc..5d29c05 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -35,6 +35,7 @@ using System.Threading; using Microsoft.CSharp; using Mono.VisualStudio.TextTemplating; +using System.Globalization; #if FEATURE_ROSLYN using Mono.TextTemplating.CodeCompilation; #endif @@ -483,7 +484,7 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars if (settings.Name == null) settings.Name = "GeneratedTextTransformation"; if (settings.Namespace == null) - settings.Namespace = string.Format (typeof (TextTransformation).Namespace + "{0:x}", new Random ().Next ()); + settings.Namespace = string.Format (CultureInfo.InvariantCulture, typeof (TextTransformation).Namespace + "{0:x}", new Random ().Next ()); //resolve the CodeDOM provider if (String.IsNullOrEmpty (settings.Language)) { From d43c621d05efd6451e76d25bc31a8629a449c646 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 11:38:44 -0600 Subject: [PATCH 44/58] when debugging I want the temp files to stick around --- Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 5d29c05..27f33a5 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -288,6 +288,9 @@ CompilerResults CompileCode (IEnumerable references, TemplateSettings se disposable.Dispose (); } } + else { + r.TempFiles.KeepFiles = args.Debug; + } return r; } From d4cd16d114f89073721e2e4df14f39666923c2b8 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 11:59:50 -0600 Subject: [PATCH 45/58] #87 --- .../Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs index 5e3145f..fa99484 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs @@ -42,6 +42,8 @@ IEnumerable GetImplicitReferences () { yield return "mscorlib.dll"; yield return "netstandard.dll"; + // issue #87 because CompilerErrorCollection is referenced by the TextTransformation base class + yield return "System.CodeDom.dll"; if (runtime.Kind == RuntimeKind.NetCore) { yield return "System.Runtime.dll"; From 2a18adf7fefee99212ca9971b63c7764fb96756f Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 12:22:43 -0600 Subject: [PATCH 46/58] no message --- Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs index b5f841d..63cb9a7 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs @@ -66,6 +66,10 @@ public IEnumerable Content { public static ParsedTemplate FromText (string content, ITextTemplatingEngineHost host) { + if (host == null) { + throw new ArgumentNullException (nameof (host)); + } + var template = new ParsedTemplate (host.TemplateFile); try { template.Parse (host, new Tokeniser (host.TemplateFile, content)); From 247402a0ce99025d06507ee36eecd240726485e0 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 13:06:19 -0600 Subject: [PATCH 47/58] #87 --- .../AssemblyResolver.cs | 4 +-- .../Mono.TextTemplating/TemplatingEngine.cs | 2 ++ .../TextTransformation.cs | 28 +++++++++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs index fa99484..19648d2 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/AssemblyResolver.cs @@ -42,9 +42,7 @@ IEnumerable GetImplicitReferences () { yield return "mscorlib.dll"; yield return "netstandard.dll"; - // issue #87 because CompilerErrorCollection is referenced by the TextTransformation base class - yield return "System.CodeDom.dll"; - + if (runtime.Kind == RuntimeKind.NetCore) { yield return "System.Runtime.dll"; //because we're referencing the impl not the ref asms, we end up diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 27f33a5..559efcc 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -685,6 +685,8 @@ public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost hos type.BaseTypes.Add (new CodeTypeReference (settings.Inherits)); } else if (!settings.IncludePreprocessingHelpers) { type.BaseTypes.Add (TypeRef ()); + // issue #87 because CompilerErrorCollection is referenced by the TextTransformation base class + TextTransformation.AddRequiredReferences (settings.Assemblies); } else { type.BaseTypes.Add (new CodeTypeReference (settings.Name + "Base")); } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs index b1e2596..39bdb9e 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs @@ -27,6 +27,7 @@ using System; using System.CodeDom.Compiler; using System.Collections.Generic; +using System.Globalization; using System.Text; namespace Mono.VisualStudio.TextTemplating @@ -48,11 +49,13 @@ public virtual void Initialize () } public abstract string TransformText (); - + +#pragma warning disable CA2227 // Collection properties should be read only public virtual IDictionary Session { get; set; } - +#pragma warning restore CA2227 // Collection properties should be read only + #region Errors - + public void Error (string message) { Errors.Add (new CompilerError ("", 0, 0, "", message)); @@ -85,8 +88,9 @@ Stack Indents { public string PopIndent () { - if (Indents.Count == 0) + if (Indents.Count == 0) { return ""; + } int lastPos = currentIndent.Length - Indents.Pop (); string last = currentIndent.Substring (lastPos); currentIndent = currentIndent.Substring (0, lastPos); @@ -95,8 +99,9 @@ public string PopIndent () public void PushIndent (string indent) { - if (indent == null) - throw new ArgumentNullException ("indent"); + if (indent == null) { + throw new ArgumentNullException (nameof (indent)); + } Indents.Push (indent.Length); currentIndent += indent; } @@ -176,7 +181,7 @@ public void Write (string textToAppend) public void Write (string format, params object[] args) { - Write (string.Format (format, args)); + Write (string.Format (CultureInfo.InvariantCulture, format, args)); } public void WriteLine (string textToAppend) @@ -188,7 +193,7 @@ public void WriteLine (string textToAppend) public void WriteLine (string format, params object[] args) { - WriteLine (string.Format (format, args)); + WriteLine (string.Format (CultureInfo.InvariantCulture, format, args)); } #endregion @@ -209,7 +214,12 @@ protected virtual void Dispose (bool disposing) { Dispose (false); } - + + internal static void AddRequiredReferences (HashSet assemblies) + { + assemblies.Add (typeof (CompilerErrorCollection).Assembly.Location); + } + #endregion } From a84ba7388a6c90a244a4c8e6fe50b3f4926b06e1 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 13:13:02 -0600 Subject: [PATCH 48/58] #87 --- .../TextTransformation.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs index 39bdb9e..322c9c2 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/TextTransformation.cs @@ -28,6 +28,7 @@ using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Text; namespace Mono.VisualStudio.TextTemplating @@ -215,9 +216,17 @@ protected virtual void Dispose (bool disposing) Dispose (false); } - internal static void AddRequiredReferences (HashSet assemblies) + internal static void AddRequiredReferences (IList standardAssemblies) { - assemblies.Add (typeof (CompilerErrorCollection).Assembly.Location); + if (standardAssemblies == null) { + throw new ArgumentNullException (nameof (standardAssemblies)); + } + + string codeDom = typeof (CompilerErrorCollection).Assembly.Location; + + if (!standardAssemblies.Any (x => x.Equals (codeDom, StringComparison.CurrentCultureIgnoreCase))) { + standardAssemblies.Add (codeDom); + } } #endregion From 6a58f710674143f239d59bbbb49e469c75628485 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 13:13:16 -0600 Subject: [PATCH 49/58] no message --- Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 559efcc..51756c2 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -686,7 +686,7 @@ public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost hos } else if (!settings.IncludePreprocessingHelpers) { type.BaseTypes.Add (TypeRef ()); // issue #87 because CompilerErrorCollection is referenced by the TextTransformation base class - TextTransformation.AddRequiredReferences (settings.Assemblies); + TextTransformation.AddRequiredReferences (host.StandardAssemblyReferences); } else { type.BaseTypes.Add (new CodeTypeReference (settings.Name + "Base")); } From faf14e4391ababd02374d46974e57b21acb0a557 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 13:46:11 -0600 Subject: [PATCH 50/58] #87 turns out building template in .net framework to run in the net core runtime, one need to account for the runtime --- .../Mono.TextTemplating/TemplatingEngine.cs | 2 +- .../DirectiveProcessor.cs | 16 +++++++--- .../Interfaces.cs | 2 +- .../ParameterDirectiveProcessor.cs | 27 +++++++++++----- .../RequiresProvidesDirectiveProcessor.cs | 31 +++++++++---------- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index 51756c2..960166b 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -465,7 +465,7 @@ public static TemplateSettings GetSettings (ITextTemplatingEngineHost host, Pars //initialize the custom processors foreach (var kv in settings.DirectiveProcessors) { - kv.Value.Initialize (host); + kv.Value.Initialize (host, settings); IRecognizeHostSpecific hs; if (settings.HostSpecific || ( diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs index 14afe5c..93e5950 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/DirectiveProcessor.cs @@ -28,27 +28,33 @@ using System.Collections.Generic; using System.CodeDom.Compiler; using System.CodeDom; +using Mono.TextTemplating; namespace Mono.VisualStudio.TextTemplating { public abstract class DirectiveProcessor : IDirectiveProcessor { + protected ITextTemplatingEngineHost Host { get; private set; } + protected TemplateSettings Settings { get; private set; } + CompilerErrorCollection errors; protected DirectiveProcessor () { } - public virtual void Initialize (ITextTemplatingEngineHost host) + public virtual void Initialize (ITextTemplatingEngineHost host, TemplateSettings settings) { - if (host == null) - throw new ArgumentNullException ("host"); + this.Host = host ?? throw new ArgumentNullException (nameof (host)); + this.Settings = settings ?? throw new ArgumentNullException (nameof (settings)); } public virtual void StartProcessingRun (CodeDomProvider languageProvider, string templateContents, CompilerErrorCollection errors) { - if (languageProvider == null) - throw new ArgumentNullException ("languageProvider"); + if (languageProvider == null) { + throw new ArgumentNullException (nameof (languageProvider)); + } + this.errors = errors; } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 176df71..023c9e3 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -177,7 +177,7 @@ public interface IDirectiveProcessor string GetPreInitializationCodeForProcessingRun (); string[] GetReferencesForProcessingRun (); CodeAttributeDeclarationCollection GetTemplateClassCustomAttributes (); //TODO - void Initialize (ITextTemplatingEngineHost host); + void Initialize (ITextTemplatingEngineHost host, TemplateSettings settings); bool IsDirectiveSupported (string directiveName); void ProcessDirective (string directiveName, IDictionary arguments); void SetProcessingRunIsHostSpecific (bool hostSpecific); diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs index afa280f..b5a31b4 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs @@ -29,6 +29,9 @@ using System.Collections.Generic; using System.IO; using Mono.TextTemplating; +#if NET45 +using Mono.TextTemplating.CodeCompilation; +#endif namespace Mono.VisualStudio.TextTemplating { @@ -159,7 +162,9 @@ public override void ProcessDirective (string directiveName, IDictionary providesDictionary); @@ -120,9 +120,9 @@ void AssertNotProcessing () if (isInProcessingRun) throw new InvalidOperationException (); } - + //FIXME: handle escaping - IEnumerable> ParseArgs (string args) + static IEnumerable> ParseArgs (string args) { var pairs = args.Split (';'); foreach (var p in pairs) { @@ -135,11 +135,12 @@ IEnumerable> ParseArgs (string args) public override void ProcessDirective (string directiveName, IDictionary arguments) { - if (directiveName == null) - throw new ArgumentNullException ("directiveName"); - if (arguments == null) - throw new ArgumentNullException ("arguments"); - + if (directiveName == null) { + throw new ArgumentNullException (nameof (directiveName)); + } + if (arguments == null) { + throw new ArgumentNullException (nameof (arguments)); + } var providesDictionary = new Dictionary (); var requiresDictionary = new Dictionary (); @@ -163,7 +164,7 @@ public override void ProcessDirective (string directiveName, IDictionary Date: Sat, 1 Aug 2020 14:32:24 -0600 Subject: [PATCH 51/58] no message --- .../Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs | 4 ++++ .../ParameterDirectiveProcessor.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs index b9615ec..d2ab001 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs @@ -32,10 +32,14 @@ namespace Mono.TextTemplating.CodeCompilation { public enum RuntimeKind { +#if !NET5 Default = 0, NetCore, NetFramework, Mono +#else + Net +#endif } class RuntimeInfo diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs index b5a31b4..d06c287 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs @@ -224,7 +224,7 @@ public override void ProcessDirective (string directiveName, IDictionary Date: Sat, 1 Aug 2020 15:26:00 -0600 Subject: [PATCH 52/58] no message --- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 023c9e3..0364166 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -61,7 +61,7 @@ public interface IProcessTextTemplating { event EventHandler TransformProcessCompleted; #if NETSTANDARD || NET45 - Task ProcessTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); + Task ProcessTemplateAsync (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); #elif NET35 void ProcessTemplate (string inputFilename, string content, ITextTemplatingCallback callback, object hierarchy, bool debugging = false); #endif From 57e4e525b8383e8b65b94a230c25ee10a8a39483 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 20:30:50 -0600 Subject: [PATCH 53/58] no message --- .../Mono.TextTemplating/ParsedTemplate.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs index 63cb9a7..062662b 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/ParsedTemplate.cs @@ -274,6 +274,9 @@ public Location (string fileName, int line, int column) : this() Column = column; Line = line; } + + public Location (string fileName) + : this (fileName, -1, -1) { } public int Line { get; private set; } public int Column { get; private set; } @@ -293,5 +296,25 @@ public bool Equals (Location other) { return other.Line == Line && other.Column == Column && other.FileName == FileName; } + + public override bool Equals (object obj) + { + return obj is Location && Equals ((Location)obj); + } + + public static bool operator == (Location left, Location right) + { + return left.Equals (right); + } + + public static bool operator != (Location left, Location right) + { + return !(left == right); + } + + public override int GetHashCode () + { + return base.GetHashCode (); + } } } From b2778d2114d58d4d3520287b3660a589f4acb451 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 21:23:31 -0600 Subject: [PATCH 54/58] no message --- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 0364166..250e668 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -94,7 +94,8 @@ public interface IProcessTextTemplatingEngine { IProcessTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false); - CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); + CompiledTemplate CompileTemplate (string content, ITextTemplatingEngineHost host); + //CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); } public interface ITextTemplatingEngine From 00f3f4bb2d5c0af46981836f9dcf7cd4dd36d457 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sat, 1 Aug 2020 21:26:11 -0600 Subject: [PATCH 55/58] no message --- .../Mono.VisualStudio.TextTemplating/Interfaces.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs index 250e668..1104b6a 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/Interfaces.cs @@ -95,7 +95,7 @@ public interface IProcessTextTemplatingEngine IProcessTransformationRun PrepareTransformationRun (string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false); CompiledTemplate CompileTemplate (string content, ITextTemplatingEngineHost host); - //CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); + CompiledTemplate CompileTemplate (ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings = null); } public interface ITextTemplatingEngine From 982e2e51755c8a010868f759246f0a36717141a0 Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Sun, 2 Aug 2020 22:43:39 -0600 Subject: [PATCH 56/58] these two items will have to cross domain process boundaries --- .../TransformationRunFactory.cs | 12 +++++------- .../TransformationRunner.cs | 8 +++----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs index 7237563..f8d8106 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunFactory.cs @@ -3,11 +3,9 @@ namespace Mono.VisualStudio.TextTemplating.VSHost { - public abstract class TransformationRunFactory : -#if FEATURE_APPDOMAINS - MarshalByRefObject, -#endif - IProcessTransformationRunFactory + public abstract class TransformationRunFactory + : MarshalByRefObject + , IProcessTransformationRunFactory { public const string TransformationRunFactoryPrefix = "TransformationRunFactoryService"; public const string TransformationRunFactorySuffix = nameof (TransformationRunFactory); @@ -24,11 +22,11 @@ public abstract class TransformationRunFactory : public abstract IProcessTransformationRun CreateTransformationRun (Type runnerType, ParsedTemplate pt, ResolveEventHandler resolver); public abstract string RunTransformation (IProcessTransformationRun transformationRun); -#if FEATURE_APPDOMAINS + public override object InitializeLifetimeService () { return null; } -#endif + } } diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs index 18b7b53..b27fa82 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating.VSHost/TransformationRunner.cs @@ -7,11 +7,9 @@ namespace Mono.VisualStudio.TextTemplating.VSHost { - public class TransformationRunner : -#if FEATURE_APPDOMAINS - MarshalByRefObject, -#endif - IProcessTransformationRun + public class TransformationRunner + : MarshalByRefObject + , IProcessTransformationRun { CompiledTemplate compiledTemplate; TemplateSettings settings; From 0a2efc864073cc723896a30d0052c026b757483b Mon Sep 17 00:00:00 2001 From: Kenneth Carter Date: Wed, 12 Aug 2020 13:28:51 -0600 Subject: [PATCH 57/58] #88 apply the patch for Parameter properties should be static --- Mono.TextTemplating.Tests/GenerationTests.cs | 33 +++++++++++++++++++ .../ParameterDirectiveProcessor.cs | 10 ++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Mono.TextTemplating.Tests/GenerationTests.cs b/Mono.TextTemplating.Tests/GenerationTests.cs index 99c8eb6..d1a60e4 100644 --- a/Mono.TextTemplating.Tests/GenerationTests.cs +++ b/Mono.TextTemplating.Tests/GenerationTests.cs @@ -48,6 +48,16 @@ public void TemplateGeneratorTest () Assert.IsNull (gen.Errors.OfType ().FirstOrDefault (), "ProcessTemplate"); } + [Test] + public void GenerateStaticPropertyForParameter () + { + var engine = new TemplatingEngine (); + + var output = engine.PreprocessTemplate (T4ParameterSample, new DummyHost (), "ParameterTestClass", "Testing", out string language, out string[] references); + + Assert.IsTrue (output.Contains ("public static string TestParameter")); + } + [Test] public void ImportReferencesTest () { @@ -105,6 +115,8 @@ public void GenerateWindowsNewlines () Generate (WinInput, WinOutput, "\r\n"); } + + [Test] public void DefaultLanguage () { @@ -164,6 +176,27 @@ string GenerateCode (ITextTemplatingEngineHost host, string content, string name #endregion + #region input strings + public static string T4ParameterSample = +@"<#@ template hostspecific=""true"" language=""C#"" #> +<#@ parameter type=""System.String"" name=""TestParameter"" #> +using System; + +namespace Testing +{ + public class Parameters + { + public string SomeParameter + { + get + { + return TestParameter; + } + } + } +}"; + #endregion + #region Expected output strings public static string OutputSample1 = diff --git a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs index d06c287..ee1a3b2 100644 --- a/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs +++ b/Mono.TextTemplating/Mono.VisualStudio.TextTemplating/ParameterDirectiveProcessor.cs @@ -146,17 +146,21 @@ public override void ProcessDirective (string directiveName, IDictionary Date: Wed, 12 Aug 2020 15:31:35 -0600 Subject: [PATCH 58/58] additional tests to make sure the parameter was set --- Mono.TextTemplating.Tests/DummyHost.cs | 16 +++-- Mono.TextTemplating.Tests/GenerationTests.cs | 70 ++++++++++++++----- .../Mono.TextTemplating/CompiledTemplate.cs | 2 +- 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/Mono.TextTemplating.Tests/DummyHost.cs b/Mono.TextTemplating.Tests/DummyHost.cs index 82796e5..93358d8 100644 --- a/Mono.TextTemplating.Tests/DummyHost.cs +++ b/Mono.TextTemplating.Tests/DummyHost.cs @@ -37,11 +37,11 @@ public class DummyHost : ITextTemplatingEngineHost public readonly Dictionary Locations = new Dictionary (); public readonly Dictionary Contents = new Dictionary (); public readonly Dictionary HostOptions = new Dictionary (); - List standardAssemblyReferences = new List (); + List standardAssemblyReferences = new List (new[] { typeof(TemplatingEngine).Assembly.Location }); List standardImports = new List (); public readonly CompilerErrorCollection Errors = new CompilerErrorCollection (); public readonly Dictionary DirectiveProcessors = new Dictionary (); - + public readonly Dictionary Parameters = new Dictionary (); public virtual object GetHostOption (string optionName) { object o; @@ -68,7 +68,7 @@ public virtual AppDomain ProvideTemplatingAppDomain (string content) public virtual string ResolveAssemblyReference (string assemblyReference) { - throw new System.NotImplementedException(); + return assemblyReference; } public virtual Type ResolveDirectiveProcessor (string processorName) @@ -80,22 +80,24 @@ public virtual Type ResolveDirectiveProcessor (string processorName) public virtual string ResolveParameterValue (string directiveId, string processorName, string parameterName) { - throw new System.NotImplementedException(); + return Parameters[parameterName]; } public virtual string ResolvePath (string path) { throw new System.NotImplementedException(); } - + + string extension; + public virtual void SetFileExtension (string extension) { - throw new System.NotImplementedException(); + this.extension = extension; } public virtual void SetOutputEncoding (System.Text.Encoding encoding, bool fromOutputDirective) { - throw new System.NotImplementedException(); + } public virtual IList StandardAssemblyReferences { diff --git a/Mono.TextTemplating.Tests/GenerationTests.cs b/Mono.TextTemplating.Tests/GenerationTests.cs index d1a60e4..dc76f6d 100644 --- a/Mono.TextTemplating.Tests/GenerationTests.cs +++ b/Mono.TextTemplating.Tests/GenerationTests.cs @@ -31,6 +31,7 @@ using Mono.VisualStudio.TextTemplating; using System.Linq; using System.CodeDom.Compiler; +using System.Reflection; namespace Mono.TextTemplating.Tests { @@ -53,9 +54,53 @@ public void GenerateStaticPropertyForParameter () { var engine = new TemplatingEngine (); - var output = engine.PreprocessTemplate (T4ParameterSample, new DummyHost (), "ParameterTestClass", "Testing", out string language, out string[] references); + var host = new DummyHost (); + + var output = engine.PreprocessTemplate (T4ParameterSample, host, "ParameterTestClass", "Testing", out string language, out string[] references); + + foreach (CompilerError error in host.Errors) { + Console.Error.WriteLine (error.ErrorText); + } Assert.IsTrue (output.Contains ("public static string TestParameter")); + + Console.Out.WriteLine (output); + } + + [Test] + [TestCase("some nonsense value")] + public void GenerateStaticPropertyForParameterCanInitilialize (string value) + { + var engine = new TemplatingEngine (); + + var host = new DummyHost () { + TemplateFile = "test.tt" + }; + + host.Parameters.Add ("TestParameter", value); + + + var tt = engine.CompileTemplate (T4ParameterSample, host); + + foreach (CompilerError error in host.Errors) { + Console.Error.WriteLine (error.ErrorText); + } + + Type ttType = tt.textTransformation?.GetType (); + + Assert.IsNotNull (ttType); + + var initMethod = ttType.GetMethod ("Initialize"); + var testAssignment = ttType.GetMethod ("TestAssignment"); + var parameter = ttType.GetProperty ("TestParameter", BindingFlags.Public | BindingFlags.Static); + + initMethod.Invoke (tt.textTransformation, null); + + if (testAssignment.Invoke(tt.textTransformation, null) is bool success) { + Assert.IsTrue (success); + } + + Assert.AreEqual (value, parameter.GetValue (null)); } [Test] @@ -177,24 +222,17 @@ string GenerateCode (ITextTemplatingEngineHost host, string content, string name #endregion #region input strings - public static string T4ParameterSample = + public const string T4ParameterSample = @"<#@ template hostspecific=""true"" language=""C#"" #> +<#@ output extension="".cs"" #> <#@ parameter type=""System.String"" name=""TestParameter"" #> +<#@ import namespace=""System"" #> using System; - -namespace Testing -{ - public class Parameters - { - public string SomeParameter - { - get - { - return TestParameter; - } - } - } -}"; +<#+ +public bool TestAssignment() { + return !string.IsNullOrEmpty(TestParameter); +} +#>"; #endregion #region Expected output strings diff --git a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs index 156246c..6ebd294 100644 --- a/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs +++ b/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.cs @@ -40,7 +40,7 @@ public sealed class CompiledTemplate : IDisposable { ITextTemplatingEngineHost host; - object textTransformation; + internal object textTransformation; readonly CultureInfo culture; readonly string [] assemblyFiles;