/// <inheritdoc /> public async Task <bool?> TryEvaluateModuleAsync([NotNull] IEvaluationScheduler scheduler, [NotNull] ModuleDefinition module, QualifierId qualifierId) { // Abstraction between SDK/Workspace/Core/Resolvers is broken here... var moduleDefinition = (ModuleDefinition)module; if (!string.Equals(moduleDefinition.Descriptor.ResolverName, Name, StringComparison.Ordinal)) { return(null); } var downloadData = m_workspaceResolver.Downloads[module.Descriptor.Name]; // Make sure evaluating is guarded by the semaphore, so it only happens one at a time // There is no need to make sure we don't evaluate duplicate work here since module evaluation // happens once per qualifier. await m_evaluationSemaphore.WaitAsync(); try { // Modules of the download resolver are always instantiated with the empty qualifier var moduleRegistry = (ModuleRegistry)m_frontEndHost.ModuleRegistry; var moduleLiteral = moduleRegistry .GetUninstantiatedModuleInfoByPath(downloadData.ModuleSpecFile) .FileModuleLiteral .InstantiateFileModuleLiteral(moduleRegistry, QualifierValue.CreateEmpty(m_context.QualifierTable)); // Evaluate all values of the module using (var contextTree = new ContextTree( m_frontEndHost, m_context, m_logger, m_evaluationStatistics, new QualifierValueCache(), isBeingDebugged: false, decorator: null, moduleLiteral, new EvaluatorConfiguration(trackMethodInvocations: false, cycleDetectorStartupDelay: TimeSpanUtilities.MillisecondsToTimeSpan(10)), scheduler, FileType.Project)) { var moduleTracker = VisitedModuleTracker.Create(isDebug: false); var success = await moduleLiteral.EvaluateAllAsync(contextTree.RootContext, moduleTracker, ModuleEvaluationMode.None); return(success); } } finally { m_evaluationSemaphore.Release(); } }
private static EvaluationResult CreateResult(bool success, VisitedModuleTracker tracker) { return(new EvaluationResult(success, tracker.GetVisitedModules())); }
/// <summary> /// Evaluates a file given the file path and a qualifier. /// </summary> /// <remarks> /// If the evaluation is part of package evaluation, then all files in the transitive closure of /// local import/export relation will be evaluated as well. /// </remarks> private async Task <EvaluationResult> EvaluateAsync(IEvaluationScheduler scheduler, AbsolutePath fullPath, QualifierValue qualifier, bool asPackageEvaluation) { Contract.Requires(fullPath.IsValid); Contract.Requires(qualifier != null); // Get an uninstantiated module. if (!((ModuleRegistry)FrontEndHost.ModuleRegistry).TryGetUninstantiatedModuleInfoByPath(fullPath, out UninstantiatedModuleInfo moduleInfo)) { Logger.ReportSourceResolverFailEvaluateUnregisteredFileModule(Context.LoggingContext, Name, fullPath.ToString(Context.PathTable)); return(CreateResult(false)); } // If this spec belongs to a V1 module, then coercion happens at this point, since in V1 the qualifier space is always defined at the file level // and we want an explicit failure if coercion fails, to keep V1 modules back compat // Otherwise, we don't coerce, since coercion will happen on a namespace level in FileModuleLiteral.EvaluateAllNamedValues if (!FrontEndHost.SpecBelongsToImplicitSemanticsModule(fullPath)) { // Coerce qualifier. if (!qualifier.TryCoerce( moduleInfo.QualifierSpaceId, Context.QualifierTable, QualifierValueCache, Context.PathTable, Context.StringTable, Context.LoggingContext, out QualifierValue coercedQualifier, default(LineInfo), FrontEndHost.ShouldUseDefaultsOnCoercion(moduleInfo.ModuleLiteral.Path), fullPath)) { string qualifierName = Context.QualifierTable.GetQualifier(qualifier.QualifierId).ToDisplayString(Context.StringTable); string qualifierSpace = Context.QualifierTable.GetQualifierSpace(moduleInfo.QualifierSpaceId).ToDisplayString(Context.StringTable); Logger.ReportQualifierCannotBeCoarcedToQualifierSpace( Context.LoggingContext, new Location { // Ideally the referencing location is used for this error, but that is a big replumbing effort. // Task 615531 File = fullPath.ToString(Context.PathTable), }, qualifierName, qualifierSpace); return(CreateResult(false)); } qualifier = coercedQualifier; } // Instantiate module with the coerced qualifier. var module = InstantiateModule(moduleInfo.FileModuleLiteral, qualifier); // Create an evaluation context tree and root context. using (var contextTree = CreateContext(module, scheduler, m_evaluationDecorator, CreateEvaluatorConfiguration(), FileType.Project)) using (FrontEndStatistics.SpecEvaluation.Start(fullPath.ToString(Context.PathTable))) { var context = contextTree.RootContext; // Evaluate module. var moduleTracker = VisitedModuleTracker.Create(IsBeingDebugged); var mode = asPackageEvaluation ? ModuleEvaluationMode.LocalImportExportTransitive : ModuleEvaluationMode.None; var success = await module.EvaluateAllAsync(context, moduleTracker, mode); return(CreateResult(success, moduleTracker)); } }