Skip to content

Commit

Permalink
Merge pull request #188 from pontem-network/move-2-spec-fixes
Browse files Browse the repository at this point in the history
Move 2 fixes
  • Loading branch information
mkurnikov authored Sep 14, 2024
2 parents 063cb4e + 9269d29 commit 505651c
Show file tree
Hide file tree
Showing 29 changed files with 615 additions and 38 deletions.
6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,18 @@ allprojects {
exclude("org.slf4j")
}
implementation("com.github.ajalt.clikt:clikt:3.5.2")

testImplementation("junit:junit:4.13.2")
testImplementation("org.opentest4j:opentest4j:1.3.0")

intellijPlatform {
create(prop("platformType"), prop("platformVersion"), useInstaller = useInstaller)
testFramework(TestFrameworkType.Platform)

pluginVerifier(Constraints.LATEST_VERSION)
bundledPlugin("org.toml.lang")
jetbrainsRuntime("17.0.11b1207.30")

testFramework(TestFrameworkType.Platform)
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle-242.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pluginSinceBuild = 242
pluginUntilBuild = 242.*

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
platformVersion = 242.12881.66-EAP-SNAPSHOT
platformType = PC
platformVersion = 2024.2
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = org.toml.lang
Expand Down
24 changes: 18 additions & 6 deletions src/main/grammars/MoveParser.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@

ADDRESS = 'address_kw'
HAS = 'has_kw'
IS = 'is_kw'
ENTRY = 'entry_kw'
INLINE = 'inline_kw'
FRIEND = 'friend_kw'
Expand Down Expand Up @@ -214,6 +215,7 @@ private ScriptItem ::= UseStmt | Const | FunctionInner

private address ::= <<addressKeyword>>
private has ::= <<hasKeyword>>
private is ::= <<isKeyword>>
private entry ::= <<entryKeyword>>
private inline ::= <<inlineKeyword>>
private schema ::= <<schemaKeyword>>
Expand Down Expand Up @@ -267,7 +269,7 @@ private ModuleItem_recover ::= !('}' | ModuleItem_first | TopLevel_first)
// | fun | CONST_KW | STRUCT_KW | spec
// | Attr_first | "friend" | "enum"
private ModuleItem_first ::= use | public | native | fun | CONST_KW | STRUCT_KW | spec
| Attr_first | "friend" | "entry" | "inline" | "enum"
| Attr_first | "friend" | "package" | "entry" | "inline" | "enum"
private TopLevel_first ::= MODULE_KW | SCRIPT_KW

private ModuleItem ::= UseStmt
Expand Down Expand Up @@ -502,7 +504,9 @@ private AttrsAndVis_first ::= '#'
private FunctionModifierSetInner ::= <<functionModifierSet VisibilityModifier>>
private NativeFunctionModifierSetInner ::= <<nativeFunctionModifierSet VisibilityModifier>>

VisibilityModifier ::= public ('(' (SCRIPT_KW | package | friend) ')')?
VisibilityModifier ::= (public ('(' (SCRIPT_KW | package | friend) ')')?)
| package
| friend

FunctionParameterList ::= '(' FunctionParameter_with_recover* ')' { pin = 1 }
private FunctionParameter_with_recover ::= !(')' | '{' | ';') FunctionParameter (',' | &')')
Expand Down Expand Up @@ -601,9 +605,9 @@ TupleFieldDecl ::= Attr* Type
hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ]
}

FriendDecl ::= Attr* friend PathImpl ';'
FriendDecl ::= Attr* (friend !fun) PathImpl ';'
{
pin = "friend"
// pin = 2
implements = [ "org.move.lang.core.psi.ext.MvDocAndAttributeOwner" ]
}

Expand Down Expand Up @@ -907,7 +911,7 @@ private CodeBlock_items_recover ::= !('}' | <<eof>>)
Expr ::= AssignmentExpr
| RangeExpr
| (ForallQuantExpr | ExistsQuantExpr | ChooseQuantExpr)
| CastExpr
| CastLikeExpr_items
| ImplyBinExpr_items
| OrBinExpr
| AndBinExpr
Expand Down Expand Up @@ -942,7 +946,9 @@ fake BinaryOp ::= '<==>' | '==>' | '='

