public RoslynOverloadProvider(SignatureHelpItems signatureHelp)
 {
     _signatureHelp = signatureHelp;
     _items         = signatureHelp.Items;
     if (signatureHelp.SelectedItemIndex != null)
     {
         _selectedIndex = signatureHelp.SelectedItemIndex.Value;
     }
 }
        public async Task <ParameterHintingResult> GetParameterDataProviderAsync(ImmutableArray <ISignatureHelpProvider> providers, Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken))
        {
            var hintingData = new List <ParameterHintingData> ();
            SignatureHelpItems bestSignatureHelpItems = null;

            foreach (var provider in providers)
            {
                try {
                    if (triggerInfo.TriggerReason == SignatureHelpTriggerReason.TypeCharCommand && !provider.IsTriggerCharacter(triggerInfo.TriggerCharacter.Value))
                    {
                        continue;
                    }
                    if (triggerInfo.TriggerReason == SignatureHelpTriggerReason.RetriggerCommand && !provider.IsRetriggerCharacter(triggerInfo.TriggerCharacter.Value))
                    {
                        continue;
                    }
                    var signatureHelpItems = await provider.GetItemsAsync(document, position, triggerInfo, token).ConfigureAwait(false);

                    if (signatureHelpItems == null)
                    {
                        continue;
                    }
                    if (bestSignatureHelpItems == null)
                    {
                        bestSignatureHelpItems = signatureHelpItems;
                    }
                    else if (signatureHelpItems.ApplicableSpan.Start > bestSignatureHelpItems.ApplicableSpan.Start)
                    {
                        bestSignatureHelpItems = signatureHelpItems;
                    }
                } catch (OperationCanceledException) {
                    return(ParameterHintingResult.Empty);
                } catch (Exception e) {
                    LoggingService.LogError("Error while getting items from parameter provider " + provider, e);
                }
            }

            if (bestSignatureHelpItems != null)
            {
                foreach (var item in bestSignatureHelpItems.Items)
                {
                    hintingData.Add(new SignatureHelpParameterHintingData(item));
                }
                var tree = await document.GetSyntaxTreeAsync(token);

                var tokenLeftOfPosition = tree.GetRoot(token).FindTokenOnLeftOfPosition(position);
                var syntaxNode          = tokenLeftOfPosition.Parent;
                var node = syntaxNode?.FirstAncestorOrSelf <ArgumentListSyntax> ();
                return(new ParameterHintingResult(hintingData)
                {
                    ApplicableSpan = bestSignatureHelpItems.ApplicableSpan,
                    SelectedItemIndex = bestSignatureHelpItems.SelectedItemIndex,
                    ParameterListStart = node != null ? node.SpanStart : bestSignatureHelpItems.ApplicableSpan.Start
                });
            }
            return(ParameterHintingResult.Empty);
        }
        private void CompareSigHelpItemsAndCurrentPosition(
            SignatureHelpItems items,
            SignatureHelpItem actualSignatureHelpItem,
            SignatureHelpTestItem expectedTestItem,
            ISignatureHelpProvider signatureHelpProvider,
            Document document,
            int cursorPosition,
            TextSpan applicableSpan)
        {
            int currentParameterIndex = -1;

            if (expectedTestItem.CurrentParameterIndex != null)
            {
                if (expectedTestItem.CurrentParameterIndex.Value >= 0 && expectedTestItem.CurrentParameterIndex.Value < actualSignatureHelpItem.Parameters.Length)
                {
                    currentParameterIndex = expectedTestItem.CurrentParameterIndex.Value;
                }
            }

            var signature = new Signature(applicableToSpan: null, signatureHelpItem: actualSignatureHelpItem, selectedParameterIndex: currentParameterIndex);

            // We're a match if the signature matches...
            // We're now combining the signature and documentation to make classification work.
            if (!string.IsNullOrEmpty(expectedTestItem.MethodDocumentation))
            {
                Assert.Equal(expectedTestItem.Signature + "\r\n" + expectedTestItem.MethodDocumentation, signature.Content);
            }
            else
            {
                Assert.Equal(expectedTestItem.Signature, signature.Content);
            }

            if (expectedTestItem.PrettyPrintedSignature != null)
            {
                Assert.Equal(expectedTestItem.PrettyPrintedSignature, signature.PrettyPrintedContent);
            }

            if (expectedTestItem.MethodDocumentation != null)
            {
                Assert.Equal(expectedTestItem.MethodDocumentation, actualSignatureHelpItem.DocumentationFactory(CancellationToken.None).GetFullText());
            }

            if (expectedTestItem.ParameterDocumentation != null)
            {
                Assert.Equal(expectedTestItem.ParameterDocumentation, signature.CurrentParameter.Documentation);
            }

            if (expectedTestItem.CurrentParameterIndex != null)
            {
                Assert.Equal(expectedTestItem.CurrentParameterIndex, items.ArgumentIndex);
            }

            if (expectedTestItem.Description != null)
            {
                Assert.Equal(expectedTestItem.Description, ToString(actualSignatureHelpItem.DescriptionParts));
            }
        }
            /// <summary>
            /// Returns <code>null</code> if our work was preempted and we want to return the
            /// previous model we've computed.
            /// </summary>
            private async Task <(ISignatureHelpProvider provider, SignatureHelpItems items)?> ComputeItemsAsync(
                int localRetriggerId,
                ImmutableArray <ISignatureHelpProvider> providers,
                SnapshotPoint caretPosition,
                SignatureHelpTriggerInfo triggerInfo,
                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)
                    {
                        // If this is a retrigger command, and another retrigger command has already
                        // been issued then we can bail out immediately.
                        if (IsNonTypeCharRetrigger(triggerInfo) &&
                            localRetriggerId != _retriggerId)
                        {
                            return(null);
                        }

                        cancellationToken.ThrowIfCancellationRequested();

                        var currentItems = await provider.GetItemsAsync(document, caretPosition, triggerInfo, 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:
                            //
                            //  Foo(new Bar($$
                            //
                            // Then invoking sig help will only show the items for "new Bar(" and not also
                            // the items for "Foo(..."
                            if (IsBetter(bestItems, currentItems.ApplicableSpan))
                            {
                                bestItems    = currentItems;
                                bestProvider = provider;
                            }
                        }
                    }

                    return(bestProvider, bestItems);
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
Example #5
0
            private static SignatureHelpItem GetSelectedItem(
                Model currentModel,
                SignatureHelpItems items,
                ISignatureHelpProvider provider,
                out bool userSelected
                )
            {
                // Try to find the most appropriate item in the list to select by default.

                // If it's the same provider as the previous model we have, and we had a user-selection,
                // then try to return the user-selection.
                if (
                    currentModel != null &&
                    currentModel.Provider == provider &&
                    currentModel.UserSelected
                    )
                {
                    var userSelectedItem = items.Items.FirstOrDefault(
                        i => DisplayPartsMatch(i, currentModel.SelectedItem)
                        );
                    if (userSelectedItem != null)
                    {
                        userSelected = true;
                        return(userSelectedItem);
                    }
                }
                userSelected = false;

                // If the provider specified a selected item, then pick that one.
                if (items.SelectedItemIndex.HasValue)
                {
                    return(items.Items[items.SelectedItemIndex.Value]);
                }

                SignatureHelpItem lastSelectionOrDefault = null;

                if (currentModel != null && currentModel.Provider == provider)
                {
                    // If the provider did not pick a default, and it's the same provider as the previous
                    // model we have, then try to return the same item that we had before.
                    lastSelectionOrDefault = items.Items.FirstOrDefault(
                        i => DisplayPartsMatch(i, currentModel.SelectedItem)
                        );
                }

                if (lastSelectionOrDefault == null)
                {
                    // Otherwise, just pick the first item we have.
                    lastSelectionOrDefault = items.Items.First();
                }

                return(lastSelectionOrDefault);
            }
            private bool IsBetter(SignatureHelpItems bestItems, TextSpan?currentTextSpan)
            {
                // If we have no best text span, then this span is definitely better.
                if (bestItems == null)
                {
                    return(true);
                }

                // Otherwise we want the one that is conceptually the innermost signature.  So it's
                // only better if the distance from it to the caret position is less than the best
                // one so far.
                return(currentTextSpan.Value.Start > bestItems.ApplicableSpan.Start);
            }
        private void CompareAndAssertCollectionsAndCurrentParameter(
            IEnumerable <SignatureHelpTestItem> expectedTestItems, SignatureHelpItems actualSignatureHelpItems)
        {
            Assert.Equal(expectedTestItems.Count(), actualSignatureHelpItems.Items.Count());

            for (var i = 0; i < expectedTestItems.Count(); i++)
            {
                CompareSigHelpItemsAndCurrentPosition(
                    actualSignatureHelpItems,
                    actualSignatureHelpItems.Items.ElementAt(i),
                    expectedTestItems.ElementAt(i));
            }
        }
        public IInsightItem[] ProvideInsight(ITextEditor editor)
        {
            SignatureHelpItems helpItems = context.GetSignature(editor.FileName, editor.Caret.Offset);

            if (helpItems == null)
            {
                return(new TypeScriptFunctionInsightItem[0]);
            }

            return(helpItems
                   .items
                   .Select(item => new TypeScriptFunctionInsightItem(item))
                   .ToArray());
        }
