2 // System.Web.Compilation.GenericBuildProvider
5 // Marek Habersack (mhabersack@novell.com)
7 // (C) 2008 Novell, Inc
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.CodeDom.Compiler;
34 using System.Collections;
35 using System.Collections.Generic;
37 using System.Reflection;
41 namespace System.Web.Compilation
43 internal abstract class GenericBuildProvider <TParser> : BuildProvider
46 CompilerType _compilerType;
47 BaseCompiler _compiler;
52 protected bool Parsed {
53 get { return _parsed; }
56 protected abstract TParser CreateParser (VirtualPath virtualPath, string physicalPath, TextReader reader, HttpContext context);
57 protected abstract TParser CreateParser (VirtualPath virtualPath, string physicalPath, HttpContext context);
58 protected abstract BaseCompiler CreateCompiler (TParser parser);
59 protected abstract string GetParserLanguage (TParser parser);
60 protected abstract ICollection GetParserDependencies (TParser parser);
61 protected abstract string GetCodeBehindSource (TParser parser);
62 protected abstract string GetClassType (BaseCompiler compiler, TParser parser);
63 protected abstract AspGenerator CreateAspGenerator (TParser parser);
64 protected abstract List <string> GetReferencedAssemblies (TParser parser);
66 protected virtual string MapPath (VirtualPath virtualPath)
68 HttpContext ctx = HttpContext.Current;
69 HttpRequest req = ctx != null ? ctx.Request : null;
72 return req.MapPath (VirtualPath);
77 protected virtual TParser Parse ()
79 TParser parser = Parser;
84 if (!IsDirectoryBuilder) {
85 AspGenerator generator = CreateAspGenerator (parser);
87 generator.Parse (_reader, MapPath (VirtualPathInternal), true);
96 protected virtual void OverrideAssemblyPrefix (TParser parser, AssemblyBuilder assemblyBuilder)
100 internal override void GenerateCode ()
102 TParser parser = Parse ();
103 _compiler = CreateCompiler (parser);
104 if (NeedsConstructType)
105 _compiler.ConstructType ();
106 _codeGenerated = true;
109 protected virtual void GenerateCode (AssemblyBuilder assemblyBuilder, TParser parser, BaseCompiler compiler)
111 CodeCompileUnit unit = _compiler.CompileUnit;
113 throw new HttpException ("Unable to generate source code.");
115 assemblyBuilder.AddCodeCompileUnit (this, unit);
118 public override void GenerateCode (AssemblyBuilder assemblyBuilder)
123 TParser parser = Parse ();
124 OverrideAssemblyPrefix (parser, assemblyBuilder);
126 string codeBehindSource = GetCodeBehindSource (parser);
127 if (codeBehindSource != null)
128 assemblyBuilder.AddCodeFile (codeBehindSource, this, true);
130 List <string> refasms = GetReferencedAssemblies (parser);
131 if (refasms != null && refasms.Count > 0) {
132 foreach (string loc in refasms)
133 assemblyBuilder.AddAssemblyReference (loc);
136 GenerateCode (assemblyBuilder, parser, _compiler);
139 protected virtual Type LoadTypeFromBin (BaseCompiler compiler, TParser parser)
144 public override Type GetGeneratedType (CompilerResults results)
146 if (NeedsLoadFromBin && _compiler != null)
147 return LoadTypeFromBin (_compiler, Parser);
149 // This is not called if compilation failed.
150 // Returning null makes the caller throw an InvalidCastException
151 Assembly assembly = results != null ? results.CompiledAssembly : null;
152 if (assembly == null)
155 return assembly.GetType (GetClassType (_compiler, Parser));
158 // This is intended to be used by builders which may need to do special processing
159 // on the virtualPath before actually opening the reader.
160 protected virtual TextReader SpecialOpenReader (VirtualPath virtualPath, out string physicalPath)
163 return OpenReader (virtualPath.Original);
166 // FIXME: figure this out.
167 public override ICollection VirtualPathDependencies {
169 TParser parser = Parser;
170 return GetParserDependencies (parser);
174 internal override string LanguageName {
176 TParser parser = Parse ();
178 return GetParserLanguage (parser);
179 return base.LanguageName;
183 public override CompilerType CodeCompilerType {
185 if (_compilerType == null)
186 _compilerType = GetDefaultCompilerTypeForLanguage (LanguageName);
188 return _compilerType;
192 public TParser Parser {
194 if (_parser == null) {
195 VirtualPath vp = VirtualPathInternal;
197 throw new HttpException ("VirtualPath not set, cannot instantiate parser.");
199 if (!IsDirectoryBuilder) {
201 _reader = SpecialOpenReader (vp, out physicalPath);
202 _parser = CreateParser (vp, physicalPath, _reader, HttpContext.Current);
204 _parser = CreateParser (vp, null, HttpContext.Current);
207 throw new HttpException ("Unable to create type parser.");
214 protected virtual bool IsDirectoryBuilder {
215 get { return false; }
218 protected virtual bool NeedsConstructType {
222 protected virtual bool NeedsLoadFromBin {
223 get { return false; }
226 internal override CodeCompileUnit CodeUnit {
230 return _compiler.CompileUnit;