internal IntellisenseResult(IIntellisenseData data, List <IntellisenseSuggestion> suggestions, Exception exception = null) { Contracts.AssertValue(suggestions); _script = data.Script; Contracts.CheckValue(_script, "script"); ReplacementStartIndex = data.ReplacementStartIndex; Contracts.CheckParam(0 <= data.ReplacementStartIndex, "replacementStartIndex"); ReplacementLength = data.ReplacementLength; Contracts.CheckParam(0 <= data.ReplacementLength, "replacementLength"); var argIndex = data.ArgIndex; var argCount = data.ArgCount; Contracts.CheckParam(0 <= argIndex, "argIndex"); Contracts.CheckParam(0 <= argCount, "argCount"); Contracts.Check(argIndex <= argCount, "argIndex out of bounds."); var func = data.CurFunc; Contracts.CheckValueOrNull(func); _suggestions = suggestions; _functionSignatures = new List <SignatureInformation>(); _functionOverloads = new List <IntellisenseSuggestion>(); CurrentFunctionOverloadIndex = -1; _currentArgumentIndex = argIndex; Exception = exception; if (func == null) { IsFunctionScope = false; } else { IsFunctionScope = true; int highlightStart = -1; int highlightEnd = -1; int minMatchingArgCount = int.MaxValue; foreach (var signature in func.GetSignatures(argCount)) { int signatureIndex = 0; string argumentSeparator = string.Empty; string highlightedFuncParamDescription = string.Empty; string listSep = TexlLexer.LocalizedInstance.LocalizedPunctuatorListSeparator + " "; StringBuilder funcDisplayString = new StringBuilder(func.Name); funcDisplayString.Append('('); var parameters = new List <ParameterInformation>(); while (signatureIndex < signature.Count()) { Contracts.AssertValue(signature[signatureIndex]); funcDisplayString.Append(argumentSeparator); // We need to change the highlight information if the argument should be highlighted, but // otherwise we still want to collect parameter information var unalteredParamName = signature[signatureIndex](); var invariantParamName = signature[signatureIndex]("en-US"); (var paramName, var parameterHighlightStart, var parameterHighlightEnd, var funcParamDescription) = GetParameterHighlightAndDescription(data, unalteredParamName, invariantParamName, funcDisplayString); parameters.Add(new ParameterInformation() { Documentation = funcParamDescription, Label = paramName }); if (ArgNeedsHighlight(func, argCount, argIndex, signature.Count(), signatureIndex)) { (highlightStart, highlightEnd, highlightedFuncParamDescription) = (parameterHighlightStart, parameterHighlightEnd, funcParamDescription); } // For variadic function, we want to generate FuncName(arg1,arg1,...,arg1,...) as description. if (func.SignatureConstraint != null && argCount > func.SignatureConstraint.RepeatTopLength && canParamOmit(func, argCount, argIndex, signature.Count(), signatureIndex)) { funcDisplayString.Append("..."); signatureIndex += func.SignatureConstraint.RepeatSpan; } else { funcDisplayString.Append(signature[signatureIndex]()); signatureIndex++; } argumentSeparator = listSep; } if (func.MaxArity > func.MinArity && func.MaxArity > argCount) { funcDisplayString.Append(argumentSeparator + "..."); } funcDisplayString.Append(')'); var signatureInformation = new SignatureInformation() { Documentation = func.Description, Label = CreateFunctionSignature(func.Name, parameters), Parameters = parameters.ToArray() }; _functionSignatures.Add(signatureInformation); _functionOverloads.Add(new IntellisenseSuggestion(new UIString(funcDisplayString.ToString(), highlightStart, highlightEnd), SuggestionKind.Function, SuggestionIconKind.Function, func.ReturnType, signatureIndex, func.Description, func.Name, highlightedFuncParamDescription)); if ((signatureIndex >= argCount || (func.SignatureConstraint != null && argCount > func.SignatureConstraint.RepeatTopLength)) && minMatchingArgCount > signatureIndex) { // _functionOverloads has at least one item at this point. CurrentFunctionOverloadIndex = _functionOverloads.Count - 1; minMatchingArgCount = signatureIndex; } } // Handling of case where the function does not take any arguments. if (_functionOverloads.Count == 0 && func.MinArity == 0) { var signatureInformation = new SignatureInformation() { Documentation = func.Description, Label = CreateFunctionSignature(func.Name), Parameters = new ParameterInformation[0] }; _functionSignatures.Add(signatureInformation); _functionOverloads.Add(new IntellisenseSuggestion(new UIString(func.Name + "()", 0, func.Name.Length + 1), SuggestionKind.Function, SuggestionIconKind.Function, func.ReturnType, string.Empty, 0, func.Description, func.Name)); CurrentFunctionOverloadIndex = 0; } } Contracts.Assert(_functionSignatures.Count == _functionOverloads.Count); }
/// <summary> /// Gets the parameter description and corresponding highlight information for the provided /// function and index. Provides special augmentation behavior via handlers. /// </summary> /// <param name="data"> /// Data off of which the result is based /// </param> /// <param name="paramName"></param> /// <param name="invariantParamName1></param> /// <param name="funcDisplayString"></param> /// <returns></returns> private static (string paramName, int highlightStart, int highlightEnd, string funcParamDescription) GetParameterHighlightAndDescription(IIntellisenseData data, string paramName, string invariantParamName, StringBuilder funcDisplayString) { Contracts.AssertValue(data); Contracts.AssertValue(paramName); Contracts.AssertValue(invariantParamName); Contracts.AssertValue(funcDisplayString); int highlightStart; int highlightEnd; string funcParamDescription; var func = data.CurFunc; var argIndex = data.ArgIndex; // Highlight has to start from the next character and end at the last character which is "length -1" highlightStart = funcDisplayString.Length; highlightEnd = highlightStart + paramName.Length - 1; // By calling this we provide the caller the ability to augment the highlight and parameter // details amidst the iteration if (data.TryAugmentSignature(func, argIndex, paramName, highlightStart, out var newHighlightStart, out var newHighlightEnd, out var newParamName, out var newInvariantParamName)) { (highlightStart, highlightEnd, paramName, invariantParamName) = (newHighlightStart, newHighlightEnd, newParamName, newInvariantParamName); } // MUST use the invariant parameter name here func.TryGetParamDescription(invariantParamName, out funcParamDescription); // Apply optional suffix provided via argument funcParamDescription += data.GenerateParameterDescriptionSuffix(func, paramName); return(paramName, highlightStart, highlightEnd, funcParamDescription); }