diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 66d2543ac..e939f1934 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -596,9 +596,15 @@ private TypeParamBound_items ::= Ability ( '+' Ability )* } private TypeParamBound_items_recover ::= !('>' | ',') -TypeArgumentList ::= '<' !'=' <'))>>? '>' { +TypeArgumentList ::= TypeArgumentListImpl { name = "type arguments" } +ColonTypeArgumentList ::= &'::' TypeArgumentListImpl { elementType = TypeArgumentList } + +//private TypeArgumentListImpl ::= '::'? '<' !'=' TypeArgumentImpl* '>' { pin = 3 } +//private TypeArgumentImpl ::= !'>' TypeArgument (',' | &'>') { pin = 2 } +private TypeArgumentListImpl ::= '::'? '<' !'=' <') )>>? '>' + TypeArgument ::= Type /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -989,7 +995,7 @@ StructDotField ::= IDENTIFIER !('(' | '::' | '!' | '{') implements = ["org.move.lang.core.psi.ext.MvMethodOrField"] mixin = "org.move.lang.core.psi.ext.MvStructDotFieldMixin" } -MethodCall ::= IDENTIFIER TypeArgumentList? ValueArgumentList +MethodCall ::= IDENTIFIER ColonTypeArgumentList? ValueArgumentList { implements = [ "org.move.lang.core.psi.ext.MvMethodOrField" @@ -1530,3 +1536,4 @@ private lt_eqeq_gt ::= <> private dotdot ::= <> private meta non_empty_comma_sep_items ::= <> ( ',' <> )* ','? +private meta list_element ::= !'>' <> (',' | &'>') { pin = 2 } diff --git a/src/main/kotlin/org/move/ide/inspections/fixes/ReplaceWithMethodCallFix.kt b/src/main/kotlin/org/move/ide/inspections/fixes/ReplaceWithMethodCallFix.kt index 303b32193..1c6f38885 100644 --- a/src/main/kotlin/org/move/ide/inspections/fixes/ReplaceWithMethodCallFix.kt +++ b/src/main/kotlin/org/move/ide/inspections/fixes/ReplaceWithMethodCallFix.kt @@ -4,7 +4,9 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile import org.move.ide.inspections.DiagnosticFix import org.move.lang.core.psi.* +import org.move.lang.core.psi.ext.typeArguments import org.move.lang.core.psi.ext.valueArguments +import org.move.stdext.notEmptyOrLet class ReplaceWithMethodCallFix(callExpr: MvCallExpr): DiagnosticFix(callExpr) { override fun getText(): String = "Replace with method call" @@ -38,12 +40,18 @@ class ReplaceWithMethodCallFix(callExpr: MvCallExpr): DiagnosticFix( } } - val dotExpr = psiFactory.expr("1.${element.path.referenceName}()") + val fakeTypeArgs = + element.path.typeArguments.map { "T" }.toList() + .notEmptyOrLet { listOf("T") }.joinToString(", ") + val dotExpr = psiFactory.expr("1.${element.path.referenceName}::<$fakeTypeArgs>()") dotExpr.expr.replace(selfArgExpr) val typeArgumentList = element.path.typeArgumentList if (typeArgumentList != null) { - dotExpr.methodCall?.typeArgumentList?.replace(typeArgumentList) + val dotExprList = dotExpr.methodCall?.typeArgumentList?.typeArgumentList!! + for ((dotExprTypeArgument, typeArgument) in dotExprList.zip(typeArgumentList.typeArgumentList)) { + dotExprTypeArgument.replace(typeArgument) + } } else { dotExpr.methodCall?.typeArgumentList?.delete() } diff --git a/src/main/kotlin/org/move/lang/core/completion/LookupElements.kt b/src/main/kotlin/org/move/lang/core/completion/LookupElements.kt index 3fd46d0d3..ddb3af803 100644 --- a/src/main/kotlin/org/move/lang/core/completion/LookupElements.kt +++ b/src/main/kotlin/org/move/lang/core/completion/LookupElements.kt @@ -157,7 +157,7 @@ fun InsertionContext.addSuffix(suffix: String) { EditorModificationUtil.moveCaretRelatively(editor, suffix.length) } -val InsertionContext.hasCallParens: Boolean +val InsertionContext.alreadyHasCallParens: Boolean get() = nextCharIs('(') val InsertionContext.alreadyHasColonColon: Boolean @@ -166,7 +166,7 @@ val InsertionContext.alreadyHasColonColon: Boolean val InsertionContext.alreadyHasSpace: Boolean get() = nextCharIs(' ') -val InsertionContext.hasAngleBrackets: Boolean +val InsertionContext.alreadyHasAngleBrackets: Boolean get() = nextCharIs('<') fun InsertionContext.nextCharIs(c: Char): Boolean = @@ -192,7 +192,7 @@ class AngleBracketsInsertHandler: InsertHandler { override fun handleInsert(context: InsertionContext, item: LookupElement) { val document = context.document - if (!context.hasAngleBrackets) { + if (!context.alreadyHasAngleBrackets) { document.insertString(context.selectionEndOffset, "<>") } EditorModificationUtil.moveCaretRelatively(context.editor, 1) @@ -212,30 +212,48 @@ open class DefaultInsertHandler(val completionCtx: CompletionContext? = null): I item: LookupElement ) { val document = context.document + when (element) { is MvFunctionLike -> { - val requiresExplicitTypeArguments = - element.requiresExplicitlyProvidedTypeArguments(completionCtx) - var suffix = "" - if (!context.hasAngleBrackets && requiresExplicitTypeArguments) { - suffix += "<>" - } - if (!context.hasAngleBrackets && !context.hasCallParens) { - suffix += "()" - } val isMethodCall = context.getElementOfType() != null - val fnParameters = if (isMethodCall) element.parameters.drop(1) else element.parameters - val caretShift = when { - requiresExplicitTypeArguments -> 1 - fnParameters.isNotEmpty() -> 1 - else -> 2 + val requiresExplicitTypes = + element.requiresExplicitlyProvidedTypeArguments(completionCtx) + if (isMethodCall) { + var suffix = "" + if (requiresExplicitTypes && !context.alreadyHasColonColon) { + suffix += "::<>" + } + if (!context.alreadyHasColonColon && !context.alreadyHasCallParens) { + suffix += "()" + } + val caretShift = when { + context.alreadyHasColonColon || requiresExplicitTypes -> 3 + // drop first for self + element.parameters.drop(1).isNotEmpty() -> 1 + else -> 2 + } + context.document.insertString(context.selectionEndOffset, suffix) + EditorModificationUtil.moveCaretRelatively(context.editor, caretShift) + } else { + var suffix = "" + if (requiresExplicitTypes && !context.alreadyHasAngleBrackets) { + suffix += "<>" + } + if (!context.alreadyHasAngleBrackets && !context.alreadyHasCallParens) { + suffix += "()" + } + val caretShift = when { + requiresExplicitTypes -> 1 + element.parameters.isNotEmpty() -> 1 + else -> 2 + } + context.document.insertString(context.selectionEndOffset, suffix) + EditorModificationUtil.moveCaretRelatively(context.editor, caretShift) } - context.document.insertString(context.selectionEndOffset, suffix) - EditorModificationUtil.moveCaretRelatively(context.editor, caretShift) } is MvSchema -> { if (element.hasTypeParameters) { - if (!context.hasAngleBrackets) { + if (!context.alreadyHasAngleBrackets) { document.insertString(context.selectionEndOffset, "<>") } EditorModificationUtil.moveCaretRelatively(context.editor, 1) @@ -247,7 +265,7 @@ open class DefaultInsertHandler(val completionCtx: CompletionContext? = null): I .findElementAt(context.startOffset) ?.ancestorOrSelf() != null if (element.hasTypeParameters && !insideAcquiresType) { - if (!context.hasAngleBrackets) { + if (!context.alreadyHasAngleBrackets) { document.insertString(context.selectionEndOffset, "<>") } EditorModificationUtil.moveCaretRelatively(context.editor, 1) diff --git a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt index 58ee2c2e3..8cf105bb6 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -140,6 +140,7 @@ fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: Co val callTy = this.declaredType(msl).substitute(this.tyInfers) as TyFunction val inferenceCtx = InferenceContext(msl) + callTy.paramTypes.forEach { inferenceCtx.combineTypes(it, it.foldTyInferWith { TyUnknown }) } diff --git a/src/test/kotlin/org/move/ide/annotator/errors/TypeParametersNumberErrorTest.kt b/src/test/kotlin/org/move/ide/annotator/errors/TypeParametersNumberErrorTest.kt index 6a8451b8e..0b2c0c109 100644 --- a/src/test/kotlin/org/move/ide/annotator/errors/TypeParametersNumberErrorTest.kt +++ b/src/test/kotlin/org/move/ide/annotator/errors/TypeParametersNumberErrorTest.kt @@ -182,7 +182,7 @@ class TypeParametersNumberErrorTest: AnnotatorTestCase(MvErrorAnnotator::class) param } fun main(s: S) { - let b = s.receiver(1); + let b = s.receiver::(1); } } """) diff --git a/src/test/kotlin/org/move/ide/inspections/ReplaceWithMethodCallInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/ReplaceWithMethodCallInspectionTest.kt index 38455ed23..083217fa1 100644 --- a/src/test/kotlin/org/move/ide/inspections/ReplaceWithMethodCallInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/ReplaceWithMethodCallInspectionTest.kt @@ -231,7 +231,7 @@ class ReplaceWithMethodCallInspectionTest: InspectionTestBase(ReplaceWithMethodC struct S { field: u8 } native fun get_type(self: &S): T; fun main(s: S) { - s.get_type(); + s.get_type::(); } } """) 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 b7794b404..7fef96c55 100644 --- a/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt +++ b/src/test/kotlin/org/move/lang/completion/names/DotAccessCompletionTest.kt @@ -147,7 +147,25 @@ module 0x1::M { struct S { field: u8 } fun receiver(self: &S): Z {} fun main(s: S) { - s.receiver(); + s.receiver::(); + } + } + """) + + fun `test receiver style function completion type annotation required with angle brackets present`() = doSingleCompletion(""" + module 0x1::main { + struct S { field: u8 } + fun receiver(self: &S): Z {} + fun main(s: S) { + s.rece/*caret*/::<>() + } + } + """, """ + module 0x1::main { + struct S { field: u8 } + fun receiver(self: &S): Z {} + fun main(s: S) { + s.receiver::() } } """) diff --git a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt index 6acfca4af..ec23c9115 100644 --- a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt +++ b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt @@ -14,6 +14,7 @@ class CompleteParsingTest : MvParsingTestCase("complete") { // expressions fun `test strings`() = doTest() fun `test vectors`() = doTest() + fun `test dot expressions`() = doTest() fun `test expressions`() = doTest() fun `test expressions assignments`() = doTest() fun `test expressions if else as`() = doTest() diff --git a/src/test/resources/org/move/lang/parser/complete/dot_expressions.move b/src/test/resources/org/move/lang/parser/complete/dot_expressions.move new file mode 100644 index 000000000..a1ac9e1db --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/dot_expressions.move @@ -0,0 +1,15 @@ +module 0x1::dot_expressions { + fun dot() { + bin.field1.field2; + bin.field < 1; + bin.receiver_func(); + bin.field.call(); + + bin.call::(); + bin.call::(); + vector[1].length::(); + } + spec dot { + bin.field[1]; + } +} diff --git a/src/test/resources/org/move/lang/parser/complete/dot_expressions.txt b/src/test/resources/org/move/lang/parser/complete/dot_expressions.txt new file mode 100644 index 000000000..3cbbda6d5 --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/dot_expressions.txt @@ -0,0 +1,192 @@ +FILE + MvModuleImpl(MODULE) + PsiElement(module)('module') + PsiWhiteSpace(' ') + MvAddressRefImpl(ADDRESS_REF) + PsiElement(DIEM_ADDRESS)('0x1') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('dot_expressions') + PsiWhiteSpace(' ') + MvModuleBlockImpl(MODULE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('dot') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('field1') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('field2') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvBinaryExprImpl(BINARY_EXPR[<]) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('field') + PsiWhiteSpace(' ') + MvBinaryOpImpl(BINARY_OP) + PsiElement(<)('<') + PsiWhiteSpace(' ') + MvLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvMethodCallImpl(METHOD_CALL) + PsiElement(IDENTIFIER)('receiver_func') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('field') + PsiElement(.)('.') + MvMethodCallImpl(METHOD_CALL) + PsiElement(IDENTIFIER)('call') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvMethodCallImpl(METHOD_CALL) + PsiElement(IDENTIFIER)('call') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(::)('::') + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvMethodCallImpl(METHOD_CALL) + PsiElement(IDENTIFIER)('call') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(::)('::') + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('U') + PsiElement(>)('>') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvVectorLitExprImpl(VECTOR_LIT_EXPR) + PsiElement(IDENTIFIER)('vector') + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') + MvVectorLitItemsImpl(VECTOR_LIT_ITEMS) + PsiElement([)('[') + MvLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(])(']') + PsiElement(.)('.') + MvMethodCallImpl(METHOD_CALL) + PsiElement(IDENTIFIER)('length') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(::)('::') + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n ') + MvItemSpecImpl(ITEM_SPEC) + PsiElement(spec)('spec') + PsiWhiteSpace(' ') + MvItemSpecRefImpl(ITEM_SPEC_REF) + PsiElement(IDENTIFIER)('dot') + PsiWhiteSpace(' ') + MvSpecCodeBlockImpl(SPEC_CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvSpecExprStmtImpl(SPEC_EXPR_STMT) + MvIndexExprImpl(INDEX_EXPR) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('field') + PsiElement([)('[') + MvLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(])(']') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n') + PsiElement(})('}') \ No newline at end of file diff --git a/src/test/resources/org/move/lang/parser/complete/expressions.move b/src/test/resources/org/move/lang/parser/complete/expressions.move index 5cb0fce59..e3037fda4 100644 --- a/src/test/resources/org/move/lang/parser/complete/expressions.move +++ b/src/test/resources/org/move/lang/parser/complete/expressions.move @@ -38,17 +38,4 @@ module M { fun m() { return 1 } - fun dot() { - bin.field1.field2; - bin.field < 1; - bin.receiver_func(); - bin.field.call(); - - bin.call(); - bin.call(); - vector[1].length(); - } - spec dot { - bin.field[1]; - } } diff --git a/src/test/resources/org/move/lang/parser/complete/expressions.txt b/src/test/resources/org/move/lang/parser/complete/expressions.txt index 6e499445d..e1e3ed8ff 100644 --- a/src/test/resources/org/move/lang/parser/complete/expressions.txt +++ b/src/test/resources/org/move/lang/parser/complete/expressions.txt @@ -387,181 +387,5 @@ FILE PsiElement(INTEGER_LITERAL)('1') PsiWhiteSpace('\n ') PsiElement(})('}') - PsiWhiteSpace('\n ') - MvFunctionImpl(FUNCTION) - PsiElement(fun)('fun') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('dot') - MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiWhiteSpace(' ') - MvCodeBlockImpl(CODE_BLOCK) - PsiElement({)('{') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) - PsiElement(IDENTIFIER)('field1') - PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) - PsiElement(IDENTIFIER)('field2') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvBinaryExprImpl(BINARY_EXPR[<]) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) - PsiElement(IDENTIFIER)('field') - PsiWhiteSpace(' ') - MvBinaryOpImpl(BINARY_OP) - PsiElement(<)('<') - PsiWhiteSpace(' ') - MvLitExprImpl(LIT_EXPR) - PsiElement(INTEGER_LITERAL)('1') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvMethodCallImpl(METHOD_CALL) - PsiElement(IDENTIFIER)('receiver_func') - MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) - PsiElement(IDENTIFIER)('field') - PsiElement(.)('.') - MvMethodCallImpl(METHOD_CALL) - PsiElement(IDENTIFIER)('call') - MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiElement(;)(';') - PsiWhiteSpace('\n\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvMethodCallImpl(METHOD_CALL) - PsiElement(IDENTIFIER)('call') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') - PsiElement(>)('>') - MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvMethodCallImpl(METHOD_CALL) - PsiElement(IDENTIFIER)('call') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') - PsiElement(,)(',') - PsiWhiteSpace(' ') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('U') - PsiElement(>)('>') - MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - MvExprStmtImpl(EXPR_STMT) - MvDotExprImpl(DOT_EXPR) - MvVectorLitExprImpl(VECTOR_LIT_EXPR) - PsiElement(IDENTIFIER)('vector') - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') - MvVectorLitItemsImpl(VECTOR_LIT_ITEMS) - PsiElement([)('[') - MvLitExprImpl(LIT_EXPR) - PsiElement(INTEGER_LITERAL)('1') - PsiElement(])(']') - PsiElement(.)('.') - MvMethodCallImpl(METHOD_CALL) - PsiElement(IDENTIFIER)('length') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') - MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) - PsiElement(()('(') - PsiElement())(')') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - PsiElement(})('}') - PsiWhiteSpace('\n ') - MvItemSpecImpl(ITEM_SPEC) - PsiElement(spec)('spec') - PsiWhiteSpace(' ') - MvItemSpecRefImpl(ITEM_SPEC_REF) - PsiElement(IDENTIFIER)('dot') - PsiWhiteSpace(' ') - MvSpecCodeBlockImpl(SPEC_CODE_BLOCK) - PsiElement({)('{') - PsiWhiteSpace('\n ') - MvSpecExprStmtImpl(SPEC_EXPR_STMT) - MvIndexExprImpl(INDEX_EXPR) - MvDotExprImpl(DOT_EXPR) - MvRefExprImpl(REF_EXPR) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('bin') - PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) - PsiElement(IDENTIFIER)('field') - PsiElement([)('[') - MvLitExprImpl(LIT_EXPR) - PsiElement(INTEGER_LITERAL)('1') - PsiElement(])(']') - PsiElement(;)(';') - PsiWhiteSpace('\n ') - PsiElement(})('}') PsiWhiteSpace('\n') PsiElement(})('}') \ No newline at end of file diff --git a/src/test/resources/org/move/lang/parser/partial/dot_exprs.move b/src/test/resources/org/move/lang/parser/partial/dot_exprs.move index 1382112cf..a8cc67e2b 100644 --- a/src/test/resources/org/move/lang/parser/partial/dot_exprs.move +++ b/src/test/resources/org/move/lang/parser/partial/dot_exprs.move @@ -14,4 +14,8 @@ module 0x1::dot_exprs { bin. x" bin. return } + + fun receiver() { + bin.no_type_args_without_colon_colon(); + } } diff --git a/src/test/resources/org/move/lang/parser/partial/dot_exprs.txt b/src/test/resources/org/move/lang/parser/partial/dot_exprs.txt index 22323cb78..0f9c55ae5 100644 --- a/src/test/resources/org/move/lang/parser/partial/dot_exprs.txt +++ b/src/test/resources/org/move/lang/parser/partial/dot_exprs.txt @@ -176,5 +176,42 @@ FILE PsiElement(return)('return') PsiWhiteSpace('\n ') PsiElement(})('}') + PsiWhiteSpace('\n\n ') + MvFunctionImpl(FUNCTION) + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('receiver') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvBinaryExprImpl(BINARY_EXPR[>]) + MvBinaryExprImpl(BINARY_EXPR[<]) + MvDotExprImpl(DOT_EXPR) + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bin') + PsiElement(.)('.') + MvStructDotFieldImpl(STRUCT_DOT_FIELD) + PsiElement(IDENTIFIER)('no_type_args_without_colon_colon') + MvBinaryOpImpl(BINARY_OP) + PsiElement(<)('<') + MvRefExprImpl(REF_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + MvBinaryOpImpl(BINARY_OP) + PsiElement(>)('>') + MvParensExprImpl(PARENS_EXPR) + PsiElement(()('(') + PsiErrorElement: expected, got ')' + + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + PsiElement(})('}') PsiWhiteSpace('\n') PsiElement(})('}') \ No newline at end of file