diff --git a/ReSharper.FSharp/src/FSharp.Psi/src/Resolve/FSharpParameterUtil.cs b/ReSharper.FSharp/src/FSharp.Psi/src/Resolve/FSharpParameterUtil.cs index 2ac4395e30..23338b1982 100644 --- a/ReSharper.FSharp/src/FSharp.Psi/src/Resolve/FSharpParameterUtil.cs +++ b/ReSharper.FSharp/src/FSharp.Psi/src/Resolve/FSharpParameterUtil.cs @@ -2,6 +2,7 @@ using System.Linq; using FSharp.Compiler.Symbols; using JetBrains.Annotations; +using JetBrains.DocumentModel; using JetBrains.ReSharper.Plugins.FSharp.Psi.Impl; using JetBrains.ReSharper.Plugins.FSharp.Psi.Tree; using JetBrains.ReSharper.Plugins.FSharp.Psi.Util; @@ -69,7 +70,7 @@ private static IDeclaredElement GetFieldDeclaredElement([NotNull] IReference ref return field?.GetDeclaredElement(referenceOwner.GetPsiModule(), referenceOwner); } - public static IReadOnlyList> GetParametersGroupNames(ITreeNode node) => + public static IReadOnlyList> GetParametersGroupNames(ITreeNode node) => (node switch { IBinding binding => binding.Expression is ILambdaExpr lambda @@ -90,8 +91,8 @@ public static IReadOnlyList> GetParametersGroupNames(ITree IMemberSignature memberSignature => GetParameterNames(((IMemberSignatureOrDeclaration)memberSignature) .ReturnTypeInfo.ReturnType), - IUnionCaseDeclaration ucDecl => new[] { ucDecl.Fields.Select(t => t.SourceName) }, - _ => EmptyList.Enumerable + IUnionCaseDeclaration ucDecl => new[] { ucDecl.Fields.Select(t => (t.SourceName, t.GetNameDocumentRange())) }, + _ => EmptyList>.Enumerable }) .Select(t => t.ToIReadOnlyList()) .ToIReadOnlyList(); @@ -104,7 +105,7 @@ public static IReadOnlyList> GetParametersGroupNames(ITree _ => false }; - private static IEnumerable> GetLambdaArgs(ILambdaExpr expr) + private static IEnumerable> GetLambdaArgs(ILambdaExpr expr) { var lambdaParams = expr.Patterns; var parameters = lambdaParams.Select(GetParameterNames); @@ -113,40 +114,48 @@ private static IEnumerable> GetLambdaArgs(ILambdaExpr expr) return parameters; } - public static IEnumerable GetParameterNames(this IFSharpPattern pattern) + public static IEnumerable<(string, DocumentRange)> GetParameterNames(this IFSharpPattern pattern) { - IEnumerable GetParameterNamesInternal(IFSharpPattern pat, bool isTopLevelParameter) + IEnumerable<(string, DocumentRange)> GetParameterNamesInternal(IFSharpPattern pat, bool isTopLevelParameter) { pat = pat.IgnoreInnerParens(); return pat switch { - ILocalReferencePat local => new[] { local.SourceName }, + ILocalReferencePat local => new[] { (local.SourceName, local.GetDocumentRange()) }, IOptionalValPat opt => GetParameterNamesInternal(opt.Pattern, isTopLevelParameter), ITypedPat typed => GetParameterNamesInternal(typed.Pattern, false), IAttribPat attrib => GetParameterNamesInternal(attrib.Pattern, false), IAsPat asPat => GetParameterNamesInternal(asPat.RightPattern, false), ITuplePat tuplePat when isTopLevelParameter => tuplePat.PatternsEnumerable.SelectMany(t => GetParameterNamesInternal(t, false)), - _ => new[] { SharedImplUtil.MISSING_DECLARATION_NAME } + _ => new[] { (SharedImplUtil.MISSING_DECLARATION_NAME, DocumentRange.InvalidRange) } }; } return GetParameterNamesInternal(pattern, true); } - public static IEnumerable> GetParameterNames(this ITypeUsage pattern) => + public static IEnumerable> GetParameterNames(this ITypeUsage pattern) => pattern switch { IParenTypeUsage parenUsage => GetParameterNames(parenUsage.InnerTypeUsage), IParameterSignatureTypeUsage local => - new[] { new[] { local.Identifier?.Name ?? SharedImplUtil.MISSING_DECLARATION_NAME } }, + new[] + { + new[] + { + local.Identifier is { } identifier + ? (identifier.Name, local.GetDocumentRange()) + : (SharedImplUtil.MISSING_DECLARATION_NAME, DocumentRange.InvalidRange) + } + }, IFunctionTypeUsage funPat => GetParameterNames(funPat.ArgumentTypeUsage).Union(GetParameterNames(funPat.ReturnTypeUsage)), ITupleTypeUsage tuplePat => tuplePat.Items.SelectMany(GetParameterNames), - _ => EmptyList>.Enumerable + _ => EmptyList>.Enumerable }; - public static IReadOnlyList> GetParametersGroups(this IBinding binding) + public static IReadOnlyList> GetParametersGroups(this IBinding binding) { var parameters = binding.ParameterPatterns.Select(GetParameterNames); var bodyExpr = binding.Expression; diff --git a/ReSharper.FSharp/src/FSharp.Psi/src/Util/XmlDocTemplateUtil.cs b/ReSharper.FSharp/src/FSharp.Psi/src/Util/XmlDocTemplateUtil.cs index 9a737cae3f..57c8b3aa02 100644 --- a/ReSharper.FSharp/src/FSharp.Psi/src/Util/XmlDocTemplateUtil.cs +++ b/ReSharper.FSharp/src/FSharp.Psi/src/Util/XmlDocTemplateUtil.cs @@ -22,6 +22,7 @@ public static (string, int caretOffset) GetDocTemplate(IDocCommentBlock docComme foreach (var parameter in FSharpParameterUtil.GetParametersGroupNames(docCommentBlock.Parent) .SelectMany(t => t) + .Select(t => t.name) .Where(t => t != SharedImplUtil.MISSING_DECLARATION_NAME)) text.Append($"{lineEnding}{linePrefix}");