コード例 #1
0
        private string getProto(IXMemberSymbol xMember, XSharpSignatureProperties props)
        {
            var proto = xMember.Prototype;

            // Adjust SELF() and SUPER: remove typename and replace {} with ()
            if (xMember.Kind == Kind.Constructor && props.triggerChar == '(')
            {
                var parlist = proto.Substring(proto.IndexOf('{') + 1);
                parlist = parlist.Substring(0, parlist.Length - 1);
                proto   = props.triggerToken + "(" + parlist + ")";
            }
            return(proto);
        }
コード例 #2
0
        internal bool StartSignatureSession(bool comma, IXTypeSymbol type = null, string methodName = null, char triggerchar = '\0')
        {
            WriteOutputMessage("StartSignatureSession()");

            if (_signatureSession != null)
            {
                return(false);
            }
            IXMemberSymbol currentElement = null;
            SnapshotPoint  ssp            = this._textView.Caret.Position.BufferPosition;

            if (triggerchar == '(' && ssp.Position < ssp.Snapshot.Length && ssp.GetChar() == ')')
            {
                ssp -= 1;
            }
            var location = _textView.FindLocation(ssp);

            if (location == null || location.Member == null)
            {
                return(false);
            }
            if (location.Member.Range.StartLine == location.LineNumber)
            {
                return(false);
            }

            var props = new XSharpSignatureProperties(location);

            props.triggerChar     = triggerchar;
            props.triggerPosition = this._textView.Caret.Position.BufferPosition.Position;

            if (type != null && methodName != null)
            {
                var findStatic = triggerchar == '.';
                currentElement = XSharpLookup.SearchMethod(location, type, methodName, Modifiers.Private, findStatic).FirstOrDefault();
            }
            else
            {
                currentElement = findElementAt(comma, ssp, props);
            }
            if (currentElement == null)
            {
                return(false);
            }

            SnapshotPoint caret         = _textView.Caret.Position.BufferPosition;
            ITextSnapshot caretsnapshot = caret.Snapshot;

            //
            if (_signatureBroker.IsSignatureHelpActive(_textView))
            {
                _signatureSession = _signatureBroker.GetSessions(_textView)[0];
            }
            else
            {
                _signatureSession = _signatureBroker.CreateSignatureHelpSession(_textView, caretsnapshot.CreateTrackingPoint(caret, PointTrackingMode.Positive), true);
            }
            _signatureSession.Properties[typeof(XSharpSignatureProperties)] = props;

            if (location.Member.Kind.IsGlobalTypeMember())
            {
                props.Visibility = Modifiers.Public;
            }
            else
            {
                props.Visibility = Modifiers.Protected;
            }
            _signatureSession.Dismissed += OnSignatureSessionDismiss;
            props.Element = currentElement;
            if (comma)
            {
                var  tokenList = XSharpTokenTools.GetTokenListBeforeCaret(location, out var state);
                bool done      = false;
                int  nested    = 0;
                for (int i = tokenList.Count - 1; i >= 0 && !done; i--)
                {
                    var token = tokenList[i];
                    switch (token.Type)
                    {
                    case XSharpLexer.LPAREN:
                    case XSharpLexer.LCURLY:
                    case XSharpLexer.LBRKT:
                        done = nested == 0;
                        if (done)
                        {
                            props.Start  = token.Position;
                            props.Length = _textView.Caret.Position.BufferPosition.Position - token.Position;
                        }
                        nested -= 1;
                        break;

                    case XSharpLexer.RPAREN:
                    case XSharpLexer.RCURLY:
                    case XSharpLexer.RBRKT:
                        nested += 1;
                        break;
                    }
                }
            }
            else
            {
                props.Start  = ssp.Position;
                props.Length = _textView.Caret.Position.BufferPosition.Position - ssp.Position;
            }


            try
            {
                _signatureSession.Start();
            }
            catch (Exception e)
            {
                XSettings.LogException(e, "Start Signature session failed:");
            }
            //
            return(true);
        }
