private static CommandLineConfiguration GetCommandLineConfiguration( WorkspaceBuilderConfiguration configuration, EnginePhases phase, AbsolutePath configFile, AbsolutePath outputDirectory, AbsolutePath objectDirectory) { return(new CommandLineConfiguration { Startup = { ConfigFile = configFile, }, FrontEnd = { DebugScript = false, PreserveFullNames = true, PreserveTrivia = true, // We want to preserve comments, so let's not skip trivia CancelParsingOnFirstFailure = configuration.CancelOnFirstParsingFailure, UseSpecPublicFacadeAndAstWhenAvailable = configuration.PublicFacadeOptimization, ConstructAndSaveBindingFingerprint = configuration.SaveBindingFingerprint, NameResolutionSemantics = NameResolutionSemantics.ImplicitProjectReferences, // If SkipNuget is specified, then all the packages should be on disk. // Skipping nuget restore in this case. UsePackagesFromFileSystem = configuration.SkipNuget, // Don't release workspace so that analyses can still be done if the min required phase is evaluation. // TODO: Hack -- when phase Evaluate is use, then release workspace. This is for Office to be performant. ReleaseWorkspaceBeforeEvaluation = !phase.HasFlag(EnginePhases.Evaluate), UnsafeOptimizedAstConversion = true, AllowUnsafeAmbient = true, }, Engine = { Phase = phase, }, Schedule = { UseFixedApiServerMoniker = true }, Layout = { OutputDirectory = outputDirectory, ObjectDirectory = objectDirectory, }, Logging = { LogsToRetain = 0, }, Cache = { CacheSpecs = SpecCachingOption.Disabled } }); }
public static bool TryBuildWorkspace( EnginePhases phase, FrontEndContext frontEndContext, EngineContext engineContext, AbsolutePath configFile, EvaluationFilter evaluationFilter, AbsolutePath outputDirectory, AbsolutePath objectDirectory, EventHandler <WorkspaceProgressEventArgs> progressHandler, out Workspace workspace, out FrontEndHostController frontEndHostController, out IPipGraph pipGraph, WorkspaceBuilderConfiguration configuration, FrontEndEngineAbstraction frontEndEngineAbstraction = null, bool collectMemoryAsSoonAsPossible = true) { Contract.Requires((phase & (EnginePhases.ParseWorkspace | EnginePhases.AnalyzeWorkspace)) != EnginePhases.None); Contract.Requires(frontEndContext != null); Contract.Requires(engineContext != null); Contract.Requires(configFile.IsValid); Contract.Requires(evaluationFilter != null); workspace = null; frontEndHostController = null; pipGraph = null; var pathTable = engineContext.PathTable; var loggingContext = frontEndContext.LoggingContext; var commandlineConfig = GetCommandLineConfiguration( configuration, phase, configFile, outputDirectory, objectDirectory); BuildXLEngine.PopulateLoggingAndLayoutConfiguration(commandlineConfig, pathTable, bxlExeLocation: null); var statistics = new FrontEndStatistics(progressHandler); var frontEndControllerFactory = FrontEndControllerFactory.Create( mode: FrontEndMode.NormalMode, loggingContext: loggingContext, configuration: commandlineConfig, collector: null, statistics: statistics, collectMemoryAsSoonAsPossible: collectMemoryAsSoonAsPossible); var controller = frontEndControllerFactory.Create(engineContext.PathTable, engineContext.SymbolTable); controller.InitializeHost(frontEndContext, commandlineConfig); frontEndHostController = (FrontEndHostController)controller; // If there is an explicit engine abstraction, we set it. This is used by IDE test. if (frontEndEngineAbstraction != null) { frontEndHostController.SetState(frontEndEngineAbstraction, pipGraph: null, configuration: commandlineConfig); } var config = controller.ParseConfig(commandlineConfig); if (config == null) { return(false); } IPipGraph pipGraphBuilder = null; using (var cache = Task.FromResult <Possible <EngineCache> >( new EngineCache( new InMemoryArtifactContentCache(), // Note that we have an 'empty' store (no hits ever) rather than a normal in memory one. new EmptyTwoPhaseFingerprintStore()))) { if (frontEndEngineAbstraction == null) { if (phase.HasFlag(EnginePhases.Schedule)) { var mountsTable = MountsTable.CreateAndRegister(loggingContext, engineContext, config, commandlineConfig.Startup.Properties); frontEndEngineAbstraction = new FrontEndEngineImplementation( loggingContext, frontEndContext.PathTable, config, commandlineConfig.Startup, mountsTable, InputTracker.CreateDisabledTracker(loggingContext), null, null, () => FileContentTable.CreateStub(), 5000, false); pipGraphBuilder = new GraphFragmentBuilder(loggingContext, engineContext, config); // TODO: Think more if an analyzer wants to use the real pip graph builder. //pipGraphBuilder = new PipGraph.Builder( // EngineSchedule.CreateEmptyPipTable(engineContext), // engineContext, // Scheduler.Tracing.Logger.Log, // loggingContext, // config, // mountsTable.MountPathExpander, // fingerprintSalt: config.Cache.CacheSalt, // directoryMembershipFingerprinterRules: new DirectoryMembershipFingerprinterRuleSet(config, engineContext.StringTable)); if (!AddConfigurationMountsAndCompleteInitialization(config, loggingContext, mountsTable)) { return(false); } IDictionary <ModuleId, MountsTable> moduleMountsTableMap; if (!mountsTable.PopulateModuleMounts(config.ModulePolicies.Values, out moduleMountsTableMap)) { Contract.Assume(loggingContext.ErrorWasLogged, "An error should have been logged after MountTable.PopulateModuleMounts()"); return(false); } } else { frontEndEngineAbstraction = new BasicFrontEndEngineAbstraction(frontEndContext.PathTable, frontEndContext.FileSystem, config); } } using (frontEndEngineAbstraction is IDisposable ? (IDisposable)frontEndEngineAbstraction : null) { // Attempt to build and/or analyze the workspace if (!controller.PopulateGraph( cache: cache, graph: pipGraphBuilder, engineAbstraction: frontEndEngineAbstraction, evaluationFilter: evaluationFilter, configuration: config, startupConfiguration: commandlineConfig.Startup)) { workspace = frontEndHostController.GetWorkspace(); // Error has been reported already return(false); } pipGraph = pipGraphBuilder; //if (pipGraphBuilder != null) //{ // pipGraph = pipGraphBuilder.Build(); // if (pipGraph == null) // { // // Error has been reported already. // return false; // } //} } } Contract.Assert(frontEndHostController != null); workspace = frontEndHostController.GetWorkspace(); if (phase == EnginePhases.AnalyzeWorkspace) { // If workspace construction is successful, we run the linter on all specs. // This makes sure the workspace will carry all the errors that will occur when running the same specs in the regular engine path workspace = CreateLintedWorkspace( workspace, frontEndContext.LoggingContext, config.FrontEnd, pathTable); } return(true); }