/// <summary> /// Converts a <see cref="CompilerErrorCollection"/> to a collection of <see cref="BindingExpressionCompilationError"/> objects. /// </summary> private static List <BindingExpressionCompilationError> CreateBindingExpressionCompilationErrors(LegacyExpressionCompilerState state, IEnumerable <DataSourceWrapperInfo> models, CompilerErrorCollection errors) { var result = new List <BindingExpressionCompilationError>(); var workingDirectory = state.GetWorkingDirectory(); var errorsByFile = errors.Cast <CompilerError>() .Where(x => !x.IsWarning).GroupBy(x => Path.GetFileName(x.FileName)).ToDictionary(x => x.Key, x => x.ToList()); foreach (var model in models) { var dataSourceWrapperFilename = Path.GetFileName(state.GetWorkingFileForDataSourceWrapper(model)); var dataSourceErrors = default(List <CompilerError>); if (errorsByFile.TryGetValue(dataSourceWrapperFilename, out dataSourceErrors)) { foreach (var dataSourceError in dataSourceErrors) { var fullPathToFile = model.DataSourceWrapperName; if (state.WriteErrorsToFile) { fullPathToFile = Path.GetFullPath(Path.Combine(workingDirectory, Path.ChangeExtension(model.DataSourceWrapperName, "cs"))); } result.Add(new BindingExpressionCompilationError(fullPathToFile, dataSourceError.Line, dataSourceError.Column, dataSourceError.ErrorNumber, dataSourceError.ErrorText)); } } } return(result); }
/// <summary> /// Compiles the specified data source wrapper sources into a managed assembly. /// </summary> private static CompilerResults CompileDataSourceWrapperSources(LegacyExpressionCompilerState state, String output, IEnumerable <DataSourceWrapperInfo> infos, IEnumerable <String> references, Boolean debug) { var options = new CompilerParameters(); options.OutputAssembly = output; options.GenerateExecutable = false; options.GenerateInMemory = true; options.IncludeDebugInformation = debug; options.TreatWarningsAsErrors = false; options.ReferencedAssemblies.AddRange(references.Distinct().ToArray()); var files = new List <String>(); files.Add(WriteCompilerMetadataFile()); foreach (var info in infos) { var path = state.GetWorkingFileForDataSourceWrapper(info); files.Add(path); File.WriteAllText(path, info.DataSourceWrapperSourceCode); } return(state.Compiler.CompileAssemblyFromFile(options, files.ToArray())); }
/// <summary> /// Performs the final compilation pass, which removes invalid expression setters based on the results of the previous pass. /// </summary> private static CompilerResults PerformFinalCompilationPass(LegacyExpressionCompilerState state, String output, IEnumerable <DataSourceWrapperInfo> models, ConcurrentBag <String> referencedAssemblies, CompilerResults nullableFixupResult, Boolean debug) { var errors = nullableFixupResult.Errors.Cast <CompilerError>().ToList(); Parallel.ForEach(models, model => { var dataSourceWrapperFilename = Path.GetFileName(state.GetWorkingFileForDataSourceWrapper(model)); var dataSourceWrapperErrors = errors.Where(x => Path.GetFileName(x.FileName) == dataSourceWrapperFilename).ToList(); foreach (var expression in model.Expressions) { if (expression.GenerateSetter && dataSourceWrapperErrors.Any(x => x.Line >= expression.SetterLineStart && x.Line <= expression.SetterLineEnd)) { expression.GenerateSetter = false; } } WriteSourceCodeForDataSourceWrapper(state, model); }); return(CompileDataSourceWrapperSources(state, output, models, referencedAssemblies, debug)); }
/// <summary> /// Performs the third compilation pass, which attempts to fix any errors caused by non-implicit conversions and nullable types that need to be cast to non-nullable types. /// </summary> private static CompilerResults PerformConversionFixupCompilationPass(LegacyExpressionCompilerState state, IEnumerable <DataSourceWrapperInfo> models, ConcurrentBag <String> referencedAssemblies, CompilerResults setterEliminationResult, Boolean debug) { var errors = setterEliminationResult.Errors.Cast <CompilerError>().ToList(); var fixableErrorNumbers = new List <String> { "CS0266", "CS1502", "CS1503" }; Parallel.ForEach(models, model => { var dataSourceWrapperFilename = Path.GetFileName(state.GetWorkingFileForDataSourceWrapper(model)); var dataSourceWrapperErrors = errors.Where(x => Path.GetFileName(x.FileName) == dataSourceWrapperFilename).ToList(); foreach (var expression in model.Expressions) { var setterErrors = dataSourceWrapperErrors.Where(x => x.Line >= expression.SetterLineStart && x.Line <= expression.SetterLineEnd).ToList(); var setterIsNullable = Nullable.GetUnderlyingType(expression.Type) != null; expression.GenerateSetter = !setterErrors.Any() || (setterIsNullable && setterErrors.All(x => fixableErrorNumbers.Contains(x.ErrorNumber))); expression.NullableFixup = setterIsNullable; if (setterErrors.Count == 1 && setterErrors.Single().ErrorNumber == "CS0266") { var error = setterErrors.Single(); var match = regexCS0266.Match(error.ErrorText); expression.CS0266SourceType = match.Groups["source"].Value; expression.CS0266TargetType = match.Groups["target"].Value; expression.GenerateSetter = true; } } WriteSourceCodeForDataSourceWrapper(state, model); }); return(CompileDataSourceWrapperSources(state, null, models, referencedAssemblies, debug)); }