Esempio n. 1
0
        internal ImmutableContextBase(
            ContextTree contextTree,
            ImmutableContextBase parent,
            [NotNull] ModuleLiteral module,
            TopLevelValueInfo topLevelValueInfo,
            FileType fileType,
            EvaluatorConfiguration configuration,
            [NotNull] IEvaluationScheduler evaluationScheduler)
        {
            Contract.Requires(contextTree.IsValid);
            Contract.Requires(parent == null || parent.ContextTree == contextTree);
            Contract.Requires(module != null);
            Contract.Requires(evaluationScheduler != null);

            ParentContext          = parent;
            LastActiveUsedModule   = module;
            TopLevelValueInfo      = topLevelValueInfo;
            ContextTree            = contextTree;
            DebugState             = new DebugState();
            m_relativePath         = RelativePath.Invalid;
            EvaluatorConfiguration = configuration;
            EvaluationScheduler    = evaluationScheduler;
            FileType = fileType;
            if (parent != null)
            {
                m_callStack = parent.m_callStack;
            }
        }
Esempio n. 2
0
 public Task <bool?> TryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition module, QualifierId qualifierId)
 {
     Contract.Requires(scheduler != null);
     Contract.Requires(module != null);
     Contract.Requires(qualifierId.IsValid);
     throw new System.NotImplementedException();
 }
Esempio n. 3
0
        /// <nodoc />
        protected ContextTree CreateContext(
            FileModuleLiteral instantiatedModule,
            IEvaluationScheduler evaluationScheduler,
            IDecorator <EvaluationResult> decorator,
            EvaluatorConfiguration configuration,
            FileType fileType)
        {
            Contract.Requires(instantiatedModule != null);
            Contract.Requires(evaluationScheduler != null);

            return(new ContextTree(
                       FrontEndHost,
                       Context,
                       Constants,
                       SharedModuleRegistry,
                       Logger,
                       Statistics,
                       qualifierValueCache: QualifierValueCache,
                       isBeingDebugged: IsBeingDebugged,
                       decorator: decorator,
                       module: instantiatedModule,
                       configuration: configuration,
                       evaluationScheduler: evaluationScheduler,
                       fileType: fileType));
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public async Task <bool?> TryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition iModule, QualifierId qualifierId)
        {
            if (!iModule.Equals(ModuleDef))
            {
                return(null);
            }

            return(await Task.FromResult(TryEvaluate(ModuleDef, qualifierId)));
        }
Esempio n. 5
0
        /// <inheritdoc/>
        public async Task <bool?> TryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition iModule, QualifierId qualifierId)
        {
            if (!iModule.Equals(ModuleDefinition))
            {
                return(null);
            }

            var module = (ModuleDefinition)iModule;

            return(await EvaluateAllFilesAsync(module.Specs, qualifierId));
        }
Esempio n. 6
0
        /// <inheritdoc/>
        public async Task <bool?> TryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition iModule, QualifierId qualifierId)
        {
            if (!iModule.Equals(ModuleDef))
            {
                return(null);
            }

            // Note: we are effectively evaluating iModule
            // Using await to suppress compiler warnings
            // TODO: Async?
            return(await Task.FromResult(TryEvaluate(ModuleDef, qualifierId)));
        }
Esempio n. 7
0
        /// <inheritdoc />
        public 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(Task.FromResult <bool?>(null));
            }

            // Downloads are not individually requested to be evaluated, we want them to be on demand.
            return(Task.FromResult <bool?>(true));
        }
Esempio n. 8
0
        public ContextTree(
            [NotNull] FrontEndHost frontEndHost,
            [NotNull] FrontEndContext frontEndContext,
            [NotNull] GlobalConstants constants,
            [NotNull] ModuleRegistry moduleRegistry,
            [NotNull] Logger logger,
            [NotNull] EvaluationStatistics statistics,
            QualifierValueCache qualifierValueCache,
            bool isBeingDebugged,
            IDecorator <EvaluationResult> decorator,
            [NotNull] FileModuleLiteral module,
            [NotNull] EvaluatorConfiguration configuration,
            [NotNull] IEvaluationScheduler evaluationScheduler,
            FileType fileType)
        {
            Contract.Requires(frontEndHost != null);
            Contract.Requires(frontEndContext != null);
            Contract.Requires(constants != null);
            Contract.Requires(moduleRegistry != null);
            Contract.Requires(logger != null);
            Contract.Requires(statistics != null);
            Contract.Requires(module != null);

            EvaluationScheduler = evaluationScheduler;

            FrontEndHost        = frontEndHost;
            FrontEndContext     = frontEndContext;
            Constants           = constants;
            ModuleRegistry      = moduleRegistry;
            Logger              = logger;
            Statistics          = statistics;
            IsBeingDebugged     = isBeingDebugged;
            Decorator           = decorator;
            EvaluationScheduler = evaluationScheduler;
            QualifierValueCache = qualifierValueCache;
            ToolDefinitionCache = new ConcurrentDictionary <ObjectLiteral, CachedToolDefinition>();
            ValueCache          = new ConcurrentDictionary <Fingerprint, EvaluationResult>();
            CommonConstants     = new CommonConstants(frontEndContext.StringTable);

            RootContext =
                new Context(
                    contextTree: this,
                    parent: null,
                    module: module,
                    topLevelValueInfo: null,
                    fileType: fileType,
                    configuration: configuration,
                    evaluationScheduler: evaluationScheduler);

            Interlocked.Increment(ref statistics.ContextTrees);
        }
