diff --git a/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt b/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt index 34a9c0298..e44cfd5db 100644 --- a/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt +++ b/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt @@ -61,7 +61,7 @@ class MvProjectSettingsService( var dumpStateOnTestFailure: Boolean by property(false) @AffectsHighlighting - var enableMove2: Boolean by property(false) + var enableMove2: Boolean by property(true) override fun copy(): MoveProjectSettings { val state = MoveProjectSettings() diff --git a/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt b/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt index 599071e9a..72c286b9e 100644 --- a/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt +++ b/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt @@ -20,7 +20,6 @@ class MvSyntaxErrorAnnotator: MvAnnotatorBase() { val visitor = object: MvVisitor() { override fun visitLitExpr(expr: MvLitExpr) = checkLitExpr(moveHolder, expr) - override fun visitCastExpr(expr: MvCastExpr) = checkCastExpr(moveHolder, expr) override fun visitFunction(o: MvFunction) = checkFunction(moveHolder, o) override fun visitSpecFunction(o: MvSpecFunction) = checkSpecFunction(moveHolder, o) override fun visitIndexExpr(o: MvIndexExpr) = checkIndexExpr(moveHolder, o) @@ -74,15 +73,6 @@ class MvSyntaxErrorAnnotator: MvAnnotatorBase() { } } - private fun checkCastExpr(holder: MvAnnotationHolder, castExpr: MvCastExpr) { - val parent = castExpr.parent - if (parent !is MvParensExpr) { - Diagnostic - .ParensAreRequiredForCastExpr(castExpr) - .addToHolder(holder) - } - } - private fun checkIndexExpr(holder: MvAnnotationHolder, indexExpr: MvIndexExpr) { // always supported in specs if (indexExpr.isMsl()) return diff --git a/src/main/kotlin/org/move/ide/annotator/externalLinter/RsExternalLinterUtils.kt b/src/main/kotlin/org/move/ide/annotator/externalLinter/RsExternalLinterUtils.kt index f762789b9..304d7deb4 100644 --- a/src/main/kotlin/org/move/ide/annotator/externalLinter/RsExternalLinterUtils.kt +++ b/src/main/kotlin/org/move/ide/annotator/externalLinter/RsExternalLinterUtils.kt @@ -48,7 +48,7 @@ import java.util.concurrent.CompletableFuture object RsExternalLinterUtils { private val LOG: Logger = logger() - const val APTOS_TEST_MESSAGE: String = "RsExternalLint" + const val APTOS_TEST_MESSAGE: String = "MvExternalLint" /** * Returns (and caches if absent) lazily computed messages from external linter. diff --git a/src/main/kotlin/org/move/ide/annotator/fixes/WrapWithParensExprFix.kt b/src/main/kotlin/org/move/ide/annotator/fixes/WrapWithParensExprFix.kt deleted file mode 100644 index 847a12650..000000000 --- a/src/main/kotlin/org/move/ide/annotator/fixes/WrapWithParensExprFix.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.move.ide.annotator.fixes - -import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo -import com.intellij.codeInspection.ProblemDescriptor -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiFile -import org.move.ide.inspections.DiagnosticIntentionFix -import org.move.lang.core.psi.* - -class WrapWithParensExprFix(castExpr: MvCastExpr) : DiagnosticIntentionFix(castExpr) { - override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo = - IntentionPreviewInfo.EMPTY - - override fun getFamilyName(): String = "Wrap cast with ()" - override fun getText(): String = "Wrap cast with ()" - - override fun stillApplicable(project: Project, file: PsiFile, element: MvCastExpr): Boolean = - element.parent !is MvParensExpr - - override fun invoke(project: Project, file: PsiFile, element: MvCastExpr) { - val psiFactory = project.psiFactory - wrapWithParensExpr(psiFactory, element) - } -} - -private fun wrapWithParensExpr(psiFactory: MvPsiFactory, expr: MvExpr): MvParensExpr { - val parensExpr = psiFactory.wrapWithParens(expr) - return expr.replace(parensExpr) as MvParensExpr -} diff --git a/src/main/kotlin/org/move/ide/hints/type/MvTypeHintsFactory.kt b/src/main/kotlin/org/move/ide/hints/type/MvTypeHintsFactory.kt index e4b58f3b6..4b2e5d5ea 100644 --- a/src/main/kotlin/org/move/ide/hints/type/MvTypeHintsFactory.kt +++ b/src/main/kotlin/org/move/ide/hints/type/MvTypeHintsFactory.kt @@ -7,6 +7,7 @@ import com.intellij.psi.createSmartPointer import org.move.ide.presentation.hintText import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyAdt +import org.move.lang.core.types.ty.TyReference import org.move.lang.core.types.ty.TyTuple import org.move.lang.core.types.ty.TyVector @@ -23,6 +24,7 @@ object MvTypeHintsFactory { is TyTuple -> tupleTypeHint(level, type) is TyAdt -> adtTypeHint(level, type) is TyVector -> vectorTypeHint(level, type) + is TyReference -> referenceTypeHint(level, type) else -> { text(type.hintText()) } @@ -90,6 +92,11 @@ object MvTypeHintsFactory { }) } + private fun PresentationTreeBuilder.referenceTypeHint(level: Int, tyRef: TyReference) { + text(if (tyRef.isMut) "&mut " else "&") + typeHint(level, tyRef.referenced) + } + private fun PresentationTreeBuilder.join( elements: List, op: PresentationTreeBuilder.(T) -> Unit, diff --git a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt index 69bf5a88a..432ed679d 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt @@ -118,7 +118,7 @@ class MvUnresolvedReferenceInspection: MvLocalInspectionTool() { if (msl && !isDebugModeEnabled()) return // no error if receiver item is unknown (won't proc if unknown is nested) - if (methodOrField.inferReceiverTy(msl) is TyUnknown) return + if (methodOrField.inferReceiverTy(msl).derefIfNeeded() is TyUnknown) return tryMultiResolveOrRegisterError(methodOrField, holder) } diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/CommonCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/CommonCompletionProvider.kt index 6dbb4bf42..5d84c1ac3 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/CommonCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/CommonCompletionProvider.kt @@ -85,12 +85,14 @@ object CommonCompletionProvider: MvCompletionProvider() { @VisibleForTesting fun addMethodOrFieldVariants(element: MvMethodOrField, result: CompletionResultSet, ctx: MvCompletionContext) { - val receiverTy = element.inferReceiverTy(ctx.msl).knownOrNull() ?: return + val receiverTy = element.inferReceiverTy(ctx.msl) + // unknown, &unknown, &mut unknown + if (receiverTy.derefIfNeeded() is TyUnknown) return val tyAdt = receiverTy.derefIfNeeded() as? TyAdt if (tyAdt != null) { collectCompletionVariants(result, ctx, subst = tyAdt.substitution) { - processFieldLookupResolveVariants(element, tyAdt, ctx.msl, it) + processFieldLookupResolveVariants(element, tyAdt.item, ctx.msl, it) } } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvPath.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvPath.kt index 4de0e7435..66b7e7c6b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvPath.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvPath.kt @@ -123,6 +123,9 @@ fun MvPath.allowedNamespaces(isCompletion: Boolean = false): Set { parent is MvCallExpr -> FUNCTIONS parent is MvPathExpr && this.hasAncestor() -> ALL_NAMESPACES + // TYPES for resource indexing, NAMES for vector indexing + parent is MvPathExpr + && parent.parent is MvIndexExpr -> TYPES_N_ENUMS_N_NAMES // can be anything in completion parent is MvPathExpr -> if (isCompletion) ALL_NAMESPACES else NAMES diff --git a/src/main/kotlin/org/move/lang/core/resolve/ref/Namespace.kt b/src/main/kotlin/org/move/lang/core/resolve/ref/Namespace.kt index 536227192..21910378d 100644 --- a/src/main/kotlin/org/move/lang/core/resolve/ref/Namespace.kt +++ b/src/main/kotlin/org/move/lang/core/resolve/ref/Namespace.kt @@ -42,10 +42,9 @@ val ENUMS = setOf(Namespace.ENUM) val LABELS = setOf(Namespace.LABEL) val TYPES_N_ENUMS = setOf(Namespace.TYPE, Namespace.ENUM) -val TYPES_N_NAMES = setOf(Namespace.TYPE, Namespace.NAME) +val TYPES_N_ENUMS_N_NAMES = setOf(Namespace.TYPE, Namespace.NAME, Namespace.ENUM) val ENUMS_N_MODULES = setOf(Namespace.ENUM, Namespace.MODULE) val TYPES_N_ENUMS_N_MODULES = setOf(Namespace.TYPE, Namespace.ENUM, Namespace.MODULE) -//val TYPES_N_ENUMS_N_MODULES_N_NAMES = setOf(Namespace.TYPE, Namespace.ENUM, Namespace.MODULE, Namespace.NAME) val ALL_NAMESPACES = Namespace.all() val ITEM_NAMESPACES = diff --git a/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt b/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt index 34d855a31..e401240de 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt @@ -9,9 +9,9 @@ import org.move.lang.core.psi.ext.* import org.move.lang.core.resolve.* import org.move.lang.core.resolve.LetStmtScope.* import org.move.lang.core.resolve.ref.ENUMS +import org.move.lang.core.resolve.ref.NAMES import org.move.lang.core.resolve.ref.NONE import org.move.lang.core.resolve.ref.Namespace -import org.move.lang.core.resolve.ref.Namespace.NAME import org.move.lang.core.resolve.ref.TYPES import org.move.lang.core.resolve2.ref.ResolutionContext import org.move.lang.core.resolve2.util.forEachLeafSpeck @@ -29,18 +29,15 @@ fun processItemsInScope( for (namespace in ns) { val elementNs = setOf(namespace) val stop = when (namespace) { - NAME -> { + Namespace.NAME -> { val found = when (scope) { is MvModule -> { // try enum variants first - if (processor.processAll(elementNs, scope.enumVariants())) return true - processor.processAllItems( - elementNs, - scope.structs(), - scope.consts() - ) + if (processor.processAll(elementNs, scope.enumVariants())) { + return true + } + processor.processAllItems(elementNs, scope.constList) } - is MvModuleSpecBlock -> processor.processAllItems(elementNs, scope.schemaList) is MvScript -> processor.processAllItems(elementNs, scope.constList) is MvFunctionLike -> processor.processAll(elementNs, scope.parametersAsBindings) is MvLambdaExpr -> processor.processAll(elementNs, scope.parametersAsBindings) diff --git a/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt b/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt index 791d482fd..05e3d3599 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt @@ -1,6 +1,5 @@ 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.* @@ -15,11 +14,10 @@ import org.move.lang.index.MvModuleIndex fun processFieldLookupResolveVariants( fieldLookup: MvMethodOrField, - receiverTy: TyAdt, + receiverItem: MvStructOrEnumItemElement, msl: Boolean, originalProcessor: RsResolveProcessorBase ): Boolean { - val receiverItem = receiverTy.item if (!isFieldsAccessible(fieldLookup, receiverItem, msl)) return false val processor = originalProcessor diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TypeInferenceWalker.kt b/src/main/kotlin/org/move/lang/core/types/infer/TypeInferenceWalker.kt index 5714d3051..b1ff308e8 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TypeInferenceWalker.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TypeInferenceWalker.kt @@ -316,7 +316,7 @@ class TypeInferenceWalker( is MvConst -> item.type?.loweredType(msl) ?: TyUnknown is MvGlobalVariableStmt -> item.type?.loweredType(true) ?: TyUnknown is MvNamedFieldDecl -> item.type?.loweredType(msl) ?: TyUnknown - is MvStruct -> { + is MvStruct, is MvEnum -> { if (project.moveSettings.enableIndexExpr && pathExpr.parent is MvIndexExpr) { TyLowering().lowerPath(pathExpr.path, item, ctx.msl) } else { @@ -324,7 +324,14 @@ class TypeInferenceWalker( TyUnknown } } - is MvEnumVariant -> TyLowering().lowerPath(pathExpr.path, item, ctx.msl) + is MvEnumVariant -> { + // MyEnum::MyVariant + // ^ we need this path to be able to handle explicit type parameters + val enumItemPath = pathExpr.path.qualifier ?: pathExpr.path + val baseTy = instantiatePath(enumItemPath, item.enumItem) + ?: return TyUnknown + baseTy + } is MvModule -> TyUnknown else -> debugErrorOrFallback( "Referenced item ${item.elementType} " + @@ -458,7 +465,7 @@ class TypeInferenceWalker( val field = resolveSingleResolveVariant(fieldLookup.referenceName) { - processFieldLookupResolveVariants(fieldLookup, tyAdt, msl, it) + processFieldLookupResolveVariants(fieldLookup, tyAdt.item, msl, it) } as? MvFieldDecl ctx.resolvedFields[fieldLookup] = field @@ -552,11 +559,12 @@ class TypeInferenceWalker( @Suppress("UNCHECKED_CAST") val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericItem, msl) as? T ?: return null + val typeParamToVarSubst = genericItem.tyVarsSubst - val tyVarsSubst = genericItem.tyVarsSubst - @Suppress("UNCHECKED_CAST") // TyTypeParameter -> TyVar for every TypeParameter which is not explicit set - return explicitPathTy.substitute(tyVarsSubst) as T + @Suppress("UNCHECKED_CAST") + val explicitPathTyWithTyVars = explicitPathTy.substitute(typeParamToVarSubst) as T + return explicitPathTyWithTyVars } @Suppress("UNCHECKED_CAST") @@ -714,8 +722,6 @@ class TypeInferenceWalker( val genericItem = if (item is MvEnumVariant) item.enumItem else (item as MvStruct) val (tyAdt, tyVarsSubst) = instantiateMethodOrPath(path, genericItem) ?: return TyUnknown -// val tyAdt = instantiatePath(path, genericItem) ?: return TyUnknown -// val tyVarsSubst = genericItem.typeParamsToTyVarsSubst expectedType?.let { expectedTy -> val expectedTyTypeParams = expectedTy.typeParameterValues @@ -811,7 +817,7 @@ class TypeInferenceWalker( return TyUnknown } - val derefTy = receiverTy.derefIfNeeded() + val derefTy = this.resolveTypeVarsIfPossible(receiverTy).derefIfNeeded() return when { derefTy is TyVector -> { // argExpr can be either TyInteger or TyRange @@ -829,7 +835,10 @@ class TypeInferenceWalker( receiverTy } else -> { - ctx.reportTypeError(TypeError.IndexingIsNotAllowed(indexExpr.receiverExpr, receiverTy)) + if (receiverTy !is TyUnknown) { + // unresolved item + ctx.reportTypeError(TypeError.IndexingIsNotAllowed(indexExpr.receiverExpr, receiverTy)) + } TyUnknown } } diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyAdt.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyAdt.kt index 8cada9887..2a5b38593 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyAdt.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyAdt.kt @@ -42,7 +42,6 @@ data class TyAdt( val typeParameters = struct.typeParamsToTypeParamsSubst return TyAdt( struct, -// CompletionUtil.getOriginalOrSelf(struct), typeParameters, struct.tyTypeParams ) diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyTypeParameter.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyTypeParameter.kt index aca9c362b..2b20b98ab 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyTypeParameter.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyTypeParameter.kt @@ -33,7 +33,6 @@ class TyTypeParameter private constructor( companion object { fun named(parameter: MvTypeParameter): TyTypeParameter { // Treat the same parameters from original/copy files as equals -// val originalParameter = parameter val originalParameter = CompletionUtil.getOriginalOrSelf(parameter) return TyTypeParameter(originalParameter) } diff --git a/src/main/kotlin/org/move/lang/utils/Diagnostic.kt b/src/main/kotlin/org/move/lang/utils/Diagnostic.kt index be87cf496..f00a45d5a 100644 --- a/src/main/kotlin/org/move/lang/utils/Diagnostic.kt +++ b/src/main/kotlin/org/move/lang/utils/Diagnostic.kt @@ -12,8 +12,6 @@ import com.intellij.openapi.util.text.StringUtil.pluralize import com.intellij.psi.PsiElement import org.move.ide.annotator.MvAnnotationHolder import org.move.ide.annotator.fixes.ItemSpecSignatureFix -import org.move.ide.annotator.fixes.WrapWithParensExprFix -import org.move.ide.annotator.pluralise import org.move.ide.inspections.fixes.EnableMoveV2Fix import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* @@ -144,26 +142,6 @@ sealed class Diagnostic( } } - class ParensAreRequiredForCastExpr(castExpr: MvCastExpr): Diagnostic(castExpr) { - override fun prepare(): PreparedAnnotation { - val castExpr = element as MvCastExpr - return PreparedAnnotation( - ERROR, - "Parentheses are required for the cast expr", - fixes = listOf(WrapWithParensExprFix(castExpr)) - ) - } - } - -// class NativeStructNotSupported(struct: MvStruct, errorRange: TextRange): Diagnostic(struct, errorRange) { -// override fun prepare(): PreparedAnnotation { -// return PreparedAnnotation( -// ERROR, -// "Native structs aren't supported by the Move VM anymore" -// ) -// } -// } - class SpecFunctionRequiresReturnType(specFunction: MvSpecFunction): Diagnostic( specFunction, diff --git a/src/test/kotlin/org/move/cli/externalLinter/MvExternalLinterPassTest.kt b/src/test/kotlin/org/move/cli/externalLinter/MvExternalLinterPassTest.kt index a41d27ec4..cf4f580d5 100644 --- a/src/test/kotlin/org/move/cli/externalLinter/MvExternalLinterPassTest.kt +++ b/src/test/kotlin/org/move/cli/externalLinter/MvExternalLinterPassTest.kt @@ -32,7 +32,7 @@ class MvExternalLinterPassTest: WithAptosCliTestBase( """ module 0x1::main { fun main() { - 1 + /*caret*/true + 1 + /*caret*/true; } } """, externalLinter = ExternalLinter.LINTER diff --git a/src/test/kotlin/org/move/ide/annotator/HighlightingAnnotatorTest.kt b/src/test/kotlin/org/move/ide/annotator/HighlightingAnnotatorTest.kt index 703971cf8..e4a4ffd64 100644 --- a/src/test/kotlin/org/move/ide/annotator/HighlightingAnnotatorTest.kt +++ b/src/test/kotlin/org/move/ide/annotator/HighlightingAnnotatorTest.kt @@ -335,6 +335,7 @@ class HighlightingAnnotatorTest: AnnotatorTestCase(HighlightingAnnotator::class) """ ) + @MoveV2(false) fun `test do not highlight methods if compiler v1`() = checkHighlighting( """ module 0x1::m { diff --git a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/RequiredParensForCastExprErrorTest.kt b/src/test/kotlin/org/move/ide/annotator/syntaxErrors/RequiredParensForCastExprErrorTest.kt deleted file mode 100644 index 756803d20..000000000 --- a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/RequiredParensForCastExprErrorTest.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.move.ide.annotator.syntaxErrors - -import org.move.ide.annotator.MvSyntaxErrorAnnotator -import org.move.utils.tests.annotation.AnnotatorTestCase - -class RequiredParensForCastExprErrorTest : AnnotatorTestCase(MvSyntaxErrorAnnotator::class) { - fun `test cast expr in parens`() = checkErrors( - """ -module 0x1::main { - fun main() { - let a = 1; - (a as u64); - } -} - """ - ) - - fun `test error if cast expr without parens`() = checkErrors( - """ -module 0x1::main { - fun main() { - let a = 1; - a as u64; - } -} - """ - ) - - fun `test error if complex cast expr without parens`() = checkErrors( - """ -module 0x1::main { - fun main() { - let a = 1; - (a.b.c + 1) as u64; - } -} - """ - ) - - fun `test cast inside other expr`() = checkErrors( - """ -module 0x1::main { - fun main() { - let a = 1; - 1 + a as u64; - } -} - """ - ) -} diff --git a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/fixes/WrapCastExprWithParensFixTest.kt b/src/test/kotlin/org/move/ide/annotator/syntaxErrors/fixes/WrapCastExprWithParensFixTest.kt deleted file mode 100644 index 234545efb..000000000 --- a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/fixes/WrapCastExprWithParensFixTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.move.ide.annotator.syntaxErrors.fixes - -import org.move.ide.annotator.MvSyntaxErrorAnnotator -import org.move.utils.tests.annotation.AnnotatorTestCase - -class WrapCastExprWithParensFixTest : AnnotatorTestCase(MvSyntaxErrorAnnotator::class) { - fun `test error if cast expr without parens`() = checkFixByText( - "Wrap cast with ()", - """ -module 0x1::main { - fun main() { - let a = 1; - a /*caret*/as u64; - } -} - """, - """ -module 0x1::main { - fun main() { - let a = 1; - (a as u64); - } -} - """, - ) - - fun `test wrap cast of binary expr`() = checkFixByText( - "Wrap cast with ()", - """ -module 0x1::main { - fun main() { - let a = 1; - 1 + 1 + a /*caret*/as u64; - } -} - """, - """ -module 0x1::main { - fun main() { - let a = 1; - (1 + 1 + a as u64); - } -} - """, - ) -} diff --git a/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt b/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt index 529cc9a40..3c6f3613d 100644 --- a/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt +++ b/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt @@ -168,6 +168,27 @@ class InlayTypeHintsProvider2Test: DeclarativeInlayHintsProviderTestCase() { } """) + fun `test inlay type hint for complex field of enum type of resource index expr`() = checkByText( + """ + module 0x1::m { + struct BigOrderedMap has store { } + struct Any has drop, store, copy { } + struct StoredPermission has store, copy, drop { } + enum PermissionStorage has key { + V1 { + perms: BigOrderedMap + } + } + fun main() { + let storage1/*<# : |&mut |PermissionStorage #>*/ = borrow_global_mut(@0x1); + let s/*<# : |&mut |BigOrderedMap|<...> #>*/ = &mut storage1.perms; + + let storage2/*<# : |&mut |PermissionStorage #>*/ = &mut PermissionStorage[@0x1]; + } + } + """ + ) + private fun checkByText(@Language("Move") code: String) { doTestProvider("main.move", code, MvTypeInlayHintsProvider2()) } diff --git a/src/test/kotlin/org/move/ide/inspections/MvMissingAcquiresInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/MvMissingAcquiresInspectionTest.kt index 7453ced3e..87861cefc 100644 --- a/src/test/kotlin/org/move/ide/inspections/MvMissingAcquiresInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/MvMissingAcquiresInspectionTest.kt @@ -210,6 +210,7 @@ module 0x1::main { } """) + @MoveV2(false) fun `test no error with index if unsupported`() = checkErrors( """ module 0x1::M { diff --git a/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt index 1bcb8baa5..7ca62c45a 100644 --- a/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt @@ -1,5 +1,6 @@ package org.move.ide.inspections +import org.move.utils.tests.MoveV2 import org.move.utils.tests.annotation.InspectionTestBase class MvTypeCheckInspectionTest: InspectionTestBase(MvTypeCheckInspection::class) { @@ -1558,9 +1559,40 @@ module 0x1::pool { } """) + @MoveV2 fun `test circular type for enum`() = checkByText(""" module 0x1::m { enum S { One { s: S }, Two } } """) + + @MoveV2 + fun `test return enum value from function`() = checkByText(""" + module 0x1::m { + enum Iterator { Empty, Some { item: u8 } } + fun create_iterator(): Iterator { + Iterator::Empty + } + } + """) + + @MoveV2 + fun `test return struct empty enum value from function`() = checkByText(""" + module 0x1::m { + struct Iterator { val: u8 } + fun create_iterator(): Iterator { + Iterator { val: 1 } + } + } + """) + + @MoveV2 + fun `test return generic empty enum value from function`() = checkByText(""" + module 0x1::m { + enum Iterator { Empty, Some { item: IterT } } + fun create_iterator(): Iterator { + Iterator::Empty + } + } + """) } diff --git a/src/test/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspectionTest.kt index 3a5566305..92d53fffd 100644 --- a/src/test/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspectionTest.kt @@ -355,12 +355,12 @@ module 0x1::main { } """) - fun `test error for field of reference of unknown type`() = checkByText(""" + fun `test no error for field of reference of unknown type`() = checkByText(""" module 0x1::main { fun call(t: T): &T { &t } fun main() { let var = &(1 + false); - var.key; + var.key; } } """) @@ -519,25 +519,14 @@ module 0x1::m { } """) - @MoveV2() - fun `test unresolved method error if receiver is unresolved`() = checkByText(""" - module 0x1::m { - struct S { field: u8 } - fun receiver(self: S): u8 { self.field } - fun main() { - (&t).receiver(); - } - } - """) - - @MoveV2() - fun `test unresolved method error if receiver is type unknown`() = checkByText(""" + @MoveV2 + fun `test no error if receiver is type unknown`() = checkByText(""" module 0x1::m { struct S { field: u8 } fun receiver(self: S): u8 { self.field } fun main() { let t = &(1 + false); - t.receiver(); + t.receiver(); } } """) @@ -569,4 +558,22 @@ module 0x1::m { fun main() {} } """) + + fun `test no error for unknown receiver method of result of unknown resource borrow`() = checkByText(""" + module 0x1::m { + fun main() { + let perm_storage = &PermissionStorage[@0x1]; + perm_storage.contains(); + } + } + """) + + fun `test no error for unknown receiver method of result of unknown mut resource borrow`() = checkByText(""" + module 0x1::m { + fun main() { + let perm_storage = &mut PermissionStorage[@0x1]; + perm_storage.contains(); + } + } + """) } diff --git a/src/test/kotlin/org/move/ide/inspections/MvUnusedAcquiresTypeInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/MvUnusedAcquiresTypeInspectionTest.kt index 67237b508..d80b5d292 100644 --- a/src/test/kotlin/org/move/ide/inspections/MvUnusedAcquiresTypeInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/MvUnusedAcquiresTypeInspectionTest.kt @@ -150,6 +150,7 @@ module 0x1::main { """ ) + @MoveV2(false) fun `test unused acquires with index expr on compiler v1`() = checkWarnings( """ module 0x1::main { diff --git a/src/test/kotlin/org/move/ide/inspections/compilerV2/TypeCheckIndexExprTest.kt b/src/test/kotlin/org/move/ide/inspections/compilerV2/TypeCheckIndexExprTest.kt index b7190e7b7..dfcc20279 100644 --- a/src/test/kotlin/org/move/ide/inspections/compilerV2/TypeCheckIndexExprTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/compilerV2/TypeCheckIndexExprTest.kt @@ -85,4 +85,26 @@ class TypeCheckIndexExprTest: InspectionTestBase(MvTypeCheckInspection::class) { } """ ) + + fun `test no error for vector reference that is result of function call`() = checkByText( + """ + module 0x1::m { + fun call(): &vector { &vector[1] } + enum BigOrderedMap has store { BPlusTreeMap } + public native fun borrow(self: &BigOrderedMap, key: &K): &V; + fun main() { + let map = BigOrderedMap, vector>::BPlusTreeMap; + borrow(&map, &vector[1])[0]; + } + } + """ + ) + + fun `test no error for resource indexing expr of unknown type`() = checkByText(""" + module 0x1::m { + fun main() { + &mut PermissionStorage[addr]; + } + } + """) } \ No newline at end of file diff --git a/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt b/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt index e4a362eaf..07d6da834 100644 --- a/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt +++ b/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt @@ -87,7 +87,7 @@ module 0x1::M { """) fun `test no duplicate completions for enum variant fields`() = checkContainsCompletionExact( - listOf("field_x", "field_y", "field_z"), + listOf("field_x", "field_y", "field_z", "t9_common_field"), """ module 0x1::m { enum CommonFields { diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt index 1bf921359..f3402fa8b 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt @@ -933,4 +933,28 @@ module 0x1::m { } } """) + + @MoveV2 + fun `test resolve enum item of resource index expr`() = checkByCode(""" + module 0x1::m { + enum Ss has key { Empty } + //X + fun main() { + &mut Ss[@0x1]; + //^ + } + } + """) + + @MoveV2 + fun `test resolve struct item of resource index expr`() = checkByCode(""" + module 0x1::m { + struct Ss has key { val: u8 } + //X + fun main() { + &mut Ss[@0x1]; + //^ + } + } + """) } diff --git a/src/test/kotlin/org/move/lang/resolve/compilerV2/ReceiverStyleFunctionTest.kt b/src/test/kotlin/org/move/lang/resolve/compilerV2/ReceiverStyleFunctionTest.kt index b57d32df9..1282be2c9 100644 --- a/src/test/kotlin/org/move/lang/resolve/compilerV2/ReceiverStyleFunctionTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/compilerV2/ReceiverStyleFunctionTest.kt @@ -265,4 +265,24 @@ class ReceiverStyleFunctionTest: ResolveTestCase() { } } """) + + @MoveV2 + fun `test enum with receiver function from a call expr`() = checkByCode(""" + module 0x1::m { + enum Ordering has copy, drop { + Less, + Equal, + Greater, + } + native public fun compare(first: &T, second: &T): Ordering; + public fun is_eq(self: &Ordering): bool { + //X + self is Ordering::Equal + } + fun main() { + compare(&1, &1).is_eq(); + //^ + } + } + """) } \ No newline at end of file diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt index fa0c97536..9f7a71e6a 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt @@ -2190,7 +2190,7 @@ module 0x1::main { @MoveV2 fun `test generic enum variant`() = testExpr(""" module 0x1::m { - enum S { One } + enum S { One } fun main() { let a = S::One; a; @@ -2252,6 +2252,7 @@ module 0x1::main { } } """) + fun `test tuple enum variant destructuring for unknown type`() = testExpr(""" module 0x1::m { enum S {} @@ -2262,4 +2263,32 @@ module 0x1::main { } } """) + + @MoveV2 + fun `test infer generic enum call expr type`() = testExpr( + """ + module 0x1::m { + enum BigOrderedMap has store { BPlusTreeMap } + public native fun borrow(self: &BigOrderedMap, key: &K): &V; + fun main() { + let map = BigOrderedMap, vector>::BPlusTreeMap; + borrow(&map, &vector[1]); + //^ &vector + } + } + """ + ) + + @MoveV2 + fun `test infer index expr of generic call expr`() = testExpr( + """ + module 0x1::m { + fun identity(t: T): T { t } + fun main() { + (identity(vector[1])[0]); + //^ integer + } + } + """ + ) } diff --git a/src/test/resources/org/move/cli/producers.fixtures/test/run_tests_for_file_with_multiple_module_single_test_module.xml b/src/test/resources/org/move/cli/producers.fixtures/test/run_tests_for_file_with_multiple_module_single_test_module.xml index ee8001009..7e4f0af67 100644 --- a/src/test/resources/org/move/cli/producers.fixtures/test/run_tests_for_file_with_multiple_module_single_test_module.xml +++ b/src/test/resources/org/move/cli/producers.fixtures/test/run_tests_for_file_with_multiple_module_single_test_module.xml @@ -1,6 +1,6 @@ -