Пример #1
0
		public CommandLineParser(CompilationParameters/*!*/ ps)
		{
			if (ps == null)
				throw new ArgumentException("ps");
		
			this.ps = ps;
#if DEBUG
			verbose = true;
#else
			verbose = false;
#endif
		}
Пример #2
0
        public void RemoteCompile(
			ref ErrorSink/*!*/ errorSink,
			CompilationParameters/*!*/ ps)
		{
			errorSink = new PassthroughErrorSink(errorSink);

			ApplicationContext.DefineDefaultContext(false, true, false);
			ApplicationContext app_context = ApplicationContext.Default;
			
			CompilerConfiguration compiler_config;

			// loads entire configuration:
			try
			{
				compiler_config = LoadConfiguration(app_context, ps.ConfigPaths, null);			
			}
			catch (ConfigurationErrorsException e)
			{
				errorSink.AddConfigurationError(e);
				return;
			}

			ps.ApplyToConfiguration(compiler_config);

			// load referenced assemblies:
			try
			{
				app_context.AssemblyLoader.Load(ps.References);
			}
			catch (ConfigurationErrorsException e)
			{
				errorSink.AddConfigurationError(e);
				return;
			}
			
			try
			{
				errorSink.DisabledGroups = compiler_config.Compiler.DisabledWarnings;
				errorSink.DisabledWarnings = compiler_config.Compiler.DisabledWarningNumbers;
                errorSink.TreatWarningsAsErrors = compiler_config.Compiler.TreatWarningsAsErrors;
			
				// initializes log:
				DebugUtils.ConsoleInitialize(Path.GetDirectoryName(ps.OutPath));

				Compile(app_context, compiler_config, errorSink, ps);
			}
			catch (InvalidSourceException e)
			{
				e.Report(errorSink);
				return;
			}
			catch (Exception e)
			{
				errorSink.AddInternalError(e);
				return;
			}
        }
Пример #3
0
		public void RemoteCompile(ref ErrorSink/*!*/ errorSink, CompilationParameters/*!*/ ps)
		{
			lock (buildMutex) // TODO: do we need thread-safety (if yes, there is a better way)?
			{
				//if (++buildCounter % 10 == 0) // TODO: is it possible to estimate size of memory allocated by the domain?
				//{
				//  // if a referenced assembly gets updated then we should reload the domain as well
				//  AppDomain.Unload(remoteCompiler.Domain);
				//  remoteCompiler = null;
				//}

                if (remoteCompiler != null)
                    AppDomain.Unload(remoteCompiler.Domain);

				remoteCompiler = ApplicationCompiler.CreateRemoteCompiler();

				remoteCompiler.RemoteCompile(ref errorSink, ps);
			}
		}
Пример #4
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
			}
        }
