/// <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();
                }
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        /// <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);
        }