Exemple #1
0
        private Task SendSignatureHelpAsync(SignatureHelpItemsData?items, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var writer = sender.StartJsonMessage("signatures");

            if (items == null)
            {
                return(sender.SendJsonMessageAsync(cancellationToken));
            }

            var selectedItemIndex = items.SelectedItemIndex;

            writer.WriteSpanProperty("span", items.ApplicableSpan);
            writer.WritePropertyStartArray("signatures");
            var itemIndex = 0;

            foreach (var item in items.Items)
            {
                writer.WriteStartObject();
                if (selectedItemIndex == null && items.ArgumentCount <= item.ParameterCount)
                {
                    selectedItemIndex = itemIndex;
                }
                if (itemIndex == selectedItemIndex)
                {
                    writer.WriteProperty("selected", true);
                }
                writer.WritePropertyStartArray("parts");
                writer.WriteTaggedTexts(item.PrefixDisplayParts);
                var parameterIndex = 0;
                foreach (var parameter in item.Parameters)
                {
                    if (parameterIndex > 0)
                    {
                        writer.WriteTaggedTexts(item.SeparatorDisplayParts);
                    }
                    var selected = items.ArgumentIndex == parameterIndex;
                    writer.WriteTaggedTexts(parameter.PrefixDisplayParts, selected);
                    writer.WriteTaggedTexts(parameter.DisplayParts, selected);
                    writer.WriteTaggedTexts(parameter.SuffixDisplayParts, selected);
                    parameterIndex += 1;
                }
                writer.WriteTaggedTexts(item.SuffixDisplayParts);
                writer.WriteEndArray();
                writer.WriteEndObject();
                itemIndex += 1;
            }
            writer.WriteEndArray();
            return(sender.SendJsonMessageAsync(cancellationToken));
        }
        private async Task SendOptionsEchoAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (session.IsRoslyn)
            {
                session.Roslyn.CurrentCodeActions.Clear();
            }
            var writer = sender.StartJsonMessage("optionsEcho");

            writer.WritePropertyStartObject("options");
            foreach (var pair in session.RawOptionsFromClient)
            {
                writer.WriteProperty(pair.Key, pair.Value);
            }
            writer.WriteEndObject();
            await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false);
        }
Exemple #3
0
        private async Task ExecuteForRoslynAsync(
            int cursorPosition,
            WorkSession session,
            ICommandResultSender sender,
            CancellationToken cancellationToken
            )
        {
            var info = await session.Roslyn.QuickInfoService
                       .GetQuickInfoAsync(session.Roslyn.Document, cursorPosition, cancellationToken)
                       .ConfigureAwait(false);

            if (IsNullOrEmpty(info))
            {
                return;
            }
            await SendInfoTipAsync(info, sender, cancellationToken).ConfigureAwait(false);
        }
        private Task SendCompletionListAsync(CompletionList completionList, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var completionSpan = completionList.Span;
            var writer         = sender.StartJsonMessage("completions");

            writer.WriteProperty("commitChars", completionList.Rules.DefaultCommitCharacters);
            writer.WritePropertyName("span");
            writer.WriteSpan(completionSpan);

            var suggestionItem = completionList.SuggestionModeItem;

            if (suggestionItem != null)
            {
                writer.WritePropertyStartObject("suggestion");
                writer.WriteProperty("displayText", suggestionItem.DisplayText);
                writer.WriteEndObject();
            }

            writer.WritePropertyStartArray("completions");
            foreach (var item in completionList.Items)
            {
                writer.WriteStartObject();
                writer.WriteProperty("filterText", item.FilterText);
                writer.WriteProperty("displayText", item.DisplayText);
                writer.WritePropertyStartArray("tags");
                foreach (var tag in item.Tags)
                {
                    writer.WriteValue(tag.ToLowerInvariant());
                }
                writer.WriteEndArray();
                if (item.Span != completionSpan)
                {
                    writer.WritePropertyName("span");
                    writer.WriteSpan(item.Span);
                }
                if (item.Rules.MatchPriority > 0)
                {
                    writer.WriteProperty("priority", item.Rules.MatchPriority);
                }
                writer.WriteEndObject();
            }
            writer.WriteEndArray();

            return(sender.SendJsonMessageAsync(cancellationToken));
        }
        public Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var current = session.CurrentCompletion;

            if (current.List != null)
            {
                return(Task.CompletedTask);
            }

            if (current.ChangeEchoPending)
            {
                current.PendingChar = @char;
                return(Task.CompletedTask);
            }
            var trigger = CompletionTrigger.CreateInsertionTrigger(@char);

            return(CheckCompletionAsync(trigger, session, sender, cancellationToken));
        }
        public async Task SendItemInfoAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var item        = session.CurrentCompletion.List.Items[selectedIndex];
            var description = await session.LanguageSession.GetCompletionDescriptionAsync(item, cancellationToken).ConfigureAwait(false);

            if (description == null)
            {
                return;
            }

            var writer = sender.StartJsonMessage("completionInfo");

            writer.WriteProperty("index", selectedIndex);
            writer.WritePropertyStartArray("parts");
            writer.WriteTaggedTexts(description.TaggedParts);
            writer.WriteEndArray();
            await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false);
        }