Пример #5
0
		public override bool Execute()
		{
			Log.LogMessage(MessageImportance.Normal, "Phalanger Compilation Task");

			CompilationParameters ps = new CompilationParameters();

			// source root (project directory by default):
			ps.SourceRoot = new FullPath(sourceRoot);

			// target type:
			string assembly_extension;
			switch (outputType.ToLower())
			{
				case "dll":
				case "library":
					ps.Target = ApplicationCompiler.Targets.Dll;
					assembly_extension = ".dll";
					break;

				case "exe":
				case "console":
					ps.Target = ApplicationCompiler.Targets.Console;
					assembly_extension = ".exe";
					break;

				case "winexe":
				case "winapp":
					ps.Target = ApplicationCompiler.Targets.WinApp;
					assembly_extension = ".exe";
					break;

				case "webapp":
                    ps.Target = ApplicationCompiler.Targets.Web;
                    assembly_extension = ".dll";
					// TODO: precompile option
					return true;

				default:
					Log.LogError("Invalid output type: '{0}'.", outputType);
					return false;
			}

			if (Path.GetExtension(outputAssembly) != assembly_extension)
			{
				Log.LogError("Output assembly extension doesn't match project type.");
				return false;
			}

			if (contentFiles != null)
			{
				foreach (string file in contentFiles)
				{
					if (String.Compare(Path.GetExtension(file), ".config", true) == 0)
					{
						ps.ConfigPaths.Add(new FullPath(file, ps.SourceRoot));
					}
				}
			}

			// debug symbols:
			ps.Debuggable = this.debug;

			// language features:
			ps.Pure = ApplicationCompiler.IsPureUnit(compilationMode);

			if (!String.IsNullOrEmpty(languageFeatures))
			{
				try
				{
					ps.LanguageFeatures = (Core.LanguageFeatures)Enum.Parse(typeof(Core.LanguageFeatures),
						languageFeatures, true);
				}
				catch (Exception)
				{
					Log.LogError("Invalid language features.");
					return false;
				}
			}
			else
			{
				ps.LanguageFeatures = (ps.Pure) ? Core.LanguageFeatures.PureModeDefault : Core.LanguageFeatures.Default;
			}

			// source paths:
			GetSourcePaths(ps.SourceRoot, ps.SourcePaths);

			// directories (TODO) 
			// ps.SourceDirs
			// extensions (TODO) 
			// ps.FileExtensions = null;

			if (ps.SourcePaths.Count == 0 && ps.SourceDirs.Count == 0)
			{
				Log.LogError("No source files to compile.");
				return false;
			}

			// out path:
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(outputAssembly));
			}
			catch (Exception e)
			{
				Log.LogErrorFromException(e);
				return false;
			}

			ps.OutPath = new FullPath(outputAssembly);

			// doc path (TODO):
			ps.DocPath = FullPath.Empty;

			// startup file/class:
			ps.StartupFile = FullPath.Empty;
			// TODO: string startup_class = null;

			if (ps.Target == ApplicationCompiler.Targets.Console || ps.Target == ApplicationCompiler.Targets.WinApp)
			{
				if (ps.Pure)
				{
					if (!String.IsNullOrEmpty(startupObject))
					{
						// TODO: startup_class = startupObject;

						Log.LogWarning("Startup class is ignored -- the feature is not supported yet.");
						return false;
					}
					else
					{
						// TODO: startup_class = null;
					}
				}
				else
				{
					if (String.IsNullOrEmpty(startupObject))
					{
						if (ps.SourcePaths.Count > 1)
						{
							Log.LogError("The startup file must be specified in the project property pages.");
							return false;
						}
						else
						{
							ps.StartupFile = new FullPath(ps.SourcePaths[0], ps.SourceRoot);
						}
					}
					else
					{
						try
						{
							ps.StartupFile = new FullPath(startupObject, ps.SourceRoot);
						}
						catch (Exception e)
						{
							Log.LogErrorFromException(e);
							return false;
						}

						// startup file is not in the list of compiled files:
						if (ps.SourcePaths.IndexOf(ps.StartupFile) == -1)
						{
							Log.LogError("The startup file specified in the property pages must be included in the project.");
							return false;
						}
					}
				}
			}

			// icon:
			ps.Icon = null;
			try
			{
				if (applicationIcon != null)
					ps.Icon = new Win32IconResource(new FullPath(applicationIcon, ps.SourceRoot));
			}
			catch (Exception e)
			{
				Log.LogErrorFromException(e);
				return false;
			}

			// strong name, version (TODO):
            try
            {
                ps.Version = new Version(1, 0, 0, 0);
                ps.Key = null;
                if (!string.IsNullOrEmpty(keyFile))
                {
                    using (FileStream file = new FileStream(new FullPath(keyFile, ps.SourceRoot), FileMode.Open))
                        ps.Key = new StrongNameKeyPair(file);
                }
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e);
                return false;
            }
            
            //Resources
            foreach(ITaskItem resource in this.ResourceFiles) {
                bool publicVisibility = true;
                string access = resource.GetMetadata("Access");
                if(String.CompareOrdinal("Private", access) == 0)
                    publicVisibility = false;
                string filename = resource.ItemSpec;
                string logicalName = resource.GetMetadata("LogicalName");
                if(String.IsNullOrEmpty(logicalName))
                    logicalName = Path.GetFileName(resource.ItemSpec);
                ps.Resources.Add(new ResourceFileReference(filename,logicalName,publicVisibility));
            }

			// referenced assemblies:

			//if (referencedAssemblies != null)
            if (references != null)
			{
                foreach (ITaskItem assemblyReference in references/*referencedAssemblies*/)
                {
                    //string hintPath = assemblyReference.GetMetadata("HintPath");
                    //if (!string.IsNullOrEmpty(hintPath) &&
                    //    System.IO.File.Exists(assemblyReference.GetMetadata("HintPath")))
                    //    ps.References.Add(hintPath);    // add the assembly reference by its file name
                    //else
                        ps.References.Add(assemblyReference.ItemSpec);
                }
			}

			// errors, warnings:
			ErrorSink sink = new CompilerErrorSink(this.Log);

			if (!String.IsNullOrEmpty(disabledWarnings))
			{
				try
				{
					ps.DisableWarningNumbers = ConfigUtils.ParseIntegerList(disabledWarnings, ',', 1, 10000, null);
				}
				catch (Exception)
				{
					Log.LogError("Invalid list of disabled warnings.");
					return false;
				}
			}
			else
			{
				ps.DisableWarningNumbers = ArrayUtils.EmptyIntegers;
			}

            ps.EnableWarnings |= WarningGroups.DeferredToRuntime;   // enable deferred to runtime warnings

            // compile

			try
			{
				//ApplicationCompiler.CompileInSeparateDomain(sink, ps);
				RemoteCompile(ref sink, ps);
			}
			catch (InvalidSourceException e)
			{
				e.Report(sink);
				return false;
			}
			catch (Exception e)
			{
				sink.AddInternalError(e);
				return false;
			}

			return !sink.AnyError;
		}