private MulExpr_items ::= DivBinExpr | MulBinExpr | ModBinExpr
private AddExpr_items ::= PlusBinExpr | MinusBinExpr
private LogicalEqExpr_items ::= EqualsBinExpr | NotEqualsBinExpr | LessEqualsBinExpr | LessBinExpr | GreaterEqualsBinExpr | GreaterBinExpr
private LogicalEqExpr_items ::=
EqualsBinExpr | NotEqualsBinExpr
| LessEqualsBinExpr | LessBinExpr | GreaterEqualsBinExpr | GreaterBinExpr

private ControlFlowExpr_items ::= IfExpr | LoopExpr | MatchExpr | WhileExpr | ForExpr
private UnaryExpr ::= CopyExpr | MoveExpr | DerefExpr | BangExpr
Expand All @@ -964,7 +970,10 @@ private AtomExpr ::=
| CodeBlockExpr


private CastLikeExpr_items ::= CastExpr | UnitExpr | IsExpr
CastExpr ::= Expr as Type
IsExpr ::= Expr is Type ('|' Type)*
UnitExpr ::= '(' ')'

private AnnotatedExpPrefix ::= '(' Expr ':'
AnnotatedExpr ::= AnnotatedExpPrefix Type ')' { pin = 1 }
Expand All @@ -987,6 +996,9 @@ GreaterBinExpr ::= Expr (!gtgt GreaterBinOp) Expr
LessEqualsBinExpr ::= Expr LessEqualsBinOp Expr
GreaterEqualsBinExpr ::= Expr GreaterEqualsBinOp Expr

//IsBinOp ::= is
//IsBinExpr ::= Expr IsBinOp Type ('|' Type)*

LessBinOp ::= '<'
GreaterBinOp ::= '>'
LessEqualsBinOp ::= lteq
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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.*
Expand All @@ -16,6 +17,9 @@ class ReplaceWithIndexExprInspection: 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