Example #9
0
            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 void CompareAndAssertCollectionsAndCurrentParameter(
            IEnumerable <SignatureHelpTestItem> expectedTestItems, SignatureHelpItems actualSignatureHelpItems, ISignatureHelpProvider signatureHelpProvider, Document document, int cursorPosition)
        {
            Assert.Equal(expectedTestItems.Count(), actualSignatureHelpItems.Items.Count());

            for (int i = 0; i < expectedTestItems.Count(); i++)
            {
                CompareSigHelpItemsAndCurrentPosition(
                    actualSignatureHelpItems,
                    actualSignatureHelpItems.Items.ElementAt(i),
                    expectedTestItems.ElementAt(i),
                    signatureHelpProvider,
                    document,
                    cursorPosition,
                    actualSignatureHelpItems.ApplicableSpan);
            }
        }
Example #11
0
        private static int GetActiveSignature(SignatureHelpItems items)
        {
            if (items.SelectedItemIndex.HasValue)
            {
                return(items.SelectedItemIndex.Value);
            }

            // From Roslyn's doc comments for SelectedItemIndex:
            //   If this is null, then the controller will pick the first item that has enough arguments
            //   to be viable based on what argument position the user is currently inside of.
            // However, the LSP spec expects the language server to make this decision.
            // So implement the logic of picking a signature that has enough arguments here.

            var matchingSignature = items.Items.FirstOrDefault(sig => sig.Parameters.Length > items.ArgumentIndex);

            return(matchingSignature != null?items.Items.IndexOf(matchingSignature) : 0);
        }
