protected override RichText GetDisplayName() { var richText = base.GetDisplayName(); LookupUtil.AddEmphasize(richText, new TextRange(0, richText.Length)); return(richText); }
private ILookupItem CreateMethodItem(CSharpCodeCompletionContext context, UnityEventFunction eventFunction, IClassLikeDeclaration declaration, bool hasReturnType, AccessRights accessRights, MemberGenerationContext generationContext) { 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 UnityEventFunctionTextualInfo(generationContext.MemberReplaceRanges, 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(textualInfo, eventFunction, accessRights)) .WithMatcher(_ => new ShiftedDeclaredElementMatcher(eventFunction.Name, modifier.Length, textualInfo)); var description = GetDescription(context, methodDeclaration); return(new WrappedLookupItem(lookupItem, description)); }
private static ILookupItem CreateMethodItem(CSharpCodeCompletionContext context, UnityEventFunction eventFunction, IClassLikeDeclaration declaration, bool addModifier) { if (CSharpLanguage.Instance == null) { return(null); } var method = eventFunction.CreateDeclaration(CSharpElementFactory.GetInstance(declaration, false), declaration); if (method.DeclaredElement == null) { return(null); } var instance = new DeclaredElementInstance(method.DeclaredElement); var declaredElementInfo = new DeclaredElementInfoWithoutParameterInfo(method.DeclaredName, instance, CSharpLanguage.Instance, context.BasicContext.LookupItemsOwner, context) { Ranges = context.CompletionRanges }; // 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); 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 = addModifier ? "private " : string.Empty; var psiIconManager = context.BasicContext.LookupItemsOwner.Services.PsiIconManager; return(LookupItemFactory.CreateLookupItem(declaredElementInfo) .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, PsiIconExtension.Private); var marker = item.Info.Ranges.CreateVisualReplaceRangeMarker(); return new SimplePresentation(displayName, image, marker); }) .WithBehavior(_ => new UnityEventFunctionBehavior(declaredElementInfo, eventFunction)) .WithMatcher(_ => new ShiftedDeclaredElementMatcher(text, modifier.Length, declaredElementInfo, context.BasicContext.IdentifierMatchingStyle))); }
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; } var factory = CSharpElementFactory.GetInstance(declaration, false); var methodDeclaration = eventFunction.CreateDeclaration(factory, declaration, accessRights); if (methodDeclaration.DeclaredElement == null) { return(null); } var instance = new DeclaredElementInstance(methodDeclaration.DeclaredElement); var declaredElementInfo = new DeclaredElementInfoWithoutParameterInfo(methodDeclaration.DeclaredName, instance, CSharpLanguage.Instance, context.BasicContext.LookupItemsOwner, context) { Ranges = context.CompletionRanges }; // 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; return(LookupItemFactory.CreateLookupItem(declaredElementInfo) .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(methodDeclaration.DeclaredElement, methodDeclaration.DeclaredElement.PresentationLanguage, true); var marker = item.Info.Ranges.CreateVisualReplaceRangeMarker(); return new SimplePresentation(displayName, image, marker); }) .WithBehavior(_ => new UnityEventFunctionBehavior(myShellLocks, declaredElementInfo, eventFunction, accessRights)) .WithMatcher(_ => new ShiftedDeclaredElementMatcher(eventFunction.Name, modifier.Length, declaredElementInfo, context.BasicContext.IdentifierMatchingStyle))); }