예제 #1
0
        /// <summary>
        /// Creates a queue that starts with some already parsed module and a pending module under construction
        /// </summary>
        public static ModuleParsingQueue CreateIncrementalQueue(
            WorkspaceProvider workspaceProvider,
            WorkspaceConfiguration workspaceConfiguration,
            IModuleReferenceResolver moduleReferenceResolver,
            ModuleDefinition designatedPrelude,
            ParsedModule configurationModule,
            IEnumerable <ParsedModule> parsedModules,
            IEnumerable <Failure> failures)
        {
            Contract.Requires(workspaceProvider != null);
            Contract.Requires(moduleReferenceResolver != null);
            Contract.Requires(parsedModules != null);
            Contract.Requires(failures != null);

            var parsedModulesDictionary =
                new ConcurrentDictionary <ModuleDescriptor, ParsedModule>(parsedModules.Select(parsedModule => new KeyValuePair <ModuleDescriptor, ParsedModule>(parsedModule.Descriptor, parsedModule)));

            var failureBag = new ConcurrentQueue <Failure>(failures);

            // For IDE mode it is very crucial to preserve trivias. For instance, without it, there is no way to check that the current position is inside a comment.
            var queue = new ModuleParsingQueue(
                workspaceProvider,
                workspaceConfiguration,
                moduleReferenceResolver,
                designatedPrelude,
                configurationModule,
                parsedModulesDictionary,
                failureBag,
                preserveTrivias: true);

            return(queue);
        }
예제 #2
0
        /// <summary>
        /// From an initial set of requested <param name="moduleDefinitions"/> returns a workspace that contains the set
        /// of corresponding modules closed under dependencies (if A is in the workspace and A imports B,
        /// then B is in the workspace).
        /// </summary>
        /// <remarks>
        /// For each module definition, it parses all its specs and builds a module out of it. Only specs successfully parsed are
        /// added to the module. Any failures are reported as part of the returned workspace instance.
        /// If <param name="computeBindingFingerprint"/> is true, then the binding fingerprint for all file would be computed after the parsing phase.
        /// </remarks>
        private async Task <Workspace> CreateWorkspaceFromModuleDefinitionsAsync(HashSet <ModuleDefinition> moduleDefinitions, bool computeBindingFingerprint)
        {
            var possiblePreludeDefinition = await TryGetPreludeModuleDefinitionAsync();

            if (!possiblePreludeDefinition.Succeeded)
            {
                return(Workspace.Failure(this, Configuration, possiblePreludeDefinition.Failure));
            }

            if (possiblePreludeDefinition.Result != null)
            {
                moduleDefinitions.Add(possiblePreludeDefinition.Result);
            }

            if (!WorkspaceValidator.ValidateModuleDefinitions(moduleDefinitions, PathTable, out var failures))
            {
                return(Workspace.Failure(this, Configuration, failures));
            }

            var queue = ModuleParsingQueue.Create(
                this,
                Configuration.WithComputeBindingFingerprint(computeBindingFingerprint),
                m_moduleReferenceResolver,
                possiblePreludeDefinition.Result,
                GetConfigurationModule());

            return(await queue.ProcessAsync(moduleDefinitions));
        }
예제 #3
0
        /// <summary>
        /// Creates a workspace from all known modules in an incremental way
        /// </summary>
        /// <remarks>
        /// It reuses already parsed modules so they don't get recomputed again
        /// </remarks>
        public async Task <Workspace> CreateIncrementalWorkspaceForAllKnownModulesAsync(
            IEnumerable <ParsedModule> parsedModules,
            ModuleUnderConstruction moduleUnderConstruction,
            IEnumerable <Failure> failures,
            [CanBeNull] ParsedModule preludeModule)
        {
            var maybeModuleDefinitions = await GetModuleDefinitionsForAllResolversAsync();

            if (!maybeModuleDefinitions.Succeeded)
            {
                return(Failure(maybeModuleDefinitions.Failure));
            }

            var moduleDefinitions = maybeModuleDefinitions.Result;

            ModuleDefinition preludeDefinition;

            if (preludeModule != null)
            {
                // Need to add prelude to a list of parsed modules if awailable
                var parsedModuleList = parsedModules.ToList();
                parsedModuleList.Add(preludeModule);
                parsedModules     = parsedModuleList;
                preludeDefinition = preludeModule.Definition;
            }
            else
            {
                var possiblePreludeDefinition = await TryGetPreludeModuleDefinitionAsync();

                if (!possiblePreludeDefinition.Succeeded)
                {
                    return(Failure(possiblePreludeDefinition.Failure));
                }

                preludeDefinition = possiblePreludeDefinition.Result;
                moduleDefinitions.Add(preludeDefinition);
            }

            if (!WorkspaceValidator.ValidateModuleDefinitions(moduleDefinitions, PathTable, out var validationFailures))
            {
                return(Failure(validationFailures));
            }

            var queue = ModuleParsingQueue.CreateIncrementalQueue(
                this,
                Configuration,
                m_moduleReferenceResolver,
                preludeDefinition,
                GetConfigurationModule(),
                parsedModules,
                failures);

            return(await queue.ProcessIncrementalAsync(moduleUnderConstruction));
        }
예제 #4
0
        /// <inheritdoc />
        public Task <Possible <ISourceFile>[]> ParseAndBindSpecsAsync(SpecWithOwningModule[] specs)
        {
            var queue = ModuleParsingQueue.CraeteFingerprintComputationQueue(this, Configuration, m_moduleReferenceResolver);

            return(Task.FromResult(queue.ParseAndBindSpecs(specs)));
        }