diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Shim/AssemblyReader/ProjectFcsModuleReader.fs b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Shim/AssemblyReader/ProjectFcsModuleReader.fs index d682d28d2e..7c8480e2db 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Shim/AssemblyReader/ProjectFcsModuleReader.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Shim/AssemblyReader/ProjectFcsModuleReader.fs @@ -820,7 +820,7 @@ type ProjectFcsModuleReader(psiModule: IPsiModule, cache: FcsModuleReaderCommonC let customAttrs = let isExtension = match method with - | :? IMethod as method -> method.IsExtensionMethod + | :? IMethod as method -> method.IsDefinedAsExtension | _ -> false let customAttributes = mkCustomAttributes method diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpExtensionMemberUtil.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpExtensionMemberUtil.fs index 80d2b512d8..9a0e249f78 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpExtensionMemberUtil.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpExtensionMemberUtil.fs @@ -4,16 +4,20 @@ open System.Collections.Generic open FSharp.Compiler.Symbols open JetBrains.ProjectModel open JetBrains.ReSharper.Plugins.FSharp.Psi +open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Cache2.Compiled open JetBrains.ReSharper.Plugins.FSharp.Psi.Metadata open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util open JetBrains.ReSharper.Psi +open JetBrains.ReSharper.Psi.ExtensionsAPI.Caches2.ExtensionMethods open JetBrains.ReSharper.Psi.ExtensionsAPI.Caches2.ExtensionMethods.Queries open JetBrains.ReSharper.Psi.Modules open JetBrains.ReSharper.Psi.Resolve open JetBrains.ReSharper.Psi.Util type FSharpRequest(psiModule, exprType: IType, name: string option) = + static let memberKinds = [ExtensionMemberKind.ExtensionMethod; FSharpExtensionMemberKind.FSharpExtensionMember] + let name = Option.toObj name let baseTypes: IReadOnlyList = @@ -32,6 +36,7 @@ type FSharpRequest(psiModule, exprType: IType, name: string option) = member this.BaseExpressionTypes = baseTypes member this.ExpressionType = exprType member this.ForModule = psiModule + member this.Kinds = memberKinds member this.IsCaseSensitive = true member this.Namespaces = [] @@ -169,11 +174,29 @@ let getExtensionMembers (context: IFSharpTreeNode) (fcsType: FSharpType) (nameOp | _ -> containingType.Module.AreInternalsVisibleTo(psiModule) isTypeAccessible && - + match typeMember with | FSharpExtensionMember _ -> true | _ -> AccessUtil.IsSymbolAccessible(typeMember, accessContext) + let matchesName (typeMember: ITypeMember) = + match nameOpt with + | None -> true + | Some name -> + + match typeMember with + | FSharpCompiledExtensionMember _ -> + let memberName = typeMember.ShortName + memberName = name || + memberName = $"get_{name}" || + memberName = $"set_{name}" || + + memberName.EndsWith($".{name}") || + memberName.EndsWith($".get_{name}") || + memberName.EndsWith($".set_{name}") + + | _ -> typeMember.ShortName = name + let isApplicable (typeMember: ITypeMember) = matchesName typeMember && not (isInScope typeMember) && @@ -182,6 +205,8 @@ let getExtensionMembers (context: IFSharpTreeNode) (fcsType: FSharpType) (nameOp let query = ExtensionMethodsQuery(solution.GetPsiServices(), FSharpRequest(psiModule, exprType, nameOpt)) - query.EnumerateMethods() + let methods = query.EnumerateMethods() + + methods |> Seq.filter isApplicable |> List diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedMethod.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedMethod.cs index d681850aa8..e595d27ad9 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedMethod.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedMethod.cs @@ -18,7 +18,7 @@ public FSharpGenerativeGenerativeProvidedMethod(ProvidedMethodInfo info, ITypeEl public override IType ReturnType => Info.ReturnType.MapType(Module); public override bool IsAbstract => Info.IsAbstract; public override bool IsStatic => Info.IsStatic; - public bool IsExtensionMethod => false; + public bool IsDefinedAsExtension => false; public bool IsAsync => false; public bool IsVarArg => false; } diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/Parts/FSharpGeneratedMethodBase.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/Parts/FSharpGeneratedMethodBase.cs index 6bcd9043c0..1477e17511 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/Parts/FSharpGeneratedMethodBase.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/Parts/FSharpGeneratedMethodBase.cs @@ -38,7 +38,7 @@ public override DeclaredElementType GetElementType() => MethodIdSubstitution.Create(this); public bool IsXamlImplicitMethod => false; - public bool IsExtensionMethod => false; + public bool IsDefinedAsExtension => false; public bool IsVarArg => false; public bool IsAsync => false; } diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedMemberBase.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedMemberBase.cs index 66375b50ee..5021ebf39a 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedMemberBase.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedMemberBase.cs @@ -58,7 +58,8 @@ public override bool Equals(object obj) public override int GetHashCode() => ShortName.GetHashCode(); - public bool IsExtensionMember => false; + public bool IsDefinedAsExtension => false; + public bool IsExtensionMethod => false; public FSharpSymbol Symbol => null; diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpAnonRecordFieldProperty.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpAnonRecordFieldProperty.cs index d4a4d7583c..394a6700ce 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpAnonRecordFieldProperty.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpAnonRecordFieldProperty.cs @@ -37,7 +37,7 @@ public override DeclaredElementType GetElementType() => public IType Type => FcsField is { } field - ? field.FieldType.MapType(Reference.GetElement()) + ? @field.FieldType.MapType(Reference.GetElement()) : TypeFactory.CreateUnknownType(Module); public IFSharpAnonRecordFieldProperty SetName(string newName) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMemberBase.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMemberBase.cs index ad1d861a81..df45ec9089 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMemberBase.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMemberBase.cs @@ -20,7 +20,7 @@ protected FSharpMemberBase([NotNull] ITypeMemberDeclaration declaration) : base( public FSharpMemberOrFunctionOrValue Mfv => Symbol as FSharpMemberOrFunctionOrValue; - public bool IsExtensionMember => + public bool IsFSharpExtensionMember => GetContainingType() is IFSharpModule && GetDeclaration() is IMemberSignatureOrDeclaration; protected override ITypeElement GetTypeElement(IDeclaration declaration) @@ -59,7 +59,7 @@ public override AccessRights GetAccessRights() // Workaround to hide extension methods from resolve in C#. // todo: calc compiled names for extension members (it'll hide needed ones properly) // todo: implement F# declared element presenter to hide compiled names in features/ui - if (IsExtensionMember && GetDeclaration() is IMemberSignatureOrDeclaration memberDeclaration) + if (IsFSharpExtensionMember && GetDeclaration() is IMemberSignatureOrDeclaration memberDeclaration) if (!(this is IMethod && memberDeclaration.Attributes.GetCompiledName(out _))) return AccessRights.INTERNAL; diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodBase.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodBase.cs index ecc298e75c..931198cf2c 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodBase.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodBase.cs @@ -18,7 +18,9 @@ protected FSharpMethodBase([NotNull] ITypeMemberDeclaration declaration) : base( public override DeclaredElementType GetElementType() => CLRDeclaredElementType.METHOD; - public bool IsExtensionMethod => + public bool IsExtensionMethod => IsDefinedAsExtension; + + public override bool IsDefinedAsExtension => Attributes.HasAttributeInstance(PredefinedType.EXTENSION_ATTRIBUTE_CLASS); public bool IsAsync => false; diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpTypeMember.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpTypeMember.cs index 873115c7d2..fe38cfe415 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpTypeMember.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpTypeMember.cs @@ -105,6 +105,7 @@ public virtual AccessRights GetAccessRights() => public virtual bool IsExtern => false; public virtual bool IsUnsafe => false; public virtual bool IsVolatile => false; + public virtual bool IsDefinedAsExtension => false; public string XMLDocId => XMLDocUtil.GetTypeMemberXmlDocId(this, ShortName);