Example #12
0
 public bool IsSameArglist(_Span span2, SignatureHelpItems r2)
 {
     if (!IsSameSpan(span2) || r2.Items.Count != r.Items.Count)
     {
         return(false);
     }
     for (int i = 0; i < r.Items.Count; i++)
     {
         var hi1 = r.Items[i] as AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem;
         var hi2 = r2.Items[i] as AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem;
         Debug.Assert(!(hi1 == null || hi2 == null));
         if (hi1 == null || hi2 == null || hi2.Symbol != hi1.Symbol)
         {
             return(false);
         }
     }
     return(true);
 }
Example #13
0
 public int GetUserSelectedItemIfSameSpan(_Span span2, SignatureHelpItems r2)
 {
     if (iUserSelected < 0 || !IsSameSpan(span2) || r2.Items.Count != r.Items.Count)
     {
         return(-1);
     }
     for (int i = 0; i < r.Items.Count; i++)
     {
         var hi1 = r.Items[i] as AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem;
         var hi2 = r2.Items[i] as AbstractSignatureHelpProvider.SymbolKeySignatureHelpItem;
         Debug.Assert(!(hi1 == null || hi2 == null));
         if (hi1 == null || hi2 == null || hi2.Symbol != hi1.Symbol)
         {
             return(-1);
         }
     }
     return(iUserSelected);
 }
            private static SignatureHelpItem GetSelectedItem(Model currentModel, SignatureHelpItems items, ISignatureHelpProvider provider)
            {
                // Try to find the most appropriate item in the list to select by default.

                // If the provider specified one a selected item, then always stick with that one.
                if (items.SelectedItemIndex.HasValue)
                {
                    return(items.Items[items.SelectedItemIndex.Value]);
                }

                // If the provider did not pick a default, and it's the same provider as the previous
                // model we have, then try to return the same item that we had before.
                if (currentModel != null && currentModel.Provider == provider)
                {
                    return(items.Items.FirstOrDefault(i => DisplayPartsMatch(i, currentModel.SelectedItem)) ?? items.Items.First());
                }

                // Otherwise, just pick the first item we have.
                return(items.Items.First());
            }
        // TODO: Some of this is duplicated from Controller.Session_ComputeModel.cs
        private async Task <SignatureHelpItems> GetItemsAsync(LogicalDocument document, int position, CancellationToken cancellationToken)
        {
            var triggerInfo = new SignatureHelpTriggerInfo(SignatureHelpTriggerReason.InvokeSignatureHelpCommand);

            var providers = _signatureHelpProviders
                            .Where(x => x.Metadata.Language == document.Language)
                            .Select(x => x.Value);

            ISignatureHelpProvider bestProvider = null;
            SignatureHelpItems     bestItems    = null;

            foreach (var provider in providers)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var currentItems = await provider.GetItemsAsync(document, position, triggerInfo, cancellationToken);

                if (currentItems != null && currentItems.ApplicableSpan.IntersectsWith(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:
                    //
                    //  Foo(new Bar($$
                    //
                    // Then invoking sig help will only show the items for "new Bar(" and not also
                    // the items for "Foo(..."
                    if (IsBetter(bestItems, currentItems.ApplicableSpan))
                    {
                        bestItems    = currentItems;
                        bestProvider = provider;
                    }
                }
            }

            return(bestItems);
        }
