public GenBinPath(StObjEngineRunContext global, StObjCollectorResult result, RunningBinPathGroup group) { Debug.Assert(!result.HasFatalError); _global = global; Result = result; ConfigurationGroup = group; Memory = new Dictionary <object, object?>(); ServiceContainer = new SimpleServiceContainer(_global.ServiceContainer); ServiceContainer.Add(result.DynamicAssembly.GetPocoSupportResult()); }
StObjEngineResult DoRun(IStObjCollectorResultResolver?resolver) { Throw.CheckState("Run can be called only once.", !_hasRun); _hasRun = true; if (!_config.CheckAndValidate(_monitor)) { return(new StObjEngineResult(false, _config)); } if (_ckSetupConfig != null) { _config.ApplyCKSetupConfiguration(_monitor, _ckSetupConfig); } if (!_config.Initialize(_monitor, out bool canSkipRun)) { return(new StObjEngineResult(false, _config)); } // If canSkipRun is true here it means that regarding the 2 core generated artifacts, there is // nothing to do. using var _ = _monitor.OpenInfo("Running StObjEngine setup."); _status = new Status(_monitor); _startContext = new StObjEngineConfigureContext(_monitor, _config, _status, canSkipRun); try { // Creating and configuring the aspects. _startContext.CreateAndConfigureAspects(() => _status.Success = false); if (_status.Success && _startContext.CanSkipRun) { _monitor.Info("Skipping run."); _status.Success |= UpdateGeneratedArtifacts(_config.Groups); _startContext.OnSkippedRun(() => _status.Success = false); return(new StObjEngineResult(_status.Success, _config)); } if (_status.Success) { StObjEngineRunContext runCtx = new StObjEngineRunContext(_monitor, _startContext); // Creates the StObjCollectorResult for each group of compatible BinPaths // and instantiates a StObjEngineRunContext.GenPath that exposes the engine map and the dynamic assembly // for each of them through IGeneratedBinPath, ICodeGenerationContext and ICSCodeGenerationContext. foreach (var g in _config.Groups) { using (_monitor.OpenInfo(g.IsUnifiedPure ? $"Analyzing types from Unified Working directory '{g.Configuration.Path}'." : $"Analyzing types from BinPaths '{g.SimilarConfigurations.Select( b => b.Path.Path ).Concatenate( "', '" )}'.")) { StObjCollectorResult?r = resolver?.GetResult(g) ?? SafeBuildStObj(g); if (r == null) { _status.Success = false; break; } runCtx.AddResult(g, r); } } // This is where all aspects runs before Code generation: this is where CK.Setupable.Engine.SetupableAspect.Run(): // - Builds the ISetupItem items (that support 3 steps setup) associated to each StObj (relies on EngineMap.StObjs.OrderedStObjs). // - Projects the StObj topological order on the ISetupItem items graph. // - Calls the DynamicItemInitialize methods that can create new Setup items (typically as child of existing containers like SqlProcedure on SqlTable) // - The ISetupItems are then sorted topologically (this is the second graph). // - The Init/Install/Settle steps are executed. if (_status.Success) { runCtx.RunAspects(() => _status.Success = false, postCode: false); } // Code Generation. if (_status.Success) { using (_monitor.OpenInfo("Code Generation.")) { foreach (var g in runCtx.AllBinPaths) { if (!g.Result.GenerateSourceCode(_monitor, g, _config.Configuration.InformationalVersion, runCtx.Aspects.OfType <ICSCodeGenerator>())) { _status.Success = false; break; } } } } // Handling generated artifacts. _status.Success &= UpdateGeneratedArtifacts(runCtx.AllBinPaths.Select(g => g.ConfigurationGroup)); // Run the aspects Post Code Generation. if (_status.Success) { runCtx.RunAspects(() => _status.Success = false, postCode: true); } // Secure errors (ensure error log and logs error path). if (!_status.Success) { // Emit the last error log path as an error and ensure that at least one error // has been logged on failure. var errorPath = _status.LastErrorPath; if (errorPath == null || errorPath.Count == 0) { _monitor.Fatal("Success status is false but no error has been logged."); } else { _monitor.Error(errorPath.ToStringPath()); } } // Always runs the aspects Termination. var termCtx = new StObjEngineTerminateContext(_monitor, runCtx); termCtx.TerminateAspects(() => _status.Success = false); } return(new StObjEngineResult(_status.Success, _config)); } finally { DisposeDisposableAspects(); _status.Dispose(); } }
public StObjEngineTerminateContext(IActivityMonitor monitor, StObjEngineRunContext runContext) { _monitor = monitor; _runContext = runContext; _trampoline = new StObjEngineAspectTrampoline <IStObjEngineTerminateContext>(this); }