Exemple #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);
        }
Exemple #2
0
        /// <nodoc/>
        public Workspace(
            [CanBeNull] IWorkspaceProvider provider,
            WorkspaceConfiguration workspaceConfiguration,
            IEnumerable <ParsedModule> modules,
            IEnumerable <Failure> failures,
            [CanBeNull] ParsedModule preludeModule,
            [CanBeNull] ParsedModule configurationModule)
        {
            Contract.Requires(workspaceConfiguration != null);
            Contract.Requires(modules != null);
            Contract.Requires(failures != null);
            Contract.RequiresForAll(modules, m => m != null);

            WorkspaceProvider      = provider;
            WorkspaceConfiguration = workspaceConfiguration;

            var allModules = GetAllParsedModules(modules, preludeModule, configurationModule);

            m_specModules = allModules.Where(m => m != preludeModule && m != configurationModule).ToArray();

            // Double ownership is not allowed: specs are already validated for double ownership
            m_specSources  = CreateSpecsFromModules(m_specModules, allowDoubleOwnership: false);
            m_specialSpecs = CreateSpecsForPreludeAndConfiguration(preludeModule, configurationModule);

            // Spec array contains all the specs for the workspace.
            m_specArray = m_specSources.ToDictionary().AddRange(m_specialSpecs).Select(s => s.Value.SourceFile).ToArray();

            m_allModulesByDescriptor = AllModulesByDescriptor(allModules);

            Failures = failures.ToArray();

            PreludeModule       = preludeModule;
            ConfigurationModule = configurationModule;
        }
Exemple #3
0
 /// <summary>
 /// Creates a special version of the parsing queue required for paring/binding spec files for fingerprint computation.
 /// </summary>
 public static ModuleParsingQueue CraeteFingerprintComputationQueue(
     WorkspaceProvider workspaceProvider,
     WorkspaceConfiguration workspaceConfiguration,
     IModuleReferenceResolver moduleReferenceResolver)
 {
     return(new FingerprintComputationParsingQueue(workspaceProvider, workspaceConfiguration, moduleReferenceResolver));
 }
        /// <nodoc/>
        public SemanticWorkspaceProvider(IWorkspaceStatistics statistics, WorkspaceConfiguration workspaceConfiguration)
        {
            Contract.Requires(statistics != null);
            Contract.Requires(workspaceConfiguration != null);

            m_statistics             = statistics;
            m_workspaceConfiguration = workspaceConfiguration;
        }
Exemple #5
0
        private ModuleParsingQueue(
            WorkspaceProvider workspaceProvider,
            WorkspaceConfiguration workspaceConfiguration,
            IModuleReferenceResolver moduleReferenceResolver,
            ModuleDefinition designatedPrelude,
            ParsedModule configurationModule,
            ConcurrentDictionary <ModuleDescriptor, ParsedModule> alreadyParsedModules,
            ConcurrentQueue <Failure> failures,
            bool preserveTrivias = false)
        {
            Contract.Requires(workspaceProvider != null);
            Contract.Requires(workspaceConfiguration != null);
            Contract.Requires(moduleReferenceResolver != null);
            Contract.Requires(alreadyParsedModules != null, "alreadyParsedModules != null");
            Contract.Requires(failures != null, "failures != null");

            m_modulesToBeParsed    = new ConcurrentDictionary <ModuleDescriptor, ModuleUnderConstruction>();
            m_modulesAlreadyParsed = alreadyParsedModules;
            m_failures             = failures;

            m_workspaceProvider       = workspaceProvider;
            m_moduleReferenceResolver = moduleReferenceResolver;
            m_designatedPrelude       = designatedPrelude;
            m_configurationModule     = configurationModule;

            m_workspaceConfiguration = workspaceConfiguration;
            m_parsingOptions         = workspaceConfiguration.ParsingOptions;

            if (preserveTrivias)
            {
                m_parsingOptions = (m_parsingOptions ?? ParsingOptions.DefaultParsingOptions).WithTrivia(true);
            }

            DegreeOfParallelism = workspaceConfiguration.MaxDegreeOfParallelismForParsing;

            // WARNING: this is extremely subtle.
            // We need to keep a 'registration token' from the chained operation we are doing next to avoid memory leak.
            // The instance of this class stores the reference to key front-end objects, like resolvers,
            // that keeps the entire front-end in memory.
            // CancellationToken.Register registers the call back, that lead to a closure allocation of the current instance.
            // And this means that the lifetime of this instance is coupled to the lifetime of the the workspaceConfiguration.CancellationToken which is global.
            // This means that if we won't dispose the resistration we'll keep the entire front-end in memory for the entire app life time.
            cancellationTokenChain = workspaceConfiguration.CancellationToken.Register(() => m_cancellationTokenSource.Cancel());

            m_queueOptions = new ModuleParsingQueueOptions()
            {
                CancelOnFirstFailure   = workspaceConfiguration.CancelOnFirstFailure,
                MaxDegreeOfParallelism = DegreeOfParallelism,
                CancellationToken      = CancellationToken,
            };

            m_parseQueue = new ActionBlock <SpecWithOwningModule>(ProcessQueuedItemForParsing, m_queueOptions);

            Action <ParsedSpecWithOwningModule> action = ProcessQueueItemForBinding;

            m_bindQueue = new ActionBlock <ParsedSpecWithOwningModule>(action, m_queueOptions);
        }
 /// <summary>
 /// Creates a new WorkspaceProvider using a <see cref="ModuleReferenceResolver"/> to identify DScript module references
 /// </summary>
 public WorkspaceProvider(
     IWorkspaceStatistics workspaceStatistics,
     List <IWorkspaceModuleResolver> resolvers,
     WorkspaceConfiguration configuration,
     PathTable pathTable,
     SymbolTable symbolTable)
     : this(workspaceStatistics, resolvers, new ModuleReferenceResolver(pathTable), configuration, pathTable, symbolTable)
 {
 }