Example #16
0
    async void _ShowSignature(SciCode doc, char ch, bool methodCompletion = false)
    {
        //using var p1 = perf.local();
        if (!CodeInfo.GetContextAndDocument(out var cd, -2) || cd.pos < 2)
        {
            return;                                                                        //returns false if position is in meta comments
        }
        _cancelTS?.Cancel();
        _cancelTS = new CancellationTokenSource();
        var cancelTS    = _cancelTS;
        var cancelToken = cancelTS.Token;

#if DEBUG
        if (Debugger.IsAttached)
        {
            cancelToken = default; _cancelTS = null;
        }
#endif

        SyntaxNode root = null;
        //ISignatureHelpProvider provider = null;
        SignatureHelpItems r = null;
        try {
            //could be sync, quite fast, but then sometimes reenters (GetItemsAsync waits/dispatches) and sometimes hangs
            r = await Task.Run(async() => {
                //p1.Next();
                root = cd.syntaxRoot;
                //p1.Next('r');
                var providers = _SignatureHelpProviders;
                //print.it(providers);
                SignatureHelpItems r = null;
                var trigger          = new SignatureHelpTriggerInfo(ch == default ? SignatureHelpTriggerReason.InvokeSignatureHelpCommand : SignatureHelpTriggerReason.TypeCharCommand, ch);
                foreach (var p in providers)
                {
                    //print.it(p);
                    var r2 = await p.GetItemsAsync(cd.document, cd.pos, trigger, SignatureHelpOptions.Default, cancelToken).ConfigureAwait(false);
                    if (cancelToken.IsCancellationRequested) /*print.it("IsCancellationRequested");*/ return {
                        (null);
                    }                                                                                                                      //often
                    if (r2 == null)
                    {
                        continue;
                    }
                    if (r == null || r2.ApplicableSpan.Start > r.ApplicableSpan.Start)
                    {
                        r = r2;
                        //provider = p;
                    }
                    //Example: 'print.it(new Something())'.
                    //	The first provider probably is for Write (invocation).
                    //	Then the second is for Something (object creation).
                    //	We need the innermost, in this case Something.
                }
                return(r);
            });
        }
        catch (OperationCanceledException) { /*Debug_.Print("canceled");*/ return; }         //never noticed
        //catch (AggregateException e1) when (e1.InnerException is TaskCanceledException) { return; }
        finally {
            cancelTS.Dispose();
            if (cancelTS == _cancelTS)
            {
                _cancelTS = null;
            }
        }
        //print.it(r, cancelToken.IsCancellationRequested);

        if (cancelToken.IsCancellationRequested)
        {
            return;
        }
        if (r == null)
        {
            _CancelUI();
            return;
        }
        Debug.Assert(doc == Panels.Editor.ZActiveDoc);         //when active doc changed, cancellation must be requested
        if (cd.pos != doc.zCurrentPos16 || (object)cd.code != doc.zText)
        {
            return;                                                                      //changed while awaiting
        }
        //p1.Next('s');

        //print.it($"<><c orange>pos={cd.pos}, span={r.ApplicableSpan},    nItems={r.Items.Count},  argCount={r.ArgumentCount}, argIndex={r.ArgumentIndex}, argName={r.ArgumentName}, sel={r.SelectedItemIndex},    provider={provider}<>");

        //get span of the arglist. r.ApplicableSpan.Start is of the statement, not of the arglist. In chained methods it is the chain start.
        var fullSpan = r.ApplicableSpan;
        //CiUtil.HiliteRange(fullSpan); wait.doEvents(500);
        var start = fullSpan.Start;
        var tok   = root.FindToken(cd.pos);
        if (tok.Kind() is SyntaxKind.OpenParenToken or SyntaxKind.OpenBracketToken or SyntaxKind.LessThanToken)
        {
            tok = tok.GetPreviousToken();
        }
        var argNode = tok.Parent;
        while (argNode != null)
        {
            int i = argNode.SpanStart; if (i <= start)
            {
                break;
            }
            if (argNode is BaseArgumentListSyntax or AttributeArgumentListSyntax or TypeArgumentListSyntax)
            {
                start = i + 1;
                break;
            }
            //CiUtil.PrintNode(argNode);
            argNode = argNode.Parent;
        }
        var argSpan = new TextSpan(start, fullSpan.End - start);
        //CiUtil.PrintNode(argNode); CiUtil.HiliteRange(argSpan); //print.it(argSpan);

        var span = new _Span(argSpan, cd.code);
        int iSel = 0, iSel2 = 0;
        if (r.Items.Count > 1)
        {
            iSel2 = r.SelectedItemIndex ?? -1;
            if (_data?.IsSameArglist(span, r) ?? false)
            {
                iSel = _data.iUserSelected;                 //preserve user selection in same session
                if (iSel2 < 0)
                {
                    iSel2 = _data.iRoslynSelected;                            //on error use last good Roslyn selection in same session, like in VS
                }
            }
            else
            {
                iSel = -1;
            }
        }

        _data = new _Data {
            r               = r,
            span            = span,
            iUserSelected   = iSel,
            iRoslynSelected = iSel2,
            sci             = doc,
        };

        if (iSel < 0)
        {
            iSel = iSel2;
        }
        if (iSel < 0)
        {
            //r.SelectedItemIndex is null when cannot resolve overloads, eg when arglist is partially typed. Example: wnd.find(1, );
            iSel = r.SelectedItemIndex ?? (r.ArgumentCount == 0 ? 0 : -1);
            if (iSel < 0)
            {
                for (int i = 0; i < r.Items.Count; i++)
                {
                    if (r.Items[i].Parameters.Length >= r.ArgumentCount)
                    {
                        iSel = i; break;
                    }
                }
                if (iSel < 0)
                {
                    for (int i = 0; i < r.Items.Count; i++)
                    {
                        if (r.Items[i].IsVariadic)
                        {
                            iSel = i; break;
                        }
                    }
                    if (iSel < 0)
                    {
                        iSel = 0;
                    }
                }
            }
        }

        doc.ZTempRanges_Add(this, argSpan.Start, argSpan.End, onLeave: () => {
            if (doc.ZTempRanges_Enum(doc.zCurrentPos8, this, utf8: true).Any())
            {
                return;
            }
            _CancelUI();
        }, SciCode.ZTempRangeFlags.NoDuplicate);

        var rect = RECT.Union(CiUtil.GetCaretRectFromPos(doc, fullSpan.Start), CiUtil.GetCaretRectFromPos(doc, cd.pos));
        doc.Hwnd.MapClientToScreen(ref rect);
        rect.Width += Dpi.Scale(200, doc.Hwnd);
        rect.left  -= 6;

        _textPopup ??= new CiPopupText(CiPopupText.UsedBy.Signature, onHiddenOrDestroyed: (_, _) => _data = null)
        {
            OnLinkClick = (ph, e) => ph.Text = _FormatText(e.ToInt(1), userSelected: true)
        };
        _textPopup.Text = _FormatText(iSel, userSelected: false);

        if (!_textPopup.IsVisible)
        {
            CodeInfo.HideTextPopupAndTempWindows();
            if (CodeInfo._compl.IsVisibleUI)             //without this does not show completions with selected enum when typed Function( when first parameter is enum
            {
                CodeInfo._compl.Cancel();
            }
            if (methodCompletion)
            {
                CodeInfo._compl.ShowList(ch);                               //when autocompletion added (); may need to show enum list
            }
        }

        _textPopup.Show(Panels.Editor.ZActiveDoc, rect, System.Windows.Controls.Dock.Bottom);

        //also show Keys/Regex tool?
        //CiUtil.PrintNode(node);
        if (argNode is ArgumentListSyntax or BracketedArgumentListSyntax && cd.code.Eq(cd.pos - 1, "\"\""))
        {
            //print.it("string");
            var semo  = cd.semanticModel;
            var token = root.FindToken(cd.pos);
            if (true == token.IsInString(cd.pos, cd.code, out var stringInfo))
            {
                var stringFormat = CiUtil.GetParameterStringFormat(stringInfo.stringNode, semo, true);
                if (stringFormat != 0)
                {
                    CodeInfo._tools.ShowForStringParameter(stringFormat, cd, stringInfo, _textPopup.PopupWindow.Hwnd);
                }
            }
        }
    }
