コード例 #1
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);
        }
コード例 #2
0
ファイル: SignatureInfo.cs プロジェクト: ktaranov/RTVS
        /// <summary>
        /// Creates formatted signature that is presented to the user
        /// during function parameter completion. Optionally provides
        /// locus points (locations withing the string) for each function
        /// parameter.
        /// </summary>
        public string GetSignatureString(List <int> locusPoints = null)
        {
            var sb        = new StringBuilder(FunctionName);
            int lineCount = 0;

            sb.Append('(');

            if (locusPoints != null)
            {
                locusPoints.Add(sb.Length);
            }

            for (int i = 0; i < Arguments.Count; i++)
            {
                IArgumentInfo arg = Arguments[i];
                sb.Append(arg.Name);

                if (!string.IsNullOrEmpty(arg.DefaultValue))
                {
                    sb.Append(" = ");
                    sb.Append(arg.DefaultValue);
                }

                if (i < Arguments.Count - 1)
                {
                    sb.Append(", ");
                }

                if (locusPoints != null)
                {
                    locusPoints.Add(sb.Length);
                }

                if (sb.Length > (lineCount + 1) * MaxSignatureLength && i != Arguments.Count - 1)
                {
                    sb.Append("\r\n");
                    lineCount++;
                }
            }

            sb.Append(')');
            return(sb.ToString());
        }
コード例 #3
0
ファイル: SignatureInfo.cs プロジェクト: ktaranov/RTVS
        /// <summary>
        /// Given argument name returns index of the argument in the signature.
        /// Performs full and then partial matching fof the argument name.
        /// </summary>
        /// <param name="argumentName">Name of the argument</param>
        /// <param name="partialMatch">
        /// If true, partial match will be performed
        /// if exact match is not found
        /// </param>
        /// <returns>Argument index or -1 if argumen is not named or was not found</returns>
        public int GetArgumentIndex(string argumentName, bool partialMatch)
        {
            // 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.

            if (string.IsNullOrEmpty(argumentName))
            {
                return(-1);
            }

            // full name match first
            for (int i = 0; i < Arguments.Count; i++)
            {
                IArgumentInfo argInfo = Arguments[i];
                if (argInfo.Name.Equals(argumentName, StringComparison.Ordinal))
                {
                    return(i);
                }
            }

            if (!partialMatch)
            {
                return(-1);
            }

            // Try partial match. Only match unique or longest
            int  minLengthDifference = Int32.MaxValue;
            int  index  = -1;
            bool unique = true;

            for (int i = 0; i < Arguments.Count; i++)
            {
                IArgumentInfo argInfo = Arguments[i];
                if (argInfo.Name.StartsWith(argumentName, StringComparison.Ordinal))
                {
                    int lengthDifference = argInfo.Name.Length - argumentName.Length;
                    if (lengthDifference < minLengthDifference)
                    {
                        minLengthDifference = lengthDifference;
                        index  = i;
                        unique = true;
                    }
                    else if (index >= 0)
                    {
                        unique = false;
                    }
                }

                if (argInfo.IsEllipsis)
                {
                    break;
                }
            }

            return(unique ? index : -1);
        }
コード例 #4
0
 internal GeneratorError(IArgumentInfo argumentInfo, GeneratorErrorType generatorErrorType)
 {
     this.Type         = generatorErrorType;
     this.ArgumentInfo = argumentInfo;
 }
コード例 #5
0
 internal GeneratorError(IArgumentInfo argumentInfo, GeneratorError innerGeneratorError)
 {
     this.Type                = GeneratorErrorType.InnerGeneratorError;
     this.ArgumentInfo        = argumentInfo;
     this.InnerGeneratorError = innerGeneratorError;
 }
コード例 #6
0
 private static bool ParameterNameMatches(IArgumentInfo argument, string propertyName)
 {
     return(argument.MatchingParameter != null &&
            string.Compare(argument.MatchingParameter.Element.ShortName, propertyName,
                           StringComparison.InvariantCultureIgnoreCase) == 0);
 }