From e591dcc1db376c61233f402759635844e5a50de9 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Mon, 11 Nov 2024 17:42:00 +0100 Subject: [PATCH 1/2] allow explicit type in lambda expr binding list --- src/main/grammars/MoveParser.bnf | 2 +- .../org/move/lang/MoveParserDefinition.kt | 2 +- .../move/lang/parser/CompleteParsingTest.kt | 1 + .../move/lang/parser/complete/lambdas.move | 6 + .../org/move/lang/parser/complete/lambdas.txt | 104 ++++++++++++++++++ 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/org/move/lang/parser/complete/lambdas.move create mode 100644 src/test/resources/org/move/lang/parser/complete/lambdas.txt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 7613bf775..199e93a2a 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -1090,7 +1090,7 @@ upper TupleLitExprUpper ::= ',' [ Expr (',' Expr)* ','? ] ')' { LambdaExpr ::= LambdaParameterList Expr? { pin = 1 } LambdaParameterList ::= '|' !',' <>? '|' -LambdaParameter ::= PatBinding +LambdaParameter ::= PatBinding TypeAscription? RangeExpr ::= Expr '..' Expr { pin = 2 } diff --git a/src/main/kotlin/org/move/lang/MoveParserDefinition.kt b/src/main/kotlin/org/move/lang/MoveParserDefinition.kt index 42ed5bf6a..f664db002 100644 --- a/src/main/kotlin/org/move/lang/MoveParserDefinition.kt +++ b/src/main/kotlin/org/move/lang/MoveParserDefinition.kt @@ -63,6 +63,6 @@ class MoveParserDefinition : ParserDefinition { /** * Should be increased after any change of parser rules */ - const val PARSER_VERSION: Int = LEXER_VERSION + 52 + const val PARSER_VERSION: Int = LEXER_VERSION + 53 } } diff --git a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt index 3590f569c..2534387d6 100644 --- a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt +++ b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt @@ -59,6 +59,7 @@ class CompleteParsingTest: MvParsingTestCase("complete") { fun `test loop invariants`() = doTest() fun `test loop labels`() = doTest() fun `test assign bin expr`() = doTest() + fun `test lambdas`() = doTest() fun doTest() { super.doTest(true, true) diff --git a/src/test/resources/org/move/lang/parser/complete/lambdas.move b/src/test/resources/org/move/lang/parser/complete/lambdas.move new file mode 100644 index 000000000..51e970520 --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/lambdas.move @@ -0,0 +1,6 @@ +module 0x1::lambdas { + fun main() { + for_each(v, |f: &Function| {}); + for_each(v, |i: u8, g: u8| {}); + } +} diff --git a/src/test/resources/org/move/lang/parser/complete/lambdas.txt b/src/test/resources/org/move/lang/parser/complete/lambdas.txt new file mode 100644 index 000000000..16817cd46 --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/lambdas.txt @@ -0,0 +1,104 @@ +FILE + MvModuleImpl(MODULE) + PsiElement(module)('module') + PsiWhiteSpace(' ') + MvAddressRefImpl(ADDRESS_REF) + PsiElement(DIEM_ADDRESS)('0x1') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('lambdas') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('main') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvCallExprImpl(CALL_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('for_each') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvPathExprImpl(PATH_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('v') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvLambdaExprImpl(LAMBDA_EXPR) + MvLambdaParameterListImpl(LAMBDA_PARAMETER_LIST) + PsiElement(|)('|') + MvLambdaParameterImpl(LAMBDA_PARAMETER) + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('f') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Function') + PsiElement(|)('|') + PsiWhiteSpace(' ') + MvCodeBlockExprImpl(CODE_BLOCK_EXPR) + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiElement(})('}') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvCallExprImpl(CALL_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('for_each') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvPathExprImpl(PATH_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('v') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvLambdaExprImpl(LAMBDA_EXPR) + MvLambdaParameterListImpl(LAMBDA_PARAMETER_LIST) + PsiElement(|)('|') + MvLambdaParameterImpl(LAMBDA_PARAMETER) + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('i') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvLambdaParameterImpl(LAMBDA_PARAMETER) + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('g') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(|)('|') + PsiWhiteSpace(' ') + MvCodeBlockExprImpl(CODE_BLOCK_EXPR) + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiElement(})('}') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n') + PsiElement(})('}') \ No newline at end of file From 179ebea56a068ee8115d99a1aed78733a9099b9d Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Mon, 11 Nov 2024 18:21:27 +0100 Subject: [PATCH 2/2] do not show type hint if explicit type is provided --- src/main/grammars/MoveParser.bnf | 16 ++++++- .../docs/MvPsiDocumentationTargetProvider.kt | 19 ++------ .../hints/type/MvTypeInlayHintsProvider2.kt | 46 ++++++++++++++----- .../MvUnresolvedReferenceInspection.kt | 3 +- .../inspections/MvUnusedVariableInspection.kt | 8 ++-- .../move/ide/presentation/PresentationInfo.kt | 4 +- .../move/lang/core/psi/ext/MvBindingPat.kt | 15 +++++- .../core/psi/ext/MvTypeAscriptionOwner.kt | 8 ++++ .../ide/hints/InlayTypeHintsProvider2Test.kt | 41 +++++++++++++++++ 9 files changed, 125 insertions(+), 35 deletions(-) create mode 100644 src/main/kotlin/org/move/lang/core/psi/ext/MvTypeAscriptionOwner.kt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 199e93a2a..ee482d8e6 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -290,6 +290,7 @@ Const ::= Attr* CONST_KW IDENTIFIER TypeAscription Initializer ';' implements = [ "org.move.lang.core.psi.MvQualNamedElement" "org.move.lang.core.psi.ext.MvItemElement" + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] mixin = "org.move.lang.core.psi.ext.MvConstMixin" stubClass = "org.move.lang.core.stubs.MvConstStub" @@ -521,6 +522,9 @@ private FunctionParameter_recover ::= !(')' | '{' | ';' | IDENTIFIER) FunctionParameter ::= PatBinding TypeAscription { pin = 1 + implements = [ + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" + ] mixin = "org.move.lang.core.psi.ext.MvFunctionParameterMixin" } @@ -589,6 +593,7 @@ NamedFieldDecl ::= Attr* IDENTIFIER TypeAscription &(',' | '}') "org.move.lang.core.psi.MvMandatoryNameIdentifierOwner" "org.move.lang.core.psi.ext.MvDocAndAttributeOwner" "org.move.lang.core.psi.ext.MvFieldDecl" + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] mixin = "org.move.lang.core.psi.ext.MvNamedFieldDeclMixin" hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] @@ -819,6 +824,9 @@ private SpecExprStmt_items ::= AssumeSpecExpr | AssertSpecExpr | AbortsIfSpecExp private post ::= <> fake LetStmt ::= let post? Pat? TypeAscription? Initializer? ';'? +{ + implements = [ "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] +} LetMoveStmt ::= let Pat TypeAscription? Initializer? ';' { @@ -1091,6 +1099,9 @@ LambdaExpr ::= LambdaParameterList Expr? { pin = 1 } LambdaParameterList ::= '|' !',' <>? '|' LambdaParameter ::= PatBinding TypeAscription? +{ + implements = [ "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] +} RangeExpr ::= Expr '..' Expr { pin = 2 } @@ -1421,6 +1432,7 @@ ItemSpecFunctionParameter ::= IDENTIFIER TypeAscription { pin = 1 implements = [ "org.move.lang.core.resolve.ref.MvItemSpecParameterReferenceElement" + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] mixin = "org.move.lang.core.psi.ext.MvItemSpecFunctionParameterMixin" } @@ -1484,6 +1496,7 @@ fake SchemaFieldStmt ::= local? PatBinding TypeAscription ';' { implements = [ "org.move.lang.core.psi.MslOnlyElement" + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] } @@ -1505,6 +1518,7 @@ GlobalVariableStmt ::= Attr* global IDENTIFIER TypeParameterList? TypeAscription "org.move.lang.core.psi.MvNameIdentifierOwner" "org.move.lang.core.psi.MslOnlyElement" "org.move.lang.core.psi.ext.MvItemElement" + "org.move.lang.core.psi.ext.MvTypeAscriptionOwner" ] mixin = "org.move.lang.core.psi.ext.MvGlobalVariableMixin" } @@ -1756,7 +1770,7 @@ RangeQuantBinding ::= PatBinding in Expr { pin = 2 extends = QuantBinding } -TypeQuantBinding ::= PatBinding ':' Type { +TypeQuantBinding ::= PatBinding TypeAscription { pin = 2 extends = QuantBinding } diff --git a/src/main/kotlin/org/move/ide/docs/MvPsiDocumentationTargetProvider.kt b/src/main/kotlin/org/move/ide/docs/MvPsiDocumentationTargetProvider.kt index bbf71a944..cc470128c 100644 --- a/src/main/kotlin/org/move/ide/docs/MvPsiDocumentationTargetProvider.kt +++ b/src/main/kotlin/org/move/ide/docs/MvPsiDocumentationTargetProvider.kt @@ -27,16 +27,7 @@ import org.move.lang.core.psi.MvStruct import org.move.lang.core.psi.MvType import org.move.lang.core.psi.MvTypeParameter import org.move.lang.core.psi.MvTypeParameterList -import org.move.lang.core.psi.ext.MvDocAndAttributeOwner -import org.move.lang.core.psi.ext.abilityBounds -import org.move.lang.core.psi.ext.ancestorOrSelf -import org.move.lang.core.psi.ext.bindingOwner -import org.move.lang.core.psi.ext.fieldOwner -import org.move.lang.core.psi.ext.isMsl -import org.move.lang.core.psi.ext.isMslOnlyItem -import org.move.lang.core.psi.ext.isPhantom -import org.move.lang.core.psi.ext.itemElement -import org.move.lang.core.psi.ext.module +import org.move.lang.core.psi.ext.* import org.move.lang.core.psi.isNative import org.move.lang.core.psi.module import org.move.lang.core.types.infer.inference @@ -88,11 +79,11 @@ class MvDocumentationTarget(val element: PsiElement, private val originalElement fun generateDoc(element: PsiElement?): String? { val buffer = StringBuilder() + var docElement = element - if ( - docElement is MvPatBinding && docElement.bindingOwner is MvConst - ) - docElement = docElement.bindingOwner + if (docElement is MvPatBinding && docElement.bindingTypeOwner is MvConst) { + docElement = docElement.bindingTypeOwner + } when (docElement) { is MvNamedAddress -> { diff --git a/src/main/kotlin/org/move/ide/hints/type/MvTypeInlayHintsProvider2.kt b/src/main/kotlin/org/move/ide/hints/type/MvTypeInlayHintsProvider2.kt index 075f09c04..b1f87c946 100644 --- a/src/main/kotlin/org/move/ide/hints/type/MvTypeInlayHintsProvider2.kt +++ b/src/main/kotlin/org/move/ide/hints/type/MvTypeInlayHintsProvider2.kt @@ -5,18 +5,22 @@ import com.intellij.codeInsight.hints.declarative.HintFontSize.ABitSmallerThanIn import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import org.move.ide.presentation.hintText +import org.move.lang.core.psi.MvConst +import org.move.lang.core.psi.MvForIterCondition import org.move.lang.core.psi.MvFunctionParameter +import org.move.lang.core.psi.MvLambdaParameter import org.move.lang.core.psi.MvLetStmt +import org.move.lang.core.psi.MvPat import org.move.lang.core.psi.MvPatBinding +import org.move.lang.core.psi.MvPatField +import org.move.lang.core.psi.MvPatFieldFull +import org.move.lang.core.psi.MvRangeQuantBinding import org.move.lang.core.psi.MvSchemaFieldStmt -import org.move.lang.core.psi.ext.bindingOwner -import org.move.lang.core.psi.ext.endOffset -import org.move.lang.core.psi.ext.hasAncestor -import org.move.lang.core.psi.ext.isMsl -import org.move.lang.core.types.infer.inferenceOwner +import org.move.lang.core.psi.MvTypeQuantBinding +import org.move.lang.core.psi.ext.* import org.move.lang.core.types.infer.inference -import org.move.lang.core.types.ty.* +import org.move.lang.core.types.infer.inferenceOwner +import org.move.lang.core.types.ty.TyUnknown class MvTypeInlayHintsProvider2: InlayHintsProvider { @@ -33,12 +37,32 @@ class MvTypeInlayHintsProvider2: InlayHintsProvider { // skip private variables if (patBinding.name.startsWith("_")) return - // does not show hints for bindings with explicit type annotations - val owner = patBinding.bindingOwner - if (owner is MvFunctionParameter || owner is MvSchemaFieldStmt) return + val parent = patBinding.bindingTypeOwner + when (parent) { + // require explicit type annotations + is MvFunctionParameter, is MvConst, is MvSchemaFieldStmt, is MvTypeQuantBinding -> return + is MvLambdaParameter -> { + // if lambda parameter has explicit type + if (parent.type != null) return + } + is MvPatFieldFull -> { + // skip hints for `field: field_alias` + return + } + is MvLetStmt -> { + // explicit type for let stmt + if (parent.type != null) return + } + is MvPatField -> { + // field shorthand, show type hint + } + is MvForIterCondition, is MvRangeQuantBinding -> { + // show hints for iteration indexes + } + else -> return + } val contextInferenceOwner = patBinding.inferenceOwner() ?: return - val msl = patBinding.isMsl() val ty = contextInferenceOwner.inference(msl).getBindingType(patBinding) if (ty is TyUnknown) return diff --git a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt index 0b87238cf..850e1be80 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt @@ -75,7 +75,8 @@ class MvUnresolvedReferenceInspection: MvLocalInspectionTool() { override fun visitSchemaLitField(field: MvSchemaLitField) { if (field.isShorthand) { val resolvedItems = field.reference.multiResolve() - val fieldBinding = resolvedItems.find { it is MvPatBinding && it.bindingOwner is MvSchemaFieldStmt } + val fieldBinding = resolvedItems + .find { it is MvPatBinding && it.bindingTypeOwner is MvSchemaFieldStmt } if (fieldBinding == null) { holder.registerProblem( field.referenceNameElement, diff --git a/src/main/kotlin/org/move/ide/inspections/MvUnusedVariableInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvUnusedVariableInspection.kt index a035b1740..86c657331 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvUnusedVariableInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvUnusedVariableInspection.kt @@ -6,12 +6,12 @@ import com.intellij.psi.util.descendantsOfType import org.move.ide.inspections.fixes.RemoveParameterFix import org.move.ide.inspections.fixes.RenameFix import org.move.lang.core.psi.* +import org.move.lang.core.psi.ext.bindingTypeOwner import org.move.lang.core.psi.ext.isMsl -import org.move.lang.core.psi.ext.bindingOwner -class MvUnusedVariableInspection : MvLocalInspectionTool() { +class MvUnusedVariableInspection: MvLocalInspectionTool() { override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = - object : MvVisitor() { + object: MvVisitor() { override fun visitLetStmt(o: MvLetStmt) { val bindings = o.pat?.descendantsOfType().orEmpty() for (binding in bindings) { @@ -37,7 +37,7 @@ class MvUnusedVariableInspection : MvLocalInspectionTool() { // filter out #[test] attributes .filter { it.element !is MvAttrItem } if (references.none()) { - val fixes = when (binding.bindingOwner) { + val fixes = when (binding.bindingTypeOwner) { is MvFunctionParameter -> arrayOf( RenameFix(binding, "_$bindingName"), RemoveParameterFix(binding, bindingName) diff --git a/src/main/kotlin/org/move/ide/presentation/PresentationInfo.kt b/src/main/kotlin/org/move/ide/presentation/PresentationInfo.kt index 2c0c08d68..46b30d4eb 100644 --- a/src/main/kotlin/org/move/ide/presentation/PresentationInfo.kt +++ b/src/main/kotlin/org/move/ide/presentation/PresentationInfo.kt @@ -1,7 +1,7 @@ package org.move.ide.presentation import org.move.lang.core.psi.* -import org.move.lang.core.psi.ext.bindingOwner +import org.move.lang.core.psi.ext.bindingTypeOwner class PresentationInfo( val element: MvNamedElement, @@ -16,7 +16,7 @@ val MvNamedElement.presentationInfo: PresentationInfo? val type = when (this) { is MvTypeParameter -> "type parameter" is MvPatBinding -> { - val owner = this.bindingOwner + val owner = this.bindingTypeOwner when (owner) { is MvFunctionParameter -> "value parameter" is MvLetStmt -> "variable" diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvBindingPat.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvBindingPat.kt index 386ed0992..c6cbe2028 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvBindingPat.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvBindingPat.kt @@ -13,12 +13,23 @@ import org.move.lang.core.resolve2.ref.MvBindingPatReferenceImpl import org.move.lang.core.types.ty.Mutability import javax.swing.Icon +// todo: replace with bindingTypeOwner later val MvPatBinding.bindingOwner: PsiElement? get() = PsiTreeUtil.findFirstParent(this) { it is MvLetStmt || it is MvFunctionParameter || it is MvSchemaFieldStmt || it is MvLambdaParameter + || it is MvConst + } + +val MvPatBinding.bindingTypeOwner: PsiElement? + get() { + var owner = this.parent + if (owner is MvPat) { + owner = this.findFirstParent { it is MvTypeAscriptionOwner } + } + return owner } sealed class RsBindingModeKind { @@ -45,14 +56,14 @@ abstract class MvPatBindingMixin(node: ASTNode) : MvMandatoryNameIdentifierOwner override val referenceName: String get() = name override fun getIcon(flags: Int): Icon = - when (this.bindingOwner) { + when (this.bindingTypeOwner) { is MvFunctionParameter -> MoveIcons.PARAMETER is MvConst -> MoveIcons.CONST else -> MoveIcons.VARIABLE } override fun getUseScope(): SearchScope { - return when (this.bindingOwner) { + return when (this.bindingTypeOwner) { is MvFunctionParameter -> { val function = this.ancestorStrict() ?: return super.getUseScope() var combinedScope: SearchScope = LocalSearchScope(function) diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeAscriptionOwner.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeAscriptionOwner.kt new file mode 100644 index 000000000..a53694174 --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeAscriptionOwner.kt @@ -0,0 +1,8 @@ +package org.move.lang.core.psi.ext + +import org.move.lang.core.psi.MvElement +import org.move.lang.core.psi.MvType + +interface MvTypeAscriptionOwner: MvElement { + val type: MvType? +} \ No newline at end of file diff --git a/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt b/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt index 168f6cbbe..529cc9a40 100644 --- a/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt +++ b/src/test/kotlin/org/move/ide/hints/InlayTypeHintsProvider2Test.kt @@ -127,6 +127,47 @@ class InlayTypeHintsProvider2Test: DeclarativeInlayHintsProviderTestCase() { } """) + fun `test no inlay hint if explicit lambda param declared`() = checkByText(""" + module 0x1::m { + fun callback(elem: u8, ident: |u8|u8): u8 { ident(elem) } + fun main() { + callback(10, |elem: u8| elem + 1); + } + } + """) + + fun `test no inlay hint if explicit let type`() = checkByText(""" + module 0x1::m { + fun main() { + let a: u8 = 1; + } + } + """) + + fun `test no inlay hints for struct pattern destructor`() = checkByText(""" + module 0x1::m { + struct S { val: u8 } + fun main(s: S) { + let S { val: myval } = s; + } + } + """) + + fun `test inlay hints for struct pattern destructor shorthand`() = checkByText(""" + module 0x1::m { + struct S { val: u8 } + fun main(s: S) { + let S { val/*<# : |u8 #>*/ } = s; + } + } + """) + + fun `test no inlay hint for const`() = checkByText(""" + module 0x1::m { + const MY_CONST: u8 = 1; + } + """) + private fun checkByText(@Language("Move") code: String) { doTestProvider("main.move", code, MvTypeInlayHintsProvider2()) }