Esempio n. 1
0
        protected override async Task <CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
        {
            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return(await base.GetDescriptionWorkerAsync(document, item, cancellationToken).ConfigureAwait(false));
            }

            if (!item.Properties.TryGetValue("ResolveData", out var serializedItem))
            {
                return(await base.GetDescriptionWorkerAsync(document, item, cancellationToken).ConfigureAwait(false));
            }

            var completionItem         = JToken.Parse(serializedItem).ToObject <RoslynCompletionItem>();
            var request                = new LspRequest <RoslynCompletionItem, RoslynCompletionItem>(LSP.Methods.TextDocumentCompletionResolveName);
            var resolvedCompletionItem = await lspClient.RequestAsync(request, completionItem, cancellationToken).ConfigureAwait(false);

            if (resolvedCompletionItem?.Description == null)
            {
                return(await base.GetDescriptionWorkerAsync(document, item, cancellationToken).ConfigureAwait(false));
            }

            var parts = resolvedCompletionItem.Description.Select(tt => tt.ToTaggedText()).AsImmutable();

            return(CompletionDescription.Create(parts));
        }
Esempio n. 2
0
        protected override async Task <IEnumerable <CodeActionOperation> > ComputePreviewOperationsAsync(CancellationToken cancellationToken)
        {
            // If we have a codeaction, then just call the base method which will call ComputeOperationsAsync below.
            // This creates an ApplyChagesOperation so that Roslyn can show a preview of the changes.
            if (_codeActionWorkspaceEdit != null)
            {
                return(await base.ComputePreviewOperationsAsync(cancellationToken).ConfigureAwait(false));
            }

            // We have a command - this will be executed on the host but the host may have a preview for the current document.
            var runCodeActionsCommand = ((JToken)_command.Arguments?.Single()).ToObject <LSP.Command>();
            var runCodeActionParams   = ((JToken)runCodeActionsCommand.Arguments?.Single())?.ToObject <RunCodeActionParams>();

            var request   = new LspRequest <RunCodeActionParams, LSP.TextEdit[]>(RoslynMethods.CodeActionPreviewName);
            var textEdits = await _lspClient.RequestAsync(request, runCodeActionParams, cancellationToken).ConfigureAwait(false);

            if (textEdits == null || textEdits.Length == 0)
            {
                return(ImmutableArray <CodeActionOperation> .Empty);
            }

            var newDocument = await ApplyEditsAsync(_document, textEdits, cancellationToken).ConfigureAwait(false);

            return(ImmutableArray.Create(new ApplyChangesOperation(newDocument.Project.Solution)));
        }
Esempio n. 3
0
 public static Task <TResult> InvokeWithParameterObjectAsync <TArgument, TResult> (
     this JsonRpc jsonRpc,
     LspRequest <TArgument, TResult> request,
     TArgument argument,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(jsonRpc.InvokeWithParameterObjectAsync <TResult> (request.Name, argument, cancellationToken));
 }
Esempio n. 4
0
        public async Task <ImmutableArray <ProjectInfo> > GetRemoteProjectInfosAsync(CancellationToken cancellationToken)
        {
            if (!_remoteLanguageServiceWorkspace.IsRemoteSession)
            {
                return(ImmutableArray <ProjectInfo> .Empty);
            }

            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return(ImmutableArray <ProjectInfo> .Empty);
            }

            CustomProtocol.Project[] projects;
            try
            {
                var request = new LspRequest <object, CustomProtocol.Project[]>(CustomProtocol.RoslynMethods.ProjectsName);
                projects = await lspClient.RequestAsync(request, new object(), cancellationToken).ConfigureAwait(false);
            }
            catch (Exception)
            {
                projects = null;
            }

            if (projects == null)
            {
                return(ImmutableArray <ProjectInfo> .Empty);
            }

            var projectInfos = ImmutableArray.CreateBuilder <ProjectInfo>();

            foreach (var project in projects)
            {
                // We don't want to add cshtml files to the workspace since the Roslyn will add the generated secondary buffer of a cshtml
                // file to a different project but with the same path. This used to be ok in Dev15 but in Dev16 this confuses Roslyn and causes downstream
                // issues. There's no need to add the actual cshtml file to the workspace - so filter those out.
                // This is also the case for files for which TypeScript adds the generated TypeScript buffer to a different project.
                var filesTasks = project.SourceFiles
                                 .Where(f => f.Scheme != SystemUriSchemeExternal)
                                 .Where(f => !this._secondaryBufferFileExtensions.Any(ext => f.LocalPath.EndsWith(ext)))
                                 .Select(f => lspClient.ProtocolConverter.FromProtocolUriAsync(f, false, cancellationToken));
                var files = await Task.WhenAll(filesTasks).ConfigureAwait(false);

                var projectInfo = CreateProjectInfo(project.Name, project.Language, files.Select(f => f.LocalPath).ToImmutableArray());
                projectInfos.Add(projectInfo);
            }

            return(projectInfos.ToImmutableArray());
        }
