Skip to content

Commit

Permalink
more fixes for stale path cache
Browse files Browse the repository at this point in the history
  • Loading branch information
mkurnikov committed Jan 15, 2025
1 parent f3c2817 commit 42187a0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext
import org.move.lang.core.completion.MvCompletionContext
import org.move.lang.core.completion.createLookupElement
import org.move.lang.core.completion.safeGetOriginalOrSelf
import org.move.lang.core.completion.getOriginalOrSelf
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.*
import org.move.lang.core.resolve2.ref.FieldResolveVariant
Expand Down Expand Up @@ -44,9 +44,9 @@ object StructFieldsCompletionProvider: MvCompletionProvider() {
val patStruct = element.patStruct
// Path resolution is cached, but sometimes path changes so much that it can't be retrieved
// from cache anymore. In this case we need to get the old path.
// "safe" here means that if tree changes too much (=any of the ancestors of path are changed),
// OLD: "safe" here means that if tree changes too much (=any of the ancestors of path are changed),
// then it's a no-op and we continue working with current path.
val struct = patStruct.path.safeGetOriginalOrSelf().maybeStruct ?: return
val struct = patStruct.path.getOriginalOrSelf().maybeFieldsOwner ?: return
addFieldsToCompletion(
struct,
patStruct.fieldNames,
Expand All @@ -57,7 +57,7 @@ object StructFieldsCompletionProvider: MvCompletionProvider() {
is MvStructLitField -> {
val structLit = element.parentStructLitExpr
// see MvPatField's comment above
val struct = structLit.path.safeGetOriginalOrSelf().maybeStruct ?: return
val struct = structLit.path.getOriginalOrSelf().maybeFieldsOwner ?: return
addFieldsToCompletion(
struct,
structLit.providedFieldNames,
Expand All @@ -70,12 +70,12 @@ object StructFieldsCompletionProvider: MvCompletionProvider() {


private fun addFieldsToCompletion(
referredStruct: MvStruct,
fieldsOwner: MvFieldsOwner,
providedFieldNames: Set<String>,
result: CompletionResultSet,
completionContext: MvCompletionContext,
) {
for (field in referredStruct.namedFields.filter { it.name !in providedFieldNames }) {
for (field in fieldsOwner.namedFields.filter { it.name !in providedFieldNames }) {
val scopeEntry = FieldResolveVariant(field.name, field)
createLookupElement(scopeEntry, completionContext)
result.addElement(
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/org/move/lang/core/psi/ext/MvPath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ val MvPath.identifierName: String? get() = identifier?.text

val MvPath.maybeStruct get() = reference?.resolveFollowingAliases() as? MvStruct

val MvPath.maybeFieldsOwner get() = reference?.resolveFollowingAliases() as? MvFieldsOwner

val MvPath.maybeSchema get() = reference?.resolveFollowingAliases() as? MvSchema

//fun MvPath.allowedNamespaces(isCompletion: Boolean = false): Set<Namespace> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.move.lang.core.psi.ext

import com.intellij.lang.ASTNode
import org.move.lang.MvElementTypes
import org.move.lang.core.completion.getOriginalOrSelf
import org.move.lang.core.completion.safeGetOriginalOrSelf
import org.move.lang.core.psi.*
import org.move.lang.core.resolve.RsResolveProcessor
Expand Down Expand Up @@ -66,8 +67,8 @@ fun processSchemaLitFieldResolveVariants(
processor: RsResolveProcessor
): Boolean {
val schemaLit = literalField.schemaLit ?: return false
// safeGetOriginalOrSelf() to prevent cache misses for the path cache in completion
val schema = schemaLit.path.safeGetOriginalOrSelf().maybeSchema ?: return false
// getOriginalOrSelf() to prevent cache misses for the path cache in completion
val schema = schemaLit.path.getOriginalOrSelf().maybeSchema ?: return false
return schema.fieldsAsBindings
.any { field ->
processor.process(SimpleScopeEntry(field.name, field, setOf(Namespace.NAME)))
Expand Down
21 changes: 11 additions & 10 deletions src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.move.lang.core.resolve2

import org.move.lang.core.completion.getOriginalOrSelf
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.*
import org.move.lang.core.resolve.*
Expand Down Expand Up @@ -66,9 +67,9 @@ fun processStructPatFieldResolveVariants(
patFieldFull: MvPatFieldFull,
processor: RsResolveProcessor
): Boolean {
val resolved = patFieldFull.patStruct.path.reference?.resolveFollowingAliases()
val resolvedStruct = resolved as? MvFieldsOwner ?: return false
return processNamedFieldDeclarations(resolvedStruct, processor)
// used in completion
val fieldsOwner = patFieldFull.patStruct.path.getOriginalOrSelf().maybeFieldsOwner ?: return false
return processNamedFieldDeclarations(fieldsOwner, processor)
}

fun processPatBindingResolveVariants(
Expand All @@ -79,10 +80,10 @@ fun processPatBindingResolveVariants(
// field pattern shorthand
if (binding.parent is MvPatField) {
val parentPat = binding.parent.parent as MvPatStruct
val structItem = parentPat.path.reference?.resolveFollowingAliases()
val fieldsOwner = parentPat.path.getOriginalOrSelf().maybeFieldsOwner
// can be null if unresolved
if (structItem is MvFieldsOwner) {
if (processNamedFieldDeclarations(structItem, originalProcessor)) return true
if (fieldsOwner != null) {
if (processNamedFieldDeclarations(fieldsOwner, originalProcessor)) return true
if (isCompletion) return false
}
}
Expand Down Expand Up @@ -254,14 +255,14 @@ fun walkUpThroughScopes(
return false
}

private fun processFieldDeclarations(item: MvFieldsOwner, processor: RsResolveProcessor): Boolean =
item.fields.any { field ->
private fun processFieldDeclarations(fieldsOwner: MvFieldsOwner, processor: RsResolveProcessor): Boolean =
fieldsOwner.fields.any { field ->
val name = field.name ?: return@any false
processor.process(name, NAMES, field)
}

private fun processNamedFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean =
struct.namedFields.any { field ->
private fun processNamedFieldDeclarations(fieldsOwner: MvFieldsOwner, processor: RsResolveProcessor): Boolean =
fieldsOwner.namedFields.any { field ->
val name = field.name
processor.process(name, NAMES, field)
}
Expand Down

0 comments on commit 42187a0

Please sign in to comment.