Пример #1
0
        /// <summary>
        /// Given position in the buffer finds index of the function parameter.
        /// </summary>
        public static int ComputeCurrentParameter(this ISignatureInfo signatureInfo, IEditorBufferSnapshot snapshot, AstRoot ast, int position, IREditorSettings settings)
        {
            var parameterInfo = ast.GetSignatureInfoFromBuffer(snapshot, position);
            var index         = 0;

            if (parameterInfo != null)
            {
                index = parameterInfo.ParameterIndex;
                if (parameterInfo.NamedParameter)
                {
                    // A function f <- function(foo, bar) is said to have formal parameters "foo" and "bar",
                    // and the call f(foo=3, ba=13) is said to have (actual) arguments "foo" and "ba".
                    // R first matches all arguments that have exactly the same name as a formal parameter.
                    // Two identical argument names cause an error. Then, R matches any argument names that
                    // partially matches a(yet unmatched) formal parameter. But if two argument names partially
                    // match the same formal parameter, that also causes an error. Also, it only matches
                    // formal parameters before ... So formal parameters after ... must be specified using
                    // their full names. Then the unnamed arguments are matched in positional order to
                    // the remaining formal arguments.

                    var argumentIndexInSignature = signatureInfo.GetArgumentIndex(parameterInfo.ParameterName, settings.PartialArgumentNameMatch);
                    if (argumentIndexInSignature >= 0)
                    {
                        index = argumentIndexInSignature;
                    }
                }
            }
            return(index);
        }
Пример #2
0
        private int ComputeActiveParameter(IRIntellisenseContext context, ISignatureInfo signatureInfo)
        {
            var settings       = _services.GetService <IREditorSettings>();
            var parameterIndex = signatureInfo.ComputeCurrentParameter(context.EditorBuffer.CurrentSnapshot, context.AstRoot, context.Position, settings);

            if (parameterIndex < signatureInfo.Arguments.Count)
            {
                return(parameterIndex);
            }
            return(signatureInfo.Arguments.Count > 0 ? signatureInfo.Arguments.Count - 1 : 0);
        }
Пример #3
0
        private RFunctionSignatureHelp(IEditorIntellisenseSession session, IEditorBuffer textBuffer, string functionName, string documentation, ISignatureInfo signatureInfo)
        {
            FunctionName  = functionName;
            SignatureInfo = signatureInfo;

            Documentation = documentation;
            Parameters    = null;

            _editorBuffer = textBuffer;
            _view         = session.View;

            Session = session;

            _signatureBroker = session.Services.GetService <IViewSignatureBroker>();
            Debug.Assert(_signatureBroker != null);
        }
Пример #4
0
        public SignatureHelp(ISignatureHelpSession session, ITextBuffer subjectBuffer, string functionName,
                             string documentation, ISignatureInfo signatureInfo) {
            FunctionName = functionName;
            _signatureInfo = signatureInfo;

            Documentation = documentation;
            Parameters = null;

            Session = session;
            Session.Dismissed += OnSessionDismissed;

            TextView = session.TextView;
            TextView.Caret.PositionChanged += OnCaretPositionChanged;

            SubjectBuffer = subjectBuffer;
            SubjectBuffer.Changed += OnSubjectBufferChanged;
        }
Пример #5
0
        public static IReadOnlyList <ISignatureInfo> ParseSignatures(string usageContent, IReadOnlyDictionary <string, string> argumentsDescriptions = null)
        {
            // RD signature text may contain \dots sequence  which denotes ellipsis.
            // R parser does not know  about it and hence we will replace \dots by ...
            // Also, signatures may contain S3 method info like
            // '\method{as.matrix}{data.frame}(x, rownames.force = NA, \dots)'
            // which we need to filter out since they are irrelevant to intellisense.

            List <ISignatureInfo> signatures = new List <ISignatureInfo>();

            usageContent = usageContent.Replace(@"\dots", "...");

            RTokenizer tokenizer = new RTokenizer(separateComments: true);
            IReadOnlyTextRangeCollection <RToken> collection = tokenizer.Tokenize(usageContent);
            ITextProvider        textProvider = new TextStream(usageContent);
            TokenStream <RToken> tokens       = new TokenStream <RToken>(collection, RToken.EndOfStreamToken);

            var parseContext = new ParseContext(textProvider,
                                                TextRange.FromBounds(tokens.CurrentToken.Start, textProvider.Length),
                                                tokens, tokenizer.CommentTokens);

            while (!tokens.IsEndOfStream())
            {
                // Filter out '\method{...}{}(signature)
                if (tokens.CurrentToken.TokenType == RTokenType.OpenCurlyBrace)
                {
                    // Check if { is preceded by \method
                }

                if (tokens.CurrentToken.TokenType != RTokenType.Identifier)
                {
                    break;
                }

                string functionName = textProvider.GetText(tokens.CurrentToken);
                tokens.MoveToNextToken();

                ISignatureInfo info = ParseSignature(functionName, parseContext, argumentsDescriptions);
                if (info != null)
                {
                    signatures.Add(info);
                }
            }

            return(signatures);
        }
