Exemplo n.º 1
0
        /// <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
			}
        }