コード例 #3
0
        IXMemberSymbol findElementAt(bool comma, SnapshotPoint ssp, XSharpSignatureProperties props)
        {
            // when coming from the completion list then there is no need to check a lot of stuff
            // we can then simply lookup the method and that is it.
            // Also no need to filter on visibility since that has been done in the completionlist already !
            // First, where are we ?
            var location = props.Location;

            // When we have a multi line source line this is the line where the open paren or open curly is

            if (location.Member != null && location.Member.Range.StartLine == ssp.GetContainingLine().LineNumber)
            {
                // if we are at the start of an entity then do not start a signature session
                return(null);
            }
            // Then, the corresponding Type/Element if possible
            // Check if we can get the member where we are

            var tokenList = XSharpTokenTools.GetTokenListBeforeCaret(location, out var state);
            // tokenlist may look like ID1 ( ID2 ( e1 , e2)
            // after the closing paren we come here and want to completely remove the  ID2 ( e1, e2 ) part
            // when we have this ID1 ( e1 ) then there should be no parameter completion at all
            // The same for ID1 { e1 }
            // so we need to see if LPAREN / RPAREN is closed and if LCURLY / RCURLY is closed and if LBRKT / RBRKT is closed
            int nested     = 0;
            var openTokens = new Stack <XSharpToken>();

            for (int i = 0; i < tokenList.Count; i++)
            {
                var token = tokenList[i];
                switch (token.Type)
                {
                case XSharpLexer.LPAREN:
                case XSharpLexer.LCURLY:
                case XSharpLexer.LBRKT:
                    openTokens.Push(token);
                    break;

                case XSharpLexer.RPAREN:
                    if (openTokens.Count > 0 && openTokens.Peek().Type == XSharpLexer.LPAREN)
                    {
                        openTokens.Pop();
                    }
                    break;

                case XSharpLexer.RCURLY:
                    if (openTokens.Count > 0 && openTokens.Peek().Type == XSharpLexer.LCURLY)
                    {
                        openTokens.Pop();
                    }
                    break;

                case XSharpLexer.RBRKT:
                    if (openTokens.Count > 0 && openTokens.Peek().Type == XSharpLexer.LBRKT)
                    {
                        openTokens.Pop();
                    }
                    break;

                case XSharpLexer.STRING_CONST:
                case XSharpLexer.INTERPOLATED_STRING_CONST:
                case XSharpLexer.CHAR_CONST:
                    if (token.Position < location.Position && location.Position < token.Position + token.Text.Length)
                    {
                        // comma inside literal !
                        return(null);
                    }
                    break;
                }
            }

            if (openTokens.Count == 0)
            {
                tokenList.Clear();
            }
            else
            {
                var pos = tokenList.IndexOf(openTokens.Peek());
                if (pos >= 0)
                {
                    tokenList.RemoveRange(pos + 1, tokenList.Count - pos - 1);
                }
            }
            if (comma)
            {
                // check to see if there is a lparen or lcurly before the comma
                bool done = false;
                nested = 0;
                while (tokenList.Count > 0 && !done)
                {
                    var  token  = tokenList[tokenList.Count - 1];
                    bool delete = false;
                    switch (token.Type)
                    {
                    case XSharpLexer.RPAREN:
                    case XSharpLexer.RBRKT:
                    case XSharpLexer.RCURLY:
                        nested += 1;
                        delete  = true;
                        break;

                    case XSharpLexer.LBRKT:
                        nested -= 1;
                        delete  = true;
                        break;

                    case XSharpLexer.LPAREN:
                    case XSharpLexer.LCURLY:
                        nested -= 1;
                        if (nested < 0)
                        {
                            done = true;
                        }
                        else
                        {
                            delete = true;
                        }
                        break;

                    default:
                        delete = true;
                        break;
                    }
                    if (delete)
                    {
                        tokenList.RemoveAt(tokenList.Count - 1);
                    }
                }
            }

            IXMemberSymbol currentElement = null;
            // We don't care of the corresponding Type, we are looking for the currentElement
            var element = XSharpLookup.RetrieveElement(location, tokenList, state, out var notProcessed, true).FirstOrDefault();

            if (element is IXMemberSymbol mem)
            {
                currentElement = mem;
                if (currentElement.Kind == Kind.Constructor)
                {
                    bool done = false;
                    for (int i = tokenList.Count - 1; !done && i > 0; i--)
                    {
                        var token = tokenList[i];
                        switch (token.Type)
                        {
                        case XSharpLexer.LPAREN:
                        case XSharpLexer.LCURLY:
                            props.triggerToken = tokenList[i - 1].Text;
                            break;
                        }
                    }
                }
            }
            else if (element is IXTypeSymbol xtype)
            {
                currentElement = xtype.Members.Where(m => m.Kind == Kind.Constructor).FirstOrDefault();
            }
            return(currentElement);
        }