/TestBoilen/CodeGeneration/Compile.cs
C# | 151 lines | 121 code | 30 blank | 0 comment | 15 complexity | ba9aefc4177bfa7ce3371a1f80070f52 MD5 | raw file
-
- using Boilen.Guards;
- using Microsoft.CSharp;
- using System;
- using System.CodeDom.Compiler;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using Xunit;
-
-
- namespace Boilen.Primitives.CodeGeneration {
-
- public static class Compile {
-
- public static MemberInfo[] PartialType( PartialType pt ) {
- var caller = GetCaller( );
- Type compiledType;
- return Compile.PartialType( caller, pt, out compiledType );
- }
-
- public static MemberInfo[] PartialType( PartialType pt, out Type compiledType ) {
- var caller = GetCaller( );
- return Compile.PartialType( caller, pt, out compiledType );
- }
-
- public static bool PartialType( PartialType pt, bool swallowRunErrors, out CompilerResults compileResults ) {
- var caller = GetCaller( );
- bool silverlight;
- return Compile.PartialType( caller, pt, swallowRunErrors, out silverlight, out compileResults );
- }
-
-
- private static MemberInfo[] PartialType( MethodBase caller, PartialType pt, out Type compiledType ) {
- bool silverlight;
- CompilerResults results;
- Compile.PartialType( caller, pt, false, out silverlight, out results );
-
- var errors = results.Errors.Cast<CompilerError>( );
- if( errors.Any( ) ) {
- string errorMessage = errors.Aggregate(
- new System.Text.StringBuilder( ).AppendLine( silverlight ? "SL" : "WPF" ),
- ( sb, e ) => sb.AppendLine( e.ToString( ) ),
- ( sb ) => sb.ToString( )
- );
- Assert.True( false, errorMessage );
- }
-
- Type[] types = results.CompiledAssembly.GetExportedTypes( );
- compiledType = Assert.Single( types );
- Assert.Equal( compiledType.FullName, pt.Type.FullName );
-
- var compiledTypeLocal = compiledType;
- var newMembers = compiledType.GetMembers( )
- .Where( m => m.DeclaringType == compiledTypeLocal )
- .ToArray( );
-
- return newMembers;
- }
-
- private static bool PartialType( MethodBase caller, PartialType pt, bool swallowRunErrors, out bool silverlight, out CompilerResults compileResults ) {
- var writer = new CodeFileWriter( caller, pt.Type );
-
- bool runResult = true;
- using( writer ) {
- if( swallowRunErrors ) {
- try { pt.Run( writer ); }
- catch { runResult = false; }
- }
- else
- pt.Run( writer );
- }
-
- string generatedFile = writer.FilePath;
- string sourceFile = Path.Combine( CodeFileWriter.CodeDirectory, writer.TypeName + ".cs" );
- silverlight = true;
- compileResults = GetCompileResults( silverlight, generatedFile, sourceFile );
- if( compileResults.Errors.Count == 0 ) {
- silverlight = false;
- compileResults = GetCompileResults( silverlight, generatedFile, sourceFile );
- }
-
- return runResult;
- }
-
- private static CompilerResults GetCompileResults( bool silverlight, params string[] files ) {
- string[] referenceAssemblies = (silverlight ? GetSilverlightReferences( ) : GetWpfReferences( )).ToArray( );
-
- var providerOptions = new Dictionary<string, string>( ) { { "CompilerVersion", "v4.0" } };
- var provider = new CSharpCodeProvider( providerOptions );
- var options = new CompilerParameters( ) { GenerateInMemory = true, TreatWarningsAsErrors = true, WarningLevel = 4 };
- options.TempFiles.KeepFiles = false;
- options.ReferencedAssemblies.AddRange( referenceAssemblies );
- if( silverlight ) { options.CompilerOptions = "/nostdlib+ /define:" + CompilationSymbol.Silverlight.Symbol; }
-
- return provider.CompileAssemblyFromFile( options, files );
- }
-
-
- private static readonly string[] excludedAssemblies = new string[] {
- typeof( int ).Assembly.FullName,
- typeof( Compile ).Assembly.FullName,
- typeof( PartialType ).Assembly.FullName,
- typeof( Xunit.Assert ).Assembly.FullName,
- typeof( Xunit.Extensions.TheoryAttribute ).Assembly.FullName,
- };
-
- private static IEnumerable<string> GetWpfReferences( ) {
- return AppDomain.CurrentDomain.GetAssemblies( )
- .Where( a => !string.IsNullOrEmpty( a.Location )
- && !a.FullName.StartsWith( "Microsoft." )
- && !excludedAssemblies.Contains( a.FullName ) )
- .Select( a => a.Location );
- }
-
- private static IEnumerable<string> GetSilverlightReferences( ) {
- string wpfSourceDependenciesFile = new Uri( typeof( TestGuards ).Assembly.CodeBase, UriKind.Absolute ).AbsolutePath;
- string sourceDependenciesName = Path.GetFileNameWithoutExtension( wpfSourceDependenciesFile );
- var sourceDependenciesDirectory = Directory.GetParent( wpfSourceDependenciesFile );
- while( sourceDependenciesDirectory.GetDirectories( sourceDependenciesName ).Length == 0 )
- sourceDependenciesDirectory = sourceDependenciesDirectory.Parent;
- string slSourceDependenciesFile = new[] {
- sourceDependenciesDirectory.FullName,
- sourceDependenciesName, "bin", "Debug", sourceDependenciesName + ".SL.dll"
- }.Aggregate( Path.Combine );
-
- string slReferencesDirectory = new[] {
- Environment.GetFolderPath( Environment.SpecialFolder.ProgramFiles ),
- "Reference Assemblies", "Microsoft", "Framework", "Silverlight", "v4.0"
- }.Aggregate( Path.Combine );
- string[] slReferences = Directory.GetFiles( slReferencesDirectory, "*.dll", SearchOption.TopDirectoryOnly );
-
- return slReferences
- .Where( path => {
- string fileName = Path.GetFileNameWithoutExtension( path );
- bool include = fileName.Any( char.IsUpper ) && fileName != "Silverlight.ConfigurationUI";
- return fileName == "system" || fileName == "mscorlib" || include;
- } )
- .Concat( new[] { slSourceDependenciesFile } );
- }
-
-
- private static MethodBase GetCaller( ) {
- return new StackTrace( ).GetFrame( 2 ).GetMethod( );
- }
-
- }
-
- }