static async Task <CompletionModel> ComputeModelAsync( RoslynCompilationWorkspace compilationWorkspace, SourceText text, int position, CancellationToken ct) { ct.ThrowIfCancellationRequested(); var completions = await compilationWorkspace.CompletionService.GetCompletionsAsync( compilationWorkspace.GetSubmissionDocument(text.Container), position, options : compilationWorkspace.Options, cancellationToken : ct).ConfigureAwait(false); if (completions == null) { return(null); } // TODO: Default tracking span //var trackingSpan = await _completionService.GetDefaultTrackingSpanAsync(_documentOpt, _subjectBufferCaretPosition, cancellationToken).ConfigureAwait(false); return(CompletionModel.CreateModel( text, default(TextSpan), completions.Items)); }
async Task InitializeCompilationWorkspaceAsync(CancellationToken cancellationToken) { WorkingDirectory = Workbook.WorkingBasePath; if (!WorkingDirectory.DirectoryExists) { WorkingDirectory = Uri.WorkingDirectory; } if (!WorkingDirectory.DirectoryExists) { WorkingDirectory = FilePath.Empty; } if (agent.IsConnected) { await GacCache.InitializingTask; await Agent.Api.AssociateClientSession( ClientSessionAssociationKind.Initial, WorkingDirectory); CompilationWorkspace = new RoslynCompilationWorkspace( await WorkspaceConfiguration.CreateAsync( Agent, SessionKind, cancellationToken)); } await RefreshForAgentIntegration(); if (CompilationWorkspace == null) { throw new Exception("Unable to get compilation workspace for agent."); } var dependencyResolver = CompilationWorkspace.DependencyResolver; if (WorkingDirectory.DirectoryExists) { dependencyResolver.BaseDirectory = WorkingDirectory; dependencyResolver.AddAssemblySearchPath(WorkingDirectory); } Workbook.WorkingPathChanged += (o, e) => { if (dependencyResolver != null) { dependencyResolver.RemoveAssemblySearchPath(WorkingDirectory); dependencyResolver.RemoveAssemblySearchPath(e.OldBasePath); WorkingDirectory = e.NewBasePath; dependencyResolver.BaseDirectory = WorkingDirectory; dependencyResolver.AddAssemblySearchPath(WorkingDirectory); } }; PostEvent(ClientSessionEventKind.CompilationWorkspaceAvailable); }
#pragma warning restore 0414 public CompletionProvider( RoslynCompilationWorkspace compilationWorkspace, XCB.ScriptContext context, Func <string, SourceText> getSourceTextByModelId) { this.context = context ?? throw new ArgumentNullException(nameof(context)); this.getSourceTextByModelId = getSourceTextByModelId ?? throw new ArgumentNullException(nameof(getSourceTextByModelId)); controller = new CompletionController(compilationWorkspace); providerTicket = context.GlobalObject.xiexports.monaco.RegisterWorkbookCompletionItemProvider( "csharp", (XCB.ScriptFunc)ProvideCompletionItems); }
#pragma warning restore 0414 public SignatureHelpProvider( RoslynCompilationWorkspace compilationWorkspace, ScriptContext context, Func <string, SourceText> getSourceTextByModelId) { this.context = context ?? throw new ArgumentNullException(nameof(context)); this.getSourceTextByModelId = getSourceTextByModelId ?? throw new ArgumentNullException(nameof(getSourceTextByModelId)); controller = new SignatureHelpController(compilationWorkspace); providerTicket = context.GlobalObject.xiexports.monaco.RegisterWorkbookSignatureHelpProvider( "csharp", (ScriptFunc)ProvideSignatureHelp); }
/// <summary> /// Filter currentCompletionList according to the current filter text. Roslyn's completion does not /// handle this automatically. /// </summary> static async Task <CompletionModel> FilterModelAsync( RoslynCompilationWorkspace compilationWorkspace, SourceText sourceText, CompletionModel model, CompletionHelper helper, CancellationToken ct) { if (model == null) { return(null); } CompletionItem bestFilterMatch = null; var bestFilterMatchIndex = 0; var document = compilationWorkspace.GetSubmissionDocument(sourceText.Container); var newFilteredCompletions = new List <CompletionItem> (); foreach (var item in model.TotalItems) { var completion = item; // TODO: Better range checking on delete before queuing up filtering (see TODO in HandleChange) if (completion.Span.Start > sourceText.Length) { continue; } var filterText = GetFilterText(sourceText, completion); // CompletionRules.MatchesFilterText seems to always return false when filterText is // empty. if (filterText != String.Empty && !helper.MatchesPattern( completion.FilterText, filterText, CultureInfo.CurrentCulture)) { continue; } var itemDetail = String.Empty; var symbols = await SymbolCompletionItem.GetSymbolsAsync(completion, document, ct) .ConfigureAwait(false); var overloads = symbols.OfType <IMethodSymbol> ().ToArray(); if (overloads.Length > 0) { itemDetail = overloads [0].ToMonacoSignatureString(); if (overloads.Length > 1) { itemDetail += $" (+ {overloads.Length - 1} overload(s))"; } } completion = completion.AddProperty(itemDetailPropertyName, itemDetail); newFilteredCompletions.Add(completion); if (bestFilterMatch == null || helper.CompareItems( completion, bestFilterMatch, filterText, CultureInfo.CurrentCulture) > 0) { bestFilterMatch = completion; bestFilterMatchIndex = newFilteredCompletions.Count - 1; } } if (newFilteredCompletions.Count == 0) { return(null); } return(model .WithFilteredItems(newFilteredCompletions) .WithSelectedItem(bestFilterMatch, bestFilterMatchIndex) .WithText(sourceText)); }
public CompletionController(RoslynCompilationWorkspace compilationWorkspace) { this.compilationWorkspace = compilationWorkspace ?? throw new ArgumentNullException(nameof(compilationWorkspace)); }