Пример #6
0
        public SignatureHelp(ISignatureHelpSession session, ITextBuffer subjectBuffer, string functionName,
                             string documentation, ISignatureInfo signatureInfo)
        {
            FunctionName   = functionName;
            _signatureInfo = signatureInfo;

            Documentation = documentation;
            Parameters    = null;

            Session            = session;
            Session.Dismissed += OnSessionDismissed;

            TextView = session.TextView;
            TextView.Caret.PositionChanged += OnCaretPositionChanged;

            SubjectBuffer          = subjectBuffer;
            SubjectBuffer.Changed += OnSubjectBufferChanged;
        }
Пример #7
0
        private ISignature CreateSignature(ISignatureHelpSession session,
                                           IFunctionInfo functionInfo, ISignatureInfo signatureInfo,
                                           ITrackingSpan span, AstRoot ast, int position)
        {
            SignatureHelp     sig       = new SignatureHelp(session, _textBuffer, functionInfo.Name, string.Empty, signatureInfo);
            List <IParameter> paramList = new List <IParameter>();

            // Locus points in the pretty printed signature (the one displayed in the tooltip)
            var    locusPoints     = new List <int>();
            string signatureString = signatureInfo.GetSignatureString(locusPoints);

            sig.Content          = signatureString;
            sig.ApplicableToSpan = span;

            sig.Documentation = functionInfo.Description?.Wrap(Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length));

            Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1);
            for (int i = 0; i < signatureInfo.Arguments.Count; i++)
            {
                IArgumentInfo p = signatureInfo.Arguments[i];
                if (p != null)
                {
                    int locusStart  = locusPoints[i];
                    int locusLength = locusPoints[i + 1] - locusStart;

                    Debug.Assert(locusLength >= 0);
                    Span locus = new Span(locusStart, locusLength);

                    /// VS may end showing very long tooltip so we need to keep
                    /// description reasonably short: typically about
                    /// same length as the function signature.
                    paramList.Add(
                        new SignatureParameter(
                            p.Description.Wrap(
                                Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)),
                            locus, locus, p.Name, sig));
                }
            }

            sig.Parameters = new ReadOnlyCollection <IParameter>(paramList);
            sig.ComputeCurrentParameter(ast, position);

            return(sig);
        }
Пример #8
0
        private ISignature CreateSignature(ISignatureHelpSession session,
                                       string functionName, IFunctionInfo functionInfo, ISignatureInfo signatureInfo,
                                       ITrackingSpan span, AstRoot ast, int position) {
            SignatureHelp sig = new SignatureHelp(session, _textBuffer, functionName, string.Empty, signatureInfo, _shell);
            List<IParameter> paramList = new List<IParameter>();

            // Locus points in the pretty printed signature (the one displayed in the tooltip)
            var locusPoints = new List<int>();
            string signatureString = signatureInfo.GetSignatureString(functionName, locusPoints);
            sig.Content = signatureString;
            sig.ApplicableToSpan = span;

            sig.Documentation = functionInfo.Description?.Wrap(Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length));

            Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1);
            for (int i = 0; i < signatureInfo.Arguments.Count; i++) {
                IArgumentInfo p = signatureInfo.Arguments[i];
                if (p != null) {
                    int locusStart = locusPoints[i];
                    int locusLength = locusPoints[i + 1] - locusStart;

                    Debug.Assert(locusLength >= 0);
                    Span locus = new Span(locusStart, locusLength);

                    /// VS may end showing very long tooltip so we need to keep 
                    /// description reasonably short: typically about
                    /// same length as the function signature.
                    paramList.Add(
                        new SignatureParameter(
                            p.Description.Wrap(
                                Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)),
                                locus, locus, p.Name, sig));
                }
            }

            sig.Parameters = new ReadOnlyCollection<IParameter>(paramList);
            sig.ComputeCurrentParameter(ast, position);

            return sig;
        }
Пример #9
0
        public static IRFunctionSignatureHelp Create(IRIntellisenseContext context, IFunctionInfo functionInfo, ISignatureInfo signatureInfo, ITrackingTextRange applicableSpan)
        {
            var sig       = new RFunctionSignatureHelp(context.Session, context.EditorBuffer, functionInfo.Name, string.Empty, signatureInfo);
            var paramList = new List <ISignatureParameterHelp>();

            // Locus points in the pretty printed signature (the one displayed in the tooltip)
            var locusPoints     = new List <int>();
            var signatureString = signatureInfo.GetSignatureString(functionInfo.Name, locusPoints);

            sig.Content           = signatureString;
            sig.ApplicableToRange = applicableSpan;

            sig.Documentation = functionInfo.Description?.Wrap(Math.Min(MaxSignatureLength, sig.Content.Length));

            Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1);
            for (var i = 0; i < signatureInfo.Arguments.Count; i++)
            {
                var p = signatureInfo.Arguments[i];
                if (p != null)
                {
                    var locusStart  = locusPoints[i];
                    var locusLength = locusPoints[i + 1] - locusStart;

                    Debug.Assert(locusLength >= 0);
                    var locus = new TextRange(locusStart, locusLength);

                    // VS may end showing very long tooltip so we need to keep
                    // description reasonably short: typically about
                    // same length as the function signature.
                    var description = p.Description.Wrap(Math.Min(MaxSignatureLength, sig.Content.Length));
                    paramList.Add(new RSignatureParameterHelp(description, locus, p.Name, sig));
                }
            }

            sig.Parameters = new ReadOnlyCollection <ISignatureParameterHelp>(paramList);
            sig.ComputeCurrentParameter(context.AstRoot, context.Position);

            return(sig);
        }