Skip to content

Commit

Permalink
Merge pull request #238 from pontem-network/named-tuple-fields-comple…
Browse files Browse the repository at this point in the history
…tion

Named tuple fields completion
  • Loading branch information
mkurnikov authored Nov 11, 2024
2 parents 4688ed3 + b074841 commit 5cc4caa
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 238 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ org.gradle.jvmargs=-Xms512m -Xmx4096m "-XX:MaxMetaspaceSize=512m"
propertiesPluginEnvironmentNameProperty=shortPlatformVersion
# properties files
# pass ORG_GRADLE_PROJECT_shortPlatformVersion environment variable to overwrite
shortPlatformVersion=243-SNAPSHOT
shortPlatformVersion=242

useInstaller=true
1 change: 0 additions & 1 deletion src/main/kotlin/org/move/ide/MoveIcons.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ object MoveIcons {
val MODULE = load("/icons/module.svg")

val STRUCT = load("/icons/struct.svg")
val STRUCT_FIELD = AllIcons.Nodes.Field
val SCHEMA = AllIcons.Nodes.Static

val FIELD = load("/icons/nodes/field.svg")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ class CommonCompletionContributor: CompletionContributor() {
extend(CompletionType.BASIC, BoolsCompletionProvider)
extend(CompletionType.BASIC, AssertMacroCompletionProvider)
extend(CompletionType.BASIC, VectorLiteralCompletionProvider)
extend(CompletionType.BASIC, MethodOrFieldCompletionProvider)

extend(CompletionType.BASIC, ReferenceCompletionProvider)
extend(CompletionType.BASIC, CommonCompletionProvider)
}

fun extend(type: CompletionType?, provider: MvCompletionProvider) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import org.move.ide.presentation.text
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.MvMethodOrField
import org.move.lang.core.psi.ext.addressRef
import org.move.lang.core.psi.ext.joinToSignature
import org.move.lang.core.psi.ext.outerFileName
import org.move.lang.core.psi.ext.*
import org.move.lang.core.resolve.ScopeEntry
import org.move.lang.core.types.infer.*
import org.move.lang.core.types.ty.TyUnknown
Expand Down Expand Up @@ -66,7 +63,7 @@ fun MvNamedElement.getLookupElementBuilder2(
.withTypeText(this.containingFile?.name)
}

is MvNamedFieldDecl -> {
is MvFieldDecl -> {
val fieldTy = this.type?.loweredType(msl)?.substitute(subst) ?: TyUnknown
base
.withTypeText(fieldTy.text(false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import com.intellij.patterns.ElementPattern
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext
import org.move.lang.core.completion.safeGetOriginalOrSelf
import org.move.lang.core.psi.ext.isMsl
import org.jetbrains.annotations.VisibleForTesting
import org.move.lang.core.completion.MvCompletionContext
import org.move.lang.core.completion.createLookupElement
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.*
import org.move.lang.core.psiElement
import org.move.lang.core.resolve.RsResolveProcessor
import org.move.lang.core.resolve.collectCompletionVariants
import org.move.lang.core.resolve.createProcessor
import org.move.lang.core.resolve.ref.MvReferenceElement
import org.move.lang.core.resolve2.ref.ResolutionContext
import org.move.lang.core.resolve.ref.processItemSpecRefResolveVariants
import org.move.lang.core.resolve.wrapWithFilter
import org.move.lang.core.resolve2.processFieldLookupResolveVariants
import org.move.lang.core.resolve2.processLabelResolveVariants
import org.move.lang.core.resolve2.processMethodResolveVariants
import org.move.lang.core.resolve2.processPatBindingResolveVariants
import org.move.lang.core.types.infer.InferenceContext
import org.move.lang.core.types.infer.substitute
import org.move.lang.core.types.ty.*

object CommonCompletionProvider: MvCompletionProvider() {
override val elementPattern: ElementPattern<PsiElement>
override val elementPattern: ElementPattern<out PsiElement>
get() = PlatformPatterns.psiElement().withParent(psiElement<MvReferenceElement>())

override fun addCompletions(
Expand All @@ -22,33 +36,95 @@ object CommonCompletionProvider: MvCompletionProvider() {
result: CompletionResultSet
) {
// Use original position if possible to re-use caches of the real file
val position = parameters.position.safeGetOriginalOrSelf()
val position = parameters.position
val element = position.parent as MvReferenceElement
if (position !== element.referenceNameElement) return

val msl = element.isMsl()
val expectedTy = getExpectedTypeForEnclosingPathOrDotExpr(element, msl)
val resolutionCtx = ResolutionContext(element, true)

// val completionContext = CompletionContext(
// element,
// msl,
// expectedTy,
// resolutionCtx = resolutionCtx,
// structAsType,
// )
val completionCtx = MvCompletionContext(element, msl, expectedTy)

// handles dot expr
if (element is MvMethodOrField) {
addMethodOrFieldVariants(element, result)
}

addCompletionVariants(element, result, completionCtx)
}

fun addCompletionVariants(
element: MvReferenceElement,
result: CompletionResultSet,
completionCtx: MvCompletionContext,
) {
collectCompletionVariants(result, completionCtx) {
val processor0 = filterCompletionVariantsByVisibility(element, it)
// todo: filter test functions
when (element) {
// `let Res/*caret*/ =`
// catches all modules, enums, enum variants and struct patterns
is MvPatBinding -> {
// for struct pat / lit, it filters out all the fields already existing in the body
val processor = skipAlreadyProvidedFields(element, processor0)
processPatBindingResolveVariants(element, true, processor)
}
// loop labels
is MvLabel -> processLabelResolveVariants(element, it)
// `spec ITEM {}` module items, where ITEM is a reference to the function/struct/enum
is MvItemSpecRef -> processItemSpecRefResolveVariants(element, it)
}
}
}

@VisibleForTesting
fun addMethodOrFieldVariants(element: MvMethodOrField, result: CompletionResultSet) {
val msl = element.isMsl()
val receiverTy = element.inferReceiverTy(msl).knownOrNull() ?: return
val expectedTy = getExpectedTypeForEnclosingPathOrDotExpr(element, msl)

val ctx = MvCompletionContext(element, msl, expectedTy)

val tyAdt = receiverTy.derefIfNeeded() as? TyAdt
if (tyAdt != null) {
collectCompletionVariants(result, ctx, subst = tyAdt.substitution) {
processFieldLookupResolveVariants(element, tyAdt, msl, it)
}
}

processMethodResolveVariants(element, receiverTy, ctx.msl, createProcessor { e ->
val function = e.element as? MvFunction ?: return@createProcessor
val subst = function.tyVarsSubst
val declaredFuncTy = function.functionTy(msl).substitute(subst) as TyFunction
val declaredSelfTy = declaredFuncTy.paramTypes.first()
val autoborrowedReceiverTy =
TyReference.autoborrow(receiverTy, declaredSelfTy)
?: error("unreachable, references always compatible")

val inferenceCtx = InferenceContext(msl)
inferenceCtx.combineTypes(declaredSelfTy, autoborrowedReceiverTy)

result.addElement(
createLookupElement(
e,
ctx,
subst = inferenceCtx.resolveTypeVarsIfPossible(subst)
)
)
})
}
}

// @VisibleForTesting
// fun addCompletionVariants(
// element: MvReferenceElement,
// result: CompletionResultSet,
// context: CompletionContext,
// processedPathNames: MutableSet<String>
// ) {
// collectCompletionVariants(result, context) {
//
// }
// }
private fun skipAlreadyProvidedFields(
refElement: MvReferenceElement,
processor0: RsResolveProcessor
): RsResolveProcessor {
val parent = refElement.parent
val providedFieldNames = when (parent) {
// shorthand, skip all provided fields
is MvPatField -> parent.parentPatStruct.fieldNames
// is MvStructLitField -> parent.parentStructLitExpr.providedFieldNames
else -> emptySet()
}
return processor0.wrapWithFilter { e -> e.name !in providedFieldNames }
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 5cc4caa

Please sign in to comment.