/// <summary> /// Emits the specified compilation to either an in-memory stream or a file. /// </summary> private static BindingExpressionCompilationResult EmitCompilation(RoslynExpressionCompilerState state, IEnumerable <DataSourceWrapperInfo> models, String output, Compilation compilation) { var outputStream = default(Stream); try { outputStream = state.GenerateInMemory ? new MemoryStream() : (Stream)File.OpenWrite(output); var options = new EmitOptions(outputNameOverride: "Ultraviolet.Presentation.CompiledExpressions.dll", debugInformationFormat: DebugInformationFormat.PortablePdb, fileAlignment: 512, baseAddress: 0x11000000); var emitResult = compilation.Emit(outputStream, options: options); if (emitResult.Success) { var assembly = state.GenerateInMemory ? Assembly.Load(((MemoryStream)outputStream).ToArray()) : null; return(BindingExpressionCompilationResult.CreateSucceeded(assembly)); } else { return(BindingExpressionCompilationResult.CreateFailed(CompilerStrings.FailedEmit, CreateBindingExpressionCompilationErrors(state, models, emitResult.Diagnostics))); } } finally { if (outputStream != null) { outputStream.Dispose(); } } }
/// <inheritdoc/> public BindingExpressionCompilationResult Compile(UltravioletContext uv, BindingExpressionCompilerOptions options) { Contract.Require(uv, nameof(uv)); Contract.Require(options, nameof(options)); if (String.IsNullOrEmpty(options.Input) || String.IsNullOrEmpty(options.Output)) { throw new ArgumentException(PresentationStrings.InvalidCompilerOptions); } var compiler = CreateCodeProvider(); var state = new LegacyExpressionCompilerState(uv, compiler) { GenerateInMemory = options.GenerateInMemory, WorkInTemporaryDirectory = options.WorkInTemporaryDirectory, WriteErrorsToFile = options.WriteErrorsToFile }; var dataSourceWrapperInfos = DataSourceLoader.GetDataSourceWrapperInfos(state, options.Input); var cacheFile = Path.ChangeExtension(options.Output, "cache"); var cacheNew = CompilerCache.FromDataSourceWrappers(this, dataSourceWrapperInfos); if (File.Exists(options.Output)) { var cacheOld = CompilerCache.TryFromFile(cacheFile); if (cacheOld != null && !options.IgnoreCache && !cacheOld.IsDifferentFrom(cacheNew)) { return(BindingExpressionCompilationResult.CreateSucceeded()); } } var result = CompileViewModels(state, dataSourceWrapperInfos, options.Output, options.GenerateDebugAssembly); if (result.Succeeded) { if (!options.GenerateInMemory) { cacheNew.Save(cacheFile); } if (!options.WriteCompiledFilesToWorkingDirectory && !options.WorkInTemporaryDirectory) { state.DeleteWorkingDirectory(); } } if (options.WriteCompiledFilesToWorkingDirectory && !options.WorkInTemporaryDirectory) { WriteCompiledFilesToWorkingDirectory(state, dataSourceWrapperInfos); } return(result); }
/// <summary> /// Compiles the specified collection of view models. /// </summary> private static BindingExpressionCompilationResult CompileViewModels(LegacyExpressionCompilerState state, IEnumerable <DataSourceWrapperInfo> models, String output, Boolean debug) { state.DeleteWorkingDirectory(); var referencedAssemblies = GetDefaultReferencedAssemblies(); var expressionVerificationResult = PerformExpressionVerificationCompilationPass(state, models, referencedAssemblies, debug); if (expressionVerificationResult.Errors.Cast <CompilerError>().Where(x => !x.IsWarning).Any()) { if (state.WriteErrorsToFile) { WriteErrorsToWorkingDirectory(state, models, expressionVerificationResult); } return(BindingExpressionCompilationResult.CreateFailed(CompilerStrings.FailedExpressionValidationPass, CreateBindingExpressionCompilationErrors(state, models, expressionVerificationResult.Errors))); } var setterEliminationPassResult = PerformSetterEliminationCompilationPass(state, models, referencedAssemblies, debug); var conversionFixupPassResult = PerformConversionFixupCompilationPass(state, models, referencedAssemblies, setterEliminationPassResult, debug); var finalPassResult = PerformFinalCompilationPass(state, state.GenerateInMemory ? null : output, models, referencedAssemblies, conversionFixupPassResult, debug); if (finalPassResult.Errors.Cast <CompilerError>().Where(x => !x.IsWarning).Any()) { if (state.WriteErrorsToFile) { WriteErrorsToWorkingDirectory(state, models, finalPassResult); } return(BindingExpressionCompilationResult.CreateFailed(CompilerStrings.FailedFinalPass, CreateBindingExpressionCompilationErrors(state, models, finalPassResult.Errors))); } return(BindingExpressionCompilationResult.CreateSucceeded(finalPassResult.CompiledAssembly)); }
/// <inheritdoc/> public BindingExpressionCompilationResult CompileSingleView(UltravioletContext uv, BindingExpressionCompilerOptions options) { Contract.Require(options, nameof(options)); if (String.IsNullOrEmpty(options.Input)) { throw new ArgumentException(PresentationStrings.InvalidCompilerOptions); } var definition = DataSourceLoader.CreateDataSourceDefinitionFromXml(options.RequestedViewModelNamespace, options.RequestedViewModelName, options.Input); if (definition == null) { return(BindingExpressionCompilationResult.CreateSucceeded()); } var compiler = CreateCodeProvider(); var state = new LegacyExpressionCompilerState(uv, compiler) { GenerateInMemory = options.GenerateInMemory, WorkInTemporaryDirectory = options.WorkInTemporaryDirectory, WriteErrorsToFile = options.WriteErrorsToFile }; var dataSourceWrapperInfo = DataSourceLoader.GetDataSourceWrapperInfo(state, definition.Value); var dataSourceWrapperInfos = new[] { dataSourceWrapperInfo }; var result = CompileViewModels(state, dataSourceWrapperInfos, null, options.GenerateDebugAssembly); if (result.Succeeded) { options.Output = dataSourceWrapperInfos[0].DataSourceWrapperSourceCode; } else { state.DeleteWorkingDirectory(); } return(result); }