diff --git a/ReSharper.FSharp/src/FSharp.Fantomas.Host/PackagesLock.targets b/ReSharper.FSharp/src/FSharp.Fantomas.Host/PackagesLock.targets index 25d834a147..940f7b61f3 100644 --- a/ReSharper.FSharp/src/FSharp.Fantomas.Host/PackagesLock.targets +++ b/ReSharper.FSharp/src/FSharp.Fantomas.Host/PackagesLock.targets @@ -5,7 +5,7 @@ - + @@ -15,4 +15,4 @@ - + \ No newline at end of file diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeStructure/FSharpCodeStructure.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeStructure/FSharpCodeStructure.fs index f69ac647c2..751747fe7c 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeStructure/FSharpCodeStructure.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeStructure/FSharpCodeStructure.fs @@ -128,6 +128,8 @@ type FSharpCodeStructureProvider() = processNode root null file root + member this.SupportsBackgroundUpdate = false + type FSharpDeclarationCodeStructureElement(declaration: IDeclaration, parent, parentBlock: ICodeStructureBlockStart) = inherit CodeStructureElement(parent) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/LanguageService/FSharpClrLanguage.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/LanguageService/FSharpClrLanguage.fs index c0985c5bd5..17c1e43254 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/LanguageService/FSharpClrLanguage.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/LanguageService/FSharpClrLanguage.fs @@ -1,10 +1,11 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.LanguageService open JetBrains.Application +open JetBrains.Application.Parts open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Feature.Services.ClrLanguages -[] +[] type FSharpClrLanguage() = interface IClrLanguagesKnown with member x.Language = FSharpLanguage.Instance :> _ diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedParameter.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedParameter.cs index 1970ec4ae0..47b917482c 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedParameter.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/FSharpGenerativeProvidedParameter.cs @@ -1,6 +1,7 @@ using JetBrains.ReSharper.Plugins.FSharp.Psi.Util; using JetBrains.ReSharper.Plugins.FSharp.TypeProviders.Protocol.Models; using JetBrains.ReSharper.Psi; +using JetBrains.ReSharper.Psi.Resolve.Managed; using static FSharp.Compiler.TypeProviders; namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Cache2 @@ -41,7 +42,7 @@ Info is ProxyProvidedParameterInfoWithContext x && public bool IsValueVariable => false; public bool IsOptional => Info.IsOptional; public bool IsVarArg => false; - public ScopedKind Scope => ScopedKind.None; + public ScopedKind GetScope(IResolveContext context = null) => ScopedKind.None; public IParametersOwner ContainingParametersOwner { get; } } } diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedParameter.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedParameter.cs index f330f77fb4..68ffb6e9fd 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedParameter.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/CompilerGenerated/FSharpGeneratedParameter.cs @@ -3,6 +3,7 @@ using JetBrains.ReSharper.Psi; using JetBrains.ReSharper.Psi.ExtensionsAPI; using JetBrains.ReSharper.Psi.Pointers; +using JetBrains.ReSharper.Psi.Resolve.Managed; using JetBrains.Util; namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.DeclaredElement.CompilerGenerated @@ -43,7 +44,7 @@ public override bool IsValid() => public override DeclaredElementType GetElementType() => CLRDeclaredElementType.PARAMETER; - public ScopedKind Scope => ScopedKind.None; + public ScopedKind GetScope(IResolveContext context = null) => ScopedKind.None; public IParametersOwner ContainingParametersOwner => Owner; protected override IClrDeclaredElement ContainingElement => Owner; public override ITypeMember GetContainingTypeMember() => Owner as ITypeMember; diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodParameterBase.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodParameterBase.cs index 1f7bb0e1fd..9c231c9bed 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodParameterBase.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/DeclaredElement/FSharpMethodParameterBase.cs @@ -5,6 +5,7 @@ using JetBrains.ReSharper.Psi; using JetBrains.ReSharper.Psi.Modules; using JetBrains.ReSharper.Psi.Resolve; +using JetBrains.ReSharper.Psi.Resolve.Managed; using JetBrains.ReSharper.Psi.Tree; using JetBrains.Util; using JetBrains.Util.DataStructures; @@ -34,7 +35,7 @@ protected FSharpMethodParameterBase([NotNull] IParametersOwner owner, int index, public abstract bool IsParameterCollection { get; } public bool IsValueVariable => false; public abstract bool IsOptional { get; } - public ScopedKind Scope => ScopedKind.None; + public ScopedKind GetScope(IResolveContext context = null) => ScopedKind.None; public IParametersOwner ContainingParametersOwner => Owner; public IPsiServices GetPsiServices() => Owner.GetPsiServices(); diff --git a/ReSharper.FSharp/src/FSharp/PackagesLock.targets b/ReSharper.FSharp/src/FSharp/PackagesLock.targets index 33d539a202..b5e0207f4f 100644 --- a/ReSharper.FSharp/src/FSharp/PackagesLock.targets +++ b/ReSharper.FSharp/src/FSharp/PackagesLock.targets @@ -9,12 +9,12 @@ - - + + - \ No newline at end of file + diff --git a/ReSharper.FSharp/test/src/PackagesLock.targets b/ReSharper.FSharp/test/src/PackagesLock.targets index 579a526bf3..68de3bc1bc 100644 --- a/ReSharper.FSharp/test/src/PackagesLock.targets +++ b/ReSharper.FSharp/test/src/PackagesLock.targets @@ -5,9 +5,9 @@ - - - + + + diff --git a/rider-fsharp/gradle.properties b/rider-fsharp/gradle.properties index 47b4daae26..54fbe148e4 100644 --- a/rider-fsharp/gradle.properties +++ b/rider-fsharp/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx2000m kotlin.stdlib.default.dependency=false rdVersion=2024.3-pre2 -rdKotlinVersion=1.9.23 +rdKotlinVersion=2.1.0-RC2 intellijPlatformGradlePluginVersion=2.0.0-beta8 grammarKitVersion=2022.3.2.1 gradleJvmWrapperVersion=0.14.0 diff --git a/rider-fsharp/protocol/build.gradle.kts b/rider-fsharp/protocol/build.gradle.kts index 260ad08bdc..b7b00c6598 100644 --- a/rider-fsharp/protocol/build.gradle.kts +++ b/rider-fsharp/protocol/build.gradle.kts @@ -9,6 +9,7 @@ plugins { repositories { maven("https://cache-redirector.jetbrains.com/intellij-dependencies") maven("https://cache-redirector.jetbrains.com/maven-central") + maven("https://cache-redirector.jetbrains.com/plugins.gradle.org") } val isMonorepo = rootProject.projectDir != projectDir.parentFile diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineCompletionContributor.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineCompletionContributor.kt new file mode 100644 index 0000000000..9234f66efc --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineCompletionContributor.kt @@ -0,0 +1,86 @@ +package com.jetbrains.rider.plugins.fsharp.completion.patchEngine + +import com.intellij.codeInsight.completion.CompletionInitializationContext +import com.intellij.openapi.diagnostic.trace +import com.intellij.psi.ElementManipulators +import com.intellij.psi.PsiFile +import com.intellij.psi.util.startOffset +import com.jetbrains.rdclient.document.textControlId +import com.jetbrains.rdclient.document.textControlModel +import com.jetbrains.rdclient.patches.isPatchEngineEnabled +import com.jetbrains.rider.completion.patchEngine.RiderPatchEngineCompletionContributor +import com.jetbrains.rider.completion.patchEngine.RiderPatchEngineProtocolProvider +import com.jetbrains.rider.completion.patchEngine.RiderPatchEngineProtocolProvider.Companion.logger +import com.jetbrains.rider.completion.patchEngine.isPreemptiveCompletionEnabled +import com.jetbrains.rider.editors.startOffset +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpFile +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpStringLiteralExpression +import com.jetbrains.rider.plugins.fsharp.completion.PACKAGE_REFERENCE_REGEX +import com.jetbrains.rider.plugins.fsharp.completion.insideReferenceDirective + +class NuGetPatchEngineCompletionContributor : RiderPatchEngineCompletionContributor() { + + override fun isAvailable(file: PsiFile, offset: Int): Boolean = file is FSharpFile && insideReferenceDirective(file, offset) + + override fun beforeCompletion(context: CompletionInitializationContext) { + if (!isPatchEngineEnabled || !isPreemptiveCompletionEnabled) + return + + val psiElement = context.file.findElementAt(context.startOffset)?.parent ?: return + if (psiElement !is FSharpStringLiteralExpression) return + + val stringRange = ElementManipulators.getValueTextRange(psiElement) + val stringContentRange = psiElement.startOffset + stringRange.startOffset + + context.offsetMap.addOffset(CompletionInitializationContext.START_OFFSET, context.editor.startOffset - stringContentRange) + context.replacementOffset = psiElement.startOffset + stringRange.endOffset + + val stringText = ElementManipulators.getValueText(psiElement) + val match = PACKAGE_REFERENCE_REGEX.find(stringText) ?: return + + val `package` = match.groups["package"]!! + val packageZone = match.groups["packageZone"]!! + val version = match.groups["version"] + val versionZone = match.groups["versionZone"] + + prepareCustomParams(stringText, context.startOffset, "NuGet:name", `package`, packageZone, context) + || prepareCustomParams(stringText, context.startOffset, "NuGet:version|${`package`.value}", version!!, versionZone!!, context) + + RiderPatchEngineProtocolProvider.getInstance().isSuppress = true + } + + private fun prepareCustomParams( + content: String, + cursorPosition: Int, + host: String, + strictGroup: MatchGroup, + zoneGroup: MatchGroup, + initContext: CompletionInitializationContext, + ): Boolean { + val textControlModel = initContext.editor.textControlModel ?: run { + logger.trace { "TextControlModel is null during starting completion :: editor=${initContext.editor}" } + return false + } + + val textControlId = initContext.editor.textControlId ?: run { + logger.trace { "TextControlId is null during starting completion :: editor=${initContext.editor}" } + return false + } + + if (containsExclusive(strictGroup.range, cursorPosition)) { + val completionPrefix = content.substring(strictGroup.range.first, cursorPosition) + RiderPatchEngineProtocolProvider.getInstance().triggerCustomCompletion(initContext.project, textControlId, textControlModel, + initContext.completionType, 1, completionPrefix, host) + return true + } + else if (containsExclusive(zoneGroup.range, cursorPosition)) { + RiderPatchEngineProtocolProvider.getInstance().triggerCustomCompletion(initContext.project, textControlId, textControlModel, + initContext.completionType, 1, "", host) + return true + } + + return false + } + + private fun containsExclusive(range: IntRange, value: Int) = value >= range.first && value <= range.last + 1 +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/NuGetPatchEngineCompletionContributor.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineLegacyCompletionContributor.kt similarity index 72% rename from rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/NuGetPatchEngineCompletionContributor.kt rename to rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineLegacyCompletionContributor.kt index 2186439b92..051843fe4f 100644 --- a/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/NuGetPatchEngineCompletionContributor.kt +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/plugins/fsharp/completion/patchEngine/NuGetPatchEngineLegacyCompletionContributor.kt @@ -1,4 +1,4 @@ -package com.jetbrains.rider.plugins.fsharp.completion +package com.jetbrains.rider.plugins.fsharp.completion.patchEngine import com.intellij.codeInsight.completion.CompletionInitializationContext import com.intellij.codeInsight.completion.CompletionParameters @@ -9,16 +9,20 @@ import com.intellij.psi.util.startOffset import com.jetbrains.rdclient.patches.isPatchEngineEnabled import com.jetbrains.rider.completion.patchEngine.RiderPatchEngineCompletionContributor import com.jetbrains.rider.completion.patchEngine.RiderPatchEngineOldProtocolProvider +import com.jetbrains.rider.completion.patchEngine.isPreemptiveCompletionEnabled import com.jetbrains.rider.editors.startOffset import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpFile import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpStringLiteralExpression +import com.jetbrains.rider.plugins.fsharp.completion.PACKAGE_REFERENCE_REGEX +import com.jetbrains.rider.plugins.fsharp.completion.insideReferenceDirective +import kotlin.text.get -class NuGetPatchEngineCompletionContributor : RiderPatchEngineCompletionContributor() { +class NuGetPatchEngineLegacyCompletionContributor : RiderPatchEngineCompletionContributor() { override fun isAvailable(file: PsiFile, offset: Int): Boolean = file is FSharpFile && insideReferenceDirective(file, offset) override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) { - if (!isPatchEngineEnabled) { + if (!isPatchEngineEnabled || isPreemptiveCompletionEnabled) { super.fillCompletionVariants(parameters, result) return } @@ -42,13 +46,13 @@ class NuGetPatchEngineCompletionContributor : RiderPatchEngineCompletionContribu } finally { // Not sure is there a better way to provide params into provider with current architecture - RiderPatchEngineOldProtocolProvider.getInstance().customPrefixThreadLocal.remove() - RiderPatchEngineOldProtocolProvider.getInstance().nuGetCustomParamThreadLocal.remove() + RiderPatchEngineOldProtocolProvider.Companion.getInstance().customPrefixThreadLocal.remove() + RiderPatchEngineOldProtocolProvider.Companion.getInstance().nuGetCustomParamThreadLocal.remove() } } override fun beforeCompletion(context: CompletionInitializationContext) { - if (!isPatchEngineEnabled) + if (!isPatchEngineEnabled || isPreemptiveCompletionEnabled) return val psiElement = context.file.findElementAt(context.startOffset)?.parent ?: return @@ -70,13 +74,13 @@ class NuGetPatchEngineCompletionContributor : RiderPatchEngineCompletionContribu ): Boolean { if (containsExclusive(strictGroup.range, cursorPosition)) { val completionPrefix = content.substring(strictGroup.range.first, cursorPosition) - RiderPatchEngineOldProtocolProvider.getInstance().customPrefixThreadLocal.set(completionPrefix) - RiderPatchEngineOldProtocolProvider.getInstance().nuGetCustomParamThreadLocal.set(host) + RiderPatchEngineOldProtocolProvider.Companion.getInstance().customPrefixThreadLocal.set(completionPrefix) + RiderPatchEngineOldProtocolProvider.Companion.getInstance().nuGetCustomParamThreadLocal.set(host) return true } else if (containsExclusive(zoneGroup.range, cursorPosition)) { - RiderPatchEngineOldProtocolProvider.getInstance().customPrefixThreadLocal.set("") - RiderPatchEngineOldProtocolProvider.getInstance().nuGetCustomParamThreadLocal.set(host) + RiderPatchEngineOldProtocolProvider.Companion.getInstance().customPrefixThreadLocal.set("") + RiderPatchEngineOldProtocolProvider.Companion.getInstance().nuGetCustomParamThreadLocal.set(host) return true } diff --git a/rider-fsharp/src/main/resources/META-INF/plugin.xml b/rider-fsharp/src/main/resources/META-INF/plugin.xml index 74da8b9d2c..6988bfb817 100644 --- a/rider-fsharp/src/main/resources/META-INF/plugin.xml +++ b/rider-fsharp/src/main/resources/META-INF/plugin.xml @@ -31,7 +31,8 @@ - + +