/// <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); }
/// <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; }
/// <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; }
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) { }
/// <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)); }
/// <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); }
/// <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); }
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; }
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); }
/// <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)); }
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); }
/// <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)); }
/// <nodoc /> public FingerprintComputationParsingQueue(WorkspaceProvider workspaceProvider, WorkspaceConfiguration workspaceConfiguration, IModuleReferenceResolver moduleReferenceResolver) : base(workspaceProvider: workspaceProvider, workspaceConfiguration: workspaceConfiguration, moduleReferenceResolver: moduleReferenceResolver, designatedPrelude: null, configurationModule: null) { }