/// <summary> /// Compiles an application. /// </summary> /// <param name="applicationContext">Application context.</param> /// <param name="config">Compiler configuration record.</param> /// <param name="errorSink">Error sink.</param> /// <param name="ps">Parameters.</param> /// <exception cref="InvalidSourceException">Cannot read a source file/directory. See the inner exception for details.</exception> public void Compile( ApplicationContext/*!*/ applicationContext, CompilerConfiguration/*!*/ config, ErrorSink/*!*/ errorSink, CompilationParameters/*!*/ ps) { if (applicationContext == null) throw new ArgumentNullException("applicationContext"); if (config == null) throw new ArgumentNullException("config"); if (errorSink == null) throw new ArgumentNullException("errorSink"); ps.Validate(); PhpSourceFile entry_point_file = (ps.StartupFile != null) ? new PhpSourceFile(config.Compiler.SourceRoot, ps.StartupFile) : null; List<ResourceFileReference> resource_files = ResourceFileReference.FromFiles(ps.Resources); // creates directory if not exists: try { Directory.CreateDirectory(Path.GetDirectoryName(ps.OutPath)); } catch (Exception ex) { errorSink.Add(FatalErrors.ErrorCreatingFile, null, ErrorPosition.Invalid, ps.OutPath, ex.Message); } AssemblyKinds kind; switch (ps.Target) { case Targets.Dll: kind = AssemblyKinds.Library; entry_point_file = null; break; case Targets.Console: kind = AssemblyKinds.ConsoleApplication; break; case Targets.WinApp: kind = AssemblyKinds.WindowApplication; break; case Targets.Web: kind = AssemblyKinds.WebPage; entry_point_file = null; break; default: throw new ArgumentException(); } PhpAssemblyBuilder assembly_builder = PhpAssemblyBuilder.Create(applicationContext, kind, ps.Pure, ps.OutPath, ps.DocPath, entry_point_file, ps.Version, ps.Key, ps.Icon, resource_files, config.Compiler.Debug, ps.Force32Bit); assembly_builder.IsMTA = ps.IsMTA; Statistics.CompilationStarted(); ICompilerManager manager = (!ps.Pure) ? new ApplicationCompilerManager(applicationContext, assembly_builder) : null; try { CompilationContext context = new CompilationContext(applicationContext, manager, config, errorSink, config.Compiler.SourceRoot); assembly_builder.Build(EnumerateScripts(ps.SourcePaths, ps.SourceDirs, ps.FileExtensions, context), context); if (!context.Errors.AnyError && (ps.Target == Targets.Console || ps.Target == Targets.WinApp)) CopyApplicationConfigFile(config.Compiler.SourceRoot, ps.OutPath); } catch (CompilerException e) { errorSink.Add(e.ErrorInfo, null, ErrorPosition.Invalid, e.ErrorParams); } catch (InvalidSourceException e) { e.Report(errorSink); } catch (Exception e) { #if DEBUG //Console.WriteLine("Unexpected error: {0}", e.ToString());// removed, exception added into the error sink, so it's displayed in the VS Integration too #endif errorSink.AddInternalError(e); // compilation will fail, error will be displayed in Errors by VS Integration } finally { #if DEBUG Console.WriteLine(); Console.WriteLine("Statistics:"); Statistics.Dump(Console.Out, Path.GetDirectoryName(ps.OutPath)); Console.WriteLine(); #endif } }