summaryrefslogtreecommitdiff
path: root/external/aspnetwebstack/src/System.Web.Razor/RazorEngineHost.cs
blob: 8125145a472ce6ba413664817ab74b2964b5ab12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;

namespace System.Web.Razor
{
    /// <summary>
    /// Defines the environment in which a Razor template will live
    /// </summary>
    /// <remarks>
    /// The host defines the following things:
    /// * What method names will be used for rendering markup, expressions etc.  For example "Write", "WriteLiteral"
    /// * The namespace imports to be added to every page generated via this host
    /// * The default Base Class to inherit the generated class from
    /// * The default Class Name and Namespace for the generated class (can be overridden by parameters in RazorTemplateEngine.GeneratedCode)
    /// * The language of the code in a Razor page
    /// * The markup, code parsers and code generators to use (the system will select defaults, but a Host gets a change to augment them)
    ///     ** See DecorateNNN methods
    /// * Additional code to add to the generated code (see PostProcessGeneratedCode)
    /// </remarks>
    public class RazorEngineHost
    {
        internal const string InternalDefaultClassName = "__CompiledTemplate";
        internal const string InternalDefaultNamespace = "Razor";

        private bool _instrumentationActive = false;
        private Func<ParserBase> _markupParserFactory;

        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The code path is safe, it is a property setter and not dependent on other state")]
        protected RazorEngineHost()
        {
            GeneratedClassContext = GeneratedClassContext.Default;
            NamespaceImports = new HashSet<string>();
            DesignTimeMode = false;
            DefaultNamespace = InternalDefaultNamespace;
            DefaultClassName = InternalDefaultClassName;
            EnableInstrumentation = false;
        }

        /// <summary>
        /// Creates a host which uses the specified code language and the HTML markup language
        /// </summary>
        /// <param name="codeLanguage">The code language to use</param>
        public RazorEngineHost(RazorCodeLanguage codeLanguage)
            : this(codeLanguage, () => new HtmlMarkupParser())
        {
        }

        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The code path is safe, it is a property setter and not dependent on other state")]
        public RazorEngineHost(RazorCodeLanguage codeLanguage, Func<ParserBase> markupParserFactory)
            : this()
        {
            if (codeLanguage == null)
            {
                throw new ArgumentNullException("codeLanguage");
            }
            if (markupParserFactory == null)
            {
                throw new ArgumentNullException("markupParserFactory");
            }

            CodeLanguage = codeLanguage;
            _markupParserFactory = markupParserFactory;
        }

        /// <summary>
        /// Details about the methods and types that should be used to generate code for Razor constructs
        /// </summary>
        public virtual GeneratedClassContext GeneratedClassContext { get; set; }

        /// <summary>
        /// A list of namespaces to import in the generated file
        /// </summary>
        public virtual ISet<string> NamespaceImports { get; private set; }

        /// <summary>
        /// The base-class of the generated class
        /// </summary>
        public virtual string DefaultBaseClass { get; set; }

        /// <summary>
        /// Indiciates if the parser and code generator should run in design-time mode
        /// </summary>
        public virtual bool DesignTimeMode { get; set; }

        /// <summary>
        /// The name of the generated class
        /// </summary>
        public virtual string DefaultClassName { get; set; }

        /// <summary>
        /// The namespace which will contain the generated class
        /// </summary>
        public virtual string DefaultNamespace { get; set; }

        /// <summary>
        /// Boolean indicating if helper methods should be instance methods or static methods
        /// </summary>
        public virtual bool StaticHelpers { get; set; }

        /// <summary>
        /// The language of the code within the Razor template.
        /// </summary>
        public virtual RazorCodeLanguage CodeLanguage { get; protected set; }

        /// <summary>
        /// Boolean indicating if instrumentation code should be injected into the output page
        /// </summary>
        public virtual bool EnableInstrumentation
        {
            // Always disable instrumentation in DesignTimeMode.
            get { return !DesignTimeMode && _instrumentationActive; }
            set { _instrumentationActive = value; }
        }

        /// <summary>
        /// Gets or sets the path to use for this document when generating Instrumentation calls
        /// </summary>
        public virtual string InstrumentedSourceFilePath { get; set; }

        /// <summary>
        /// Constructs the markup parser.  Must return a new instance on EVERY call to ensure thread-safety
        /// </summary>
        public virtual ParserBase CreateMarkupParser()
        {
            if (_markupParserFactory != null)
            {
                return _markupParserFactory();
            }
            return null;
        }

        /// <summary>
        /// Gets an instance of the code parser and is provided an opportunity to decorate or replace it
        /// </summary>
        /// <param name="incomingCodeParser">The code parser</param>
        /// <returns>Either the same code parser, after modifications, or a different code parser</returns>
        public virtual ParserBase DecorateCodeParser(ParserBase incomingCodeParser)
        {
            if (incomingCodeParser == null)
            {
                throw new ArgumentNullException("incomingCodeParser");
            }
            return incomingCodeParser;
        }

        /// <summary>
        /// Gets an instance of the markup parser and is provided an opportunity to decorate or replace it
        /// </summary>
        /// <param name="incomingMarkupParser">The markup parser</param>
        /// <returns>Either the same markup parser, after modifications, or a different markup parser</returns>
        public virtual ParserBase DecorateMarkupParser(ParserBase incomingMarkupParser)
        {
            if (incomingMarkupParser == null)
            {
                throw new ArgumentNullException("incomingMarkupParser");
            }
            return incomingMarkupParser;
        }

        /// <summary>
        /// Gets an instance of the code generator and is provided an opportunity to decorate or replace it
        /// </summary>
        /// <param name="incomingCodeGenerator">The code generator</param>
        /// <returns>Either the same code generator, after modifications, or a different code generator</returns>
        public virtual RazorCodeGenerator DecorateCodeGenerator(RazorCodeGenerator incomingCodeGenerator)
        {
            if (incomingCodeGenerator == null)
            {
                throw new ArgumentNullException("incomingCodeGenerator");
            }
            return incomingCodeGenerator;
        }

        /// <summary>
        /// Gets the important CodeDOM nodes generated by the code generator and has a chance to add to them.
        /// </summary>
        /// <remarks>
        /// All the other parameter values can be located by traversing tree in the codeCompileUnit node, they
        /// are simply provided for convenience
        /// </remarks>
        /// <param name="context">The current <see cref="CodeGeneratorContext"/>.</param>
        public virtual void PostProcessGeneratedCode(CodeGeneratorContext context)
        {
#pragma warning disable 0618
            PostProcessGeneratedCode(context.CompileUnit, context.Namespace, context.GeneratedClass, context.TargetMethod);
#pragma warning restore 0618
        }

        [Obsolete("This method is obsolete, use the override which takes a CodeGeneratorContext instead")]
        public virtual void PostProcessGeneratedCode(CodeCompileUnit codeCompileUnit, CodeNamespace generatedNamespace, CodeTypeDeclaration generatedClass, CodeMemberMethod executeMethod)
        {
            if (codeCompileUnit == null)
            {
                throw new ArgumentNullException("codeCompileUnit");
            }
            if (generatedNamespace == null)
            {
                throw new ArgumentNullException("generatedNamespace");
            }
            if (generatedClass == null)
            {
                throw new ArgumentNullException("generatedClass");
            }
            if (executeMethod == null)
            {
                throw new ArgumentNullException("executeMethod");
            }
        }
    }
}