Exemple #7
0
 /// <summary>
 /// Creates a workspace for configuration processing.
 /// </summary>
 public static Workspace CreateConfigurationWorkspace(WorkspaceConfiguration configuration, ParsedModule configurationModule, ParsedModule preludeModule)
 {
     return(new Workspace(
                provider: null,
                workspaceConfiguration: configuration,
                modules: CollectionUtilities.EmptyArray <ParsedModule>(),
                failures: CollectionUtilities.EmptyArray <Failure>(),
                preludeModule: preludeModule,
                configurationModule: configurationModule));
 }
Exemple #8
0
 /// <summary>
 /// Creates a module parsing queue. The queue options are specified by the provided queueOptions.
 /// </summary>
 public ModuleParsingQueue(
     [NotNull] WorkspaceProvider workspaceProvider,
     WorkspaceConfiguration workspaceConfiguration,
     IModuleReferenceResolver moduleReferenceResolver,
     ModuleDefinition designatedPrelude,
     ParsedModule configurationModule)
     : this(workspaceProvider, workspaceConfiguration, moduleReferenceResolver, designatedPrelude, configurationModule,
            new ConcurrentDictionary <ModuleDescriptor, ParsedModule>(), new ConcurrentQueue <Failure>())
 {
     Contract.Requires(moduleReferenceResolver != null);
 }
Exemple #9
0
        /// <summary>
        /// Constructs the workspace with given errors in the case where not even a workspace provider could be successfully constructed.
        /// </summary>
        public static Workspace Failure(WorkspaceConfiguration workspaceConfiguration, params Failure[] failures)
        {
            Contract.Requires(failures.Length != 0);
            var workspace = new Workspace(
                provider: null,
                workspaceConfiguration: workspaceConfiguration,
                modules: CollectionUtilities.EmptyArray <ParsedModule>(),
                failures: failures,
                preludeModule: null,
                configurationModule: null);

            return(workspace);
        }
Exemple #10
0
        public SemanticWorkspace(
            IWorkspaceProvider workspaceProvider,
            WorkspaceConfiguration workspaceConfiguration,
            IEnumerable <ParsedModule> modules,
            [CanBeNull] ParsedModule preludeModule,
            [CanBeNull] ParsedModule configurationModule,
            ISemanticModel semanticModel,
            IReadOnlyCollection <Failure> failures)
            : base(workspaceProvider, workspaceConfiguration, modules, failures, preludeModule, configurationModule)
        {
            Contract.Requires(semanticModel != null);

            m_semanticModel = semanticModel;
        }
