protected ILookupItem GetLookupElement(string replace, TextLookupRanges ranges) { var info = new TextualInfo(replace, replace) { ReplaceText = replace, Ranges = ranges }; var item = LookupItemFactory.CreateLookupItem(info) .WithPresentation(_ => new TextPresentation <TextualInfo>(info)) .WithBehavior(_ => new TextualBehavior <TextualInfo>(info)) .WithMatcher(_ => new TextualMatcher <TextualInfo>(info)); return(item); }
private static LookupItem <TextualInfo> CreateLookupItem([NotNull] IMethodDeclaration methodDeclaration, [NotNull] CSharpCodeCompletionContext context) { var typeParameterName = GetTypeParameterName(methodDeclaration); var textualInfo = new TextualInfo(typeParameterName, typeParameterName, context.BasicContext) { Ranges = context.CompletionRanges }; var lookupItem = LookupItemFactory.CreateLookupItem(textualInfo) .WithPresentation(item => { var presentation = new PostfixTemplatePresentation(typeParameterName); var grayText = TextStyle.FromForeColor(Color.Gray); presentation.DisplayName.Append("*", grayText); presentation.DisplayTypeName = new RichText("(create type parameter)", grayText); return(presentation); }) .WithMatcher(item => new TextualMatcher <TextualInfo>(item.Info, IdentifierMatchingStyle.Default)) .WithBehavior(item => new TypeParameterFromUsageBehavior(item.Info)); return(lookupItem); }
private ILookupItem CreateMethodItem(CSharpCodeCompletionContext context, UnityEventFunction eventFunction, IClassLikeDeclaration declaration, bool hasReturnType, AccessRights accessRights) { if (CSharpLanguage.Instance == null) { return(null); } // Only show the modifier in the list text if it's not already specified and there isn't a return type, in // which case we default to `private`. E.g. if someone types `OnAnim`, then show `private void OnAnimate...` // but if they type `void OnAnim`, they don't want a modifier, and if they type `public void OnAnim` then // they want to use `public` var showModifier = false; if (!hasReturnType && accessRights == AccessRights.NONE) { showModifier = true; accessRights = AccessRights.PRIVATE; } // Note that we can't keep this declaration - it will become invalid as the user types to narrow down the // search and modifies the PSI file. This only affects ReSharper, Rider has different code completion // mechanism var factory = CSharpElementFactory.GetInstance(declaration, false); var methodDeclaration = eventFunction.CreateDeclaration(factory, declaration, accessRights); if (methodDeclaration.DeclaredElement == null) { return(null); } // This is effectively the same as GenerateMemberPresentation, but without the overhead that comes // with the flexibility of formatting any time of declared element. We just hard code the format var predefinedType = context.PsiModule.GetPredefinedType(); var parameters = string.Empty; if (eventFunction.Parameters.Length > 0) { var sb = new StringBuilder(); for (var i = 0; i < eventFunction.Parameters.Length; i++) { if (i > 0) { sb.Append(", "); } var parameter = eventFunction.Parameters[i]; var type = predefinedType.TryGetType(parameter.ClrTypeName, NullableAnnotation.Unknown); var typeName = type?.GetPresentableName(CSharpLanguage.Instance) ?? parameter.ClrTypeName.ShortName; sb.AppendFormat("{0}{1}{2}", parameter.IsByRef ? "out" : string.Empty, typeName, parameter.IsArray ? "[]" : string.Empty); } parameters = sb.ToString(); } var text = $"{eventFunction.Name}({parameters})"; var parameterOffset = eventFunction.Name.Length; var modifier = showModifier ? CSharpDeclaredElementPresenter.Instance.Format(accessRights) + " " : string.Empty; var psiIconManager = context.BasicContext.LookupItemsOwner.Services.PsiIconManager; // Note that because this is a text based lookup item, then it won't be included if the normal C# method // filter is applied. We can't make it a method based lookup item because the DeclaredElement isn't valid in // this situation - it's not a real method, and a DeclaredElementInfo would try to store a pointer to it, // and be unable to recreate it when it's needed. var textualInfo = new TextualInfo(text, text) { Ranges = context.CompletionRanges }; var lookupItem = LookupItemFactory.CreateLookupItem(textualInfo) .WithPresentation(item => { var displayName = new RichText($"{modifier}{text} {{ ... }}"); // GenerateMemberPresentation marks everything as bold, and the parameters + block syntax as not important var parameterStartOffset = modifier.Length + parameterOffset; LookupUtil.MarkAsNotImportant(displayName, TextRange.FromLength(parameterStartOffset, displayName.Length - parameterStartOffset)); LookupUtil.AddEmphasize(displayName, new TextRange(modifier.Length, displayName.Length)); var image = psiIconManager.GetImage(CLRDeclaredElementType.METHOD); psiIconManager.AttachExtensions(image, GetAccessExtensions(accessRights)); var marker = item.Info.Ranges.CreateVisualReplaceRangeMarker(); return(new SimplePresentation(displayName, image, marker)); }) .WithBehavior(_ => new UnityEventFunctionBehavior(myShellLocks, textualInfo, eventFunction, accessRights)) .WithMatcher(_ => new ShiftedDeclaredElementMatcher(eventFunction.Name, modifier.Length, textualInfo)); var description = GetDescription(context, methodDeclaration); return(new WrappedLookupItem(lookupItem, description)); }