Exemple #7
0
        public Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var writer = sender.StartJsonMessage("self:debug");

            writer.WritePropertyStartArray("log");
            // ReSharper disable once PossibleNullReferenceException
            foreach (var entry in session.SelfDebug.GetLogEntries())
            {
                writer.WriteStartObject();
                writer.WriteProperty("time", entry.DateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffK"));
                writer.WriteProperty("event", entry.EventType);
                writer.WriteProperty("message", entry.Message);
                writer.WriteProperty("cursor", entry.CursorPosition);
                writer.WriteProperty("text", entry.Text);
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
            return(sender.SendJsonMessageAsync(cancellationToken));
        }
        public Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var first     = data.GetFirst();
            var firstByte = first.Array[first.Offset];

            if (firstByte == (byte)'X')
            {
                return(_completion.CancelCompletionAsync(session, sender, cancellationToken));
            }

            if (firstByte == (byte)'F')
            {
                return(_completion.ForceCompletionAsync(session, sender, cancellationToken));
            }

            var itemIndex = FastConvert.Utf8ByteArrayToInt32(first);

            return(_completion.SelectCompletionAsync(itemIndex, session, sender, cancellationToken));
        }
Exemple #9
0
        private Task SendSignatureHelpAsync(SignatureHelpItemsData?items, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var writer = sender.StartJsonMessage("signatures");

            if (items == null)
            {
                return(sender.SendJsonMessageAsync(cancellationToken));
            }

            var selectedItemIndex = items.SelectedItemIndex;

            writer.WriteSpanProperty("span", items.ApplicableSpan);
            writer.WritePropertyStartArray("signatures");
            var itemIndex = 0;

            foreach (var item in items.Items)
            {
                writer.WriteStartObject();
                if (selectedItemIndex == null && items.ArgumentCount <= item.ParameterCount)
                {
                    selectedItemIndex = itemIndex;
                }
                var isSelected = (itemIndex == selectedItemIndex);
                if (isSelected)
                {
                    writer.WriteProperty("selected", true);
                }

                WriteSignatureParts(writer, item, items, out var selectedParameter);
                if (isSelected)
                {
                    WriteSignatureDocumentation(writer, item, selectedParameter, cancellationToken);
                }

                writer.WriteEndObject();
                itemIndex += 1;
            }
            writer.WriteEndArray();
            return(sender.SendJsonMessageAsync(cancellationToken));
        }
        public async Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            // this doesn't happen too often, so microptimizations are not required
            var optionsString = await AsyncDataConvert.ToUtf8StringAsync(data, 0, _charArrayPool).ConfigureAwait(false);

            var options = optionsString
                          .Split(Comma)
                          .Select(p => p.Split(EqualsSign))
                          .ToDictionary(p => p[0], p => p[1]);

            if (options.TryGetValue(LanguageOptionName, out var language))
            {
                // this has to be done first, as it might reset other options
                SetLanguage(session, language);
                session.RawOptionsFromClient[LanguageOptionName] = language;
            }

            foreach (var option in options)
            {
                var(name, value) = (option.Key, option.Value);
                if (name == LanguageOptionName)
                {
                    continue;
                }

                if (name.StartsWith("x-"))
                {
                    if (!(_extension?.TrySetOption(session, name, value) ?? false))
                    {
                        throw new FormatException($"Extension option '{name}' was not recognized.");
                    }
                    session.RawOptionsFromClient[name] = value;
                    continue;
                }

                throw new FormatException($"Option '{name}' was not recognized (to use {nameof(ISetOptionsFromClientExtension)}, make sure your option name starts with 'x-').");
            }

            await SendOptionsEchoAsync(session, sender, cancellationToken).ConfigureAwait(false);
        }
