2 // System.Web.Compilation.CachingCompiler
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
8 // (c) Copyright Novell, Inc. (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System
.CodeDom
.Compiler
;
33 using System
.Collections
;
34 using System
.Collections
.Specialized
;
36 using System
.Reflection
;
38 using System
.Web
.Caching
;
39 using System
.Web
.Configuration
;
41 namespace System
.Web
.Compilation
45 static object compilationLock
= new object ();
46 const string cachePrefix
= "@@Assembly";
47 const string cacheTypePrefix
= "@@@Type";
49 public static void InsertType (Type type
, string filename
)
51 string [] cacheKeys
= new string [] { cachePrefix + filename }
;
52 CacheDependency dep
= new CacheDependency (null, cacheKeys
);
53 HttpRuntime
.Cache
.Insert (cacheTypePrefix
+ filename
, type
, dep
);
56 public static Type
GetTypeFromCache (string filename
)
58 return (Type
) HttpRuntime
.Cache
[cacheTypePrefix
+ filename
];
61 public static CompilerResults
Compile (BaseCompiler compiler
)
63 Cache cache
= HttpRuntime
.Cache
;
64 string key
= cachePrefix
+ compiler
.Parser
.InputFile
;
65 CompilerResults results
= (CompilerResults
) cache
[key
];
69 lock (compilationLock
) {
70 results
= (CompilerResults
) cache
[key
];
74 ICodeCompiler comp
= compiler
.Compiler
;
75 results
= comp
.CompileAssemblyFromDom (compiler
.CompilerParameters
, compiler
.Unit
);
76 string [] deps
= (string []) compiler
.Parser
.Dependencies
.ToArray (typeof (string));
77 cache
.Insert (key
, results
, new CacheDependency (deps
));
83 public static CompilerResults
Compile (WebServiceCompiler compiler
)
85 string key
= cachePrefix
+ compiler
.Parser
.PhysicalPath
;
86 Cache cache
= HttpRuntime
.Cache
;
87 CompilerResults results
= (CompilerResults
) cache
[key
];
91 lock (compilationLock
) {
92 results
= (CompilerResults
) cache
[key
];
96 SimpleWebHandlerParser parser
= compiler
.Parser
;
97 CompilerParameters options
= compiler
.CompilerOptions
;
98 options
.IncludeDebugInformation
= parser
.Debug
;
99 results
= compiler
.Compiler
.CompileAssemblyFromFile (options
, compiler
.InputFile
);
100 string [] deps
= (string []) parser
.Dependencies
.ToArray (typeof (string));
101 cache
.Insert (key
, results
, new CacheDependency (deps
));
107 internal static CompilerParameters
GetOptions (ICollection assemblies
)
109 CompilerParameters options
= new CompilerParameters ();
110 if (assemblies
!= null) {
111 StringCollection coll
= options
.ReferencedAssemblies
;
112 foreach (string str
in assemblies
)
119 public static CompilerResults
Compile (string language
, string key
, string file
,
120 ArrayList assemblies
)
122 Cache cache
= HttpRuntime
.Cache
;
123 CompilerResults results
= (CompilerResults
) cache
[cachePrefix
+ key
];
127 lock (compilationLock
) {
128 results
= (CompilerResults
) cache
[cachePrefix
+ key
];
132 CompilationConfiguration config
;
133 config
= CompilationConfiguration
.GetInstance (HttpContext
.Current
);
134 CodeDomProvider provider
= config
.GetProvider (language
);
135 if (provider
== null)
136 throw new HttpException ("Configuration error. Language not supported: " +
139 ICodeCompiler compiler
= provider
.CreateCompiler ();
140 CompilerParameters options
= GetOptions (assemblies
);
141 results
= compiler
.CompileAssemblyFromFile (options
, file
);
142 ArrayList realdeps
= new ArrayList (assemblies
.Count
+ 1);
144 for (int i
= assemblies
.Count
- 1; i
>= 0; i
--) {
145 string current
= (string) assemblies
[i
];
146 if (Path
.IsPathRooted (current
))
147 realdeps
.Add (current
);
150 string [] deps
= (string []) realdeps
.ToArray (typeof (string));
151 cache
.Insert (cachePrefix
+ key
, results
, new CacheDependency (deps
));
157 public static Type
CompileAndGetType (string typename
, string language
, string key
,
158 string file
, ArrayList assemblies
)
160 CompilerResults result
= CachingCompiler
.Compile (language
, key
, file
, assemblies
);
161 if (result
.NativeCompilerReturnValue
!= 0) {
162 StreamReader reader
= new StreamReader (file
);
163 throw new CompilationException (file
, result
.Errors
, reader
.ReadToEnd ());
166 Assembly assembly
= result
.CompiledAssembly
;
167 if (assembly
== null) {
168 StreamReader reader
= new StreamReader (file
);
169 throw new CompilationException (file
, result
.Errors
, reader
.ReadToEnd ());
172 Type type
= assembly
.GetType (typename
, true);
173 InsertType (type
, file
);