Esempio n. 9
0
        /// <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();
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Evaluates a single package, and all projects that the package owns.
        /// </summary>
        private IReadOnlyList <Task <EvaluationResult> > EvaluatePackage(IEvaluationScheduler scheduler, Package package, QualifierValue qualifier)
        {
            Contract.Requires(package != null);
            Contract.Requires(qualifier != null);

            var projectsToEvaluate            = GetProjectsOfPackage(package);
            var shouldEvaluateLocalTransitive = ShouldEvaluateLocalTransitivePackage(package);

            // Note that, if package does not explicitly specifies the projects that it owns, then
            // we only evaluate the package's main file, and rely on the import/export relation to evaluate all
            // specs in the package. Another alternative is to glob all projects in the package's cone, and
            // evaluate those projects as well. Globbing involves IO, and can be expensive in a spinning disk.
            // For a consideration, WDG may only have one package, and may not specifiy all projects that the package
            // owns. Globbing the entire WDG tree will be very costly.
            return(projectsToEvaluate.Select(project => EvaluateAsync(scheduler, project, qualifier, asPackageEvaluation: shouldEvaluateLocalTransitive)).ToList());
        }
Esempio n. 11
0
        /// <inheritdoc/>
        public async Task <bool?> TryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition module, QualifierId qualifierId)
        {
            Contract.Requires(scheduler != null);
            Contract.Requires(module != null);
            Contract.Requires(qualifierId.IsValid);

            Contract.Assert(m_resolverState == State.ResolverInitialized);
            Contract.Assert(m_owningModules != null, "Owning modules should not be null if the instance is initialized.");

            var moduleDefinition = (ModuleDefinition)module;

            if (!m_owningModules.TryGetValue(moduleDefinition.Descriptor.Id, out Package package))
            {
                // Current resolver doesn't own the given module.
                return(null);
            }

            return(await DoTryEvaluateModuleAsync(scheduler, moduleDefinition, qualifierId));
        }
Esempio n. 12
0
        private async Task <bool> DoTryEvaluateModuleAsync(IEvaluationScheduler scheduler, ModuleDefinition module, QualifierId qualifierId)
        {
            var qualifier = QualifierValue.Create(qualifierId, QualifierValueCache, Context.QualifierTable, Context.StringTable);

            // We don't want to evaluate the transitive closure of the import/export relationship, just the package.
            var evalJobs = module.Specs.Select(
                spec => EvaluateAsync(scheduler, spec, qualifier, asPackageEvaluation: false));

            var allTasks = await Task.WhenAll(evalJobs);

            var result = allTasks.All(t => t.Success);

            if (m_evaluationDecorator != null)
            {
                foreach (var evaluationResult in allTasks)
                {
                    m_evaluationResults.Enqueue(evaluationResult);
                }
            }

            return(result);
        }
Esempio n. 13
0
        private async Task <EvaluationResult> CollectProjectOutputsAsync(IReadOnlySet <AbsolutePath> evaluationGoals, QualifierId qualifierId, ResolvedJavaScriptExport export, IEvaluationScheduler scheduler)
        {
            // Make sure all project files are evaluated before collecting their outputs
            if (!await EvaluateAllFilesOnceAsync(evaluationGoals, qualifierId, scheduler))
            {
                return(EvaluationResult.Error);
            }

            var processOutputs = export.ExportedProjects.SelectMany(project => {
                if (!m_scheduledProcessOutputs.TryGetValue(project, out var projectOutputs))
                {
                    // The requested project was not scheduled. This can happen when a filter gets applied, so even
                    // though the export points to a valid project (which is already validated), the project is not part
                    // of the graph. In this case just log an informational message.
                    Tracing.Logger.Log.RequestedExportIsNotPresent(
                        Context.LoggingContext,
                        m_resolverSettings.Location(Context.PathTable),
                        export.FullSymbol.ToString(Context.SymbolTable),
                        project.Name,
                        project.ScriptCommandName);
                }

                return(projectOutputs);
            });

            // Let's put together all output directories for all pips under this project
            var sealedDirectories = processOutputs.SelectMany(process => process.GetOutputDirectories().Select(staticDirectory => new EvaluationResult(staticDirectory))).ToArray();

            return(new EvaluationResult(new EvaluatedArrayLiteral(sealedDirectories, default, m_javaScriptWorkspaceResolver.ExportsFile)));
Esempio n. 14
0
        /// <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));
                }
        }