Exemple #11
0
        public async Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            // Temporary suppression, need to figure out the best approach here.
            // ReSharper disable once HeapView.BoxingAllocation
            var diagnostics = (IReadOnlyList <Diagnostic>) await session.LanguageSession.GetDiagnosticsAsync(cancellationToken).ConfigureAwait(false);

            object extensionResult = null;

            try {
                if (_extension != null)
                {
                    var mutableDiagnostics = diagnostics.ToList();
                    extensionResult = await _extension.ProcessAsync(session, mutableDiagnostics, cancellationToken).ConfigureAwait(false);

                    diagnostics = mutableDiagnostics;
                }
                await SendSlowUpdateAsync(diagnostics, session, extensionResult, sender, cancellationToken).ConfigureAwait(false);
            }
            finally {
                (extensionResult as IDisposable)?.Dispose();
            }
        }
Exemple #12
0
        public Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (!session.IsRoslyn)
            {
                return(Task.CompletedTask);
            }

            var trigger = new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.TypeCharCommand, @char);

            if (session.Roslyn.CurrentSignatureHelp != null)
            {
                var provider = session.Roslyn.CurrentSignatureHelp.Value.Provider;
                if (provider.IsRetriggerCharacter(@char))
                {
                    session.Roslyn.CurrentSignatureHelp = null;
                    return(SendSignatureHelpAsync(null, sender, cancellationToken));
                }

                return(TryApplySignatureHelpAsync(provider, trigger, session, sender, cancellationToken, sendIfEmpty: true));
            }

            return(TryApplySignatureHelpAsync(session, sender, cancellationToken, trigger));
        }
Exemple #13
0
        private Task SendInfoTipAsync(QuickInfoItem info, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var writer = sender.StartJsonMessage("infotip");

            if (IsNullOrEmpty(info))
            {
                return(sender.SendJsonMessageAsync(cancellationToken));
            }

            writer.WriteTagsProperty("kinds", info.Tags);
            writer.WritePropertyStartArray("sections");
            foreach (var section in info.Sections)
            {
                writer.WriteStartObject();
                writer.WriteProperty("kind", FastConvert.StringToLowerInvariantString(section.Kind));
                writer.WritePropertyStartArray("parts");
                writer.WriteTaggedTexts(section.TaggedParts);
                writer.WriteEndArray();
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
            writer.WriteSpanProperty("span", info.Span);
            return(sender.SendJsonMessageAsync(cancellationToken));
        }
Exemple #14
0
        public Task ApplyCursorPositionChangeAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (!session.IsRoslyn)
            {
                return(Task.CompletedTask);
            }

            var currentHelp = session.Roslyn.CurrentSignatureHelp;

            if (currentHelp == null)
            {
                return(Task.CompletedTask);
            }

            if (!currentHelp.Value.Items.ApplicableSpan.Contains(session.CursorPosition))
            {
                session.Roslyn.CurrentSignatureHelp = null;
                return(SendSignatureHelpAsync(null, sender, cancellationToken));
            }

            // not sure if there is any better way to recalculate the selected parameter only,
            // but doesn't seem so at the moment
            return(TryApplySignatureHelpAsync(currentHelp.Value.Provider, new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.RetriggerCommand), session, sender, cancellationToken, true));
        }
