~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/addins/AspNet/MonoDevelop.AspNet.Mvc/RazorGenerator/PreprocessedTemplateCodeTransformer.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Based on TemplateCodeTransformer.cs from Razor Generator (http://razorgenerator.codeplex.com/)
 
3
//     Licensed under the Microsoft Public License (MS-PL)
 
4
//
 
5
// Changes:
 
6
//     Author: Michael Hutchinson <mhutch@xamarin.com>
 
7
//     Copyright (c) 2012 Xamarin Inc (http://xamarin.com)
 
8
//     Licensed under the Microsoft Public License (MS-PL)
 
9
//
 
10
 
 
11
using System.CodeDom;
 
12
using System.Collections.Generic;
 
13
using System.Linq;
 
14
using System;
 
15
 
 
16
namespace MonoDevelop.RazorGenerator
 
17
{
 
18
        class PreprocessedTemplateCodeTransformers
 
19
        {
 
20
                public static void MakePartialAndRemoveCtor (RazorHost host, CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod)
 
21
                {
 
22
                        generatedClass.IsPartial = true;
 
23
                        // The generated class has a constructor in there by default.
 
24
                        generatedClass.Members.Remove (generatedClass.Members.OfType<CodeConstructor> ().Single ());
 
25
                }
 
26
 
 
27
                public static void AddGeneratedTemplateClassAttribute (RazorHost host, CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod)
 
28
                {
 
29
                        string tool = "RazorTemplatePreprocessor";
 
30
                        Version version = typeof (PreprocessedTemplateCodeTransformers).Assembly.GetName().Version;
 
31
                        generatedClass.CustomAttributes.Add(
 
32
                                new CodeAttributeDeclaration(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).FullName,
 
33
                                        new CodeAttributeArgument(new CodePrimitiveExpression(tool)),
 
34
                                        new CodeAttributeArgument(new CodePrimitiveExpression(version.ToString()))
 
35
                        ));
 
36
                }
 
37
 
 
38
                static void AddComments (CodeTypeMember member, bool docComment, params string[] comments)
 
39
                {
 
40
                        foreach (var c in comments) {
 
41
                                member.Comments.Add (new CodeCommentStatement (c, docComment));
 
42
                        }
 
43
                }
 
44
 
 
45
                public static void InjectBaseClass (RazorHost host, CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod)
 
46
                {
 
47
                        bool generateBaseClass = generatedClass.BaseTypes.Count == 0;
 
48
                        bool integrateHelpers = !generateBaseClass && generatedClass.BaseTypes [0].BaseType == "object";
 
49
                        if (!generateBaseClass && !integrateHelpers)
 
50
                                return;
 
51
 
 
52
                        if (generateBaseClass) {
 
53
                                var baseName = generatedClass.Name + "Base";
 
54
                                generatedClass.BaseTypes.Add (new CodeTypeReference (baseName));
 
55
 
 
56
                                var baseClass = new CodeTypeDeclaration (baseName) {
 
57
                                        TypeAttributes = generatedClass.TypeAttributes | System.Reflection.TypeAttributes.Abstract,
 
58
                                };
 
59
                                AddComments (baseClass, false,
 
60
                                        "NOTE: this is the default generated helper class. You may choose to extract it to a separate file ",
 
61
                                        "in order to customize it or share it between multiple templates, and specify the template's base ",
 
62
                                        "class via the @inherits directive."
 
63
                                );
 
64
                                generatedNamespace.Types.Add (baseClass);
 
65
 
 
66
                                baseClass.Members.Add (new CodeSnippetTypeMember (baseMembersString));
 
67
                                baseClass.Members.Add (new CodeSnippetTypeMember (baseExecuteMethodString));
 
68
                        } else {
 
69
                                generatedClass.BaseTypes [0].BaseType = "System.Object";
 
70
                                executeMethod.Attributes = (executeMethod.Attributes & (~MemberAttributes.AccessMask | ~MemberAttributes.Override))
 
71
                                        | MemberAttributes.Private | MemberAttributes.Final;
 
72
                                generatedClass.Members.Add (new CodeSnippetTypeMember (baseMembersString));
 
73
                        }
 
74
                }
 
75
 
 
76
                /* rewrite:
 
77
                public System.Web.WebPages.HelperResult foo (int i)
 
78
                {
 
79
                        return new System.Web.WebPages.HelperResult(__razor_helper_writer => {
 
80
                                WriteLiteralTo(__razor_helper_writer, "<p>");
 
81
                                WriteTo(__razor_helper_writer, i);
 
82
                                WriteLiteralTo(__razor_helper_writer, "</p>\n");
 
83
                        });
 
84
                }
 
85
                to:
 
86
                public static Action<TextWriter> foo (int i)
 
87
                {
 
88
                        return __razor_helper_writer => {
 
89
                                __razor_helper_writer.Write("<p>");
 
90
                                WriteTo(__razor_helper_writer, i);
 
91
                                __razor_helper_writer.Write("</p>\n");
 
92
                        };
 
93
                }
 
94
                */
 
95
                static string[,] replacements = new string [,] {
 
96
                        { "public System.Web.WebPages.HelperResult " , "public static Action<System.IO.TextWriter> " },
 
97
                        { "return new System.Web.WebPages.HelperResult(__razor_helper_writer" , "return __razor_helper_writer" },
 
98
                        { "WriteLiteralTo(__razor_helper_writer," , "__razor_helper_writer.Write(" },
 
99
                };
 
100
 
 
101
                public static void SimplifyHelpers (RazorHost host, CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod)
 
102
                {
 
103
                        foreach (var method in generatedClass.Members.OfType<CodeSnippetTypeMember> ()) {
 
104
                                using (var writer = new System.IO.StringWriter (new System.Text.StringBuilder (method.Text.Length))) {
 
105
                                        bool foundStart = false;
 
106
                                        using (var reader = new System.IO.StringReader (method.Text)) {
 
107
                                                bool lineHidden = false;
 
108
                                                string line;
 
109
                                                while ((line = reader.ReadLine ()) != null) {
 
110
                                                        if (!foundStart) {
 
111
                                                                if (line.StartsWith ("public System.Web.WebPages.HelperResult")) {
 
112
                                                                        foundStart = true;
 
113
                                                                } else if (!string.IsNullOrWhiteSpace (line) && !line.StartsWith ("#line")) {
 
114
                                                                        break;
 
115
                                                                }
 
116
                                                        }
 
117
                                                        if (line.StartsWith ("#line")) {
 
118
                                                                lineHidden = line == "#line hidden";
 
119
                                                        }
 
120
                                                        if (lineHidden && line == "});") {
 
121
                                                                writer.WriteLine ("};");
 
122
                                                                continue;
 
123
                                                        }
 
124
                                                        var len = replacements.GetLength (0);
 
125
                                                        for (int i = 0; i < len; i++) {
 
126
                                                                var bad = replacements[i,0];
 
127
                                                                if (line.StartsWith (bad)) {
 
128
                                                                        line = replacements[i,1] + line.Substring (bad.Length);
 
129
                                                                }
 
130
                                                        }
 
131
                                                        writer.WriteLine (line);
 
132
                                                }
 
133
                                        }
 
134
                                        if (foundStart) {
 
135
                                                method.Text = writer.ToString ();
 
136
                                        }
 
137
                                }
 
138
                        }
 
139
                }
 
140
 
 
141
                const string baseExecuteMethodString =
 
142
@"              // This method is REQUIRED. The generated Razor subclass will override it with the generated code.
 
143
                //
 
144
                ///<summary>Executes the template, writing output to the Write and WriteLiteral methods.</summary>.
 
145
                ///<remarks>Not intended to be called directly. Call the Generate method instead.</remarks>
 
146
                public abstract void Execute ();
 
147
";
 
148
 
 
149
                const string baseMembersString =
 
150
@"              // This field is OPTIONAL, but used by the default implementation of Generate, Write and WriteLiteral
 
151
                //
 
152
                System.IO.TextWriter __razor_writer;
 
153
 
 
154
                // This method is OPTIONAL
 
155
                //
 
156
                ///<summary>Executes the template and returns the output as a string.</summary>
 
157
                public string GenerateString ()
 
158
                {
 
159
                        using (var sw = new System.IO.StringWriter ()) {
 
160
                                Generate (sw);
 
161
                                return sw.ToString();
 
162
                        }
 
163
                }
 
164
 
 
165
                // This method is OPTIONAL, you may choose to implement Write and WriteLiteral without use of __razor_writer
 
166
                // and provide another means of invoking Execute.
 
167
                //
 
168
                ///<summary>Executes the template, writing to the provided text writer.</summary>
 
169
                public void Generate (System.IO.TextWriter writer)
 
170
                {
 
171
                        __razor_writer = writer;
 
172
                        Execute ();
 
173
                        __razor_writer = null;
 
174
                }
 
175
 
 
176
                // This method is REQUIRED, but you may choose to implement it differently
 
177
                //
 
178
                ///<summary>Writes literal values to the template output without HTML escaping them.</summary>
 
179
                protected void WriteLiteral (string value)
 
180
                {
 
181
                        __razor_writer.Write (value);
 
182
                }
 
183
 
 
184
                // This method is REQUIRED, but you may choose to implement it differently
 
185
                //
 
186
                ///<summary>Writes values to the template output, HTML escaping them if necessary.</summary>
 
187
                protected void Write (object value)
 
188
                {
 
189
                        WriteTo (__razor_writer, value);
 
190
                }
 
191
 
 
192
                // This method is REQUIRED if the template uses any Razor helpers, but you may choose to implement it differently
 
193
                //
 
194
                ///<summary>Invokes the action to write directly to the template output.</summary>
 
195
                ///<remarks>This is used for Razor helpers, which already perform any necessary HTML escaping.</remarks>
 
196
                protected void Write (Action<System.IO.TextWriter> write)
 
197
                {
 
198
                        write (__razor_writer);
 
199
                }
 
200
 
 
201
                // This method is REQUIRED if the template has any Razor helpers, but you may choose to implement it differently
 
202
                //
 
203
                ///<remarks>Used by Razor helpers to HTML escape values.</remarks>
 
204
                protected static void WriteTo (System.IO.TextWriter writer, object value)
 
205
                {
 
206
                        if (value != null) {
 
207
                                writer.Write (System.Web.HttpUtility.HtmlEncode (value.ToString ()));
 
208
                                // NOTE: better version for .NET 4+, handles pre-escape HTML (IHtmlString)
 
209
                                // writer.Write (System.Web.HttpUtility.HtmlEncode (value));
 
210
                        }
 
211
                }
 
212
";
 
213
        }
 
214
}
 
 
b'\\ No newline at end of file'