val function = callExpr.path.reference?.resolveFollowingAliases() as? MvFunction ?: return
val module = function.module ?: return
val moveProject = function.moveProject ?: return
Expand Down
41 changes: 34 additions & 7 deletions src/main/kotlin/org/move/lang/core/MoveParserUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import com.intellij.psi.TokenType.WHITE_SPACE
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import com.intellij.util.BitUtil
import org.move.cli.settings.moveSettings
import org.move.lang.MoveParserDefinition.Companion.EOL_COMMENT
import org.move.lang.MoveParserDefinition.Companion.EOL_DOC_COMMENT
import org.move.lang.MvElementTypes.*
Expand Down Expand Up @@ -247,7 +246,7 @@ object MoveParserUtil: GeneratedParserUtilBase() {
visParser: Parser,
native: Boolean,
): Boolean {
val modifiersLeft = FunModifier.values().toMutableSet()
val modifiersLeft = FunModifier.entries.toMutableSet()
if (!native) {
modifiersLeft.remove(FunModifier.NATIVE)
}
Expand All @@ -258,7 +257,9 @@ object MoveParserUtil: GeneratedParserUtilBase() {

while (modifiersLeft.isNotEmpty()) {
when {
b.tokenType == PUBLIC -> {
b.tokenType == PUBLIC
|| isContextualKeyword(b, "friend", FRIEND)
|| isContextualKeyword(b, "package", PACKAGE) -> {
if (FunModifier.VIS !in modifiersLeft) return isParsed()
if (!visParser.parse(b, level)) return false
modifiersLeft.remove(FunModifier.VIS)
Expand Down Expand Up @@ -286,9 +287,24 @@ object MoveParserUtil: GeneratedParserUtilBase() {

}
return isParsed()

}

// @JvmStatic
// fun parseCastOrIsExpr(
// b: PsiBuilder,
// level: Int,
// exprParser: Parser,
// allowColon: Boolean
// ): Boolean {
// if (!recursion_guard_(b, level, "parseCastOrIsExpr")) return false
// var result = false
//
// val isExpr = exprParser.parse(b, level + 1);
// if (isExpr) {
//
// }
// }

@JvmStatic
fun invariantModifierKeyword(b: PsiBuilder, level: Int): Boolean {
if (b.tokenType in tokenSetOf(PACK, UNPACK, UPDATE)) {
Expand Down Expand Up @@ -336,6 +352,9 @@ object MoveParserUtil: GeneratedParserUtilBase() {
@JvmStatic
fun hasKeyword(b: PsiBuilder, level: Int): Boolean = contextualKeyword(b, "has", HAS)

@JvmStatic
fun isKeyword(b: PsiBuilder, level: Int): Boolean = contextualKeyword(b, "is", IS)

@JvmStatic
fun entryKeyword(b: PsiBuilder, level: Int): Boolean = contextualKeyword(b, "entry", ENTRY)

Expand Down Expand Up @@ -484,15 +503,23 @@ object MoveParserUtil: GeneratedParserUtilBase() {
get() = getUserData(MSL_LEVEL) ?: 0
set(value) = putUserData(MSL_LEVEL, value)

private fun isContextualKeyword(
b: PsiBuilder,
keyword: String,
elementType: IElementType,
nextElementPredicate: (IElementType?) -> Boolean = { it !in tokenSetOf() }
): Boolean {
return b.tokenType == elementType ||
b.tokenType == IDENTIFIER && b.tokenText == keyword && nextElementPredicate(b.lookAhead(1))
}

private fun contextualKeyword(
b: PsiBuilder,
keyword: String,
elementType: IElementType,
nextElementPredicate: (IElementType?) -> Boolean = { it !in tokenSetOf() }
): Boolean {
if (b.tokenType == elementType ||
b.tokenType == IDENTIFIER && b.tokenText == keyword && nextElementPredicate(b.lookAhead(1))
) {
if (isContextualKeyword(b, keyword, elementType, nextElementPredicate)) {
b.remapCurrentToken(elementType)
b.advanceLexer()
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ private val VISIBILITY_MODIFIERS = arrayOf(
"public",
// "public(script)",
"public(friend)",
"public(package)"
"public(package)",
"friend",
"package",
)

private val CONTEXT_FUNCTION_MODIFIERS = arrayOf("entry", "inline")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import org.move.lang.core.psi.MvVisibilityModifier

val MvVisibilityModifier.hasPublic get() = hasChild(PUBLIC)
val MvVisibilityModifier.hasScript get() = hasChild(SCRIPT)
// package fun | public(package) fun
val MvVisibilityModifier.hasPackage get() = hasChild(PACKAGE)
// friend fun | public(friend) fun
val MvVisibilityModifier.hasFriend get() = hasChild(FRIEND)

val MvVisibilityModifier.function: MvFunction? get() = parent as? MvFunction
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,29 @@ class MvPath2ReferenceImpl(element: MvPath): MvPolyVariantReferenceBase<MvPath>(
rawMultiResolve().filter { it.isVisible }

fun rawMultiResolve(): List<RsPathResolveResult<MvElement>> =
// rawCachedMultiResolve()
rawMultiResolveUsingInferenceCache() ?: rawCachedMultiResolve()

private fun rawMultiResolveUsingInferenceCache(): List<RsPathResolveResult<MvElement>>? {
val pathElement = element.parent as? InferenceCachedPathElement ?: return null
val pathElement = element.parent
val msl = pathElement.isMsl()
return pathElement.inference(msl)?.getResolvedPath(pathElement.path)

// try resolving MvPathType inside MvIsExpr
if (pathElement is MvPathType) {
if (pathElement.parent is MvIsExpr) {
// special case for MvPathType, specifically for is expr
return getResolvedPathFromInference(element, msl)
}
// other path type cases are not cached in the inference
return null
}
if (pathElement is InferenceCachedPathElement) {
return getResolvedPathFromInference(pathElement.path, msl)
}
return null
}

private fun getResolvedPathFromInference(path: MvPath, msl: Boolean): List<RsPathResolveResult<MvElement>>? {
return path.inference(msl)?.getResolvedPath(path)
?.map {
RsPathResolveResult(it.element, it.isVisible)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ data class InferenceResult(
fun getExpectedType(expr: MvExpr): Ty = exprExpectedTypes[expr] ?: TyUnknown
fun getCallableType(callable: MvCallable): Ty? = callableTypes[callable]

fun hasResolvedPath(path: MvPath): Boolean = path in resolvedPaths
fun getResolvedPath(path: MvPath): List<ResolvedItem>? =
resolvedPaths[path] ?: inferenceErrorOrFallback(path, null)

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode
fcx.ctx.writePatTy(this, expected)

val item =
fcx.resolvePathElement(this, expected) as? MvFieldsOwner
fcx.resolvePathCached(this.path, expected) as? MvFieldsOwner
?: (expected as? TyAdt)?.item as? MvStruct
?: return

Expand Down Expand Up @@ -78,7 +78,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode
val (expected, patBm) = ty.stripReferences(defBm)
fcx.ctx.writePatTy(this, expected)
val item =
fcx.resolvePathElement(this, expected) as? MvFieldsOwner
fcx.resolvePathCached(this.path, expected) as? MvFieldsOwner
?: (expected as? TyAdt)?.item as? MvStruct
?: return
val tupleFields = item.positionalFields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import org.move.lang.core.resolve.ref.NONE
import org.move.lang.core.resolve.resolveSingleResolveVariant
import org.move.lang.core.resolve2.processFieldLookupResolveVariants
import org.move.lang.core.resolve2.processMethodResolveVariants
import org.move.lang.core.resolve2.ref.InferenceCachedPathElement
import org.move.lang.core.resolve2.ref.ResolutionContext
import org.move.lang.core.resolve2.ref.resolveAliases
import org.move.lang.core.resolve2.ref.resolvePathRaw
Expand Down Expand Up @@ -251,7 +250,9 @@ class TypeInferenceWalker(
}
ty
}
is MvIsExpr -> inferIsExprTy(expr)
is MvParensExpr -> expr.expr?.inferType(expected) ?: TyUnknown
is MvUnitExpr -> TyUnit

is MvBinaryExpr -> inferBinaryExprTy(expr)
is MvBangExpr -> {
Expand Down Expand Up @@ -308,7 +309,7 @@ class TypeInferenceWalker(
private fun inferPathExprTy(pathExpr: MvPathExpr, expected: Expectation): Ty {

val expectedType = expected.onlyHasTy(ctx)
val item = resolvePathElement(pathExpr, expectedType) ?: return TyUnknown
val item = resolvePathCached(pathExpr.path, expectedType) ?: return TyUnknown

val ty = when (item) {
is MvPatBinding -> ctx.getBindingType(item)
Expand All @@ -334,11 +335,10 @@ class TypeInferenceWalker(
return ty
}

fun resolvePathElement(
pathElement: InferenceCachedPathElement,
fun resolvePathCached(
path: MvPath,
expectedType: Ty?
): MvNamedElement? {
val path = pathElement.path
val resolvedItems = resolvePathRaw(path, expectedType).map { ResolvedItem.from(it, path) }
ctx.writePath(path, resolvedItems)
// resolve aliases
Expand All @@ -353,6 +353,14 @@ class TypeInferenceWalker(
return TyUnit
}

private fun inferIsExprTy(isExpr: MvIsExpr): Ty {
val itemTy = isExpr.expr.inferType()
for (pathType in isExpr.typeList.filterIsInstance<MvPathType>()) {
resolvePathCached(pathType.path, itemTy)
}
return TyBool
}

private fun inferBorrowExprTy(borrowExpr: MvBorrowExpr, expected: Expectation): Ty {
val innerExpr = borrowExpr.expr ?: return TyUnknown
val expectedInnerTy = (expected.onlyHasTy(ctx) as? TyReference)?.referenced
Expand Down Expand Up @@ -386,7 +394,7 @@ class TypeInferenceWalker(

private fun inferCallExprTy(callExpr: MvCallExpr, expected: Expectation): Ty {
val path = callExpr.path
val namedItem = resolvePathElement(callExpr, expectedType = null)
val namedItem = resolvePathCached(path, expectedType = null)
val baseFuncTy =
when (namedItem) {
is MvFunctionLike -> {
Expand Down Expand Up @@ -702,7 +710,7 @@ class TypeInferenceWalker(
val path = litExpr.path
val expectedType = expected.onlyHasTy(ctx)

val item = resolvePathElement(litExpr, expectedType) as? MvFieldsOwner
val item = resolvePathCached(path, expectedType) as? MvFieldsOwner
if (item == null) {
for (field in litExpr.fields) {
field.expr?.inferType()
Expand Down
Loading

0 comments on commit 505651c

Please sign in to comment.