public CommandLineParser(CompilationParameters/*!*/ ps) { if (ps == null) throw new ArgumentException("ps"); this.ps = ps; #if DEBUG verbose = true; #else verbose = false; #endif }
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; } }
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); } }
/// <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 } }
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; }