Exemple #15
0
        private async Task SendSlowUpdateAsync(IReadOnlyList <Diagnostic> diagnostics, WorkSession session, object extensionResult, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (session.IsRoslyn)
            {
                session.Roslyn.CurrentCodeActions.Clear();
            }
            var writer = sender.StartJsonMessage("slowUpdate");

            writer.WritePropertyStartArray("diagnostics");
            foreach (var diagnostic in diagnostics)
            {
                writer.WriteStartObject();
                writer.WriteProperty("id", diagnostic.Id);
                writer.WriteProperty("message", diagnostic.GetMessage());
                writer.WriteProperty("severity", FastConvert.EnumToLowerInvariantString(diagnostic.Severity));
                writer.WritePropertyStartArray("tags");
                foreach (var tag in diagnostic.Descriptor.CustomTags)
                {
                    if (tag != WellKnownDiagnosticTags.Unnecessary)
                    {
                        continue;
                    }
                    writer.WriteValue(tag.ToLowerInvariant());
                }
                writer.WriteEndArray();
                writer.WriteSpanProperty("span", diagnostic.Location.SourceSpan);

                var actions = await GetCodeActionsAsync(diagnostic, session, cancellationToken).ConfigureAwait(false);

                if (actions.Length > 0)
                {
                    writer.WritePropertyStartArray("actions");
                    WriteActions(writer, actions, session);
                    writer.WriteEndArray();
                }
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
            if (_extension != null)
            {
                writer.WritePropertyName("x");
                _extension.WriteResult(writer, extensionResult, session);
            }
            await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false);
        }
        public async Task SelectCompletionAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var current = session.CurrentCompletion;

            // ReSharper disable once PossibleNullReferenceException
            var completionList = current.List;
            // ReSharper disable once PossibleNullReferenceException
            var item   = completionList.Items[selectedIndex];
            var change = await session.LanguageSession.GetCompletionChangeAsync(completionList.Span, item, cancellationToken : cancellationToken).ConfigureAwait(false);

            current.List = null;

            var textChange = ReplaceIncompleteText(session, completionList, change.TextChange);

            current.ChangeEchoPending = true;

            var writer = sender.StartJsonMessage("changes");

            writer.WriteProperty("reason", ChangeReasonCompletion);
            writer.WritePropertyStartArray("changes");
            writer.WriteChange(textChange);
            writer.WriteEndArray();
            await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false);
        }
        public async Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            await _completion.ApplyTypedCharAsync(@char, session, sender, cancellationToken).ConfigureAwait(false);

            await _signatureHelp.ApplyTypedCharAsync(@char, session, sender, cancellationToken).ConfigureAwait(false);
        }
        private Task CheckCompletionAsync(CompletionTrigger trigger, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (!session.LanguageSession.ShouldTriggerCompletion(session.CursorPosition, trigger))
            {
                return(Task.CompletedTask);
            }

            return(TriggerCompletionAsync(session, sender, cancellationToken, trigger));
        }
        public Task ApplyReplacedTextAsync(string reason, ITypedCharEffects typedCharEffects, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            if (reason != ChangeReasonCompletion)
            {
                return(Task.CompletedTask);
            }

            var pendingChar = session.CurrentCompletion.PendingChar;

            session.CurrentCompletion.ResetPending();
            if (pendingChar == null)
            {
                return(Task.CompletedTask);
            }

            return(typedCharEffects.ApplyTypedCharAsync(pendingChar.Value, session, sender, cancellationToken));
        }
Exemple #20
0
        public Task ForceSignatureHelpAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var trigger = new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.InvokeSignatureHelpCommand);

            return(TryApplySignatureHelpAsync(session, sender, cancellationToken, trigger));
        }
 public Task CancelCompletionAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
 {
     session.CurrentCompletion.ResetPending();
     session.CurrentCompletion.List = null;
     return(Task.CompletedTask);
 }
 public Task ForceCompletionAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
 {
     return(TriggerCompletionAsync(session, sender, cancellationToken, CompletionTrigger.Invoke));
 }
Exemple #23
0
        private async Task <bool> TryApplySignatureHelpAsync(ISignatureHelpProviderWrapper provider, SignatureHelpTriggerInfoData trigger, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken, bool sendIfEmpty = false)
        {
            // ReSharper disable once PossibleInvalidOperationException
            if (trigger.TriggerReason == SignatureHelpTriggerReason.TypeCharCommand && !provider.IsTriggerCharacter(trigger.TriggerCharacter.Value))
            {
                return(false);
            }

            var help = await provider.GetItemsAsync(session.Roslyn.Document, session.CursorPosition, trigger, cancellationToken).ConfigureAwait(false);

            if (!sendIfEmpty && help == null)
            {
                return(false);
            }

            session.Roslyn.CurrentSignatureHelp = help != null ? new CurrentSignatureHelp(provider, help) : (CurrentSignatureHelp?)null;
            await SendSignatureHelpAsync(help, sender, cancellationToken).ConfigureAwait(false);

            return(true);
        }
        public async Task SelectCompletionAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken)
        {
            var current        = session.CurrentCompletion;
            var completionList = current.List;

            if (completionList == null)
            {
                throw new InvalidOperationException("Cannot select completion when completion list is not active.");
            }

            var item   = completionList.Items[selectedIndex];
            var change = await session.LanguageSession.GetCompletionChangeAsync(completionList.Span, item, cancellationToken : cancellationToken).ConfigureAwait(false);

            current.List = null;

            var textChange = ReplaceIncompleteText(session, completionList, change.TextChange);

            current.ChangeEchoPending = true;

            var writer = sender.StartJsonMessage("changes");

            writer.WriteProperty("reason", ChangeReasonCompletion);
            writer.WritePropertyStartArray("changes");
            writer.WriteChange(textChange);
            writer.WriteEndArray();
            await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false);
        }