Skip to content

Commit

Permalink
add Move2OnlyInspectionBase (#221)
Browse files Browse the repository at this point in the history
* add Move2OnlyInspection

* move move2 only inspections to its own package

* replace with method call is move2only

* cleanup
  • Loading branch information
mkurnikov authored Oct 26, 2024
1 parent 550e420 commit b45f73f
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 91 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.move.ide.inspections.compilerV2

import com.intellij.codeInspection.ProblemsHolder
import org.move.cli.settings.moveSettings
import org.move.ide.inspections.MvLocalInspectionTool
import org.move.lang.core.psi.MvElement
import org.move.lang.core.psi.MvVisitor

abstract class Move2OnlyInspectionBase<TElement: MvElement>(
val elementClass: Class<TElement>
): MvLocalInspectionTool() {

override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): MvVisitor =
object: MvVisitor() {
override fun visitElement(o: MvElement) {
super.visitElement(o)
if (!elementClass.isInstance(o) || o.textLength == 0) return

// disable for move v1
if (!o.project.moveSettings.enableMove2) return

@Suppress("UNCHECKED_CAST")
visitTargetElement(o as TElement, holder, isOnTheFly)
}
}

abstract fun visitTargetElement(element: TElement, holder: ProblemsHolder, isOnTheFly: Boolean)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package org.move.ide.inspections.compilerV2

import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import org.move.cli.settings.moveSettings
import org.move.ide.inspections.MvLocalInspectionTool
import org.move.ide.inspections.compilerV2.fixes.ReplaceWithIndexExprFix
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.argumentExprs
Expand All @@ -13,43 +11,38 @@ import org.move.lang.core.types.infer.inference
import org.move.lang.core.types.ty.isCopy
import org.move.lang.moveProject

class MvReplaceWithIndexExprInspection: MvLocalInspectionTool() {
override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): MvVisitor {
return object: MvVisitor() {
override fun visitCallExpr(callExpr: MvCallExpr) {
// disable for move v1
if (!callExpr.project.moveSettings.enableMove2) return
class MvReplaceWithIndexExprInspection:
Move2OnlyInspectionBase<MvCallExpr>(MvCallExpr::class.java) {

val function = callExpr.path.reference?.resolveFollowingAliases() as? MvFunction ?: return
val module = function.module ?: return
val moveProject = function.moveProject ?: return
val msl = callExpr.isMsl()
val inference = callExpr.inference(msl) ?: return
val callExprRange = callExpr.textRange
// vector methods
if (inference.typeErrors.any { callExprRange.contains(it.range()) }) {
// type error inside the call expr
return
}
if (module.name == "vector" && module.is0x1Address(moveProject)) {
val parentExpr = callExpr.parent
if (function.name == "borrow" && parentExpr is MvDerefExpr) {
val receiverParamExpr = callExpr.argumentExprs.firstOrNull() ?: return
if (receiverParamExpr is MvBorrowExpr) {
val itemExpr = receiverParamExpr.expr ?: return
if (!inference.getExprType(itemExpr).isCopy) {
// cannot borrow deref without copy
return
}
}
holder.registerProblem(
parentExpr,
"Can be replaced with index expr",
ProblemHighlightType.WEAK_WARNING,
ReplaceWithIndexExprFix(parentExpr)
)
override fun visitTargetElement(element: MvCallExpr, holder: ProblemsHolder, isOnTheFly: Boolean) {
val function = element.path.reference?.resolveFollowingAliases() as? MvFunction ?: return
val module = function.module ?: return
val moveProject = function.moveProject ?: return
val msl = element.isMsl()
val inference = element.inference(msl) ?: return
val callExprRange = element.textRange
// vector methods
if (inference.typeErrors.any { callExprRange.contains(it.range()) }) {
// type error inside the call expr
return
}
if (module.name == "vector" && module.is0x1Address(moveProject)) {
val parentExpr = element.parent
if (function.name == "borrow" && parentExpr is MvDerefExpr) {
val receiverParamExpr = element.argumentExprs.firstOrNull() ?: return
if (receiverParamExpr is MvBorrowExpr) {
val itemExpr = receiverParamExpr.expr ?: return
if (!inference.getExprType(itemExpr).isCopy) {
// cannot borrow deref without copy
return
}
}
holder.registerProblem(
parentExpr,
"Can be replaced with index expr",
ProblemHighlightType.WEAK_WARNING,
ReplaceWithIndexExprFix(parentExpr)
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.move.ide.inspections.compilerV2

import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import org.move.ide.inspections.compilerV2.fixes.ReplaceWithMethodCallFix
import org.move.lang.core.psi.*
import org.move.lang.core.psi.ext.isMsl
import org.move.lang.core.psi.ext.itemModule
import org.move.lang.core.psi.ext.valueArguments
import org.move.lang.core.types.infer.deepFoldTyTypeParameterWith
import org.move.lang.core.types.infer.inference
import org.move.lang.core.types.ty.TyInfer
import org.move.lang.core.types.ty.TyReference.Companion.isCompatibleWithAutoborrow
import org.move.lang.core.types.ty.hasTyUnknown
import org.move.lang.moveProject

class MvReplaceWithMethodCallInspection:
Move2OnlyInspectionBase<MvCallExpr>(MvCallExpr::class.java) {

override fun visitTargetElement(element: MvCallExpr, holder: ProblemsHolder, isOnTheFly: Boolean) {
val function = element.path.reference?.resolveFollowingAliases() as? MvFunction ?: return
val msl = element.isMsl()
val inference = element.inference(msl) ?: return

val firstArgExpr = element.valueArguments.firstOrNull()?.expr ?: return
val firstArgExprTy = inference.getExprType(firstArgExpr)
if (firstArgExprTy.hasTyUnknown) return

val moveProject = element.moveProject ?: return
val methodModule = function.module ?: return
val itemModule = firstArgExprTy.itemModule(moveProject) ?: return
if (methodModule != itemModule) return

val selfTy = function.selfParamTy(msl)
?.deepFoldTyTypeParameterWith { TyInfer.TyVar(it) } ?: return
if (selfTy.hasTyUnknown) return

if (isCompatibleWithAutoborrow(firstArgExprTy, selfTy, msl)) {
// can be converted
holder.registerProblem(
element,
"Can be replaced with method call",
ProblemHighlightType.WEAK_WARNING,
ReplaceWithMethodCallFix(element)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.move.ide.inspections.fixes
package org.move.ide.inspections.compilerV2.fixes

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@
<localInspection language="Move" groupName="Move"
displayName="Convert to method call"
enabledByDefault="true" level="WEAK WARNING"
implementationClass="org.move.ide.inspections.MvReplaceWithMethodCallInspection" />
implementationClass="org.move.ide.inspections.compilerV2.MvReplaceWithMethodCallInspection" />
<localInspection language="Move" groupName="Move"
displayName="Convert to index expr"
enabledByDefault="true" level="WEAK WARNING"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.move.ide.inspections.compilerV2

import org.intellij.lang.annotations.Language
import org.move.ide.inspections.MvReplaceWithMethodCallInspection
import org.move.utils.tests.MoveV2
import org.move.utils.tests.FileTreeBuilder
import org.move.utils.tests.annotation.InspectionProjectTestBase
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.move.ide.inspections.compilerV2

import org.intellij.lang.annotations.Language
import org.move.ide.inspections.MvReplaceWithMethodCallInspection
import org.move.utils.tests.MoveV2
import org.move.utils.tests.annotation.InspectionTestBase

Expand Down

0 comments on commit b45f73f

Please sign in to comment.