public Model( DisconnectedBufferGraph disconnectedBufferGraph, TextSpan textSpan, ISignatureHelpProvider provider, IList<SignatureHelpItem> items, SignatureHelpItem selectedItem, int argumentIndex, int argumentCount, string argumentName, int? selectedParameter) { Contract.ThrowIfNull(selectedItem); Contract.ThrowIfFalse(items.Count != 0, "Must have at least one item."); Contract.ThrowIfFalse(items.Contains(selectedItem), "Selected item must be in list of items."); _disconnectedBufferGraph = disconnectedBufferGraph; this.TextSpan = textSpan; this.Items = items; this.Provider = provider; this.SelectedItem = selectedItem; this.ArgumentIndex = argumentIndex; this.ArgumentCount = argumentCount; this.ArgumentName = argumentName; this.SelectedParameter = selectedParameter; }
public Signature(ITrackingSpan applicableToSpan, SignatureHelpItem signatureHelpItem, int selectedParameterIndex) { if (selectedParameterIndex < -1 || selectedParameterIndex >= signatureHelpItem.Parameters.Length) { throw new ArgumentOutOfRangeException(nameof(selectedParameterIndex)); } this.ApplicableToSpan = applicableToSpan; _signatureHelpItem = signatureHelpItem; _parameterIndex = selectedParameterIndex; }
public static SignatureHelpSelection GetSelection( IList<SignatureHelpItem> items, SignatureHelpItem selectedItem, int argumentIndex, int argumentCount, string argumentName, bool isCaseSensitive) { var bestItem = GetBestItem(selectedItem, items, argumentIndex, argumentCount, argumentName, isCaseSensitive); var selectedParameter = GetSelectedParameter(bestItem, argumentIndex, argumentName, isCaseSensitive); return new SignatureHelpSelection(bestItem, selectedParameter); }
private static int GetSelectedParameter(SignatureHelpItem bestItem, int parameterIndex, string parameterName, bool isCaseSensitive) { if (parameterName != null) { var comparer = isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; var index = bestItem.Parameters.IndexOf(p => comparer.Equals(p.Name, parameterName)); if (index >= 0) { return index; } } return parameterIndex; }
public Builder(Signature signature, SignatureHelpItem item, int? selectedParameter) { this = default(Builder); this.item = item; content = new StringBuilder(); contentTagged = new List<TaggedText>(); Parameters = new List<IParameter>(); Add(item.PrefixDisplayParts); int pi = 0; foreach (var parameter in item.Parameters) { if (pi > 0) Add(item.SeparatorDisplayParts); pi++; Add(parameter.PrefixDisplayParts); int paramStart = content.Length; if (parameter.IsOptional) Add(new TaggedText(TextTags.Punctuation, "[")); Add(parameter.DisplayParts); if (parameter.IsOptional) Add(new TaggedText(TextTags.Punctuation, "]")); int paramEnd = content.Length; Add(parameter.SuffixDisplayParts); var locus = Span.FromBounds(paramStart, paramEnd); var prettyPrintedLocus = Span.FromBounds(paramStart, paramEnd); Parameters.Add(new Parameter(signature, parameter, locus, prettyPrintedLocus)); } Add(item.SuffixDisplayParts); if (selectedParameter != null && (uint)selectedParameter.Value < (uint)item.Parameters.Length) { var parameter = item.Parameters[selectedParameter.Value]; Add(parameter.SelectedDisplayParts); } Add(item.DescriptionParts); int docCount = 0; foreach (var taggedText in item.DocumentationFactory(CancellationToken.None)) { if (docCount == 0) Add(new TaggedText(TextTags.LineBreak, "\r\n")); docCount++; Add(taggedText); } Content = content.ToString(); ContentTaggedText = contentTagged; PrettyPrintedContent = Content; PrettyPrintedContentTaggedText = ContentTaggedText; }
private static int GetParameterIndexForItem(SignatureHelpItem item, int?selectedParameter) { if (selectedParameter.HasValue) { if (selectedParameter.Value < item.Parameters.Length) { // If the selected parameter is within the range of parameters of this item then set // that as the current parameter. return(selectedParameter.Value); } else if (item.IsVariadic) { // It wasn't in range, but the item takes an unlimited number of parameters. So // just set current parameter to the last parameter (the variadic one). return(item.Parameters.Length - 1); } } // It was out of bounds, there is no current parameter now. return(-1); }
private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) { var signature = new SignatureHelpItem(); signature.Documentation = symbol.GetDocumentationCommentXml(); signature.Name = symbol.MethodKind == MethodKind.Constructor ? symbol.ContainingType.Name : symbol.Name; signature.Label = symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); signature.StructuredDocumentation = DocumentationConverter.GetStructuredDocumentation(symbol); signature.Parameters = symbol.Parameters.Select(parameter => { return(new SignatureHelpParameter() { Name = parameter.Name, Label = parameter.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), Documentation = signature.StructuredDocumentation.GetParameterText(parameter.Name) }); }); return(signature); }
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 static SignatureHelpItem GetBestItem( SignatureHelpItem currentItem, IList <SignatureHelpItem> filteredItems, int selectedParameter, int argumentCount, string name, bool isCaseSensitive) { // If the current item is still applicable, then just keep it. if (filteredItems.Contains(currentItem) && IsApplicable(currentItem, argumentCount, name, isCaseSensitive)) { return(currentItem); } // Try to find the first applicable item. If there is none, then that means the // selected parameter was outside the bounds of all methods. i.e. all methods only // went up to 3 parameters, and selected parameter is 3 or higher. In that case, // just pick the very last item as it is closest in parameter count. var result = filteredItems.FirstOrDefault(i => IsApplicable(i, argumentCount, name, isCaseSensitive)); if (result != null) { return(result); } // if we couldn't find a best item, and htey provided a name, then try again without // a name. if (name != null) { return(GetBestItem(currentItem, filteredItems, selectedParameter, argumentCount, null, isCaseSensitive)); } // If we don't have an item that can take that number of parameters, then just pick // the last item. Or stick with the current item if the last item isn't any better. var lastItem = filteredItems.Last(); if (currentItem.IsVariadic || currentItem.Parameters.Count == lastItem.Parameters.Count) { return(currentItem); } return(lastItem); }
private static SignatureInformation ConvertSignature(SignatureHelpItem signatureHelpItem, CancellationToken cancellationToken) { var fullLabel = new List <TaggedText>(); fullLabel.AddRange(signatureHelpItem.PrefixDisplayParts); for (var i = 0; i < signatureHelpItem.Parameters.Length; i++) { fullLabel.AddRange(signatureHelpItem.Parameters[i].DisplayParts); if (i < signatureHelpItem.Parameters.Length - 1) { fullLabel.AddRange(signatureHelpItem.SeparatorDisplayParts); } } fullLabel.AddRange(signatureHelpItem.SuffixDisplayParts); return(new SignatureInformation { Label = fullLabel.GetFullText(), Documentation = signatureHelpItem.DocumentationFactory(cancellationToken).GetFullText(), Parameters = signatureHelpItem.Parameters.Select(x => ConvertParameter(x, cancellationToken)).ToArray() }); }
private static bool IsApplicable( SignatureHelpItem item, int argumentCount, string name, bool isCaseSensitive ) { // If they provided a name, then the item is only valid if it has a parameter that // matches that name. if (name != null) { var comparer = isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; return(item.Parameters.Any(p => comparer.Equals(p.Name, name))); } // An item is applicable if it has at least as many parameters as the selected // parameter index. i.e. if it has 2 parameters and we're at index 0 or 1 then it's // applicable. However, if it has 2 parameters and we're at index 2, then it's not // applicable. if (item.Parameters.Length >= argumentCount) { return(true); } // However, if it is variadic then it is applicable as it can take any number of // items. if (item.IsVariadic) { return(true); } // Also, we special case 0. that's because if the user has "Goo(" and goo takes no // arguments, then we'll see that it's arg count is 0. We still want to consider // any item applicable here though. return(argumentCount == 0); }
private static int GetSelectedParameter( SignatureHelpItem bestItem, int parameterIndex, string parameterName, bool isCaseSensitive ) { if (!string.IsNullOrEmpty(parameterName)) { var comparer = isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; var index = bestItem.Parameters.IndexOf( p => comparer.Equals(p.Name, parameterName) ); if (index >= 0) { return(index); } } return(parameterIndex); }
private static SignatureHelpItem GetBestItem( SignatureHelpItem currentItem, IList<SignatureHelpItem> filteredItems, int selectedParameter, int argumentCount, string name, bool isCaseSensitive) { // If the current item is still applicable, then just keep it. if (filteredItems.Contains(currentItem) && IsApplicable(currentItem, argumentCount, name, isCaseSensitive)) { return currentItem; } // Try to find the first applicable item. If there is none, then that means the // selected parameter was outside the bounds of all methods. i.e. all methods only // went up to 3 parameters, and selected parameter is 3 or higher. In that case, // just pick the very last item as it is closest in parameter count. var result = filteredItems.FirstOrDefault(i => IsApplicable(i, argumentCount, name, isCaseSensitive)); if (result != null) { return result; } // if we couldn't find a best item, and they provided a name, then try again without // a name. if (name != null) { return GetBestItem(currentItem, filteredItems, selectedParameter, argumentCount, null, isCaseSensitive); } // If we don't have an item that can take that number of parameters, then just pick // the last item. Or stick with the current item if the last item isn't any better. var lastItem = filteredItems.Last(); if (currentItem.IsVariadic || currentItem.Parameters.Length == lastItem.Parameters.Length) { return currentItem; } return lastItem; }
private static bool Include(SignatureHelpItem item, IEnumerable<string> parameterNames) { var itemParameterNames = item.Parameters.Select(p => p.Name).ToSet(); return parameterNames.All(itemParameterNames.Contains); }
private SignatureHelpItem UpdateItem(SignatureHelpItem item, SupportedPlatformData platformData, ISymbol symbol) { var platformParts = platformData.ToDisplayParts(); if (platformParts.Count == 0) { return item; } var startingNewLine = new List<SymbolDisplayPart>(); startingNewLine.AddLineBreak(); var updatedDescription = item.DescriptionParts == null ? item.DescriptionParts.Concat(startingNewLine.Concat(platformParts)) : startingNewLine.Concat(platformParts); item.DescriptionParts = updatedDescription.ToImmutableArrayOrEmpty(); return item; }
private static bool DisplayPartsMatch(SignatureHelpItem i1, SignatureHelpItem i2) { return i1.GetAllParts().SequenceEqual(i2.GetAllParts(), CompareParts); }
public void PresentItems( ITrackingSpan triggerSpan, IList<SignatureHelpItem> signatureHelpItems, SignatureHelpItem selectedItem, int? selectedParameter) { _signatureHelpItems = signatureHelpItems; _selectedItem = selectedItem; // Create all the editor signatures for the sig help items we have. this.CreateSignatures(triggerSpan, selectedParameter); // It's a new list of items. Either create the editor session if this is the // first time, or ask the editor session that we already have to recalculate. if (_editorSessionOpt == null) { // We're tracking the caret. Don't have the editor do it. _editorSessionOpt = _sigHelpBroker.CreateSignatureHelpSession( _textView, triggerSpan.GetStartTrackingPoint(PointTrackingMode.Negative), trackCaret: false); var debugTextView = _textView as IDebuggerTextView; if (debugTextView != null && !debugTextView.IsImmediateWindow) { debugTextView.HACK_StartCompletionSession(_editorSessionOpt); } _editorSessionOpt.Dismissed += (s, e) => OnEditorSessionDismissed(); _editorSessionOpt.SelectedSignatureChanged += OnSelectedSignatureChanged; } // So here's the deal. We cannot create the editor session and give it the right // signatures (even though we know what they are). Instead, the session with // call back into the ISignatureHelpSourceProvider (which is us) to get those // values. It will pass itself along with the calls back into // ISignatureHelpSourceProvider. So, in order to make that connection work, we // add properties to the session so that we can call back into ourselves, get // the signatures and add it to the session. if (!_editorSessionOpt.Properties.ContainsProperty(s_augmentSessionKey)) { _editorSessionOpt.Properties.AddProperty(s_augmentSessionKey, this); } try { // Don't want to get any callbacks while we do this. _ignoreSelectionStatusChangedEvent = true; _editorSessionOpt.Recalculate(); // Now let the editor know what the currently selected item is. Contract.Requires(_signatureMap.ContainsKey(selectedItem)); Contract.ThrowIfNull(_signatureMap); var defaultValue = _signatureMap.GetValueOrDefault(_selectedItem); if (_editorSessionOpt != null) { _editorSessionOpt.SelectedSignature = defaultValue; } } finally { _ignoreSelectionStatusChangedEvent = false; } }
public async Task <SignatureHelpResponse> Handle(SignatureHelpRequest request, Document document2) { var invocations = new List <InvocationContext>(); foreach (var document in new [] { document2 }) { var invocation = await GetInvocation(document, request); if (invocation != null) { invocations.Add(invocation); } } if (invocations.Count == 0) { return(null); } var response = new SignatureHelpResponse(); // define active parameter by position foreach (var comma in invocations.First().Separators) { if (comma.Span.Start > invocations.First().Position) { break; } response.ActiveParameter += 1; } // process all signatures, define active signature by types var signaturesSet = new HashSet <SignatureHelpItem>(); var bestScore = int.MinValue; SignatureHelpItem bestScoredItem = null; foreach (var invocation in invocations) { var types = invocation.ArgumentTypes; ISymbol throughSymbol = null; ISymbol throughType = null; var methodGroup = invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType <IMethodSymbol>(); if (invocation.Receiver is MemberAccessExpressionSyntax) { var throughExpression = ((MemberAccessExpressionSyntax)invocation.Receiver).Expression; throughSymbol = invocation.SemanticModel.GetSpeculativeSymbolInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsExpression).Symbol; throughType = invocation.SemanticModel.GetSpeculativeTypeInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; var includeInstance = (throughSymbol != null && !(throughSymbol is ITypeSymbol)) || throughExpression is LiteralExpressionSyntax || throughExpression is TypeOfExpressionSyntax; var includeStatic = (throughSymbol is INamedTypeSymbol) || throughType != null; methodGroup = methodGroup.Where(m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance)); } else if (invocation.Receiver is SimpleNameSyntax && invocation.IsInStaticContext) { methodGroup = methodGroup.Where(m => m.IsStatic || m.MethodKind == MethodKind.LocalFunction); } foreach (var methodOverload in methodGroup) { var signature = BuildSignature(methodOverload); signaturesSet.Add(signature); var score = InvocationScore(methodOverload, types); if (score > bestScore) { bestScore = score; bestScoredItem = signature; } } } var signaturesList = signaturesSet.ToList(); response.Signatures = signaturesList; response.ActiveSignature = signaturesList.IndexOf(bestScoredItem); return(response); }
public SignatureHelpItemEventArgs(SignatureHelpItem signatureHelpItem) { this.SignatureHelpItem = signatureHelpItem; }
public Signature(ITrackingSpan applicableToSpan, SignatureHelpItem item, bool isSelected, int? selectedParameter) { if (applicableToSpan == null) throw new ArgumentNullException(nameof(applicableToSpan)); if (item == null) throw new ArgumentNullException(nameof(item)); IsSelected = isSelected; ApplicableToSpan = applicableToSpan; this.item = item; var builder = new Builder(this, item, selectedParameter); Content = builder.Content; ContentTaggedText = builder.ContentTaggedText; PrettyPrintedContent = builder.PrettyPrintedContent; PrettyPrintedContentTaggedText = builder.PrettyPrintedContentTaggedText; Parameters = new ReadOnlyCollection<IParameter>(builder.Parameters); if (selectedParameter != null) { if ((uint)selectedParameter.Value < (uint)Parameters.Count) CurrentParameter = Parameters[selectedParameter.Value]; else if (item.IsVariadic && Parameters.Count > 0) CurrentParameter = Parameters[Parameters.Count - 1]; } }
public Model WithSelectedItem(SignatureHelpItem selectedItem) { return(selectedItem == this.SelectedItem ? this : new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, selectedItem, ArgumentIndex, ArgumentCount, ArgumentName, SelectedParameter)); }
private static bool Include(SignatureHelpItem item, IEnumerable <string> parameterNames) { var itemParameterNames = item.Parameters.Select(p => p.Name).ToSet(); return(parameterNames.All(itemParameterNames.Contains)); }
private static int GetParameterIndexForItem(SignatureHelpItem item, int? selectedParameter) { if (selectedParameter.HasValue) { if (selectedParameter.Value < item.Parameters.Length) { // If the selected parameter is within the range of parameters of this item then set // that as the current parameter. return selectedParameter.Value; } else if (item.IsVariadic) { // It wasn't in range, but the item takes an unlimited number of parameters. So // just set current parameter to the last parameter (the variadic one). return item.Parameters.Length - 1; } } // It was out of bounds, there is no current parameter now. return -1; }
private static void SelectBestItem( ref SignatureHelpItem currentItem, ref bool userSelected, IList <SignatureHelpItem> filteredItems, int selectedParameter, int argumentCount, string name, bool isCaseSensitive ) { // If the current item is still applicable, then just keep it. if ( filteredItems.Contains(currentItem) && IsApplicable(currentItem, argumentCount, name, isCaseSensitive) ) { // If the current item was user-selected, we keep it as such. return; } // If the current item is no longer applicable, we'll be choosing a new one, // which was definitely not previously user-selected. userSelected = false; // Try to find the first applicable item. If there is none, then that means the // selected parameter was outside the bounds of all methods. i.e. all methods only // went up to 3 parameters, and selected parameter is 3 or higher. In that case, // just pick the very last item as it is closest in parameter count. var result = filteredItems.FirstOrDefault( i => IsApplicable(i, argumentCount, name, isCaseSensitive) ); if (result != null) { currentItem = result; return; } // if we couldn't find a best item, and they provided a name, then try again without // a name. if (name != null) { SelectBestItem( ref currentItem, ref userSelected, filteredItems, selectedParameter, argumentCount, null, isCaseSensitive ); return; } // If we don't have an item that can take that number of parameters, then just pick // the last item. Or stick with the current item if the last item isn't any better. var lastItem = filteredItems.Last(); if ( currentItem.IsVariadic || currentItem.Parameters.Length == lastItem.Parameters.Length ) { return; } currentItem = lastItem; }
public TypeScriptFunctionInsightItem(SignatureHelpItem helpItem) { this.helpItem = helpItem; }
private SignatureHelpItem FixAnonymousTypeParts( ISymbol orderSymbol, SignatureHelpItem item, SemanticModel semanticModel, int position, ISymbolDisplayService symbolDisplayService, IAnonymousTypeDisplayService anonymousTypeDisplayService) { var currentItem = new SymbolKeySignatureHelpItem( orderSymbol, item.IsVariadic, item.DocumenationFactory, anonymousTypeDisplayService.InlineDelegateAnonymousTypes(item.PrefixDisplayParts, semanticModel, position, symbolDisplayService), anonymousTypeDisplayService.InlineDelegateAnonymousTypes(item.SeparatorDisplayParts, semanticModel, position, symbolDisplayService), anonymousTypeDisplayService.InlineDelegateAnonymousTypes(item.SuffixDisplayParts, semanticModel, position, symbolDisplayService), item.Parameters.Select(p => InlineDelegateAnonymousTypes(p, semanticModel, position, symbolDisplayService, anonymousTypeDisplayService)), item.DescriptionParts); var directAnonymousTypeReferences = from part in currentItem.GetAllParts() where part.Symbol.IsNormalAnonymousType() select (INamedTypeSymbol)part.Symbol; var info = anonymousTypeDisplayService.GetNormalAnonymousTypeDisplayInfo( orderSymbol, directAnonymousTypeReferences, semanticModel, position, symbolDisplayService); if (info.AnonymousTypesParts.Count > 0) { var anonymousTypeParts = new List<SymbolDisplayPart> { new SymbolDisplayPart(SymbolDisplayPartKind.Space, null, "\r\n\r\n") }; anonymousTypeParts.AddRange(info.AnonymousTypesParts); currentItem = new SymbolKeySignatureHelpItem( orderSymbol, currentItem.IsVariadic, currentItem.DocumenationFactory, info.ReplaceAnonymousTypes(currentItem.PrefixDisplayParts), info.ReplaceAnonymousTypes(currentItem.SeparatorDisplayParts), info.ReplaceAnonymousTypes(currentItem.SuffixDisplayParts), currentItem.Parameters.Select(p => ReplaceAnonymousTypes(p, info)), anonymousTypeParts); } return currentItem; }
private void SetCurrentParameter(SignatureHelpItem item, int? selectedParameter) { Contract.ThrowIfFalse(_signatureMap.ContainsKey(item)); var signature = _signatureMap.GetValueOrDefault(item); if (selectedParameter.HasValue) { if (selectedParameter.Value < item.Parameters.Count) { // If the selected parameter is within the range of parameters of this item then set // that as the current parameter. signature.CurrentParameter = signature.Parameters[selectedParameter.Value]; return; } else if (item.IsVariadic) { // It wasn't in range, but the item takes an unlmiited number of parameters. So // just set current parameter to the last parameter (the variadic one). signature.CurrentParameter = signature.Parameters.Last(); return; } } // It was out of bounds, there is no current parameter now. signature.CurrentParameter = null; }
public SignatureHelpSelection(SignatureHelpItem selectedItem, int? selectedParameter) : this() { _selectedItem = selectedItem; _selectedParameter = selectedParameter; }
public Model WithSelectedItem(SignatureHelpItem selectedItem) { return selectedItem == this.SelectedItem ? this : new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, selectedItem, ArgumentIndex, ArgumentCount, ArgumentName, SelectedParameter); }
public Signature(ITrackingSpan applicableToSpan, SignatureHelpItem signatureHelpItem) { this.ApplicableToSpan = applicableToSpan; _signatureHelpItem = signatureHelpItem; this.Initialize(setParameters: true); }
public void PresentItems( ITrackingSpan triggerSpan, IList <SignatureHelpItem> signatureHelpItems, SignatureHelpItem selectedItem, int?selectedParameter ) { _signatureHelpItems = signatureHelpItems; _selectedItem = selectedItem; // Create all the editor signatures for the sig help items we have. this.CreateSignatures(triggerSpan, selectedParameter); // It's a new list of items. Either create the editor session if this is the // first time, or ask the editor session that we already have to recalculate. if (_editorSessionOpt == null) { // We're tracking the caret. Don't have the editor do it. _editorSessionOpt = _sigHelpBroker.CreateSignatureHelpSession( _textView, triggerSpan.GetStartTrackingPoint(PointTrackingMode.Negative), trackCaret: false ); if ( _textView is IDebuggerTextView2 debugTextView && !debugTextView.IsImmediateWindow ) { debugTextView.HACK_StartCompletionSession(_editorSessionOpt); } _editorSessionOpt.Dismissed += (s, e) => OnEditorSessionDismissed(); _editorSessionOpt.SelectedSignatureChanged += OnSelectedSignatureChanged; } // So here's the deal. We cannot create the editor session and give it the right // signatures (even though we know what they are). Instead, the session with // call back into the ISignatureHelpSourceProvider (which is us) to get those // values. It will pass itself along with the calls back into // ISignatureHelpSourceProvider. So, in order to make that connection work, we // add properties to the session so that we can call back into ourselves, get // the signatures and add it to the session. if (!_editorSessionOpt.Properties.ContainsProperty(s_augmentSessionKey)) { _editorSessionOpt.Properties.AddProperty(s_augmentSessionKey, this); } try { // Don't want to get any callbacks while we do this. _ignoreSelectionStatusChangedEvent = true; _editorSessionOpt.Recalculate(); // Now let the editor know what the currently selected item is. Debug.Assert(_signatureMap.ContainsKey(selectedItem)); Contract.ThrowIfNull(_signatureMap); var defaultValue = _signatureMap.GetValueOrDefault(_selectedItem); if (_editorSessionOpt != null) { _editorSessionOpt.SelectedSignature = defaultValue; } } finally { _ignoreSelectionStatusChangedEvent = false; } }
private static bool IsApplicable(SignatureHelpItem item, int argumentCount, string name, bool isCaseSensitive) { // If they provided a name, then the item is only valid if it has a parameter that // matches that name. if (name != null) { var comparer = isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; return item.Parameters.Any(p => comparer.Equals(p.Name, name)); } // An item is applicable if it has at least as many parameters as the selected // parameter index. i.e. if it has 2 parameters and we're at index 0 or 1 then it's // applicable. However, if it has 2 parameters and we're at index 2, then it's not // applicable. if (item.Parameters.Length >= argumentCount) { return true; } // However, if it is variadic then it is applicable as it can take any number of // items. if (item.IsVariadic) { return true; } // Also, we special case 0. that's because if the user has "Foo(" and foo takes no // arguments, then we'll see that it's arg count is 0. We still want to consider // any item applicable here though. return argumentCount == 0; }
public SignatureHelpSelection(SignatureHelpItem selectedItem, int?selectedParameter) : this() { _selectedItem = selectedItem; _selectedParameter = selectedParameter; }
public PythiaSignatureHelpItemWrapper(SignatureHelpItem underlyingObject) { UnderlyingObject = underlyingObject; }
public SignatureHelpSelection(SignatureHelpItem selectedItem, bool userSelected, int?selectedParameter) : this() { _selectedItem = selectedItem; _userSelected = userSelected; _selectedParameter = selectedParameter; }
public async Task <SignatureHelpResponse> Handle(SignatureHelpRequest request) { var invocations = new List <InvocationContext>(); foreach (var document in _workspace.GetDocuments(request.FileName)) { var invocation = await GetInvocation(document, request); if (invocation != null) { invocations.Add(invocation); } } if (invocations.Count == 0) { return(null); } var response = new SignatureHelpResponse(); // define active parameter by position foreach (var comma in invocations.First().ArgumentList.Arguments.GetSeparators()) { if (comma.Span.Start > invocations.First().Position) { break; } response.ActiveParameter += 1; } // process all signatures, define active signature by types var signaturesSet = new HashSet <SignatureHelpItem>(); var bestScore = int.MinValue; SignatureHelpItem bestScoredItem = null; foreach (var invocation in invocations) { var types = invocation.ArgumentList.Arguments .Select(argument => invocation.SemanticModel.GetTypeInfo(argument.Expression)); foreach (var methodOverload in GetMethodOverloads(invocation.SemanticModel, invocation.Receiver)) { var signature = BuildSignature(methodOverload); signaturesSet.Add(signature); var score = InvocationScore(methodOverload, types); if (score > bestScore) { bestScore = score; bestScoredItem = signature; } } } var signaturesList = signaturesSet.ToList(); response.Signatures = signaturesList; response.ActiveSignature = signaturesList.IndexOf(bestScoredItem); return(response); }
private static bool DisplayPartsMatch(SignatureHelpItem i1, SignatureHelpItem i2) => i1.GetAllParts().SequenceEqual(i2.GetAllParts(), CompareParts);