Exemple #11
0
        private static bool TryCreateResolvers(
            [NotNull] FrontEndFactory frontEndFactory,
            WorkspaceConfiguration configuration,
            PathTable pathTable,
            AbsolutePath mainConfigurationFile,
            bool addBuiltInPreludeResolver,
            out List <IWorkspaceModuleResolver> resolvers,
            out IEnumerable <Failure> failures)
        {
            Contract.Ensures(Contract.Result <List <IWorkspaceModuleResolver> >() != null);
            Contract.EnsuresForAll(Contract.Result <List <IWorkspaceModuleResolver> >(), r => r != null);

            resolvers = new List <IWorkspaceModuleResolver>(configuration.ResolverSettings.Count + (addBuiltInPreludeResolver ? 1 : 0));

            var resolverFailures = new List <Failure>();

            var resolverSettings = new List <IResolverSettings>(configuration.ResolverSettings);

            // The built in resolver is generally not added only for some tests. Regular spec processing always adds it.
            if (addBuiltInPreludeResolver)
            {
                // We add a resolver that points to the built-in prelude at the end of the resolver collection
                // so the built-in prelude is used if no prelude is specified explicitly
                var builtInPreludeSettings = PreludeManager.GetResolverSettingsForBuiltInPrelude(mainConfigurationFile, pathTable);
                resolverSettings.Add(builtInPreludeSettings);
            }

            foreach (var resolverConfiguration in resolverSettings)
            {
                var kind = resolverConfiguration.Kind;
                if (!frontEndFactory.TryGetFrontEnd(kind, out var frontEnd))
                {
                    resolverFailures.Add(new WorkspaceModuleResolverGenericInitializationFailure(kind));
                    continue;
                }

                if (!frontEnd.TryCreateWorkspaceResolver(resolverConfiguration, out var resolver))
                {
                    resolverFailures.Add(new WorkspaceModuleResolverGenericInitializationFailure(resolverConfiguration.Kind));
                }
                else
                {
                    resolvers.Add(resolver);
                }
            }

            failures = resolverFailures;
            return(resolverFailures.Count == 0);
        }
Exemple #12
0
        /// <summary>
        /// Creates a parsing queue for parsing specs in a regular BuildXL invocation.
        /// </summary>
        public static ModuleParsingQueue Create(
            [NotNull] WorkspaceProvider workspaceProvider,
            [NotNull] WorkspaceConfiguration workspaceConfiguration,
            [NotNull] IModuleReferenceResolver moduleReferenceResolver,
            [CanBeNull] ModuleDefinition designatedPrelude,
            [CanBeNull] ParsedModule configurationModule)
        {
            Contract.Requires(workspaceProvider != null);

            return(new ModuleParsingQueue(
                       workspaceProvider,
                       workspaceConfiguration,
                       moduleReferenceResolver,
                       designatedPrelude,
                       configurationModule));
        }