Esempio n. 5
0
        private async Task AddRemoteSemanticClassificationsAsync(SourceText text, string filePath, TextSpan textSpan, ArrayBuilder <ClassifiedSpan> result, CancellationToken cancellationToken)
        {
            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return;
            }

            var classificationParams = new ClassificationParams
            {
                TextDocument = new TextDocumentIdentifier {
                    Uri = lspClient.ProtocolConverter.ToProtocolUri(new Uri(filePath))
                },
                Range = ProtocolConversions.TextSpanToRange(textSpan, text)
            };

            var request             = new LspRequest <ClassificationParams, ClassificationSpan[]>(RoslynMethods.ClassificationsName);
            var classificationSpans = await lspClient.RequestAsync(request, classificationParams, cancellationToken).ConfigureAwait(false);

            if (classificationSpans == null)
            {
                return;
            }

            foreach (var classificationSpan in classificationSpans)
            {
                // The host may return more classifications than are supported by the guest. As an example, 15.7 added classifications for type members which wouldnt be understood by a 15.6 guest.
                // Check with the classificationTypeMap to see if this is a known classification.
                var classification = classificationSpan.Classification;
                if (_classificationTypeMap.GetClassificationType(classification) == null)
                {
                    classification = ClassificationTypeNames.Identifier;
                }

                var span = ProtocolConversions.RangeToTextSpan(classificationSpan.Range, text);
                if (span.End <= text.Length)
                {
                    result.Add(new ClassifiedSpan(classification, span));
                }
            }
        }
Esempio n. 6
0
        public async Task <ImmutableArray <Diagnostic> > GetDiagnosticsAsync(Document document, CancellationToken cancellationToken)
        {
            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return(ImmutableArray <Diagnostic> .Empty);
            }

            var textDocumentParams = new TextDocumentParams
            {
                TextDocument = new LSP.TextDocumentIdentifier
                {
                    Uri = lspClient.ProtocolConverter.ToProtocolUri(new Uri(document.FilePath))
                }
            };

            var request        = new LspRequest <TextDocumentParams, RoslynDiagnostic[]>(CustomMethods.GetDocumentDiagnosticsName);
            var lspDiagnostics = await lspClient.RequestAsync(request, textDocumentParams, cancellationToken).ConfigureAwait(false);

            if (lspDiagnostics == null)
            {
                return(ImmutableArray <Diagnostic> .Empty);
            }

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var diagnostics = ImmutableArray.CreateBuilder <Diagnostic>();

            foreach (var diagnostic in lspDiagnostics)
            {
                var location = Location.Create(document.FilePath, ProtocolConversions.RangeToTextSpan(diagnostic.Range, text),
                                               ProtocolConversions.RangeToLinePositionSpan(diagnostic.Range));
                var severity = ToDiagnosticSeverity(diagnostic.Severity);
                var diag     = Diagnostic.Create(diagnostic.Code ?? "VSLS", string.Empty, diagnostic.Message, severity, severity,
                                                 true, severity == DiagnosticSeverity.Error ? 0 : 1, location: location, customTags: diagnostic.Tags);
                diagnostics.Add(diag);
            }

            return(diagnostics.ToImmutableArray());
        }
        public async Task <TOut> RequestAsync <TIn, TOut>(LspRequest <TIn, TOut> method, TIn param, RequestContext context, CancellationToken cancellationToken)
        {
            if (method.Name == Methods.Initialize.Name)
            {
                var capabilities = new ServerCapabilities {
                    CompletionProvider = new LSP.CompletionOptions {
                        TriggerCharacters = new[] { "." }
                    },
                    SignatureHelpProvider = new SignatureHelpOptions {
                        TriggerCharacters = new[] { "(", ",", ")" }
                    },
                    HoverProvider      = true,
                    DefinitionProvider = true,
                    ReferencesProvider = true
                };
                object result = new InitializeResult {
                    Capabilities = capabilities
                };
                return((TOut)(result));
            }

            if (method.Name == Methods.TextDocumentCompletion.Name ||
                method.Name == Methods.TextDocumentHover.Name ||
                method.Name == Methods.TextDocumentDefinition.Name ||
                method.Name == Methods.TextDocumentReferences.Name ||
                method.Name == Methods.TextDocumentSignatureHelp.Name
                )
            {
                var doc = (param as TextDocumentPositionParams)?.TextDocument;
                if (doc == null)
                {
                    return(default(TOut));
                }

                var analyzer = await FindAnalyzerAsync(doc);

                if (analyzer == null)
                {
                    return(default(TOut));
                }

                if (method.Name == Methods.TextDocumentDefinition.Name)
                {
                    return((TOut)(object)await analyzer.SendLanguageServerRequestAsync <TIn, Location[]>(method.Name, param));
                }

                var entry = analyzer.GetAnalysisEntryFromUri(doc.Uri);
                if (entry != null)
                {
                    var buffers = entry.TryGetBufferParser()?.AllBuffers;
                    if (buffers != null)
                    {
                        foreach (var b in buffers)
                        {
                            await entry.EnsureCodeSyncedAsync(b);
                        }
                    }
                }

                return(await analyzer.SendLanguageServerRequestAsync <TIn, TOut>(method.Name, param));
            }

            return(default(TOut));
        }