public override InitializeResult OnInitialize(InitializeParams parameters) { this.RemoteConsole.NoLogsMessageNotification = NoLogsMessageNotification; var rootDirectory = new DirectoryInfo(parameters.rootPath); string workspaceName = rootDirectory.Name + "#" + parameters.processId; // Initialize the workspace typeCobolWorkspace = new Workspace(rootDirectory.FullName, workspaceName, _MessagesActionsQueue, Logger); //Propagate LSR testing options. if (LsrSourceTesting) { typeCobolWorkspace.IsLsrSourceTesting = LsrSourceTesting; } if (LsrScannerTesting) { typeCobolWorkspace.IsLsrScannerTesting = LsrScannerTesting; } if (LsrPreprocessTesting) { typeCobolWorkspace.IsLsrPreprocessinTesting = LsrPreprocessTesting; } if (LsrParserTesting) { typeCobolWorkspace.IsLsrParserTesting = LsrParserTesting; } if (LsrSemanticTesting) { typeCobolWorkspace.IsLsrSemanticTesting = LsrSemanticTesting; } typeCobolWorkspace.UseAntlrProgramParsing = UseAntlrProgramParsing; typeCobolWorkspace.TimerDisabledOption = TimerDisabledOption; typeCobolWorkspace.LoadingIssueEvent += LoadingIssueDetected; typeCobolWorkspace.ExceptionTriggered += ExceptionTriggered; typeCobolWorkspace.WarningTrigger += WarningTrigger; // Return language server capabilities var initializeResult = base.OnInitialize(parameters); initializeResult.capabilities.textDocumentSync = TextDocumentSyncKind.Incremental; initializeResult.capabilities.hoverProvider = true; CompletionOptions completionOptions = new CompletionOptions(); completionOptions.resolveProvider = false; completionOptions.triggerCharacters = new string[] { "::" }; initializeResult.capabilities.completionProvider = completionOptions; SignatureHelpOptions sigHelpOptions = new SignatureHelpOptions { triggerCharacters = new string[0] }; initializeResult.capabilities.signatureHelpProvider = sigHelpOptions; return(initializeResult); }
public void SimpleTest(string expected) { var model = new SignatureHelpOptions { TriggerCharacters = new[] { "1", "2" } }; var result = Fixture.SerializeObject(model); result.Should().Be(expected); var deresult = new Serializer(ClientVersion.Lsp3).DeserializeObject <SignatureHelpOptions>(expected); deresult.Should().BeEquivalentTo(model); }
private static async Task <(ISignatureHelpProvider provider, SignatureHelpItems items)> ComputeItemsAsync( ImmutableArray <ISignatureHelpProvider> providers, SnapshotPoint caretPosition, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, Document document, CancellationToken cancellationToken) { try { ISignatureHelpProvider bestProvider = null; SignatureHelpItems bestItems = null; // TODO(cyrusn): We're calling into extensions, we need to make ourselves resilient // to the extension crashing. foreach (var provider in providers) { cancellationToken.ThrowIfCancellationRequested(); var currentItems = await provider.GetItemsAsync(document, caretPosition, triggerInfo, options, cancellationToken).ConfigureAwait(false); if (currentItems != null && currentItems.ApplicableSpan.IntersectsWith(caretPosition.Position)) { // If another provider provides sig help items, then only take them if they // start after the last batch of items. i.e. we want the set of items that // conceptually are closer to where the caret position is. This way if you have: // // Goo(new Bar($$ // // Then invoking sig help will only show the items for "new Bar(" and not also // the items for "Goo(..." if (IsBetter(bestItems, currentItems.ApplicableSpan)) { bestItems = currentItems; bestProvider = provider; } } } return(bestProvider, bestItems); } catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken, ErrorSeverity.Critical)) { return(null, null); } }
private static (IList <SignatureHelpItem> items, int?selectedItem) GetNormalTypeConstructors( BaseObjectCreationExpressionSyntax objectCreationExpression, SemanticModel semanticModel, IStructuralTypeDisplayService structuralTypeDisplayService, IDocumentationCommentFormattingService documentationCommentFormattingService, INamedTypeSymbol normalType, ISymbol within, SignatureHelpOptions options, CancellationToken cancellationToken) { var accessibleConstructors = normalType.InstanceConstructors .WhereAsArray(c => c.IsAccessibleWithin(within)) .WhereAsArray(s => s.IsEditorBrowsable(options.HideAdvancedMembers, semanticModel.Compilation)) .Sort(semanticModel, objectCreationExpression.SpanStart); var symbolInfo = semanticModel.GetSymbolInfo(objectCreationExpression, cancellationToken); var selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo.Symbol); var items = accessibleConstructors.SelectAsArray(c => ConvertNormalTypeConstructor(c, objectCreationExpression, semanticModel, structuralTypeDisplayService, documentationCommentFormattingService)); return(items, selectedItem); }
private async Task <Model> ComputeModelInBackgroundAsync( Model currentModel, ImmutableArray <ISignatureHelpProvider> providers, SnapshotPoint caretPosition, DisconnectedBufferGraph disconnectedBufferGraph, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SignatureHelp_ModelComputation_ComputeModelInBackground, cancellationToken)) { AssertIsBackground(); cancellationToken.ThrowIfCancellationRequested(); var document = Controller.DocumentProvider.GetDocument(caretPosition.Snapshot, cancellationToken); if (document == null) { return(currentModel); } // Let LSP handle signature help in the cloud scenario if (Controller.SubjectBuffer.IsInLspEditorContext()) { return(null); } if (triggerInfo.TriggerReason == SignatureHelpTriggerReason.RetriggerCommand) { if (currentModel == null) { return(null); } if (triggerInfo.TriggerCharacter.HasValue && !currentModel.Provider.IsRetriggerCharacter(triggerInfo.TriggerCharacter.Value)) { return(currentModel); } } var options = SignatureHelpOptions.From(document.Project); // first try to query the providers that can trigger on the specified character var(provider, items) = await ComputeItemsAsync( providers, caretPosition, triggerInfo, options, document, cancellationToken).ConfigureAwait(false); if (provider == null) { // No provider produced items. So we can't produce a model return(null); } if (currentModel != null && currentModel.Provider == provider && currentModel.GetCurrentSpanInSubjectBuffer(disconnectedBufferGraph.SubjectBufferSnapshot).Span.Start == items.ApplicableSpan.Start && currentModel.Items.IndexOf(currentModel.SelectedItem) == items.SelectedItemIndex && currentModel.ArgumentIndex == items.ArgumentIndex && currentModel.ArgumentCount == items.ArgumentCount && currentModel.ArgumentName == items.ArgumentName) { // The new model is the same as the current model. Return the currentModel // so we keep the active selection. return(currentModel); } var selectedItem = GetSelectedItem(currentModel, items, provider, out var userSelected); var model = new Model(disconnectedBufferGraph, items.ApplicableSpan, provider, items.Items, selectedItem, items.ArgumentIndex, items.ArgumentCount, items.ArgumentName, selectedParameter: 0, userSelected); var syntaxFactsService = document.GetLanguageService <ISyntaxFactsService>(); var isCaseSensitive = syntaxFactsService == null || syntaxFactsService.IsCaseSensitive; var selection = DefaultSignatureHelpSelector.GetSelection(model.Items, model.SelectedItem, model.UserSelected, model.ArgumentIndex, model.ArgumentCount, model.ArgumentName, isCaseSensitive); return(model.WithSelectedItem(selection.SelectedItem, selection.UserSelected) .WithSelectedParameter(selection.SelectedParameter)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken, ErrorSeverity.Critical)) { throw ExceptionUtilities.Unreachable; } }
public async Task <SignatureHelpItems> GetItemsAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, CancellationToken cancellationToken) { var mappedTriggerReason = FSharpSignatureHelpTriggerReasonHelpers.ConvertFrom(triggerInfo.TriggerReason); var mappedTriggerInfo = new FSharpSignatureHelpTriggerInfo(mappedTriggerReason, triggerInfo.TriggerCharacter); var mappedSignatureHelpItems = await _provider.GetItemsAsync(document, position, mappedTriggerInfo, cancellationToken).ConfigureAwait(false); if (mappedSignatureHelpItems != null) { return(new SignatureHelpItems( mappedSignatureHelpItems.Items?.Select(x => new SignatureHelpItem( x.IsVariadic, x.DocumentationFactory, x.PrefixDisplayParts, x.SeparatorDisplayParts, x.SuffixDisplayParts, x.Parameters.Select(y => new SignatureHelpParameter( y.Name, y.IsOptional, y.DocumentationFactory, y.DisplayParts, y.PrefixDisplayParts, y.SuffixDisplayParts, y.SelectedDisplayParts)).ToList(), x.DescriptionParts)).ToList(), mappedSignatureHelpItems.ApplicableSpan, mappedSignatureHelpItems.ArgumentIndex, mappedSignatureHelpItems.ArgumentCount, mappedSignatureHelpItems.ArgumentName, mappedSignatureHelpItems.SelectedItemIndex)); } else { return(null); } }
protected abstract Task <SignatureHelpItems?> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, CancellationToken cancellationToken);
public async Task <SignatureHelpItems?> GetItemsAsync( Document document, int position, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, CancellationToken cancellationToken) { var itemsForCurrentDocument = await GetItemsWorkerAsync(document, position, triggerInfo, options, cancellationToken).ConfigureAwait(false); if (itemsForCurrentDocument == null) { return(itemsForCurrentDocument); } var relatedDocuments = await FindActiveRelatedDocumentsAsync(position, document, cancellationToken).ConfigureAwait(false); if (relatedDocuments.IsEmpty) { return(itemsForCurrentDocument); } var totalProjects = relatedDocuments.Select(d => d.Project.Id).Concat(document.Project.Id); var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); var compilation = semanticModel.Compilation; var finalItems = new List <SignatureHelpItem>(); foreach (var item in itemsForCurrentDocument.Items) { if (item is not SymbolKeySignatureHelpItem symbolKeyItem || symbolKeyItem.SymbolKey is not SymbolKey symbolKey || symbolKey.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken).Symbol is not ISymbol symbol) { finalItems.Add(item); continue; } // If the symbol is an instantiated generic method, ensure we use its original // definition for symbol key resolution in related compilations. if (symbol is IMethodSymbol methodSymbol && methodSymbol.IsGenericMethod && methodSymbol != methodSymbol.OriginalDefinition) { symbolKey = SymbolKey.Create(methodSymbol.OriginalDefinition, cancellationToken); } var invalidProjectsForCurrentSymbol = new List <ProjectId>(); foreach (var relatedDocument in relatedDocuments) { // Try to resolve symbolKey in each related compilation, // unresolvable key means the symbol is unavailable in the corresponding project. var relatedSemanticModel = await relatedDocument.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); if (symbolKey.Resolve(relatedSemanticModel.Compilation, ignoreAssemblyKey: true, cancellationToken).Symbol == null) { invalidProjectsForCurrentSymbol.Add(relatedDocument.Project.Id); } } var platformData = new SupportedPlatformData(document.Project.Solution, invalidProjectsForCurrentSymbol, totalProjects); finalItems.Add(UpdateItem(item, platformData)); } return(new SignatureHelpItems( finalItems, itemsForCurrentDocument.ApplicableSpan, itemsForCurrentDocument.ArgumentIndex, itemsForCurrentDocument.ArgumentCount, itemsForCurrentDocument.ArgumentName, itemsForCurrentDocument.SelectedItemIndex)); }
Task <SignatureHelpItems?> ISignatureHelpProvider.GetItemsAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, CancellationToken cancellationToken) => GetItemsAsync(document, position, triggerInfo, cancellationToken);
public static async Task <ImmutableArray <IMethodSymbol> > GetCollectionInitializerAddMethodsAsync( Document document, SyntaxNode initializer, SignatureHelpOptions options, CancellationToken cancellationToken) { if (initializer == null || initializer.Parent == null) { return(default);
public override async Task <LSP.SignatureHelp?> HandleRequestAsync(LSP.TextDocumentPositionParams request, RequestContext context, CancellationToken cancellationToken) { var document = context.Document; if (document == null) { return(null); } var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); var providers = _allProviders.Where(p => p.Metadata.Language == document.Project.Language); var triggerInfo = new SignatureHelpTriggerInfo(SignatureHelpTriggerReason.InvokeSignatureHelpCommand); var options = SignatureHelpOptions.From(document.Project); foreach (var provider in providers) { var items = await provider.Value.GetItemsAsync(document, position, triggerInfo, options, cancellationToken).ConfigureAwait(false); if (items != null) { var sigInfos = new ArrayBuilder <LSP.SignatureInformation>(); foreach (var item in items.Items) { LSP.SignatureInformation sigInfo; if (context.ClientCapabilities?.HasVisualStudioLspCapability() == true) { sigInfo = new LSP.VSInternalSignatureInformation { ColorizedLabel = GetSignatureClassifiedText(item) }; } else { sigInfo = new LSP.SignatureInformation(); } sigInfo.Label = GetSignatureText(item); sigInfo.Documentation = new LSP.MarkupContent { Kind = LSP.MarkupKind.PlainText, Value = item.DocumentationFactory(cancellationToken).GetFullText() }; sigInfo.Parameters = item.Parameters.Select(p => new LSP.ParameterInformation { Label = p.Name, Documentation = new LSP.MarkupContent { Kind = LSP.MarkupKind.PlainText, Value = p.DocumentationFactory(cancellationToken).GetFullText() } }).ToArray(); sigInfos.Add(sigInfo); } var sigHelp = new LSP.SignatureHelp { ActiveSignature = GetActiveSignature(items), ActiveParameter = items.ArgumentIndex, Signatures = sigInfos.ToArrayAndFree() }; return(sigHelp); } } return(null); }