Exemple #13
0
        private static bool TryCreateResolvers <T>(
            IWorkspaceResolverFactory <T> workspaceResolverFactory,
            WorkspaceConfiguration configuration,
            AbsolutePath mainConfigurationFile,
            PathTable pathTable,
            bool addBuiltInPreludeResolver,
            out List <IWorkspaceModuleResolver> resolvers,
            out IEnumerable <Failure> failures)
        {
            Contract.Ensures(Contract.Result <List <IWorkspaceModuleResolver> >() != null);
            Contract.EnsuresForAll(Contract.Result <List <IWorkspaceModuleResolver> >(), r => r != null);

            resolvers = new List <IWorkspaceModuleResolver>(configuration.ResolverSettings.Count + (addBuiltInPreludeResolver ? 1 : 0));

            var resolverFailures = new List <Failure>();

            var resolverSettings = new List <IResolverSettings>(configuration.ResolverSettings);

            // The built in resolver is generally not added only for some tests. Regular spec processing always adds it.
            if (addBuiltInPreludeResolver)
            {
                // We add a resolver that points to the built-in prelude at the end of the resolver collection
                // so the built-in prelude is used if no prelude is specified explicitly
                var builtInPreludeSettings = PreludeManager.GetResolverSettingsForBuiltInPrelude(mainConfigurationFile, pathTable);
                resolverSettings.Add(builtInPreludeSettings);
            }

            foreach (var resolverConfiguration in resolverSettings)
            {
                var maybeResolver = workspaceResolverFactory.TryGetResolver(resolverConfiguration);
                if (!maybeResolver.Succeeded)
                {
                    resolverFailures.Add(maybeResolver.Failure);
                }
                else
                {
                    var resolver = (IWorkspaceModuleResolver)maybeResolver.Result;
                    resolvers.Add(resolver);
                }
            }

            failures = resolverFailures;
            return(resolverFailures.Count == 0);
        }
        /// <nodoc/>
        public WorkspaceProvider(
            IWorkspaceStatistics workspaceStatistics,
            List <IWorkspaceModuleResolver> resolvers,
            IModuleReferenceResolver moduleReferenceResolver,
            WorkspaceConfiguration configuration,
            PathTable pathTable,
            SymbolTable symbolTable)
        {
            Contract.Requires(workspaceStatistics != null);
            Contract.Requires(configuration != null);
            Contract.Requires(moduleReferenceResolver != null);
            Contract.Requires(pathTable != null);

            Statistics = workspaceStatistics;
            m_moduleReferenceResolver = moduleReferenceResolver;
            PathTable     = pathTable;
            Configuration = configuration;
            SymbolTable   = symbolTable;
            m_resolvers   = resolvers;
        }
        /// <nodoc/>
        public static bool TryCreate(
            [CanBeNull] Workspace mainConfigurationWorkspace,
            IWorkspaceStatistics workspaceStatistics,
            FrontEndFactory frontEndFactory,
            PathTable pathTable,
            SymbolTable symbolTable,
            WorkspaceConfiguration configuration,
            bool useDecorator,
            bool addBuiltInPreludeResolver,
            out IWorkspaceProvider workspaceProvider,
            out IEnumerable <Failure> failures)
        {
            // mainConfigurationWorkspace can be null for some tests
            var mainFile = mainConfigurationWorkspace != null ?
                           mainConfigurationWorkspace.ConfigurationModule.Definition.MainFile :
                           AbsolutePath.Invalid;

            if (!TryCreateResolvers(
                    frontEndFactory,
                    configuration,
                    pathTable,
                    mainFile,
                    addBuiltInPreludeResolver,
                    out var resolvers,
                    out failures))
            {
                workspaceProvider = default(IWorkspaceProvider);
                return(false);
            }

            var provider = new WorkspaceProvider(workspaceStatistics, resolvers, configuration, pathTable, symbolTable);

            provider.m_mainConfigurationWorkspace = mainConfigurationWorkspace;

            workspaceProvider = useDecorator
                ? (IWorkspaceProvider) new WorkspaceProviderStatisticsDecorator(workspaceStatistics, provider)
                : provider;
            return(true);
        }
Exemple #16
0
 /// <summary>
 /// Constructs the workspace with given errors.
 /// </summary>
 public static Workspace Failure(IWorkspaceProvider provider, WorkspaceConfiguration workspaceConfiguration, params Failure[] failures)
 {
     Contract.Requires(failures.Length != 0);
     return(new Workspace(provider, workspaceConfiguration, new List <ParsedModule>(), failures, preludeModule: null, configurationModule: null));
 }
        /// <summary>
        /// Computes semantic workspace from parsed workspace.
        /// </summary>
        public static Task <Workspace> ComputeSemanticWorkspace(PathTable pathTable, Workspace workspace, WorkspaceConfiguration configuration)
        {
            var provider = new SemanticWorkspaceProvider(new WorkspaceStatistics(), configuration);

            return(provider.ComputeSemanticWorkspaceAsync(pathTable, workspace));
        }
Exemple #18
0
 /// <nodoc />
 public FingerprintComputationParsingQueue(WorkspaceProvider workspaceProvider, WorkspaceConfiguration workspaceConfiguration, IModuleReferenceResolver moduleReferenceResolver)
     : base(workspaceProvider: workspaceProvider, workspaceConfiguration: workspaceConfiguration, moduleReferenceResolver: moduleReferenceResolver, designatedPrelude: null, configurationModule: null)
 {
 }