Example #17
0
 public RoslynOverloadProvider(SignatureHelpItems signatureHelp)
 {
     _signatureHelp = signatureHelp;
     _items         = signatureHelp.Items;
     CreateSignatureHelp();
 }
Example #18
0
		public SignatureHelpResult(SignatureHelpItems items, SignatureHelpItem selectedItem, int? selectedParameter) {
			Items = items;
			SelectedItem = selectedItem;
			SelectedParameter = selectedParameter;
		}
            private static SignatureHelpItem GetSelectedItem(Model currentModel, SignatureHelpItems items, ISignatureHelpProvider provider)
            {
                // Try to find the most appropriate item in the list to select by default.

                // If the provider specified one a selected item, then always stick with that one. 
                if (items.SelectedItemIndex.HasValue)
                {
                    return items.Items[items.SelectedItemIndex.Value];
                }

                // If teh provider did not pick a default, and it's hte same provider as the previous
                // model we have, then try to return the same item that we had before. 
                if (currentModel != null && currentModel.Provider == provider)
                {
                    return items.Items.FirstOrDefault(i => DisplayPartsMatch(i, currentModel.SelectedItem)) ?? items.Items.First();
                }

                // Otherwise, just pick the first item we have.
                return items.Items.First();
            }
Example #20
0
    void _ShowSignature(SciCode doc, char ch)
    {
        //APerf.First();
        if (!CodeInfo.GetContextAndDocument(out var cd, -2))
        {
            return;                                                         //returns false if position is in meta comments
        }
        //APerf.Next();
        var trigger   = new SignatureHelpTriggerInfo(ch == default ? SignatureHelpTriggerReason.InvokeSignatureHelpCommand : SignatureHelpTriggerReason.TypeCharCommand, ch);
        var providers = _SignatureHelpProviders;
        //AOutput.Write(providers);
        //APerf.Next();
        SignatureHelpItems r = null;

        foreach (var p in providers)
        {
            //APerf.First();
            var r2 = p.GetItemsAsync(cd.document, cd.pos16, trigger, default).Result;
            //APerf.NW(); //quite fast, don't need async. But in the future can try to wrap this foreach+SignatureHelpProviders in async Task. Need to test with large files.
            if (r2 == null)
            {
                continue;
            }
            if (r == null || r2.ApplicableSpan.Start > r.ApplicableSpan.Start)
            {
                r = r2;
            }
            //Example: 'AOutput.Write(new Something())'.
            //	The first provider probably is for Write (invocation).
            //	Then the second is for Something (object creation).
            //	We need the innermost, in this case Something.
        }

        if (r == null)
        {
            Cancel();
            return;
        }
        //APerf.NW('s');
        //AOutput.Write($"<><c orange>pos={de.position}, span={r.ApplicableSpan},    nItems={r.Items.Count},  argCount={r.ArgumentCount}, argIndex={r.ArgumentIndex}, argName={r.ArgumentName}, sel={r.SelectedItemIndex},    provider={provider}<>");

        //var node = document.GetSyntaxRootAsync().Result;
        var span = new _Span(r.ApplicableSpan, cd.code);
        int iSel = _data?.GetUserSelectedItemIfSameSpan(span, r) ?? -1;         //preserve user selection in same session

        _data = new _Data {
            r             = r,
            span          = span,
            iUserSelected = iSel,
            sciDoc        = doc,
        };

        if (iSel < 0)
        {
            iSel = r.SelectedItemIndex ?? (r.ArgumentCount == 0 ? 0 : -1);
            if (iSel < 0)
            {
                for (int i = 0; i < r.Items.Count; i++)
                {
                    if (r.Items[i].Parameters.Length >= r.ArgumentCount)
                    {
                        iSel = i; break;
                    }
                }
                if (iSel < 0)
                {
                    for (int i = 0; i < r.Items.Count; i++)
                    {
                        if (r.Items[i].IsVariadic)
                        {
                            iSel = i; break;
                        }
                    }
                    if (iSel < 0)
                    {
                        iSel = 0;
                    }
                }
            }
        }

        string html = _FormatHtml(iSel, userSelected: false);

        doc.ZTempRanges_Add(this, r.ApplicableSpan.Start, r.ApplicableSpan.End, onLeave: () => {
            if (doc.ZTempRanges_Enum(doc.Z.CurrentPos8, this, utf8: true).Any())
            {
                return;
            }
            Cancel();
        }, SciCode.ZTempRangeFlags.NoDuplicate);

        var rect1 = CiUtil.GetCaretRectFromPos(doc, r.ApplicableSpan.Start);
        var rect2 = CiUtil.GetCaretRectFromPos(doc, cd.pos16);
        var rect  = doc.RectangleToScreen(Rectangle.Union(rect1, rect2));

        rect.Width += Au.Util.ADpi.ScaleInt(200);
        rect.X     -= 6;

        _popupHtml ??= new CiPopupHtml(CiPopupHtml.UsedBy.Signature, onHiddenOrDestroyed: _ => _data = null)
        {
            OnLinkClick = (ph, e) => ph.Html = _FormatHtml(e.Link.ToInt(1), userSelected: true)
        };
        _popupHtml.Html = html;
        _popupHtml.Show(Panels.Editor.ZActiveDoc, rect, PopupAlignment.TPM_VERTICAL);
        //APerf.NW();
    }
Example #21
0
 public RoslynOverloadProvider(SignatureHelpItems signatureHelp)
 {
     _signatureHelp = signatureHelp;
     SelectItem();
 }
            private bool IsBetter(SignatureHelpItems bestItems, TextSpan? currentTextSpan)
            {
                // If we have no best text span, then this span is definitely better.
                if (bestItems == null)
                {
                    return true;
                }

                // Otherwise we want the one that is conceptually the innermost signature.  So it's
                // only better if the distance from it to the caret position is less than the best
                // one so far.
                return currentTextSpan.Value.Start > bestItems.ApplicableSpan.Start;
            }