From a6e2ffc91a03e3e683d107faf82f0be162e54372 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Sun, 25 Aug 2024 15:35:45 +0300 Subject: [PATCH 01/13] support tuple struct in parser --- src/main/grammars/MoveParser.bnf | 124 +++++--- .../ide/annotator/HighlightingAnnotator.kt | 2 +- .../ide/annotator/MvSyntaxErrorAnnotator.kt | 14 +- .../MvUnresolvedReferenceInspection.kt | 6 +- .../move/lang/core/psi/ext/MvFieldsOwner.kt | 1 + .../lang/core/psi/ext/MvStructDotField.kt | 15 +- .../lang/core/types/infer/InferenceContext.kt | 6 +- .../core/types/infer/TypeInferenceWalker.kt | 12 +- .../kotlin/org/move/lang/utils/Diagnostic.kt | 16 +- .../move/lang/parser/CompleteParsingTest.kt | 1 + .../move/lang/parser/complete/assignments.txt | 12 +- .../move/lang/parser/complete/attributes.move | 3 - .../move/lang/parser/complete/attributes.txt | 15 - .../move/lang/parser/complete/comments.move | 12 +- .../move/lang/parser/complete/comments.txt | 43 ++- .../lang/parser/complete/dot_expressions.txt | 10 +- .../complete/expressions_assignments.txt | 2 +- .../lang/parser/complete/function_calls.txt | 2 +- .../move/lang/parser/complete/index_expr.txt | 42 +-- .../parser/complete/positional_fields.move | 23 ++ .../parser/complete/positional_fields.txt | 278 ++++++++++++++++++ .../parser/complete/struct_declarations.move | 4 - .../parser/complete/struct_declarations.txt | 25 -- .../move/lang/parser/partial/assignments.txt | 4 +- .../move/lang/parser/partial/dot_exprs.txt | 18 +- .../move/lang/parser/partial/expressions.txt | 2 +- .../lang/parser/partial/function_calls.txt | 6 +- .../parser/partial/function_signatures.move | 4 +- .../parser/partial/function_signatures.txt | 14 +- .../lang/parser/partial/struct_decls.move | 5 +- .../move/lang/parser/partial/struct_decls.txt | 42 ++- .../lang/parser/partial/top_level_items.txt | 4 +- .../org/move/lang/parser/specs/conditions.txt | 16 +- .../org/move/lang/parser/specs/spec_file.txt | 2 +- .../lang/parser/specs/spec_statements.txt | 2 +- 35 files changed, 584 insertions(+), 203 deletions(-) create mode 100644 src/test/resources/org/move/lang/parser/complete/positional_fields.move create mode 100644 src/test/resources/org/move/lang/parser/complete/positional_fields.txt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 5382278d3..d55415475 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -16,7 +16,7 @@ tokenTypeClass="org.move.lang.core.MvTokenType" extends(".*Expr")=Expr - extends("Pat(Struct|Binding|Tuple|Wild|Const)")=Pat + extends("Pat(Struct|TupleStruct|Binding|Tuple|Wild|Const)")=Pat extends("(Lambda|Ref|Path|Tuple|Unit|Parens)Type")=Type elementType(".+BinExpr")=BinaryExpr @@ -269,7 +269,7 @@ private TopLevel_first ::= MODULE_KW | SCRIPT_KW private ModuleItem ::= UseStmt | FriendDecl - | StructItem + | Struct | Enum | FunctionItem | SpecFunctionItem @@ -365,36 +365,51 @@ SpecInlineFunctionStmt ::= SpecInlineFunctionInner ] } -fake Struct ::= Attr* native? STRUCT_KW IDENTIFIER? TypeParameterList? AbilitiesList? - (';' | BlockFields)? +//fake Struct ::= Attr* native? STRUCT_KW IDENTIFIER? TypeParameterList? AbilitiesList? +// (';' | BlockFields)? +//{ +// implements = [ +// "org.move.lang.core.psi.ext.MvStructOrEnumItemElement" +// "org.move.lang.core.psi.ext.MvFieldsOwner" +// ] +// mixin = "org.move.lang.core.psi.ext.MvStructMixin" +// stubClass = "org.move.lang.core.stubs.MvStructStub" +// elementTypeFactory = "org.move.lang.core.stubs.StubsKt.factory" +//} +Struct ::= Attr* STRUCT_KW IDENTIFIER TypeParameterList? AbilitiesList? + ( TupleStructTail | BlockStructTail ) { + pin = 2 implements = [ -// "org.move.lang.core.psi.MvQualNamedElement" -// "org.move.lang.core.psi.MvTypeParametersOwner" "org.move.lang.core.psi.ext.MvStructOrEnumItemElement" "org.move.lang.core.psi.ext.MvFieldsOwner" ] mixin = "org.move.lang.core.psi.ext.MvStructMixin" stubClass = "org.move.lang.core.stubs.MvStructStub" elementTypeFactory = "org.move.lang.core.stubs.StubsKt.factory" -} - -private StructInnerFirst ::= STRUCT_KW -StructInner ::= Attr* StructInnerFirst IDENTIFIER TypeParameterList? AbilitiesList? - BlockFields -{ - pin = StructInnerFirst - elementType = Struct - hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] -} -private NativeStructInnerFirst ::= native STRUCT_KW -NativeStructInner ::= Attr* NativeStructInnerFirst IDENTIFIER TypeParameterList? AbilitiesList? ';' -{ - pin = NativeStructInnerFirst - elementType = Struct hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] } -private StructItem ::= StructInner | NativeStructInner + +private TupleStructTail ::= TupleFields ';' { pin = 1 } +private BlockStructTail ::= BlockFields +private UnitStructTail ::= ';' + +//private StructInnerFirst ::= STRUCT_KW +//StructInner ::= Attr* StructInnerFirst IDENTIFIER TypeParameterList? AbilitiesList? +// BlockFields +//{ +// pin = StructInnerFirst +// elementType = Struct +// hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] +//} +//private NativeStructInnerFirst ::= native STRUCT_KW +//NativeStructInner ::= Attr* NativeStructInnerFirst IDENTIFIER TypeParameterList? AbilitiesList? ';' +//{ +// pin = NativeStructInnerFirst +// elementType = Struct +// hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] +//} +//private StructItem ::= StructInner Enum ::= Attr* enum IDENTIFIER TypeParameterList? AbilitiesList? EnumBody { @@ -412,7 +427,7 @@ EnumBody ::= '{' (EnumVariant ','?)* '}' { pin = 1 } -EnumVariant ::= Attr* IDENTIFIER BlockFields? +EnumVariant ::= Attr* IDENTIFIER VariantArgs? { pin = 2 implements = [ @@ -425,6 +440,7 @@ EnumVariant ::= Attr* IDENTIFIER BlockFields? elementTypeFactory = "org.move.lang.core.stubs.StubsKt.factory" hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] } +private VariantArgs ::= BlockFields | TupleFields fake Function ::= Attr* native? VisibilityModifier? entry? inline? fun? IDENTIFIER? TypeParameterList? FunctionParameterList? @@ -550,6 +566,16 @@ private NamedFieldDecl_with_recover ::= !'}' NamedFieldDecl (',' | &'}') } private NamedFieldDecl_recover ::= !('}' | NamedFieldDecl_first) +TupleFields ::= '(' TupleFieldDecl_with_recover* ')' +{ + pin = 1 +} +private TupleFieldDecl_with_recover ::= !')' TupleFieldDecl (',' | &')') { + pin = 1 + recoverWhile = TupleFieldDecl_recover +} +private TupleFieldDecl_recover ::= !(')' | AttrsAndVis_first | Type_first) + NamedFieldDecl ::= Attr* IDENTIFIER TypeAnnotation &(',' | '}') { pin = 2 @@ -563,6 +589,12 @@ NamedFieldDecl ::= Attr* IDENTIFIER TypeAnnotation &(',' | '}') } private NamedFieldDecl_first ::= AttrsAndVis_first | IDENTIFIER +TupleFieldDecl ::= Attr* Type +{ + + hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] +} + FriendDecl ::= Attr* friend PathImpl ';' { pin = "friend" @@ -604,7 +636,14 @@ TypeAnnotation ::= ':' Type { name = "type annotation" } -Type ::= RefType | PathType | TupleType | LambdaType | UnitType | ParensType +Type ::= RefType + | PathType + | TupleType + | LambdaType + | UnitType + | ParensType +private Type_first ::= '&' | '|' | Path_first + ParensType ::= '(' (Type !',') ')' { pin = 2 } UnitType ::= '(' ')' @@ -682,6 +721,7 @@ Pat ::= PatWild | PatTuple | PatBinding | PatStruct + | PatTupleStruct | PatConst MatchPat ::= Pat | PathPat @@ -715,24 +755,29 @@ PatBinding ::= IDENTIFIER !ForbiddenPatBindingLast { BindingPat ::= IDENTIFIER !ForbiddenPatBindingLast //private ForbiddenBindingPatLast ::= '...' | '::' | '..=' | '..' | '<' | '(' | '{' | '!' { -private ForbiddenPatBindingLast ::= '::' | '<' | '(' | '{' | '!' { +private ForbiddenPatBindingLast ::= '::' | '<' | '(' | '{' | '!' +{ consumeTokenMethod = "consumeTokenFast" } -TuplePat ::= '(' ParenListElemPat_with_recover* ')' -PatTuple ::= '(' ParenListElemPat_with_recover* ')' -private ParenListElemPat_with_recover ::= !')' Pat (',' | &')') { - pin = 1 - recoverWhile = ParenListElemPat_recover -} -private ParenListElemPat_recover ::= !(')' | Pat_first) +TuplePat ::= '(' PatParenListElem_with_recover* ')' +PatTuple ::= '(' PatParenListElem_with_recover* ')' StructPat ::= PathImpl '{' PatField_with_recover* '}' PatStruct ::= PathImpl '{' PatField_with_recover* '}' { implements = [ "org.move.lang.core.resolve2.ref.InferenceCachedPathElement" ] } -//StructPatFieldsBlock ::= '{' FieldPat_with_recover* '}' +PatTupleStruct ::= PathImpl '(' PatParenListElem_with_recover* ')' +{ + implements = [ "org.move.lang.core.resolve2.ref.InferenceCachedPathElement" ] +} + +private PatParenListElem_with_recover ::= !')' Pat (',' | &')') { + pin = 1 + recoverWhile = PatParenListElem_recover +} +private PatParenListElem_recover ::= !(')' | Pat_first) private PatField_with_recover ::= !'}' PatField (',' | &'}') { @@ -1128,18 +1173,27 @@ BorrowExpr ::= '&' mut? Expr DotExpr ::= Expr DotExpr_inner // Do not inline this rule, it breaks expression parsing -private DotExpr_inner ::= '.' !('.' | VectorStart) (MethodCall | StructDotField) { +private DotExpr_inner ::= '.' !('.' | VectorStart) (MethodCall | FieldLookup) { pin = 2 consumeTokenMethod = "consumeTokenFast" } private VectorStart ::= (<> ('[' | '<')) + StructDotField ::= IDENTIFIER !('(' | '::' | '!' | '{') +//StructDotField ::= IDENTIFIER !('(' | '::' | '!' | '{') + +FieldLookup ::= (IDENTIFIER | INTEGER_LITERAL) !ForbiddenFieldLookupLast { implements = ["org.move.lang.core.psi.ext.MvMethodOrField"] - mixin = "org.move.lang.core.psi.ext.MvStructDotFieldMixin" + mixin = "org.move.lang.core.psi.ext.MvFieldLookupMixin" } +private ForbiddenFieldLookupLast ::= '::' | '(' | '{' | '!' +{ + consumeTokenMethod = "consumeTokenFast" +} + MethodCall ::= IDENTIFIER ColonTypeArgumentList? ValueArgumentList { implements = [ diff --git a/src/main/kotlin/org/move/ide/annotator/HighlightingAnnotator.kt b/src/main/kotlin/org/move/ide/annotator/HighlightingAnnotator.kt index 008fb6b79..3fd7dad0e 100644 --- a/src/main/kotlin/org/move/ide/annotator/HighlightingAnnotator.kt +++ b/src/main/kotlin/org/move/ide/annotator/HighlightingAnnotator.kt @@ -72,7 +72,7 @@ class HighlightingAnnotator: MvAnnotatorBase() { } if (element is MvStruct) return MvColor.STRUCT if (element is MvNamedFieldDecl) return MvColor.FIELD - if (element is MvStructDotField) return MvColor.FIELD + if (element is MvFieldLookup) return MvColor.FIELD if (element is MvMethodCall) return MvColor.METHOD_CALL if (element is MvPatFieldFull) return MvColor.FIELD if (element is MvPatField) return MvColor.FIELD diff --git a/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt b/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt index 356d90a4b..7efcfe007 100644 --- a/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt +++ b/src/main/kotlin/org/move/ide/annotator/MvSyntaxErrorAnnotator.kt @@ -20,7 +20,7 @@ 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 visitStruct(s: MvStruct) = checkStruct(moveHolder, s) +// override fun visitStruct(s: MvStruct) = checkStruct(moveHolder, s) override fun visitFunction(o: MvFunction) = checkFunction(moveHolder, o) override fun visitSpecFunction(o: MvSpecFunction) = checkSpecFunction(moveHolder, o) override fun visitIndexExpr(o: MvIndexExpr) = checkIndexExpr(moveHolder, o) @@ -75,12 +75,12 @@ class MvSyntaxErrorAnnotator: MvAnnotatorBase() { } } - private fun checkStruct(holder: MvAnnotationHolder, struct: MvStruct) { - val native = struct.native ?: return - val errorRange = TextRange.create(native.startOffset, struct.structKw.endOffset) - Diagnostic.NativeStructNotSupported(struct, errorRange) - .addToHolder(holder) - } +// private fun checkStruct(holder: MvAnnotationHolder, struct: MvStruct) { +// val native = struct.native ?: return +// val errorRange = TextRange.create(native.startOffset, struct.structKw.endOffset) +// Diagnostic.NativeStructNotSupported(struct, errorRange) +// .addToHolder(holder) +// } private fun checkVisibilityModifiers( holder: MvAnnotationHolder, diff --git a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt index 2931586fa..e31dc4737 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvUnresolvedReferenceInspection.kt @@ -102,9 +102,7 @@ class MvUnresolvedReferenceInspection: MvLocalInspectionTool() { } } - override fun visitStructDotField(dotField: MvStructDotField) { - checkMethodOrField(dotField) - } + override fun visitFieldLookup(o: MvFieldLookup) = checkMethodOrField(o) override fun visitMethodCall(methodCall: MvMethodCall) { if (!methodCall.project.moveSettings.enableReceiverStyleFunctions) return @@ -138,7 +136,7 @@ class MvUnresolvedReferenceInspection: MvLocalInspectionTool() { parent is MvPathType -> "type" parent is MvCallExpr -> "function" parent is MvPatField -> "field" - referenceElement is MvStructDotField -> "field" + referenceElement is MvFieldLookup -> "field" referenceElement is MvStructLitField -> "field" else -> "reference" } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt index 2d10f1e21..f72194ae2 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt @@ -4,6 +4,7 @@ import org.move.lang.core.psi.* interface MvFieldsOwner: MvNameIdentifierOwner { val blockFields: MvBlockFields? + val tupleFields: MvTupleFields? } val MvFieldsOwner.itemElement: MvStructOrEnumItemElement diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt index 56e2bf27f..94896ef5c 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt @@ -57,9 +57,9 @@ private fun isFieldsAccessible( return true } -class MvStructDotFieldReferenceImpl( - element: MvStructDotField -): MvPolyVariantReferenceBase(element) { +class MvFieldLookupReferenceImpl( + element: MvFieldLookup +): MvPolyVariantReferenceBase(element) { override fun multiResolve(): List { val msl = element.isMsl() @@ -69,9 +69,8 @@ class MvStructDotFieldReferenceImpl( } } -abstract class MvStructDotFieldMixin(node: ASTNode): MvElementImpl(node), - MvStructDotField { - override fun getReference(): MvPolyVariantReference { - return MvStructDotFieldReferenceImpl(this) - } +abstract class MvFieldLookupMixin(node: ASTNode): MvElementImpl(node), + MvFieldLookup { + + override fun getReference(): MvPolyVariantReference = MvFieldLookupReferenceImpl(this) } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index 8781487b6..118b58502 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -89,7 +89,7 @@ data class InferenceResult( private val methodOrPathTypes: Map, private val resolvedPaths: Map>, - private val resolvedFields: Map, + private val resolvedFields: Map, private val resolvedMethodCalls: Map, private val resolvedBindings: Map, private val resolvedLitFields: Map>, @@ -113,7 +113,7 @@ data class InferenceResult( fun getResolvedPath(path: MvPath): List? = resolvedPaths[path] ?: inferenceErrorOrFallback(path, null) - fun getResolvedField(field: MvStructDotField): MvNamedElement? = resolvedFields[field] + fun getResolvedField(field: MvFieldLookup): MvNamedElement? = resolvedFields[field] fun getResolvedMethod(methodCall: MvMethodCall): MvNamedElement? = resolvedMethodCalls[methodCall] fun getResolvedPatBinding(binding: MvPatBinding): MvNamedElement? = resolvedBindings[binding] @@ -195,7 +195,7 @@ class InferenceContext( private val methodOrPathTypes = mutableMapOf() val resolvedPaths = mutableMapOf>() - val resolvedFields = mutableMapOf() + val resolvedFields = mutableMapOf() val resolvedMethodCalls = mutableMapOf() val resolvedBindings = mutableMapOf() 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 686b459b7..2cb6db381 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 @@ -447,15 +447,15 @@ class TypeInferenceWalker( return ctx.resolvedPaths[path] ?: emptyList() } - fun inferDotFieldTy(receiverTy: Ty, dotField: MvStructDotField): Ty { + fun inferFieldLookupTy(receiverTy: Ty, fieldLookup: MvFieldLookup): Ty { val tyAdt = receiverTy.derefIfNeeded() as? TyAdt ?: return TyUnknown val field = - resolveSingleResolveVariant(dotField.referenceName) { - processNamedFieldVariants(dotField, tyAdt, msl, it) + resolveSingleResolveVariant(fieldLookup.referenceName) { + processNamedFieldVariants(fieldLookup, tyAdt, msl, it) } as? MvNamedFieldDecl - ctx.resolvedFields[dotField] = field + ctx.resolvedFields[fieldLookup] = field val fieldTy = field?.type?.loweredType(msl)?.substitute(tyAdt.typeParameterValues) return fieldTy ?: TyUnknown @@ -634,10 +634,10 @@ class TypeInferenceWalker( val receiverTy = ctx.resolveTypeVarsIfPossible(dotExpr.expr.inferType()) val methodCall = dotExpr.methodCall - val field = dotExpr.structDotField + val field = dotExpr.fieldLookup return when { + field != null -> inferFieldLookupTy(receiverTy, field) methodCall != null -> inferMethodCallTy(receiverTy, methodCall, expected) - field != null -> inferDotFieldTy(receiverTy, field) // incomplete else -> TyUnknown } diff --git a/src/main/kotlin/org/move/lang/utils/Diagnostic.kt b/src/main/kotlin/org/move/lang/utils/Diagnostic.kt index 53ab8e2b3..9eb2a7622 100644 --- a/src/main/kotlin/org/move/lang/utils/Diagnostic.kt +++ b/src/main/kotlin/org/move/lang/utils/Diagnostic.kt @@ -153,14 +153,14 @@ sealed class Diagnostic( } } - 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 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( diff --git a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt index 1c0d291e7..c2be0db5c 100644 --- a/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt +++ b/src/test/kotlin/org/move/lang/parser/CompleteParsingTest.kt @@ -51,6 +51,7 @@ class CompleteParsingTest: MvParsingTestCase("complete") { fun `test public package`() = doTest() fun `test enums`() = doTest() fun `test match`() = doTest() + fun `test positional fields`() = doTest() // feature declaration is required here, as it's a parser-level feature @CompilerV2Features(RESOURCE_CONTROL) diff --git a/src/test/resources/org/move/lang/parser/complete/assignments.txt b/src/test/resources/org/move/lang/parser/complete/assignments.txt index 25a7cc827..b27afedb1 100644 --- a/src/test/resources/org/move/lang/parser/complete/assignments.txt +++ b/src/test/resources/org/move/lang/parser/complete/assignments.txt @@ -37,7 +37,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('record') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -54,7 +54,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('record') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -95,7 +95,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('record') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -116,7 +116,7 @@ FILE PsiElement(()('(') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('operator') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -137,10 +137,10 @@ FILE PsiElement(()('(') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('operator') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('main') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) diff --git a/src/test/resources/org/move/lang/parser/complete/attributes.move b/src/test/resources/org/move/lang/parser/complete/attributes.move index a680cc46f..f47bbf9d3 100644 --- a/src/test/resources/org/move/lang/parser/complete/attributes.move +++ b/src/test/resources/org/move/lang/parser/complete/attributes.move @@ -9,9 +9,6 @@ module 0x1::M { #[test_only] struct SomeStruct {} - #[test_only] - native struct S; - #[test] #[expected_failure] #[test, expected_failure = std::type_name::ENonModuleType] diff --git a/src/test/resources/org/move/lang/parser/complete/attributes.txt b/src/test/resources/org/move/lang/parser/complete/attributes.txt index dfaabd7b9..08c831ecf 100644 --- a/src/test/resources/org/move/lang/parser/complete/attributes.txt +++ b/src/test/resources/org/move/lang/parser/complete/attributes.txt @@ -76,21 +76,6 @@ FILE PsiElement({)('{') PsiElement(})('}') PsiWhiteSpace('\n\n ') - MvStructImpl(STRUCT) - MvAttrImpl(ATTR) - PsiElement(#)('#') - PsiElement([)('[') - MvAttrItemImpl(ATTR_ITEM) - PsiElement(IDENTIFIER)('test_only') - PsiElement(])(']') - PsiWhiteSpace('\n ') - PsiElement(native)('native') - PsiWhiteSpace(' ') - PsiElement(struct_kw)('struct') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('S') - PsiElement(;)(';') - PsiWhiteSpace('\n\n ') MvFunctionImpl(FUNCTION) MvAttrImpl(ATTR) PsiElement(#)('#') diff --git a/src/test/resources/org/move/lang/parser/complete/comments.move b/src/test/resources/org/move/lang/parser/complete/comments.move index b520bb514..ebe2d5288 100644 --- a/src/test/resources/org/move/lang/parser/complete/comments.move +++ b/src/test/resources/org/move/lang/parser/complete/comments.move @@ -28,5 +28,15 @@ module 0x1::M { native fun native_m(); /// docs - native struct NatS; + struct S1 {} + /// docs + struct S2(u8); + + /// docs + enum S { + /// docs + One, + /// docs + Two + } } diff --git a/src/test/resources/org/move/lang/parser/complete/comments.txt b/src/test/resources/org/move/lang/parser/complete/comments.txt index 2e87f0a6c..448457ca9 100644 --- a/src/test/resources/org/move/lang/parser/complete/comments.txt +++ b/src/test/resources/org/move/lang/parser/complete/comments.txt @@ -110,11 +110,50 @@ FILE MvStructImpl(STRUCT) PsiComment(EOL_DOC_COMMENT)('/// docs') PsiWhiteSpace('\n ') - PsiElement(native)('native') + PsiElement(struct_kw)('struct') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('S1') PsiWhiteSpace(' ') + MvBlockFieldsImpl(BLOCK_FIELDS) + PsiElement({)('{') + PsiElement(})('}') + PsiWhiteSpace('\n ') + MvStructImpl(STRUCT) + PsiComment(EOL_DOC_COMMENT)('/// docs') + PsiWhiteSpace('\n ') PsiElement(struct_kw)('struct') PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('NatS') + PsiElement(IDENTIFIER)('S2') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement())(')') PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + MvEnumImpl(ENUM) + PsiComment(EOL_DOC_COMMENT)('/// docs') + PsiWhiteSpace('\n ') + PsiElement(enum_kw)('enum') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('S') + PsiWhiteSpace(' ') + MvEnumBodyImpl(ENUM_BODY) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvEnumVariantImpl(ENUM_VARIANT) + PsiComment(EOL_DOC_COMMENT)('/// docs') + PsiWhiteSpace('\n ') + PsiElement(IDENTIFIER)('One') + PsiElement(,)(',') + PsiWhiteSpace('\n ') + MvEnumVariantImpl(ENUM_VARIANT) + PsiComment(EOL_DOC_COMMENT)('/// docs') + PsiWhiteSpace('\n ') + PsiElement(IDENTIFIER)('Two') + PsiWhiteSpace('\n ') + PsiElement(})('}') PsiWhiteSpace('\n') PsiElement(})('}') \ No newline at end of file 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 index d9ebf3669..ac2e30f1b 100644 --- a/src/test/resources/org/move/lang/parser/complete/dot_expressions.txt +++ b/src/test/resources/org/move/lang/parser/complete/dot_expressions.txt @@ -27,10 +27,10 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field1') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field2') PsiElement(;)(';') PsiWhiteSpace('\n ') @@ -41,7 +41,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -71,7 +71,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') MvMethodCallImpl(METHOD_CALL) @@ -178,7 +178,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement([)('[') MvLitExprImpl(LIT_EXPR) diff --git a/src/test/resources/org/move/lang/parser/complete/expressions_assignments.txt b/src/test/resources/org/move/lang/parser/complete/expressions_assignments.txt index db647cf52..48d2889fa 100644 --- a/src/test/resources/org/move/lang/parser/complete/expressions_assignments.txt +++ b/src/test/resources/org/move/lang/parser/complete/expressions_assignments.txt @@ -85,7 +85,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('a') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) diff --git a/src/test/resources/org/move/lang/parser/complete/function_calls.txt b/src/test/resources/org/move/lang/parser/complete/function_calls.txt index 54ca0bfbf..2ca85ffd8 100644 --- a/src/test/resources/org/move/lang/parser/complete/function_calls.txt +++ b/src/test/resources/org/move/lang/parser/complete/function_calls.txt @@ -178,7 +178,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('a') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('b') PsiElement(,)(',') PsiWhiteSpace(' ') diff --git a/src/test/resources/org/move/lang/parser/complete/index_expr.txt b/src/test/resources/org/move/lang/parser/complete/index_expr.txt index 7d6bb1c14..032b70366 100644 --- a/src/test/resources/org/move/lang/parser/complete/index_expr.txt +++ b/src/test/resources/org/move/lang/parser/complete/index_expr.txt @@ -134,7 +134,7 @@ FILE PsiElement(INTEGER_LITERAL)('0') PsiElement(])(']') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -207,10 +207,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -240,10 +240,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -277,10 +277,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -320,10 +320,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -415,10 +415,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -524,10 +524,10 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('y') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -575,10 +575,10 @@ FILE PsiElement(IDENTIFIER)('addr') PsiElement(])(']') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -630,10 +630,10 @@ FILE PsiElement(])(']') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -739,10 +739,10 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('y') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -800,10 +800,10 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('y_resource') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) diff --git a/src/test/resources/org/move/lang/parser/complete/positional_fields.move b/src/test/resources/org/move/lang/parser/complete/positional_fields.move new file mode 100644 index 000000000..f9d478312 --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/positional_fields.move @@ -0,0 +1,23 @@ +module 0x1::positional_fields { + struct S1(u8); + struct S2(u8, bool, aptos_framework::option::Option); + + enum E { + V(bool, aptos_framework::option::Option) + } + + // value construction with anonymous fields + fun construct() { + let x = S(42); + let y = E::V(true, 42); + } + + // value destruction with anonymous fields + fun destruct(x: S, y: E) { + x.0; + let S(_x) = x; + match (y) { + E::V(_x, _y) => {}, + } + } +} diff --git a/src/test/resources/org/move/lang/parser/complete/positional_fields.txt b/src/test/resources/org/move/lang/parser/complete/positional_fields.txt new file mode 100644 index 000000000..3acec0532 --- /dev/null +++ b/src/test/resources/org/move/lang/parser/complete/positional_fields.txt @@ -0,0 +1,278 @@ +FILE + MvModuleImpl(MODULE) + PsiElement(module)('module') + PsiWhiteSpace(' ') + MvAddressRefImpl(ADDRESS_REF) + PsiElement(DIEM_ADDRESS)('0x1') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('positional_fields') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvStructImpl(STRUCT) + PsiElement(struct_kw)('struct') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('S1') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvStructImpl(STRUCT) + PsiElement(struct_kw)('struct') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('S2') + MvTypeParameterListImpl(TYPE_PARAMETER_LIST) + PsiElement(<)('<') + MvTypeParameterImpl(TYPE_PARAMETER) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bool') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + MvPathImpl(PATH) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('aptos_framework') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('option') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Option') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + MvEnumImpl(ENUM) + PsiElement(enum_kw)('enum') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E') + MvTypeParameterListImpl(TYPE_PARAMETER_LIST) + PsiElement(<)('<') + MvTypeParameterImpl(TYPE_PARAMETER) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') + PsiWhiteSpace(' ') + MvEnumBodyImpl(ENUM_BODY) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvEnumVariantImpl(ENUM_VARIANT) + PsiElement(IDENTIFIER)('V') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('bool') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + MvPathImpl(PATH) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('aptos_framework') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('option') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Option') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') + PsiElement())(')') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n\n ') + MvFunctionImpl(FUNCTION) + PsiComment(EOL_COMMENT)('// value construction with anonymous fields') + PsiWhiteSpace('\n ') + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('construct') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvLetStmtImpl(LET_STMT) + PsiElement(let)('let') + PsiWhiteSpace(' ') + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('x') + PsiWhiteSpace(' ') + MvInitializerImpl(INITIALIZER) + PsiElement(=)('=') + PsiWhiteSpace(' ') + MvCallExprImpl(CALL_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('S') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('42') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvLetStmtImpl(LET_STMT) + PsiElement(let)('let') + PsiWhiteSpace(' ') + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('y') + PsiWhiteSpace(' ') + MvInitializerImpl(INITIALIZER) + PsiElement(=)('=') + PsiWhiteSpace(' ') + MvCallExprImpl(CALL_EXPR) + MvPathImpl(PATH) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('E') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('V') + MvValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvLitExprImpl(LIT_EXPR) + PsiElement(BOOL_LITERAL)('true') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvValueArgumentImpl(VALUE_ARGUMENT) + MvLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('42') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n\n ') + MvFunctionImpl(FUNCTION) + PsiComment(EOL_COMMENT)('// value destruction with anonymous fields') + PsiWhiteSpace('\n ') + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('destruct') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + MvFunctionParameterImpl(FUNCTION_PARAMETER) + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('x') + MvTypeAnnotationImpl(TYPE_ANNOTATION) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('S') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvFunctionParameterImpl(FUNCTION_PARAMETER) + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('y') + MvTypeAnnotationImpl(TYPE_ANNOTATION) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('E') + PsiElement())(')') + PsiWhiteSpace(' ') + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvExprStmtImpl(EXPR_STMT) + MvDotExprImpl(DOT_EXPR) + MvPathExprImpl(PATH_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('x') + PsiElement(.)('.') + MvFieldLookupImpl(FIELD_LOOKUP) + PsiElement(INTEGER_LITERAL)('0') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvLetStmtImpl(LET_STMT) + PsiElement(let)('let') + PsiWhiteSpace(' ') + MvPatTupleStructImpl(PAT_TUPLE_STRUCT) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('S') + PsiElement(()('(') + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('_x') + PsiElement())(')') + PsiWhiteSpace(' ') + MvInitializerImpl(INITIALIZER) + PsiElement(=)('=') + PsiWhiteSpace(' ') + MvPathExprImpl(PATH_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('x') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + MvMatchExprImpl(MATCH_EXPR) + PsiElement(match_kw)('match') + PsiWhiteSpace(' ') + MvMatchArgumentImpl(MATCH_ARGUMENT) + PsiElement(()('(') + MvPathExprImpl(PATH_EXPR) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('y') + PsiElement())(')') + PsiWhiteSpace(' ') + MvMatchBodyImpl(MATCH_BODY) + PsiElement({)('{') + PsiWhiteSpace('\n ') + MvMatchArmImpl(MATCH_ARM) + MvPatTupleStructImpl(PAT_TUPLE_STRUCT) + MvPathImpl(PATH) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('E') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('V') + PsiElement(()('(') + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('_x') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvPatBindingImpl(PAT_BINDING) + PsiElement(IDENTIFIER)('_y') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement(=>)('=>') + PsiWhiteSpace(' ') + MvCodeBlockExprImpl(CODE_BLOCK_EXPR) + MvCodeBlockImpl(CODE_BLOCK) + PsiElement({)('{') + PsiElement(})('}') + PsiElement(,)(',') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n ') + PsiElement(})('}') + PsiWhiteSpace('\n') + PsiElement(})('}') \ No newline at end of file diff --git a/src/test/resources/org/move/lang/parser/complete/struct_declarations.move b/src/test/resources/org/move/lang/parser/complete/struct_declarations.move index 22e625aaf..56481dd9b 100644 --- a/src/test/resources/org/move/lang/parser/complete/struct_declarations.move +++ b/src/test/resources/org/move/lang/parser/complete/struct_declarations.move @@ -12,8 +12,4 @@ module 0x1::M { operator_account: Option
, operator_account2: Option<&signer>, } - - native struct NativeStruct; - - native struct NativeStructParams; } diff --git a/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt b/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt index ccdae9a44..db3508108 100644 --- a/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt +++ b/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt @@ -166,30 +166,5 @@ FILE PsiElement(,)(',') PsiWhiteSpace('\n ') PsiElement(})('}') - PsiWhiteSpace('\n\n ') - MvStructImpl(STRUCT) - PsiElement(native)('native') - PsiWhiteSpace(' ') - PsiElement(struct_kw)('struct') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('NativeStruct') - PsiElement(;)(';') - PsiWhiteSpace('\n\n ') - MvStructImpl(STRUCT) - PsiElement(native)('native') - PsiWhiteSpace(' ') - PsiElement(struct_kw)('struct') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('NativeStructParams') - MvTypeParameterListImpl(TYPE_PARAMETER_LIST) - PsiElement(<)('<') - MvTypeParameterImpl(TYPE_PARAMETER) - PsiElement(IDENTIFIER)('K') - PsiElement(,)(',') - PsiWhiteSpace(' ') - MvTypeParameterImpl(TYPE_PARAMETER) - PsiElement(IDENTIFIER)('V') - PsiElement(>)('>') - PsiElement(;)(';') PsiWhiteSpace('\n') PsiElement(})('}') \ No newline at end of file diff --git a/src/test/resources/org/move/lang/parser/partial/assignments.txt b/src/test/resources/org/move/lang/parser/partial/assignments.txt index bf98293e9..4ed51569d 100644 --- a/src/test/resources/org/move/lang/parser/partial/assignments.txt +++ b/src/test/resources/org/move/lang/parser/partial/assignments.txt @@ -194,7 +194,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('record') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -213,7 +213,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('record') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) 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 89a1b9453..63f0e137e 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 @@ -26,7 +26,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'assert' + PsiErrorElement: or IDENTIFIER expected, got 'assert' PsiWhiteSpace(' ') MvExprStmtImpl(EXPR_STMT) @@ -52,7 +52,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'S' + PsiErrorElement: or IDENTIFIER expected, got 'S' PsiWhiteSpace(' ') MvExprStmtImpl(EXPR_STMT) @@ -95,7 +95,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiErrorElement:';' expected, got 'bin' @@ -106,7 +106,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('field') PsiErrorElement:';' expected, got 'bin' @@ -117,7 +117,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'aptos_token' + PsiErrorElement: or IDENTIFIER expected, got 'aptos_token' PsiWhiteSpace(' ') MvExprStmtImpl(EXPR_STMT) @@ -138,7 +138,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'b"' + PsiErrorElement: or IDENTIFIER expected, got 'b"' PsiWhiteSpace(' ') MvExprStmtImpl(EXPR_STMT) @@ -153,7 +153,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'x"' + PsiErrorElement: or IDENTIFIER expected, got 'x"' PsiWhiteSpace(' ') MvExprStmtImpl(EXPR_STMT) @@ -168,7 +168,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got 'return' + PsiErrorElement: or IDENTIFIER expected, got 'return' PsiWhiteSpace(' ') MvReturnExprImpl(RETURN_EXPR) @@ -195,7 +195,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('no_type_args_without_colon_colon') MvBinaryOpImpl(BINARY_OP) PsiElement(<)('<') diff --git a/src/test/resources/org/move/lang/parser/partial/expressions.txt b/src/test/resources/org/move/lang/parser/partial/expressions.txt index c9ec0f983..87fdbe2c5 100644 --- a/src/test/resources/org/move/lang/parser/partial/expressions.txt +++ b/src/test/resources/org/move/lang/parser/partial/expressions.txt @@ -21,7 +21,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('bin') PsiElement(.)('.') - PsiErrorElement:IDENTIFIER expected, got ';' + PsiErrorElement: or IDENTIFIER expected, got ';' PsiElement(;)(';') PsiWhiteSpace('\n ') diff --git a/src/test/resources/org/move/lang/parser/partial/function_calls.txt b/src/test/resources/org/move/lang/parser/partial/function_calls.txt index 01128507d..a47aca767 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_calls.txt +++ b/src/test/resources/org/move/lang/parser/partial/function_calls.txt @@ -284,7 +284,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('s') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -307,7 +307,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('s') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -330,7 +330,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('s') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('val') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) diff --git a/src/test/resources/org/move/lang/parser/partial/function_signatures.move b/src/test/resources/org/move/lang/parser/partial/function_signatures.move index 651cdae83..8bcd8fb72 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_signatures.move +++ b/src/test/resources/org/move/lang/parser/partial/function_signatures.move @@ -1,4 +1,4 @@ -module M { +module 0x1::m { fun main(a,) {} fun main(a: u8, b) {} fun main(a: u8, b:) {} @@ -9,7 +9,7 @@ module M { public(script) public fun - native + fun native fun native public native public(friend) diff --git a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt index bd1330779..b6e59cea3 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt +++ b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt @@ -2,7 +2,10 @@ FILE MvModuleImpl(MODULE) PsiElement(module)('module') PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('M') + MvAddressRefImpl(ADDRESS_REF) + PsiElement(DIEM_ADDRESS)('0x1') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('m') PsiWhiteSpace(' ') PsiElement({)('{') PsiWhiteSpace('\n ') @@ -114,12 +117,13 @@ FILE PsiElement(public)('public') PsiWhiteSpace(' ') PsiElement(fun)('fun') - PsiErrorElement:IDENTIFIER expected, got 'native' + PsiErrorElement:IDENTIFIER expected, got 'fun' PsiWhiteSpace('\n\n ') - PsiElement(native)('native') - PsiErrorElement:struct_kw expected, got 'native' - + MvFunctionImpl(FUNCTION) + PsiElement(fun)('fun') + PsiErrorElement:IDENTIFIER expected, got 'native' + PsiWhiteSpace('\n ') MvFunctionImpl(FUNCTION) PsiElement(native)('native') diff --git a/src/test/resources/org/move/lang/parser/partial/struct_decls.move b/src/test/resources/org/move/lang/parser/partial/struct_decls.move index b3a38176b..58105dce5 100644 --- a/src/test/resources/org/move/lang/parser/partial/struct_decls.move +++ b/src/test/resources/org/move/lang/parser/partial/struct_decls.move @@ -1,9 +1,10 @@ module 0x1::M { struct - native struct struct S struct {} - native struct S1 + struct () + struct (u8) + struct (); struct S struct S } diff --git a/src/test/resources/org/move/lang/parser/partial/struct_decls.txt b/src/test/resources/org/move/lang/parser/partial/struct_decls.txt index 425008303..af7703f42 100644 --- a/src/test/resources/org/move/lang/parser/partial/struct_decls.txt +++ b/src/test/resources/org/move/lang/parser/partial/struct_decls.txt @@ -10,13 +10,6 @@ FILE PsiElement({)('{') PsiWhiteSpace('\n ') MvStructImpl(STRUCT) - PsiElement(struct_kw)('struct') - PsiErrorElement:IDENTIFIER expected, got 'native' - - PsiWhiteSpace('\n ') - MvStructImpl(STRUCT) - PsiElement(native)('native') - PsiWhiteSpace(' ') PsiElement(struct_kw)('struct') PsiErrorElement:IDENTIFIER expected, got 'struct' @@ -25,7 +18,7 @@ FILE PsiElement(struct_kw)('struct') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('S') - PsiErrorElement: or '{' expected, got 'struct' + PsiErrorElement:'(', or '{' expected, got 'struct' PsiWhiteSpace('\n ') MvStructImpl(STRUCT) @@ -38,13 +31,40 @@ FILE PsiElement(})('}') PsiWhiteSpace('\n ') MvStructImpl(STRUCT) - PsiElement(native)('native') + PsiElement(struct_kw)('struct') + PsiErrorElement:IDENTIFIER expected, got '(' + PsiWhiteSpace(' ') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + PsiElement())(')') + PsiErrorElement:';' expected, got 'struct' + + PsiWhiteSpace('\n ') + MvStructImpl(STRUCT) PsiElement(struct_kw)('struct') + PsiErrorElement:IDENTIFIER expected, got '(' + PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('S1') - PsiErrorElement:';' or expected, got 'struct' + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + MvTupleFieldDeclImpl(TUPLE_FIELD_DECL) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement())(')') + PsiErrorElement:';' expected, got 'struct' + + PsiWhiteSpace('\n ') + MvStructImpl(STRUCT) + PsiElement(struct_kw)('struct') + PsiErrorElement:IDENTIFIER expected, got '(' + PsiWhiteSpace(' ') + MvTupleFieldsImpl(TUPLE_FIELDS) + PsiElement(()('(') + PsiElement())(')') + PsiElement(;)(';') PsiWhiteSpace('\n ') MvStructImpl(STRUCT) PsiElement(struct_kw)('struct') diff --git a/src/test/resources/org/move/lang/parser/partial/top_level_items.txt b/src/test/resources/org/move/lang/parser/partial/top_level_items.txt index ecbdcbb6a..7ac387644 100644 --- a/src/test/resources/org/move/lang/parser/partial/top_level_items.txt +++ b/src/test/resources/org/move/lang/parser/partial/top_level_items.txt @@ -294,7 +294,7 @@ FILE PsiErrorElement:
or IDENTIFIER expected, got '{' PsiWhiteSpace(' ') - PsiErrorElement:'#',
, , , , , , , IDENTIFIER or spec expected, got '{' + PsiErrorElement:'#',
, , , , , , IDENTIFIER or spec expected, got '{' PsiElement({)('{') PsiWhiteSpace('\n ') MvUseStmtImpl(USE_STMT) @@ -347,7 +347,7 @@ FILE PsiErrorElement:
or IDENTIFIER expected, got '{' PsiWhiteSpace(' ') - PsiErrorElement:'#',
, , , , , , , IDENTIFIER or spec expected, got '{' + PsiErrorElement:'#',
, , , , , , IDENTIFIER or spec expected, got '{' PsiElement({)('{') PsiWhiteSpace('\n ') MvUseStmtImpl(USE_STMT) diff --git a/src/test/resources/org/move/lang/parser/specs/conditions.txt b/src/test/resources/org/move/lang/parser/specs/conditions.txt index 64ca2dfea..d7916c1a3 100644 --- a/src/test/resources/org/move/lang/parser/specs/conditions.txt +++ b/src/test/resources/org/move/lang/parser/specs/conditions.txt @@ -184,7 +184,7 @@ FILE PsiElement(IDENTIFIER)('a') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -800,7 +800,7 @@ FILE PsiElement(IDENTIFIER)('a') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('value') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -915,7 +915,7 @@ FILE PsiElement(IDENTIFIER)('i') PsiElement(])(']') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('id') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -988,7 +988,7 @@ FILE PsiElement(IDENTIFIER)('i') PsiElement(])(']') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('id') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -1042,7 +1042,7 @@ FILE PsiElement(HEX_INTEGER_LITERAL)('0x0') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('f') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -1066,7 +1066,7 @@ FILE PsiElement(HEX_INTEGER_LITERAL)('0x1') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('f') PsiElement(;)(';') PsiWhiteSpace('\n ') @@ -1093,7 +1093,7 @@ FILE PsiElement(HEX_INTEGER_LITERAL)('0x0') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('f') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) @@ -1117,7 +1117,7 @@ FILE PsiElement(HEX_INTEGER_LITERAL)('0x1') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('f') PsiElement(;)(';') PsiWhiteSpace('\n ') diff --git a/src/test/resources/org/move/lang/parser/specs/spec_file.txt b/src/test/resources/org/move/lang/parser/specs/spec_file.txt index 647c55f6a..935c39da0 100644 --- a/src/test/resources/org/move/lang/parser/specs/spec_file.txt +++ b/src/test/resources/org/move/lang/parser/specs/spec_file.txt @@ -70,7 +70,7 @@ FILE PsiElement(IDENTIFIER)('aptos_framework') PsiElement())(')') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('microseconds') PsiWhiteSpace('\n ') PsiElement(})('}') diff --git a/src/test/resources/org/move/lang/parser/specs/spec_statements.txt b/src/test/resources/org/move/lang/parser/specs/spec_statements.txt index d502ae74e..683ff718f 100644 --- a/src/test/resources/org/move/lang/parser/specs/spec_statements.txt +++ b/src/test/resources/org/move/lang/parser/specs/spec_statements.txt @@ -532,7 +532,7 @@ FILE MvPathImpl(PATH) PsiElement(IDENTIFIER)('vote') PsiElement(.)('.') - MvStructDotFieldImpl(STRUCT_DOT_FIELD) + MvFieldLookupImpl(FIELD_LOOKUP) PsiElement(IDENTIFIER)('agree') PsiWhiteSpace(' ') MvBinaryOpImpl(BINARY_OP) From 7b58f8e53df7f181dab44700331d7e0f3147ee8c Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Sun, 25 Aug 2024 16:56:23 +0300 Subject: [PATCH 02/13] fix function modifiers completion in absence of native struct support --- src/main/grammars/MoveParser.bnf | 5 +- .../org/move/lang/core/MoveParserUtil.kt | 3 +- .../kotlin/org/move/lang/core/MvPsiPattern.kt | 3 + .../kotlin/org/move/lang/core/MvTokenType.kt | 1 + .../KeywordCompletionContributor.kt | 38 +++++----- .../providers/KeywordCompletionProvider.kt | 75 ++++++++++++------- .../NativeStructNotSupportedTest.kt | 12 --- .../org/move/ide/refactoring/RenameTest.kt | 16 ---- .../lang/completion/KeywordCompletionTest.kt | 18 ++++- .../org/move/lang/resolve/ResolveTypesTest.kt | 23 ------ .../parser/partial/function_signatures.move | 8 ++ .../parser/partial/function_signatures.txt | 61 ++++++++++++++- 12 files changed, 161 insertions(+), 102 deletions(-) delete mode 100644 src/test/kotlin/org/move/ide/annotator/syntaxErrors/NativeStructNotSupportedTest.kt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index d55415475..af3ba6902 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -263,6 +263,9 @@ private ModuleItem_with_recover ::= !('}' | <>) ModuleItem } private ModuleItem_recover ::= !('}' | ModuleItem_first | TopLevel_first) // top-level recovery +//private ModuleItem_first ::= use | <> +// | 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" private TopLevel_first ::= MODULE_KW | SCRIPT_KW @@ -460,8 +463,8 @@ fake Function ::= Attr* native? VisibilityModifier? entry? inline? hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] } -private FunctionInnerNoVisFirst ::= fun private FunctionInnerVisFirst ::= FunctionModifierSetInner fun { pin = 1 } +private FunctionInnerNoVisFirst ::= fun private FunctionInnerFirst ::= FunctionInnerVisFirst | FunctionInnerNoVisFirst FunctionInner ::= Attr* FunctionInnerFirst FunctionSignatureInner CodeBlock diff --git a/src/main/kotlin/org/move/lang/core/MoveParserUtil.kt b/src/main/kotlin/org/move/lang/core/MoveParserUtil.kt index bf2c97714..8d7b4d61b 100644 --- a/src/main/kotlin/org/move/lang/core/MoveParserUtil.kt +++ b/src/main/kotlin/org/move/lang/core/MoveParserUtil.kt @@ -268,9 +268,8 @@ object MoveParserUtil: GeneratedParserUtilBase() { b.tokenType == NATIVE -> { if (FunModifier.NATIVE !in modifiersLeft) return isParsed() modifiersLeft.remove(FunModifier.NATIVE) - // native alone only should give true for next token fun - parsed = parsed || (b.lookAhead(1) == FUN) nativeEncountered = true + parsed = true b.advanceLexer() } entryKeyword(b, level) -> { diff --git a/src/main/kotlin/org/move/lang/core/MvPsiPattern.kt b/src/main/kotlin/org/move/lang/core/MvPsiPattern.kt index 9bd68a728..053f0fdd8 100644 --- a/src/main/kotlin/org/move/lang/core/MvPsiPattern.kt +++ b/src/main/kotlin/org/move/lang/core/MvPsiPattern.kt @@ -158,6 +158,9 @@ object MvPsiPattern { } } + fun afterAnySibling(siblings: TokenSet, withPossibleError: Boolean = true) = + AfterAnySibling(siblings, withPossibleError) + class AfterAnySibling(val siblings: TokenSet, val withPossibleError: Boolean = true): PatternCondition("afterSiblingKeywords") { override fun accepts(t: PsiElement, context: ProcessingContext?): Boolean { diff --git a/src/main/kotlin/org/move/lang/core/MvTokenType.kt b/src/main/kotlin/org/move/lang/core/MvTokenType.kt index 391f76497..3b45f502d 100644 --- a/src/main/kotlin/org/move/lang/core/MvTokenType.kt +++ b/src/main/kotlin/org/move/lang/core/MvTokenType.kt @@ -23,6 +23,7 @@ val MOVE_KEYWORDS = tokenSetOf( ) val CONTEXTUAL_KEYWORDS = tokenSetOf(MATCH_KW) +val FUNCTION_MODIFIERS = tokenSetOf(VISIBILITY_MODIFIER, NATIVE, ENTRY, INLINE) val TYPES = tokenSetOf(PATH_TYPE, REF_TYPE, TUPLE_TYPE) val MOVE_COMMENTS = tokenSetOf(BLOCK_COMMENT, EOL_COMMENT, EOL_DOC_COMMENT) diff --git a/src/main/kotlin/org/move/lang/core/completion/KeywordCompletionContributor.kt b/src/main/kotlin/org/move/lang/core/completion/KeywordCompletionContributor.kt index 849be46a9..368f72e52 100644 --- a/src/main/kotlin/org/move/lang/core/completion/KeywordCompletionContributor.kt +++ b/src/main/kotlin/org/move/lang/core/completion/KeywordCompletionContributor.kt @@ -6,10 +6,10 @@ import com.intellij.codeInsight.completion.CompletionResultSet import com.intellij.codeInsight.completion.CompletionType import com.intellij.patterns.PlatformPatterns import com.intellij.patterns.PlatformPatterns.psiElement -import com.jetbrains.rd.util.remove import org.move.cli.settings.moveSettings import org.move.lang.MvElementTypes.* -import org.move.lang.core.MvPsiPattern +import org.move.lang.core.* +import org.move.lang.core.MvPsiPattern.afterAnySibling import org.move.lang.core.MvPsiPattern.anySpecStart import org.move.lang.core.MvPsiPattern.codeStatementPattern import org.move.lang.core.MvPsiPattern.function @@ -17,11 +17,10 @@ import org.move.lang.core.MvPsiPattern.identifierStatementBeginningPattern import org.move.lang.core.MvPsiPattern.itemSpecStmt import org.move.lang.core.MvPsiPattern.module import org.move.lang.core.MvPsiPattern.moduleSpecBlock -import org.move.lang.core.MvPsiPattern.onStatementBeginning import org.move.lang.core.MvPsiPattern.script import org.move.lang.core.MvPsiPattern.toplevel import org.move.lang.core.MvPsiPattern.typeParameter -import org.move.lang.core.TYPES +import org.move.lang.core.completion.providers.FunctionModifierCompletionProvider import org.move.lang.core.completion.providers.KeywordCompletionProvider class KeywordCompletionContributor: CompletionContributor() { @@ -45,8 +44,8 @@ class KeywordCompletionContributor: CompletionContributor() { CompletionType.BASIC, module().and(identifierStatementBeginningPattern()), KeywordCompletionProvider( - *(VIS_MODIFIERS.remove("public(script)")), - *FUNCTION_MODIFIERS, + *VISIBILITY_MODIFIERS, + *CONTEXT_FUNCTION_MODIFIERS, "native", "fun", "struct", @@ -67,19 +66,24 @@ class KeywordCompletionContributor: CompletionContributor() { ) extend( CompletionType.BASIC, - function().with(MvPsiPattern.AfterSibling(VISIBILITY_MODIFIER)), - KeywordCompletionProvider("fun", *FUNCTION_MODIFIERS) + function().with(afterAnySibling(FUNCTION_MODIFIERS)), + FunctionModifierCompletionProvider() ) extend( CompletionType.BASIC, - function().with(MvPsiPattern.AfterSibling(NATIVE)), + function().with(afterAnySibling(FUNCTION_MODIFIERS)), KeywordCompletionProvider("fun") ) - extend( - CompletionType.BASIC, - module().and(identifierStatementBeginningPattern("native")), - KeywordCompletionProvider(*VIS_MODIFIERS, "fun", "entry") - ) +// extend( +// CompletionType.BASIC, +// function().with(MvPsiPattern.AfterSibling(NATIVE)), +// FunctionModifierCompletionProvider() +// ) +// extend( +// CompletionType.BASIC, +// module().and(identifierStatementBeginningPattern("native")), +// KeywordCompletionProvider(*VISIBILITY_MODIFIERS, "fun", "entry") +// ) extend( CompletionType.BASIC, codeStatementPattern().and(identifierStatementBeginningPattern()), @@ -153,12 +157,12 @@ class KeywordCompletionContributor: CompletionContributor() { } } -private val VIS_MODIFIERS = arrayOf( +private val VISIBILITY_MODIFIERS = arrayOf( "public", - "public(script)", +// "public(script)", "public(friend)", "public(package)" ) -private val FUNCTION_MODIFIERS = arrayOf("entry", "inline") +private val CONTEXT_FUNCTION_MODIFIERS = arrayOf("entry", "inline") diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/KeywordCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/KeywordCompletionProvider.kt index d5ae6d960..82d291afb 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/KeywordCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/KeywordCompletionProvider.kt @@ -1,8 +1,7 @@ package org.move.lang.core.completion.providers -import com.intellij.codeInsight.completion.CompletionParameters -import com.intellij.codeInsight.completion.CompletionProvider -import com.intellij.codeInsight.completion.CompletionResultSet +import com.intellij.codeInsight.completion.* +import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.openapi.editor.EditorModificationUtil import com.intellij.openapi.project.Project @@ -10,9 +9,9 @@ import com.intellij.psi.util.elementType import com.intellij.util.ProcessingContext import org.move.lang.MvElementTypes.L_BRACE import org.move.lang.core.completion.* -import org.move.lang.core.psi.ext.isErrorElement -import org.move.lang.core.psi.ext.isWhitespace -import org.move.lang.core.psi.ext.rightSiblings +import org.move.lang.core.psi.MvFunction +import org.move.lang.core.psi.ext.* +import org.move.lang.core.psi.isNative class KeywordCompletionProvider( private val fillCompletions: (Project) -> List @@ -29,45 +28,71 @@ class KeywordCompletionProvider( val project = parameters.position.project val keywords = fillCompletions(project) for (keyword in keywords) { - var builder = LookupElementBuilder.create(keyword).bold() - builder = addInsertionHandler(keyword, builder, parameters) - result.addElement(builder.withPriority(KEYWORD_PRIORITY)) + result.addElement(createKeywordLookupElement(keyword, parameters)) } } } -private fun addInsertionHandler( - keyword: String, - builder: LookupElementBuilder, - parameters: CompletionParameters -): LookupElementBuilder { - val posParent = parameters.position.parent - val posRightSiblings = - posParent.rightSiblings.filter { !it.isWhitespace() && !it.isErrorElement() } - val posParentNextSibling = posRightSiblings.firstOrNull()?.firstChild +class FunctionModifierCompletionProvider: CompletionProvider() { + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet + ) { + val ident = parameters.position + val function = ident.parent as? MvFunction ?: return + + val keywords = buildList { + if (function.visibilityModifier == null) add("public") + if (!function.isEntry) add("entry") + if (!function.isNative) add("native") + if (!function.isInline) add("inline") + } + for (keyword in keywords) { + result.addElement(createKeywordLookupElement(keyword, parameters)) + } + } +} + +private fun createKeywordLookupElement(keyword: String, parameters: CompletionParameters): LookupElement { + return LookupElementBuilder + .create(keyword) + .bold() + .withInsertHandler(KeywordInsertionHandler(keyword, parameters)) + .withPriority(KEYWORD_PRIORITY) +} + +private class KeywordInsertionHandler( + val keyword: String, + val parameters: CompletionParameters, +): InsertHandler { + override fun handleInsert(context: InsertionContext, item: LookupElement) { + val posParent = parameters.position.parent + val posRightSiblings = + posParent.rightSiblings.filter { !it.isWhitespace() && !it.isErrorElement() } + val posParentNextSibling = posRightSiblings.firstOrNull()?.firstChild - return builder.withInsertHandler { ctx, _ -> val elemSibling = parameters.position.nextSibling val suffix = when { keyword == "acquires" && posParentNextSibling.elementType == L_BRACE -> { when { - ctx.nextCharIs(' ', 0) && ctx.nextCharIs(' ', 1) -> { - EditorModificationUtil.moveCaretRelatively(ctx.editor, 1) + context.nextCharIs(' ', 0) && context.nextCharIs(' ', 1) -> { + EditorModificationUtil.moveCaretRelatively(context.editor, 1) "" } - ctx.nextCharIs(' ') -> { + context.nextCharIs(' ') -> { " " } else -> { - EditorModificationUtil.moveCaretRelatively(ctx.editor, -1) + EditorModificationUtil.moveCaretRelatively(context.editor, -1) " " } } } elemSibling != null && elemSibling.isWhitespace() -> "" - posParentNextSibling == null || !ctx.alreadyHasSpace -> " " + posParentNextSibling == null || !context.alreadyHasSpace -> " " else -> "" } - ctx.addSuffix(suffix) + context.addSuffix(suffix) } } diff --git a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/NativeStructNotSupportedTest.kt b/src/test/kotlin/org/move/ide/annotator/syntaxErrors/NativeStructNotSupportedTest.kt deleted file mode 100644 index a7c2d32ea..000000000 --- a/src/test/kotlin/org/move/ide/annotator/syntaxErrors/NativeStructNotSupportedTest.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.move.ide.annotator.syntaxErrors - -import org.move.ide.annotator.MvSyntaxErrorAnnotator -import org.move.utils.tests.annotation.AnnotatorTestCase - -class NativeStructNotSupportedTest: AnnotatorTestCase(MvSyntaxErrorAnnotator::class) { - fun `test native struct is not supported by the vm`() = checkWarnings(""" - module 0x1::m { - native struct S; - } - """) -} \ No newline at end of file diff --git a/src/test/kotlin/org/move/ide/refactoring/RenameTest.kt b/src/test/kotlin/org/move/ide/refactoring/RenameTest.kt index 311e5a254..bbe4f4af8 100644 --- a/src/test/kotlin/org/move/ide/refactoring/RenameTest.kt +++ b/src/test/kotlin/org/move/ide/refactoring/RenameTest.kt @@ -292,22 +292,6 @@ class RenameTest : MvTestBase() { """ ) - fun `test native struct`() = doTest( - "RenamedNative", """ - module M { - native struct /*caret*/Native; - - native fun main(n: Native): u8; - } - """, """ - module M { - native struct RenamedNative; - - native fun main(n: RenamedNative): u8; - } - """ - ) - fun `test import alias`() = doTest( "RenamedStruct", """ address 0x1 { diff --git a/src/test/kotlin/org/move/lang/completion/KeywordCompletionTest.kt b/src/test/kotlin/org/move/lang/completion/KeywordCompletionTest.kt index 02090223f..675010a07 100644 --- a/src/test/kotlin/org/move/lang/completion/KeywordCompletionTest.kt +++ b/src/test/kotlin/org/move/lang/completion/KeywordCompletionTest.kt @@ -221,13 +221,16 @@ class KeywordCompletionTest: CompletionTestCase() { """ ) - fun `test native fun to public`() = checkContainsCompletion( - "public", """ + fun `test native fun to public`() = doSingleCompletion( + """ module 0x1::M { native pub/*caret*/ fun main(); } - """ - ) + """, """ + module 0x1::M { + native public/*caret*/ fun main(); + } + """) fun `test public fun`() = doSingleCompletion( """ @@ -454,6 +457,13 @@ class KeywordCompletionTest: CompletionTestCase() { """ ) + fun `test no native completion after native`() = checkNoCompletion( + """ + module 0x1::M { + native nat/*caret*/ + } + """) + fun `test visibility modifiers compiler v1`() = completionFixture.checkContainsCompletion( """ module 0x1::M { diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt index 8ebd71aa9..6b8a1c5a3 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt @@ -129,29 +129,6 @@ class ResolveTypesTest : ResolveTestCase() { """ ) - fun `test pass native struct to native fun`() = checkByCode( - """ - module M { - native struct Native; - //X - native fun main(n: Native): u8; - //^ - } - """ - ) - -// fun `test resolve type to import`() = checkByCode( -// """ -// script { -// use 0x1::Transaction::Sender; -// //X -// -// fun main(s: Sender) {} -// //^ -// } -// """ -// ) - fun `test resolve type from import`() = checkByCode( """ address 0x1 { diff --git a/src/test/resources/org/move/lang/parser/partial/function_signatures.move b/src/test/resources/org/move/lang/parser/partial/function_signatures.move index 8bcd8fb72..f9b0fa506 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_signatures.move +++ b/src/test/resources/org/move/lang/parser/partial/function_signatures.move @@ -9,6 +9,11 @@ module 0x1::m { public(script) public fun + native fu + public fu + entry fu + inline fu + fun native fun native public @@ -16,6 +21,9 @@ module 0x1::m { native public(script) native public fun + native pub + fun main(); + fun main_01(a b: u8) {} fun main_02(, b: u8) {} fun main_03(a: &, b: u8) {} diff --git a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt index b6e59cea3..c0957d30e 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt +++ b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt @@ -117,7 +117,44 @@ FILE PsiElement(public)('public') PsiWhiteSpace(' ') PsiElement(fun)('fun') - PsiErrorElement:IDENTIFIER expected, got 'fun' + PsiErrorElement:IDENTIFIER expected, got 'native' + + PsiWhiteSpace('\n\n ') + MvFunctionImpl(FUNCTION) + PsiElement(native)('native') + PsiErrorElement:fun expected, got 'fu' + + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('fu') + PsiErrorElement:'(' or expected, got 'public' + + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + MvVisibilityModifierImpl(VISIBILITY_MODIFIER) + PsiElement(public)('public') + PsiErrorElement:'(' or fun expected, got 'fu' + + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('fu') + PsiErrorElement:'(' or expected, got 'entry' + + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + PsiElement(entry_kw)('entry') + PsiErrorElement:fun expected, got 'fu' + + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('fu') + PsiErrorElement:'(' or expected, got 'inline' + + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + PsiElement(inline_kw)('inline') + PsiErrorElement:fun expected, got 'fu' + + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('fu') + PsiErrorElement:'(' or expected, got 'fun' PsiWhiteSpace('\n\n ') MvFunctionImpl(FUNCTION) @@ -169,8 +206,28 @@ FILE PsiElement(public)('public') PsiWhiteSpace(' ') PsiElement(fun)('fun') - PsiErrorElement:IDENTIFIER expected, got 'fun' + PsiErrorElement:IDENTIFIER expected, got 'native' + + PsiWhiteSpace('\n\n ') + MvFunctionImpl(FUNCTION) + PsiElement(native)('native') + PsiErrorElement:fun expected, got 'pub' + + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('pub') + PsiErrorElement:'(' or expected, got 'fun' + + PsiWhiteSpace('\n ') + MvFunctionImpl(FUNCTION) + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('main') + MvFunctionParameterListImpl(FUNCTION_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiErrorElement:'{' expected, got ';' + PsiElement(;)(';') PsiWhiteSpace('\n\n ') MvFunctionImpl(FUNCTION) PsiElement(fun)('fun') From fd39761e715a4c5a93cfc1389251e5c92a022b67 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Mon, 26 Aug 2024 19:16:31 +0300 Subject: [PATCH 03/13] type inference for positional fields in structs --- .../hints/StructLiteralFieldsInfoHandler.kt | 5 +- .../ide/inspections/MvTypeCheckInspection.kt | 96 ++++++++----------- .../kotlin/org/move/ide/presentation/ty.kt | 6 +- .../lang/core/completion/FuncSignature.kt | 2 +- .../lang/core/completion/MvLookupElement.kt | 2 +- .../org/move/lang/core/psi/MvFunctionLike.kt | 48 +++++----- .../org/move/lang/core/psi/ext/MvEnum.kt | 6 ++ .../move/lang/core/psi/ext/MvFieldsOwner.kt | 4 + .../org/move/lang/core/psi/ext/MvFunction.kt | 4 +- .../org/move/lang/core/psi/ext/MvModule.kt | 3 + .../org/move/lang/core/psi/ext/MvPath.kt | 3 +- .../org/move/lang/core/psi/ext/MvRangeExpr.kt | 7 ++ .../org/move/lang/core/psi/ext/MvStruct.kt | 14 +-- .../core/psi/ext/MvStructOrEnumItemElement.kt | 21 +++- .../move/lang/core/resolve/ref/Namespace.kt | 3 - .../move/lang/core/resolve2/ItemResolution.kt | 21 ++++ .../core/resolve2/LexicalDeclarations2.kt | 1 + .../lang/core/resolve2/NameResolution2.kt | 10 +- .../core/resolve2/ref/MvPath2ReferenceImpl.kt | 4 +- .../lang/core/types/infer/InferenceContext.kt | 15 +-- .../move/lang/core/types/infer/Patterns.kt | 70 +++++++++++--- .../core/types/infer/TypeInferenceWalker.kt | 48 ++++++---- .../org/move/lang/core/types/ty/TyFunction.kt | 18 ++-- .../org/move/lang/core/types/ty/TyLambda.kt | 10 +- .../inspections/MvTypeCheckInspectionTest.kt | 4 +- .../org/move/lang/resolve/ResolveTypesTest.kt | 32 +++++++ .../move/lang/resolve/ResolveVariablesTest.kt | 23 +++++ .../move/lang/types/ExpressionTypesTest.kt | 55 +++++++++++ 28 files changed, 373 insertions(+), 162 deletions(-) create mode 100644 src/main/kotlin/org/move/lang/core/psi/ext/MvRangeExpr.kt diff --git a/src/main/kotlin/org/move/ide/hints/StructLiteralFieldsInfoHandler.kt b/src/main/kotlin/org/move/ide/hints/StructLiteralFieldsInfoHandler.kt index 53813b0d6..eed35d12c 100644 --- a/src/main/kotlin/org/move/ide/hints/StructLiteralFieldsInfoHandler.kt +++ b/src/main/kotlin/org/move/ide/hints/StructLiteralFieldsInfoHandler.kt @@ -99,11 +99,10 @@ class FieldsDescription(val fields: Array) { val structPath = block.litExpr.path val struct = structPath.maybeStruct ?: return null val msl = structPath.isMslScope -// val itemContext = struct.outerItemContext(msl) val fieldParams = - struct.fieldsMap.entries.map { (name, field) -> + struct.namedFields.map { field -> + val name = field.name val type = field.type?.loweredType(msl) ?: TyUnknown -// val type = itemContext.getStructFieldItemTy(field).fullname() "$name: $type" }.toTypedArray() return FieldsDescription(fieldParams) diff --git a/src/main/kotlin/org/move/ide/inspections/MvTypeCheckInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvTypeCheckInspection.kt index fa2657831..5af39ef5d 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvTypeCheckInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvTypeCheckInspection.kt @@ -3,12 +3,14 @@ package org.move.ide.inspections import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.util.descendantsOfType +import com.intellij.psi.util.parents import org.move.cli.settings.isTypeUnknownAsError import org.move.lang.MvElementTypes.LAMBDA_EXPR import org.move.lang.MvElementTypes.MODULE import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* import org.move.lang.core.resolve2.ref.InferenceCachedPathElement +import org.move.lang.core.types.infer.MvInferenceContextOwner import org.move.lang.core.types.infer.TypeError import org.move.lang.core.types.infer.inference import org.move.lang.core.types.ty.TyUnknown @@ -16,60 +18,12 @@ import org.move.lang.core.types.ty.TyUnknown class MvTypeCheckInspection: MvLocalInspectionTool() { override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = object: MvVisitor() { - override fun visitExpr(o: MvExpr) { - super.visitExpr(o) - if (isTypeUnknownAsError()) { - checkForUnknownType(o, holder) - } - } - - override fun visitItemSpec(o: MvItemSpec) { - val inference = o.inference(true) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } - - override fun visitModuleItemSpec(o: MvModuleItemSpec) { - val inference = o.inference(true) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } - - override fun visitFunction(o: MvFunction) { - val inference = o.inference(o.isMsl()) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } - - override fun visitSpecFunction(o: MvSpecFunction) { - val inference = o.inference(true) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } - - override fun visitSpecInlineFunction(o: MvSpecInlineFunction) { - val inference = o.inference(true) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } - - override fun visitSchema(o: MvSchema) { - val inference = o.inference(true) - inference.typeErrors - .forEach { - holder.registerTypeError(it) - } - } + override fun visitItemSpec(o: MvItemSpec) = checkInferenceOwner(o, holder) + override fun visitModuleItemSpec(o: MvModuleItemSpec) = checkInferenceOwner(o, holder) + override fun visitFunction(o: MvFunction) = checkInferenceOwner(o, holder) + override fun visitSpecFunction(o: MvSpecFunction) = checkInferenceOwner(o, holder) + override fun visitSpecInlineFunction(o: MvSpecInlineFunction) = checkInferenceOwner(o, holder) + override fun visitSchema(o: MvSchema) = checkInferenceOwner(o, holder) override fun visitNamedFieldDecl(field: MvNamedFieldDecl) { val ownerItem = field.fieldOwner.itemElement as MvItemElement @@ -82,10 +36,42 @@ class MvTypeCheckInspection: MvLocalInspectionTool() { } } } + + // debug only + override fun visitExpr(o: MvExpr) { + super.visitExpr(o) + if (isTypeUnknownAsError()) { + checkForUnknownType(o, holder) + } + } } + private fun checkInferenceOwner(inferenceOwner: MvInferenceContextOwner, holder: ProblemsHolder) { + val msl = inferenceOwner.isMsl() + val inference = inferenceOwner.inference(msl) + var remainingErrors = inference.typeErrors + inference.typeErrors + .forEach { currentError -> + val otherErrors = (remainingErrors - currentError) + val element = currentError.element + val skipError = otherErrors.any { filteredError -> + // todo: change to `withSelf = false` to deal with duplicate errors + val parents = filteredError.element.parents(withSelf = true) + // if any of the other errors contain deeper element, drop this one + // NOTE: if there's a duplicate, it remains in the tree (achieved with withSelf = false) + parents.contains(element) + } + // todo: drop this to deal with duplicate errors + if (skipError) { + remainingErrors -= currentError + } + if (!skipError) { + holder.registerTypeError(currentError) + } + } + } - fun ProblemsHolder.registerTypeError(typeError: TypeError) { + private fun ProblemsHolder.registerTypeError(typeError: TypeError) { this.registerProblem( typeError.element, typeError.message(), diff --git a/src/main/kotlin/org/move/ide/presentation/ty.kt b/src/main/kotlin/org/move/ide/presentation/ty.kt index a07eee8a2..d201859c6 100644 --- a/src/main/kotlin/org/move/ide/presentation/ty.kt +++ b/src/main/kotlin/org/move/ide/presentation/ty.kt @@ -121,7 +121,7 @@ private fun render( return when (ty) { is TyFunction -> { val params = ty.paramTypes.joinToString(", ", "fn(", ")", transform = r) - var s = if (ty.retType is TyUnit) params else "$params -> ${r(ty.retType)}" + var s = if (ty.returnType is TyUnit) params else "$params -> ${r(ty.returnType)}" if (ty.acquiresTypes.isNotEmpty()) { s += ty.acquiresTypes.joinToString(", ", " acquires ", transform = r) } @@ -155,10 +155,10 @@ private fun render( } is TyLambda -> { val params = ty.paramTypes.joinToString(",", "|", "|", transform = r) - val retType = if (ty.retType is TyUnit) + val retType = if (ty.returnType is TyUnit) "()" else - r(ty.retType) + r(ty.returnType) "$params -> $retType" } is TySchema -> { diff --git a/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt b/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt index cb1ce1b0f..91e92a011 100644 --- a/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt +++ b/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt @@ -53,7 +53,7 @@ data class FuncSignature( val declaredType = function.declaredType(msl) val params = function.parameters.zip(declaredType.paramTypes) .associate { (param, paramTy) -> Pair(param.name, paramTy) } - val retType = declaredType.retType + val retType = declaredType.returnType return FuncSignature(params, retType) } } diff --git a/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt b/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt index 0888ede2d..3a2bbf3a1 100644 --- a/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt +++ b/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt @@ -63,7 +63,7 @@ fun getLookupElementProperties( val msl = context.msl val declaredTy = when (element) { - is MvFunctionLike -> element.declaredType(msl).retType + is MvFunctionLike -> element.declaredType(msl).returnType is MvStruct -> element.declaredType(msl) is MvConst -> element.type?.loweredType(msl) ?: TyUnknown is MvPatBinding -> { 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 2763a83e0..6f558a6d0 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -17,9 +17,9 @@ import org.move.lang.core.types.ty.TyFunction import org.move.lang.core.types.ty.TyLambda import org.move.lang.core.types.ty.TyUnknown -interface MvFunctionLike : MvNameIdentifierOwner, - MvTypeParametersOwner, - MvDocAndAttributeOwner { +interface MvFunctionLike: MvNameIdentifierOwner, + MvTypeParametersOwner, + MvDocAndAttributeOwner { val functionParameterList: MvFunctionParameterList? @@ -29,13 +29,13 @@ interface MvFunctionLike : MvNameIdentifierOwner, val typeParameters = this.tyTypeParams val paramTypes = parameters.map { it.type?.loweredType(msl) ?: TyUnknown } val acquiredTypes = this.acquiresPathTypes.map { it.loweredType(msl) } - val retType = rawReturnType(msl) + val retType = returnTypeTy(msl) return TyFunction( this, typeParameters, paramTypes, + retType, acquiredTypes, - retType ) } } @@ -116,10 +116,11 @@ val MvFunctionLike.signatureText: String return "$paramsText$retTypeSuffix" } -val MvFunction.selfParam: MvFunctionParameter? get() { - if (!project.moveSettings.enableReceiverStyleFunctions) return null - return this.parameters.firstOrNull()?.takeIf { it.name == "self" } -} +val MvFunction.selfParam: MvFunctionParameter? + get() { + if (!project.moveSettings.enableReceiverStyleFunctions) return null + return this.parameters.firstOrNull()?.takeIf { it.name == "self" } + } fun MvFunction.selfParamTy(msl: Boolean): Ty? = this.selfParam?.type?.loweredType(msl) @@ -133,20 +134,19 @@ val MvFunction.selfSignatureText: String return "$paramsText$retTypeSuffix" } -fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: CompletionContext?): Boolean - { - val msl = this.isMslOnlyItem - val callTy = this.declaredType(msl).substitute(this.tyInfers) as TyFunction +fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: CompletionContext?): Boolean { + val msl = this.isMslOnlyItem + val callTy = this.declaredType(msl).substitute(this.tyInfers) as TyFunction - val inferenceCtx = InferenceContext(msl) + val inferenceCtx = InferenceContext(msl) - callTy.paramTypes.forEach { - inferenceCtx.combineTypes(it, it.deepFoldTyInferWith { TyUnknown }) - } - val expectedTy = completionContext?.expectedTy - if (expectedTy != null && expectedTy !is TyUnknown) { - inferenceCtx.combineTypes(callTy.retType, expectedTy) - } - val resolvedCallTy = inferenceCtx.resolveTypeVarsIfPossible(callTy) as TyFunction - return resolvedCallTy.needsTypeAnnotation() - } \ No newline at end of file + callTy.paramTypes.forEach { + inferenceCtx.combineTypes(it, it.deepFoldTyInferWith { TyUnknown }) + } + val expectedTy = completionContext?.expectedTy + if (expectedTy != null && expectedTy !is TyUnknown) { + inferenceCtx.combineTypes(callTy.returnType, expectedTy) + } + val resolvedCallTy = inferenceCtx.resolveTypeVarsIfPossible(callTy) as TyFunction + return resolvedCallTy.needsTypeAnnotation() +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt index 2e7fa26b9..91899210f 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt @@ -12,6 +12,12 @@ import javax.swing.Icon val MvEnum.variants: List get() = enumBody?.enumVariantList.orEmpty() +val MvEnum.tupleVariants: List get() = variants.filter { it.tupleFields != null } +val MvEnum.structVariants: List get() = variants.filter { it.blockFields != null } +val MvEnum.unitVariants: List + get() = + variants.filter { it.tupleFields == null && it.blockFields == null } + abstract class MvEnumMixin: MvStubbedNamedElementImpl, MvEnum { constructor(node: ASTNode): super(node) diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt index f72194ae2..1e952c4a2 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt @@ -28,6 +28,10 @@ val MvFieldsOwner.fields: List val MvFieldsOwner.namedFields: List get() = blockFields?.namedFieldDeclList.orEmpty() +val MvFieldsOwner.fieldNames: List get() = namedFields.map { it.name } + +val MvFieldsOwner.positionalFields: List + get() = tupleFields?.tupleFieldDeclList.orEmpty() /** * True for: diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt index 7e5229cc9..a8888353b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt @@ -82,8 +82,8 @@ val MvFunction.transactionParameters: List get() = this.par // return TyFunction2(subst, paramTypes, acquiresTypes, retType) //} -fun MvFunctionLike.rawReturnType(msl: Boolean): Ty { - val retType = returnType ?: return TyUnit +fun MvFunctionLike.returnTypeTy(msl: Boolean): Ty { + val retType = this.returnType ?: return TyUnit return retType.type?.loweredType(msl) ?: TyUnknown } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvModule.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvModule.kt index e6e3c43a9..c283a5f28 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvModule.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvModule.kt @@ -104,6 +104,9 @@ fun builtinSpecFunction(text: String, project: Project): MvSpecFunction { return project.psiFactory.specFunction(trimmedText, moduleName = "builtin_spec_functions") } +fun MvModule.tupleStructs(): List = + this.structs().filter { it.tupleFields != null } + fun MvModule.structs(): List { return getProjectPsiDependentCache(this) { val stub = it.greenStub 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 49d037427..70c4ce724 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 @@ -129,7 +129,8 @@ fun MvPath.allowedNamespaces(isCompletion: Boolean = false): Set { || parent is MvSchemaRef -> SCHEMAS parent is MvStructLitExpr || parent is MvPatStruct - || parent is MvPatConst -> TYPES_N_ENUMS + || parent is MvPatConst + || parent is MvPatTupleStruct -> TYPES_N_ENUMS parent is MvAccessSpecifier -> TYPES_N_ENUMS parent is MvAddressSpecifierArg -> FUNCTIONS parent is MvAddressSpecifierCallParam -> NAMES diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvRangeExpr.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvRangeExpr.kt new file mode 100644 index 000000000..7cb101b51 --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvRangeExpr.kt @@ -0,0 +1,7 @@ +package org.move.lang.core.psi.ext + +import org.move.lang.core.psi.MvExpr +import org.move.lang.core.psi.MvRangeExpr + +val MvRangeExpr.fromExpr: MvExpr get() = exprList.first() +val MvRangeExpr.toExpr: MvExpr? get() = exprList.drop(1).firstOrNull() \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt index 69bf02ed9..dc53d074b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt @@ -17,15 +17,15 @@ import org.move.lang.core.types.ty.Ability import org.move.stdext.withAdded import javax.swing.Icon -val MvStruct.fields: List - get() = blockFields?.namedFieldDeclList.orEmpty() +//val MvStruct.fields: List +// get() = blockFields?.namedFieldDeclList.orEmpty() -val MvStruct.fieldsMap: Map - get() { - return fields.associateBy { it.name } - } +//val MvStruct.fieldsMap: Map +// get() { +// return fields.associateBy { it.name } +// } -val MvStruct.fieldNames: List get() = fields.map { it.name } +//val MvStruct.fieldNames: List get() = fields.map { it.name } //fun MvStruct.getField(fieldName: String): MvStructField? = // this.descendantsOfType().find { it.name == fieldName } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt index d05d2c32b..7456b2ec5 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt @@ -3,8 +3,8 @@ package org.move.lang.core.psi.ext import com.intellij.psi.StubBasedPsiElement import org.move.lang.core.psi.* import org.move.lang.core.stubs.MvModuleStub -import org.move.lang.core.types.ty.Ability -import org.move.lang.core.types.ty.TyAdt +import org.move.lang.core.types.infer.loweredType +import org.move.lang.core.types.ty.* interface MvStructOrEnumItemElement: MvQualNamedElement, MvItemElement, @@ -12,7 +12,22 @@ interface MvStructOrEnumItemElement: MvQualNamedElement, val abilitiesList: MvAbilitiesList? - override fun declaredType(msl: Boolean): TyAdt = TyAdt(this, this.tyTypeParams, this.generics) + override fun declaredType(msl: Boolean): Ty { + val typeParameters = this.tyTypeParams + val itemTy = TyAdt(this, typeParameters, this.generics) + if (this is MvFieldsOwner && this.tupleFields != null) { + // tuple struct or tuple enum variant + val paramTypes = this.positionalFields.map { it.type.loweredType(msl) } + return TyFunction( + this, + typeParameters, + paramTypes, + returnType = itemTy, + acquiresTypes = emptyList(), + ) + } + return itemTy + } } val MvStructOrEnumItemElement.psiAbilities: List 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 2a05046de..478f82cf6 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 @@ -23,15 +23,12 @@ enum class Namespace { ENUM, SCHEMA, MODULE; -// CONST; companion object { fun all(): Set { return EnumSet.of(NAME, FUNCTION, TYPE, ENUM, SCHEMA, MODULE) } - fun moduleItems(): Set = EnumSet.of(NAME, FUNCTION, TYPE, ENUM, SCHEMA) - fun none(): Set = setOf() } } diff --git a/src/main/kotlin/org/move/lang/core/resolve2/ItemResolution.kt b/src/main/kotlin/org/move/lang/core/resolve2/ItemResolution.kt index 7cb1dfd58..87a0107cc 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/ItemResolution.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/ItemResolution.kt @@ -3,7 +3,11 @@ package org.move.lang.core.resolve2 import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* import org.move.lang.core.resolve.* +import org.move.lang.core.resolve.ref.FUNCTIONS +import org.move.lang.core.resolve.ref.NAMES import org.move.lang.core.resolve.ref.Namespace +import org.move.lang.core.resolve.ref.Namespace.* +import org.move.lang.core.resolve.ref.TYPES import org.move.lang.core.types.infer.deepFoldTyTypeParameterWith import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyInfer @@ -43,6 +47,23 @@ fun processMethodResolveVariants( .processAllItems(setOf(Namespace.FUNCTION), itemModule.allNonTestFunctions()) } +fun processEnumVariantDeclarations( + enum: MvEnum, + ns: Set, + processor: RsResolveProcessor +): Boolean { + for (namespace in ns) { + val stop = when (namespace) { + NAME -> processor.processAll(NAMES, enum.variants) + TYPE -> processor.processAll(TYPES, enum.variants) + FUNCTION -> processor.processAll(FUNCTIONS, enum.tupleVariants) + else -> continue + } + if (stop) return true + } + return false +} + fun processItemDeclarations( itemsOwner: MvItemsOwner, ns: Set, 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 becc068e0..ef49ed7d4 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt @@ -152,6 +152,7 @@ fun processItemsInScope( val specInlineFunctions = scope.moduleItemSpecList.flatMap { it.specInlineFunctions() } processor.processAllItems( ns, + scope.tupleStructs(), scope.builtinFunctions(), scope.allNonTestFunctions(), specFunctions, 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 29af1349a..0452475c3 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt @@ -17,7 +17,7 @@ fun processStructLitFieldResolveVariants( processor: RsResolveProcessor, ): Boolean { val fieldsOwner = litField.structLitExpr.path.reference?.resolveFollowingAliases() as? MvFieldsOwner - if (fieldsOwner != null && processFieldDeclarations(fieldsOwner, processor)) return true + if (fieldsOwner != null && processNamedFieldDeclarations(fieldsOwner, processor)) return true // if it's a shorthand, try to resolve to the underlying binding pat if (!isCompletion && litField.expr == null) { val ctx = ResolutionContext(litField, false) @@ -33,7 +33,7 @@ fun processStructPatFieldResolveVariants( ): Boolean { val resolved = field.parentPatStruct.path.reference?.resolveFollowingAliases() val resolvedStruct = resolved as? MvFieldsOwner ?: return false - return processFieldDeclarations(resolvedStruct, processor) + return processNamedFieldDeclarations(resolvedStruct, processor) } fun processPatBindingResolveVariants( @@ -47,7 +47,7 @@ fun processPatBindingResolveVariants( val structItem = parentPat.path.reference?.resolveFollowingAliases() // can be null if unresolved if (structItem is MvFieldsOwner) { - if (processFieldDeclarations(structItem, originalProcessor)) return true + if (processNamedFieldDeclarations(structItem, originalProcessor)) return true if (isCompletion) return false } } @@ -218,8 +218,8 @@ fun walkUpThroughScopes( return false } -private fun processFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean = - struct.fields.any { field -> +private fun processNamedFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean = + struct.namedFields.any { field -> val name = field.name processor.process(name, NAMES, field) } diff --git a/src/main/kotlin/org/move/lang/core/resolve2/ref/MvPath2ReferenceImpl.kt b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvPath2ReferenceImpl.kt index ddfc385a9..a057aab44 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/ref/MvPath2ReferenceImpl.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvPath2ReferenceImpl.kt @@ -6,7 +6,7 @@ import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* import org.move.lang.core.resolve.* import org.move.lang.core.resolve.ref.* -import org.move.lang.core.resolve.ref.Namespace.MODULE +import org.move.lang.core.resolve.ref.Namespace.* import org.move.lang.core.resolve2.* import org.move.lang.core.resolve2.PathKind.NamedAddress import org.move.lang.core.resolve2.PathKind.ValueAddress @@ -178,7 +178,7 @@ fun processQualifiedPathResolveVariants( if (processItemDeclarations(module, ns, processor)) return true } if (resolvedQualifier is MvEnum) { - if (processor.processAll(TYPES, resolvedQualifier.variants)) return true + if (processEnumVariantDeclarations(resolvedQualifier, ns, processor)) return true } return false } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index 118b58502..7a0547083 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -222,7 +222,7 @@ class InferenceContext( fun infer(owner: MvInferenceContextOwner): InferenceResult { val returnTy = when (owner) { - is MvFunctionLike -> owner.rawReturnType(msl) + is MvFunctionLike -> owner.returnTypeTy(msl) else -> TyUnknown } val inference = TypeInferenceWalker(this, owner.project, returnTy) @@ -556,12 +556,13 @@ class InferenceContext( // Awful hack: check that inner expressions did not annotated as an error // to disallow annotation intersections. This should be done in a different way fun reportTypeError(typeError: TypeError) { - val element = typeError.element - if (!element.descendantHasTypeError(this.typeErrors) - && typeError.element.containingFile.isPhysical - ) { - typeErrors.add(typeError) - } + typeErrors.add(typeError) +// val element = typeError.element +// if (!element.descendantHasTypeError(this.typeErrors) +// && typeError.element.containingFile.isPhysical +// ) { +// typeErrors.add(typeError) +// } } } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt index 7635854fd..4d9edfb8a 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt @@ -53,8 +53,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) } } - - val structFields = item.fields.associateBy { it.name } + val structFields = item.namedFields.associateBy { it.name } for (fieldPat in this.patFieldList) { val kind = fieldPat.kind val fieldType = structFields[kind.fieldName] @@ -74,6 +73,24 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode } } } + is MvPatTupleStruct -> { + val (expected, patBm) = ty.stripReferences(defBm) + fcx.ctx.writePatTy(this, expected) + val item = + fcx.resolvePathElement(this, expected) as? MvFieldsOwner + ?: (expected as? TyAdt)?.item as? MvStruct + ?: return + val tupleFields = item.positionalFields + inferTupleFieldsTypes(fcx, patList, patBm) { indx -> + tupleFields + .getOrNull(indx) + ?.type + ?.loweredType(fcx.msl) + ?.substituteOrUnknown(ty.typeParameterValues) + ?: TyUnknown + + } + } is MvPatTuple -> { if (patList.size == 1 && ty !is TyTuple) { // let (a) = 1; @@ -81,21 +98,52 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode patList.single().extractBindings(fcx, ty) return } - val patTy = TyTuple.unknown(patList.size) - val expectedTypes = if (!isCompatible(ty, patTy, fcx.msl)) { + + // try for invalid unpacking + if (!isCompatible(ty, TyTuple.unknown(patList.size), fcx.msl)) { fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) - emptyList() - } else { - (ty as? TyTuple)?.types.orEmpty() - } - for ((idx, p) in patList.withIndex()) { - val patType = expectedTypes.getOrNull(idx) ?: TyUnknown - p.extractBindings(fcx, patType) } + + val types = (ty as? TyTuple)?.types.orEmpty() + inferTupleFieldsTypes(fcx, patList, BindByValue) { types.getOrElse(it) { TyUnknown } } } } } +private fun inferTupleFieldsTypes( + fcx: TypeInferenceWalker, + patList: List, + bm: RsBindingModeKind, +// tupleSize: Int, + type: (Int) -> Ty, +) { + + // In correct code, tuple or tuple struct patterns contain only one `..` pattern. + // But it's pretty simple to support type inference for cases with multiple `..` patterns like `let (x, .., y, .., z) = tuple` + // just ignoring all binding between first and last `..` patterns +// val firstPatRestIndex = Int.MAX_VALUE +// val lastPatRestIndex = -1 +// for ((index, pat) in patList.withIndex()) { +// if (pat.isRest) { +// firstPatRestIndex = minOf(firstPatRestIndex, index) +// lastPatRestIndex = maxOf(lastPatRestIndex, index) +// } +// } +// for ((idx, p) in patList.withIndex()) { +// val fieldType = when { +// idx < firstPatRestIndex -> type(idx) +// idx > lastPatRestIndex -> type(tupleSize - (patList.size - idx)) +// else -> TyUnknown +// } +// p.extractBindings(fcx, fieldType, bm) +// } + + for ((indx, p) in patList.withIndex()) { + val fieldType = type(indx) + p.extractBindings(fcx, fieldType, bm) + } +} + private fun Ty.applyBm(defBm: RsBindingModeKind, msl: Boolean): Ty = if (defBm is BindByReference) TyReference(this, defBm.mutability, msl) else this 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 2cb6db381..af5b266af 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 @@ -19,6 +19,7 @@ import org.move.lang.core.resolve2.ref.ResolutionContext import org.move.lang.core.resolve2.ref.resolveAliases import org.move.lang.core.resolve2.ref.resolvePathRaw import org.move.lang.core.resolve2.resolveBindingForFieldShorthand +import org.move.lang.core.types.infer.Expectation.NoExpectation import org.move.lang.core.types.ty.* import org.move.lang.core.types.ty.TyReference.Companion.autoborrow import org.move.stdext.RsResult @@ -79,7 +80,7 @@ class TypeInferenceWalker( fun inferFnBody(block: AnyBlock): Ty = block.inferBlockCoercableTo(returnTy) fun inferSpec(block: AnyBlock): Ty = - mslScope { block.inferBlockType(Expectation.NoExpectation) } + mslScope { block.inferBlockType(NoExpectation) } private fun AnyBlock.inferBlockCoercableTo(expectedTy: Ty): Ty { return this.inferBlockCoercableTo(Expectation.maybeHasType(expectedTy)) @@ -89,7 +90,10 @@ class TypeInferenceWalker( return this.inferBlockType(expected, coerce = true) } - private fun AnyBlock.inferBlockType(expected: Expectation, coerce: Boolean = false): Ty { + private fun AnyBlock.inferBlockType( + expected: Expectation = NoExpectation, + coerce: Boolean = false + ): Ty { val stmts = when (this) { is MvSpecCodeBlock, is MvModuleSpecBlock -> { // reorder stmts, move let stmts to the top, then let post, then others @@ -163,7 +167,7 @@ class TypeInferenceWalker( private fun MvExpr.inferType(expected: Ty?): Ty = this.inferType(Expectation.maybeHasType(expected)) - private fun MvExpr.inferType(expected: Expectation = Expectation.NoExpectation): Ty { + private fun MvExpr.inferType(expected: Expectation = NoExpectation): Ty { try { return inferExprTy(this, expected) } catch (e: UnificationError) { @@ -204,7 +208,7 @@ class TypeInferenceWalker( private fun inferExprTy( expr: MvExpr, - expected: Expectation = Expectation.NoExpectation + expected: Expectation = NoExpectation ): Ty { ProgressManager.checkCanceled() if (ctx.isTypeInferred(expr)) error("Trying to infer expression type twice") @@ -386,7 +390,7 @@ class TypeInferenceWalker( val ty = lambdaTy.paramTypes.getOrElse(i) { TyUnknown } ctx.writePatTy(binding, ty) } - lambdaExpr.expr?.inferTypeCoercableTo(lambdaTy.retType) + lambdaExpr.expr?.inferTypeCoercableTo(lambdaTy.returnType) return TyUnknown } @@ -400,6 +404,12 @@ class TypeInferenceWalker( ?: return TyUnknown itemTy } + is MvStruct -> { + if (namedItem.tupleFields == null) return TyUnknown + val (itemTy, _) = ctx.instantiateMethodOrPath(path, namedItem) + ?: return TyUnknown + itemTy + } is MvPatBinding -> { ctx.getBindingType(namedItem) as? TyLambda ?: TyFunction.unknownTyFunction(callExpr.project, callExpr.valueArguments.size) @@ -409,7 +419,7 @@ class TypeInferenceWalker( val funcTy = ctx.resolveTypeVarsIfPossible(baseTy) as TyCallable val expectedInputTys = - expectedInputsForExpectedOutput(expected, funcTy.retType, funcTy.paramTypes) + expectedInputsForExpectedOutput(expected, funcTy.returnType, funcTy.paramTypes) inferArgumentTypes( funcTy.paramTypes, @@ -418,7 +428,7 @@ class TypeInferenceWalker( writeCallableType(callExpr, funcTy, method = false) - return funcTy.retType + return funcTy.returnType } private fun writeCallableType(callable: MvCallable, funcTy: TyCallable, method: Boolean) { @@ -487,7 +497,7 @@ class TypeInferenceWalker( val methodTy = ctx.resolveTypeVarsIfPossible(baseTy) as TyCallable val expectedInputTys = - expectedInputsForExpectedOutput(expected, methodTy.retType, methodTy.paramTypes) + expectedInputsForExpectedOutput(expected, methodTy.returnType, methodTy.paramTypes) inferArgumentTypes( methodTy.paramTypes, @@ -498,7 +508,7 @@ class TypeInferenceWalker( writeCallableType(methodCall, methodTy, method = true) - return methodTy.retType + return methodTy.returnType } sealed class InferArg { @@ -801,11 +811,9 @@ class TypeInferenceWalker( } private fun inferRangeExprTy(rangeExpr: MvRangeExpr): Ty { - val leftTy = rangeExpr.exprList.firstOrNull()?.inferType() ?: TyUnknown -// rangeExpr.exprList.firstOrNull()?.inferTypeCoercableTo(TyInteger.DEFAULT) - rangeExpr.exprList.drop(1).firstOrNull()?.inferType(expected = leftTy) -// rangeExpr.exprList.drop(1).firstOrNull()?.inferTypeCoercableTo(TyInteger.DEFAULT) - return TyRange(leftTy) + val fromTy = rangeExpr.fromExpr.inferType() + rangeExpr.toExpr?.inferTypeCoercableTo(fromTy) + return TyRange(fromTy) } private fun inferBinaryExprTy(binaryExpr: MvBinaryExpr): Ty { @@ -995,20 +1003,24 @@ class TypeInferenceWalker( litExpr.hexStringLiteral != null -> TyHexString(ctx.msl) else -> TyUnknown } - expected.onlyHasTy(this.ctx) - ?.let { - coerce(litExpr, litTy, it) - } +// expected.onlyHasTy(this.ctx) +// ?.let { +// coerce(litExpr, litTy, it) +// } return litTy } private fun inferIfExprTy(ifExpr: MvIfExpr, expected: Expectation): Ty { ifExpr.condition?.expr?.inferTypeCoercableTo(TyBool) val actualIfTy = +// ifExpr.codeBlock?.inferBlockType(expected, coerce = false) +// ?: ifExpr.inlineBlock?.expr?.inferType(expected) ifExpr.codeBlock?.inferBlockType(expected, coerce = true) ?: ifExpr.inlineBlock?.expr?.inferTypeCoercableTo(expected) val elseBlock = ifExpr.elseBlock ?: return TyUnit val actualElseTy = +// elseBlock.codeBlock?.inferBlockType(expected) +// ?: elseBlock.inlineBlock?.expr?.inferType(expected) elseBlock.codeBlock?.inferBlockType(expected, coerce = true) ?: elseBlock.inlineBlock?.expr?.inferTypeCoercableTo(expected) diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt index e99490235..55899a5ae 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt @@ -2,20 +2,20 @@ package org.move.lang.core.types.ty import com.intellij.openapi.project.Project import org.move.ide.presentation.tyToString -import org.move.lang.core.psi.MvFunctionLike +import org.move.lang.core.psi.MvTypeParametersOwner import org.move.lang.core.psi.psiFactory import org.move.lang.core.types.infer.* data class TyFunction( - override val item: MvFunctionLike, + override val item: MvTypeParametersOwner, override val substitution: Substitution, override val paramTypes: List, + override val returnType: Ty, val acquiresTypes: List, - override val retType: Ty, -) : TyCallable, GenericTy( +): TyCallable, GenericTy( item, substitution, - mergeFlags(paramTypes) or mergeFlags(acquiresTypes) or retType.flags + mergeFlags(paramTypes) or mergeFlags(acquiresTypes) or returnType.flags ) { fun needsTypeAnnotation(): Boolean = this.substitution.hasTyInfer @@ -25,15 +25,15 @@ data class TyFunction( item, substitution.foldValues(folder), paramTypes.map { it.foldWith(folder) }, + returnType.foldWith(folder), acquiresTypes.map { it.foldWith(folder) }, - retType.foldWith(folder), ) } override fun innerVisitWith(visitor: TypeVisitor): Boolean = substitution.visitValues(visitor) || paramTypes.any { it.visitWith(visitor) } - || retType.visitWith(visitor) + || returnType.visitWith(visitor) || acquiresTypes.any { it.visitWith(visitor) } override fun abilities(): Set = Ability.all() @@ -47,8 +47,8 @@ data class TyFunction( fakeFunction, emptySubstitution, generateSequence { TyUnknown }.take(numParams).toList(), - emptyList(), - TyUnknown + TyUnknown, + acquiresTypes = emptyList(), ) } } diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyLambda.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyLambda.kt index f5204295e..1a562c4f0 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyLambda.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyLambda.kt @@ -8,13 +8,13 @@ import org.move.lang.core.types.infer.mergeFlags // TODO: inherit from GenericTy ? interface TyCallable { val paramTypes: List - val retType: Ty + val returnType: Ty } data class TyLambda( override val paramTypes: List, - override val retType: Ty -) : Ty(mergeFlags(paramTypes) or retType.flags), TyCallable { + override val returnType: Ty +) : Ty(mergeFlags(paramTypes) or returnType.flags), TyCallable { override fun abilities(): Set = emptySet() @@ -23,12 +23,12 @@ data class TyLambda( override fun innerFoldWith(folder: TypeFolder): Ty { return TyLambda( paramTypes.map { it.foldWith(folder) }, - retType.foldWith(folder), + returnType.foldWith(folder), ) } override fun innerVisitWith(visitor: TypeVisitor): Boolean = - paramTypes.any { it.visitWith(visitor) } || retType.visitWith(visitor) + paramTypes.any { it.visitWith(visitor) } || returnType.visitWith(visitor) companion object { fun unknown(numParams: Int): TyLambda { diff --git a/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt b/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt index 296732254..1bcb8baa5 100644 --- a/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt +++ b/src/test/kotlin/org/move/ide/inspections/MvTypeCheckInspectionTest.kt @@ -640,13 +640,13 @@ module 0x1::M { """ ) - fun `test tuple unpacking no nested errors`() = checkErrors( + fun `test invalid tuple unpacking with nested error`() = checkErrors( """ module 0x1::M { struct S { val: u8 } fun tuple(): (u8, u8, u8) { (1, 1, 1) } fun main() { - let (S { val }, b) = tuple(); + let (S { val }, b) = tuple(); } } """ diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt index 6b8a1c5a3..109c1b31e 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt @@ -816,4 +816,36 @@ module 0x1::m { //^ } """) + + fun `test resolve tuple struct`() = checkByCode(""" + module 0x1::m { + struct S(u8); + //X + fun main() { + S(1); + //^ + } + } + """) + + fun `test resolve enum variant tuple struct`() = checkByCode(""" + module 0x1::m { + enum S { One(u8), Two } + //X + fun main() { + S::One(1); + //^ + } + } + """) + + fun `test cannot resolve enum variant non tuple struct in call position`() = checkByCode(""" + module 0x1::m { + enum S { One(u8), Two } + fun main() { + S::Two(1); + //^ unresolved + } + } + """) } diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveVariablesTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveVariablesTest.kt index df19ad1ea..4daa3c493 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveVariablesTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveVariablesTest.kt @@ -696,4 +696,27 @@ module 0x1::string_tests { } } """) + + fun `test resolve tuple struct pattern`() = checkByCode(""" + module 0x1::m { + struct S(u8, u8); + //X + fun main(s: S) { + let S ( field1, field2 ) = s; + //^ + } + } + """) + + fun `test resolve variables in tuple struct pattern`() = checkByCode(""" + module 0x1::m { + struct S(u8, u8); + fun main(s: S) { + let S ( field1, field2 ) = s; + //X + field1; + //^ + } + } + """) } diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt index dfcaabf7a..78528e0a2 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt @@ -2003,4 +2003,59 @@ module 0x1::main { } } """) + + fun `test types for fields in tuple struct pattern`() = testExpr(""" + module 0x1::m { + struct S(u8, u8); + fun main(s: S) { + let S ( field1, field2 ) = s; + field1; + //^ u8 + } + } + """) + + fun `test field type for tuple struct pattern if more than number of fields but field is there`() = testExpr(""" + module 0x1::m { + struct S(u8); + fun main(s: S) { + let S ( field1, field2 ) = s; + field1; + //^ u8 + } + } + """) + + fun `test unknown type for tuple struct pattern if more than number of fields`() = testExpr(""" + module 0x1::m { + struct S(u8); + fun main(s: S) { + let S ( field1, field2 ) = s; + field2; + //^ + } + } + """) + + fun `test type for tuple struct literal`() = testExpr(""" + module 0x1::m { + struct S(T); + fun main() { + let s = S(true); + s; + //^ 0x1::m::S + } + } + """) + + fun `test type for tuple struct literal with multiple type parameters`() = testExpr(""" + module 0x1::m { + struct S(T, U); + fun main() { + let s = S(true, 1u8); + s; + //^ 0x1::m::S + } + } + """) } From 2160601cf7904cc03b19b12fa8215cd8c72e7fad Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Mon, 26 Aug 2024 22:48:27 +0300 Subject: [PATCH 04/13] remove type annotation element from ast --- src/main/grammars/MoveParser.bnf | 53 +++-- .../move/ide/docs/MvDocumentationProvider.kt | 2 +- .../org/move/ide/formatter/impl/spacing.kt | 2 +- .../hints/type/MvInlayTypeHintsProvider.kt | 2 +- .../PhantomTypeParameterInspection.kt | 2 +- .../org/move/ide/utils/FunctionSignature.kt | 2 +- .../org/move/lang/core/psi/ext/MvConst.kt | 4 +- .../org/move/lang/core/psi/ext/MvFieldDecl.kt | 7 + .../core/psi/ext/MvFunctionParameterList.kt | 2 +- .../move/lang/core/psi/ext/MvStructField.kt | 12 +- .../core/types/infer/TypeInferenceWalker.kt | 1 - .../MvListSelectionHandlerTest.kt | 4 - .../move/lang/types/ExpressionTypesTest.kt | 21 ++ .../lang/parser/complete/access_control.txt | 67 +++--- .../move/lang/parser/complete/attributes.txt | 11 +- .../org/move/lang/parser/complete/enums.txt | 181 +++++++-------- .../parser/complete/function_declarations.txt | 214 +++++++++--------- .../move/lang/parser/complete/index_expr.txt | 22 +- .../lang/parser/complete/let_patterns.txt | 63 +++--- .../org/move/lang/parser/complete/macros.txt | 168 +++++++------- .../org/move/lang/parser/complete/match.txt | 140 ++++++------ .../parser/complete/positional_fields.txt | 22 +- .../lang/parser/complete/public_package.txt | 11 +- .../parser/complete/struct_declarations.txt | 128 +++++------ .../org/move/lang/parser/complete/vectors.txt | 25 +- .../move/lang/parser/partial/assignments.txt | 18 +- .../parser/partial/function_signatures.txt | 83 ++++--- .../move/lang/parser/partial/module_const.txt | 51 ++--- .../org/move/lang/parser/partial/spec.txt | 2 +- .../lang/parser/partial/struct_fields.txt | 64 +++--- .../org/move/lang/parser/specs/conditions.txt | 52 ++--- .../org/move/lang/parser/specs/scopes.txt | 105 ++++----- .../lang/parser/specs/spec_statements.txt | 17 +- .../move/lang/parser/specs/spec_variables.txt | 44 ++-- 34 files changed, 761 insertions(+), 841 deletions(-) create mode 100644 src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index af3ba6902..1cc4fa281 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -281,13 +281,13 @@ private ModuleItem ::= UseStmt | ModuleItemSpec | ItemSpec -Const ::= Attr* CONST_KW IDENTIFIER TypeAnnotation Initializer ';' +Const ::= Attr* CONST_KW IDENTIFIER TypeAscription Initializer ';' { pin = "CONST_KW" implements = [ "org.move.lang.core.psi.MvQualNamedElement" "org.move.lang.core.psi.ext.MvItemElement" - "org.move.lang.core.psi.MvTypeAnnotationOwner" +// "org.move.lang.core.psi.MvTypeAnnotationOwner" ] mixin = "org.move.lang.core.psi.ext.MvConstMixin" stubClass = "org.move.lang.core.stubs.MvConstStub" @@ -513,11 +513,11 @@ private FunctionParameter_with_recover ::= !(')' | '{' | ';') FunctionParameter } private FunctionParameter_recover ::= !(')' | '{' | ';' | IDENTIFIER) -FunctionParameter ::= PatBinding TypeAnnotation { +FunctionParameter ::= PatBinding TypeAscription { pin = 1 - implements = [ - "org.move.lang.core.psi.MvTypeAnnotationOwner" - ] +// implements = [ +// "org.move.lang.core.psi.MvTypeAnnotationOwner" +// ] mixin = "org.move.lang.core.psi.ext.MvFunctionParameterMixin" } @@ -579,13 +579,14 @@ private TupleFieldDecl_with_recover ::= !')' TupleFieldDecl (',' | &')') { } private TupleFieldDecl_recover ::= !(')' | AttrsAndVis_first | Type_first) -NamedFieldDecl ::= Attr* IDENTIFIER TypeAnnotation &(',' | '}') +NamedFieldDecl ::= Attr* IDENTIFIER TypeAscription &(',' | '}') { pin = 2 implements = [ "org.move.lang.core.psi.MvMandatoryNameIdentifierOwner" "org.move.lang.core.psi.ext.MvDocAndAttributeOwner" - "org.move.lang.core.psi.MvTypeAnnotationOwner" +// "org.move.lang.core.psi.MvTypeAnnotationOwner" + "org.move.lang.core.psi.ext.MvFieldDecl" ] mixin = "org.move.lang.core.psi.ext.MvNamedFieldDeclMixin" hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] @@ -594,7 +595,9 @@ private NamedFieldDecl_first ::= AttrsAndVis_first | IDENTIFIER TupleFieldDecl ::= Attr* Type { - + implements = [ + "org.move.lang.core.psi.ext.MvFieldDecl" + ] hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] } @@ -634,10 +637,10 @@ UseAlias ::= as IDENTIFIER /////////////////////////////////////////////////////////////////////////////////////////////////// // Types /////////////////////////////////////////////////////////////////////////////////////////////////// -TypeAnnotation ::= ':' Type { - pin = 1 - name = "type annotation" -} + +private TypeAscription ::= ':' Type { pin = 1 } + +TypeAnnotation ::= ':' Type { pin = 1 } Type ::= RefType | PathType @@ -837,17 +840,17 @@ private SpecExprStmt_items ::= AssumeSpecExpr | AssertSpecExpr | AbortsIfSpecExp | EmitsSpecExpr private post ::= <> -fake LetStmt ::= let post? Pat? TypeAnnotation? Initializer? ';'? +fake LetStmt ::= let post? Pat? TypeAscription? Initializer? ';'? { - implements = ["org.move.lang.core.psi.MvTypeAnnotationOwner"] +// implements = ["org.move.lang.core.psi.MvTypeAnnotationOwner"] } -LetMoveStmt ::= let Pat TypeAnnotation? Initializer? ';' +LetMoveStmt ::= let Pat TypeAscription? Initializer? ';' { pin = 1 elementType = LetStmt } -LetMslStmt ::= (let post?) Pat TypeAnnotation? Initializer? ';' +LetMslStmt ::= (let post?) Pat TypeAscription? Initializer? ';' { pin = 1 elementType = LetStmt @@ -1406,11 +1409,11 @@ private ItemSpecFunctionParameter_with_recover ::= !(')' | '{' | ';') ItemSpecFu } private ItemSpecFunctionParameter_recover ::= !(')' | '{' | ';' | IDENTIFIER) -ItemSpecFunctionParameter ::= IDENTIFIER TypeAnnotation { +ItemSpecFunctionParameter ::= IDENTIFIER TypeAscription { pin = 1 implements = [ "org.move.lang.core.resolve.ref.MvItemSpecParameterReferenceElement" - "org.move.lang.core.psi.MvTypeAnnotationOwner" +// "org.move.lang.core.psi.MvTypeAnnotationOwner" ] mixin = "org.move.lang.core.psi.ext.MvItemSpecFunctionParameterMixin" } @@ -1469,31 +1472,31 @@ private SpecStmt ::= UseStmt | LetMslStmt | SpecExprStmt -fake SchemaFieldStmt ::= local? PatBinding TypeAnnotation ';' +fake SchemaFieldStmt ::= local? PatBinding TypeAscription ';' { implements = [ - "org.move.lang.core.psi.MvTypeAnnotationOwner" +// "org.move.lang.core.psi.MvTypeAnnotationOwner" "org.move.lang.core.psi.MslOnlyElement" ] } private SchemaFieldStmtImpl ::= SchemaFieldStmt_local | SchemaFieldStmt_simple -SchemaFieldStmt_simple ::= PatBinding TypeAnnotation ';' { +SchemaFieldStmt_simple ::= PatBinding TypeAscription ';' { pin = 2 elementType = SchemaFieldStmt } -SchemaFieldStmt_local ::= local PatBinding TypeAnnotation ';' { +SchemaFieldStmt_local ::= local PatBinding TypeAscription ';' { pin = 1 elementType = SchemaFieldStmt } -GlobalVariableStmt ::= Attr* global IDENTIFIER TypeParameterList? TypeAnnotation ('=' Expr)? ';' +GlobalVariableStmt ::= Attr* global IDENTIFIER TypeParameterList? TypeAscription ('=' Expr)? ';' { pin = 2 implements = [ "org.move.lang.core.psi.MvNameIdentifierOwner" - "org.move.lang.core.psi.MvTypeAnnotationOwner" +// "org.move.lang.core.psi.MvTypeAnnotationOwner" "org.move.lang.core.psi.MslOnlyElement" "org.move.lang.core.psi.ext.MvItemElement" ] diff --git a/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt b/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt index 255fcd069..8fe94b945 100644 --- a/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt +++ b/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt @@ -178,7 +178,7 @@ private fun PsiElement.generateDocumentation( is MvFunctionParameter -> { buffer += this.patBinding.identifier.text - this.typeAnnotation?.type?.generateDocumentation(buffer, ": ") + this.type?.generateDocumentation(buffer, ": ") } is MvTypeParameterList -> diff --git a/src/main/kotlin/org/move/ide/formatter/impl/spacing.kt b/src/main/kotlin/org/move/ide/formatter/impl/spacing.kt index 144f6dca9..27f0005a3 100644 --- a/src/main/kotlin/org/move/ide/formatter/impl/spacing.kt +++ b/src/main/kotlin/org/move/ide/formatter/impl/spacing.kt @@ -30,7 +30,7 @@ fun createSpacingBuilder(commonSettings: CommonCodeStyleSettings): SpacingBuilde .after(COLON).spaceIf(true) .before(COLON).spaceIf(false) - .before(TYPE_ANNOTATION).spacing(0, 0, 0, true, 0) +// .before(TYPE_ANNOTATION).spacing(0, 0, 0, true, 0) .before(INITIALIZER).spacing(1, 1, 0, true, 0) .between(AND, MUT).spacing(0, 0, 0, false, 0) diff --git a/src/main/kotlin/org/move/ide/hints/type/MvInlayTypeHintsProvider.kt b/src/main/kotlin/org/move/ide/hints/type/MvInlayTypeHintsProvider.kt index fe3bff372..f01c5a160 100644 --- a/src/main/kotlin/org/move/ide/hints/type/MvInlayTypeHintsProvider.kt +++ b/src/main/kotlin/org/move/ide/hints/type/MvInlayTypeHintsProvider.kt @@ -88,7 +88,7 @@ class MvInlayTypeHintsProvider : InlayHintsProvider { - if (element.typeAnnotation != null) return + if (element.type != null) return val pat = element.pat ?: return presentTypeForPat(pat, element.initializer?.expr) } diff --git a/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt b/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt index 6fa282567..7e996b2e7 100644 --- a/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt @@ -18,7 +18,7 @@ class PhantomTypeParameterInspection : MvLocalInspectionTool() { for (structField in o.fields) { val fieldUsedTypeParams = mutableSetOf() - val fieldType = structField.typeAnnotation?.type ?: continue + val fieldType = structField.type ?: continue for (path in fieldType.descendantsOfType()) { if (path.typeArguments.isNotEmpty()) continue val typeParam = path.reference?.resolve() as? MvTypeParameter ?: continue diff --git a/src/main/kotlin/org/move/ide/utils/FunctionSignature.kt b/src/main/kotlin/org/move/ide/utils/FunctionSignature.kt index 1232b1d52..6e12ef1b2 100644 --- a/src/main/kotlin/org/move/ide/utils/FunctionSignature.kt +++ b/src/main/kotlin/org/move/ide/utils/FunctionSignature.kt @@ -77,7 +77,7 @@ data class FunctionSignature( val specParameters = paramList.itemSpecFunctionParameterList val signatureParams = specParameters.map { specParam -> val paramName = specParam.referenceName - val paramType = specParam.typeAnnotation?.type?.text ?: "" + val paramType = specParam.type?.text ?: "" Parameter(paramName, paramType) } val specTypeParameters = diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvConst.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvConst.kt index 05bd11251..a5719e711 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvConst.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvConst.kt @@ -31,9 +31,9 @@ abstract class MvConstMixin : MvStubbedNamedElementImpl, override fun getIcon(flags: Int): Icon? = MoveIcons.CONST override fun getPresentation(): ItemPresentation { - val constType = this.typeAnnotation?.text ?: "" + val type = this.type?.let { ": ${it.text}" } ?: "" return PresentationData( - "${this.name}$constType", + "${this.name}$type", this.locationString(true), MoveIcons.CONST, null diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt new file mode 100644 index 000000000..9439d7a35 --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt @@ -0,0 +1,7 @@ +package org.move.lang.core.psi.ext + +import org.move.lang.core.psi.MvType + +interface MvFieldDecl: MvDocAndAttributeOwner { + val type: MvType? +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunctionParameterList.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunctionParameterList.kt index 6a79f3d1e..b5a133936 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunctionParameterList.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunctionParameterList.kt @@ -4,6 +4,6 @@ import org.move.lang.core.psi.MvFunctionParameter import org.move.utils.SignatureUtils fun List.joinToSignature(): String { - val parameterPairs = this.map { Pair(it.patBinding.name, it.typeAnnotation?.type?.text) } + val parameterPairs = this.map { Pair(it.patBinding.name, it.type?.text) } return SignatureUtils.joinParameters(parameterPairs) } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructField.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructField.kt index 6bdb212bc..775e1c42f 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructField.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructField.kt @@ -9,13 +9,9 @@ import org.move.lang.core.psi.MvNamedFieldDecl import org.move.lang.core.psi.impl.MvMandatoryNameIdentifierOwnerImpl import javax.swing.Icon -val MvNamedFieldDecl.blockFields: MvBlockFields? - get() = - parent as? MvBlockFields +val MvNamedFieldDecl.blockFields: MvBlockFields? get() = parent as? MvBlockFields -val MvNamedFieldDecl.fieldOwner: MvFieldsOwner - get() = - blockFields?.parent as MvFieldsOwner +val MvNamedFieldDecl.fieldOwner: MvFieldsOwner get() = blockFields?.parent as MvFieldsOwner abstract class MvNamedFieldDeclMixin(node: ASTNode) : MvMandatoryNameIdentifierOwnerImpl(node), MvNamedFieldDecl { @@ -23,9 +19,9 @@ abstract class MvNamedFieldDeclMixin(node: ASTNode) : MvMandatoryNameIdentifierO override fun getIcon(flags: Int): Icon = MoveIcons.STRUCT_FIELD override fun getPresentation(): ItemPresentation { - val fieldType = this.typeAnnotation?.text ?: "" + val type = this.type?.let { ": ${it.text}" } ?: "" return PresentationData( - "${this.name}${fieldType}", + "${this.name}$type", this.locationString(true), MoveIcons.STRUCT_FIELD, null 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 af5b266af..35f6a0a88 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 @@ -460,7 +460,6 @@ class TypeInferenceWalker( fun inferFieldLookupTy(receiverTy: Ty, fieldLookup: MvFieldLookup): Ty { val tyAdt = receiverTy.derefIfNeeded() as? TyAdt ?: return TyUnknown - val field = resolveSingleResolveVariant(fieldLookup.referenceName) { processNamedFieldVariants(fieldLookup, tyAdt, msl, it) diff --git a/src/test/kotlin/org/move/ide/wordSelection/MvListSelectionHandlerTest.kt b/src/test/kotlin/org/move/ide/wordSelection/MvListSelectionHandlerTest.kt index 573da0356..28d2f5f1e 100644 --- a/src/test/kotlin/org/move/ide/wordSelection/MvListSelectionHandlerTest.kt +++ b/src/test/kotlin/org/move/ide/wordSelection/MvListSelectionHandlerTest.kt @@ -17,10 +17,6 @@ class MvListSelectionHandlerTest : MvSelectionHandlerTestBase() { module 0x1::m { fun main(a: u32, b: bool) {} } - """, """ - module 0x1::m { - fun main(a: u32, b: bool) {} - } """, """ module 0x1::m { fun main(a: u32, b: bool) {} diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt index 78528e0a2..18fac9f42 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt @@ -2058,4 +2058,25 @@ module 0x1::main { } } """) + + fun `test positional field lookup type`() = testExpr(""" + module 0x1::m { + struct S(u8) + fun main(s: S) { + s.0; + //^ u8 + } + } + """) + + fun `test positional field lookup generic type`() = testExpr(""" + module 0x1::m { + struct S(T) + fun main() { + let s = S(true); + s.0; + //^ bool + } + } + """) } diff --git a/src/test/resources/org/move/lang/parser/complete/access_control.txt b/src/test/resources/org/move/lang/parser/complete/access_control.txt index 2c180e684..57de0aebc 100644 --- a/src/test/resources/org/move/lang/parser/complete/access_control.txt +++ b/src/test/resources/org/move/lang/parser/complete/access_control.txt @@ -291,12 +291,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') PsiElement())(')') PsiWhiteSpace(' ') MvResourceAccessItemListImpl(RESOURCE_ACCESS_ITEM_LIST) @@ -326,12 +325,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('param') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement())(')') PsiWhiteSpace(' ') MvResourceAccessItemListImpl(RESOURCE_ACCESS_ITEM_LIST) @@ -367,12 +365,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('x') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -458,15 +455,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('s') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('signer') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('signer') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -511,15 +507,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('s') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('signer') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('signer') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/complete/attributes.txt b/src/test/resources/org/move/lang/parser/complete/attributes.txt index 08c831ecf..32b7e2273 100644 --- a/src/test/resources/org/move/lang/parser/complete/attributes.txt +++ b/src/test/resources/org/move/lang/parser/complete/attributes.txt @@ -46,12 +46,11 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') diff --git a/src/test/resources/org/move/lang/parser/complete/enums.txt b/src/test/resources/org/move/lang/parser/complete/enums.txt index dd87fa2a6..c2d97a810 100644 --- a/src/test/resources/org/move/lang/parser/complete/enums.txt +++ b/src/test/resources/org/move/lang/parser/complete/enums.txt @@ -33,32 +33,29 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('red') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('green') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('blue') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(})('}') PsiElement(,)(',') PsiWhiteSpace('\n ') @@ -86,32 +83,29 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('red') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('green') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('blue') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(})('}') PsiWhiteSpace('\n ') MvEnumVariantImpl(ENUM_VARIANT) @@ -138,22 +132,20 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('x') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('y') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(})('}') PsiElement(,)(',') PsiWhiteSpace('\n ') @@ -163,22 +155,20 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('x') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('z') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u32') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u32') PsiElement(})('}') PsiWhiteSpace('\n ') PsiElement(})('}') @@ -201,12 +191,11 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('i') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Inner') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Inner') PsiElement(})('}') PsiElement(,)(',') PsiWhiteSpace('\n ') @@ -216,22 +205,20 @@ FILE PsiElement({)('{') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('i') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Inner') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Inner') PsiElement(,)(',') PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Box') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Box') PsiElement(})('}') PsiElement(,)(',') PsiWhiteSpace('\n ') @@ -246,39 +233,37 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('one') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - MvPathAddressImpl(PATH_ADDRESS) - PsiElement(DIEM_ADDRESS)('0x1') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('m') + MvPathAddressImpl(PATH_ADDRESS) + PsiElement(DIEM_ADDRESS)('0x1') PsiElement(::)('::') - PsiElement(IDENTIFIER)('S') + PsiElement(IDENTIFIER)('m') PsiElement(::)('::') - PsiElement(IDENTIFIER)('One') + PsiElement(IDENTIFIER)('S') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('One') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('two') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('m') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('S') + PsiElement(IDENTIFIER)('m') PsiElement(::)('::') - PsiElement(IDENTIFIER)('Two') + PsiElement(IDENTIFIER)('S') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Two') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) diff --git a/src/test/resources/org/move/lang/parser/complete/function_declarations.txt b/src/test/resources/org/move/lang/parser/complete/function_declarations.txt index 43b31980d..4958cdfb5 100644 --- a/src/test/resources/org/move/lang/parser/complete/function_declarations.txt +++ b/src/test/resources/org/move/lang/parser/complete/function_declarations.txt @@ -299,15 +299,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('s') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('signer') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('signer') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) @@ -323,18 +322,17 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('s') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Transaction') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('Sender') + PsiElement(IDENTIFIER)('Transaction') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Sender') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) @@ -350,44 +348,41 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('c') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Transaction') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('Sender') + PsiElement(IDENTIFIER)('Transaction') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Sender') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -488,19 +483,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -524,19 +518,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -560,19 +553,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -599,19 +591,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -638,19 +629,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/complete/index_expr.txt b/src/test/resources/org/move/lang/parser/complete/index_expr.txt index 032b70366..0f394a25d 100644 --- a/src/test/resources/org/move/lang/parser/complete/index_expr.txt +++ b/src/test/resources/org/move/lang/parser/complete/index_expr.txt @@ -38,12 +38,11 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('value') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('M') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('M') PsiWhiteSpace('\n ') PsiElement(})('}') PsiWhiteSpace('\n\n ') @@ -72,12 +71,11 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') PsiWhiteSpace('\n ') PsiElement(})('}') PsiWhiteSpace('\n\n ') diff --git a/src/test/resources/org/move/lang/parser/complete/let_patterns.txt b/src/test/resources/org/move/lang/parser/complete/let_patterns.txt index a5a9e2cc8..e8f3afe14 100644 --- a/src/test/resources/org/move/lang/parser/complete/let_patterns.txt +++ b/src/test/resources/org/move/lang/parser/complete/let_patterns.txt @@ -425,15 +425,14 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvParensTypeImpl(PARENS_TYPE) - PsiElement(()('(') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement())(')') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement())(')') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') @@ -447,21 +446,20 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') MvParensTypeImpl(PARENS_TYPE) PsiElement(()('(') MvParensTypeImpl(PARENS_TYPE) PsiElement(()('(') - MvParensTypeImpl(PARENS_TYPE) - PsiElement(()('(') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement())(')') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') PsiElement())(')') + PsiElement())(')') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') @@ -475,23 +473,22 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvParensTypeImpl(PARENS_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') + MvTupleTypeImpl(TUPLE_TYPE) PsiElement(()('(') - MvTupleTypeImpl(TUPLE_TYPE) - PsiElement(()('(') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(,)(',') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement())(')') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(,)(',') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') + PsiElement())(')') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') diff --git a/src/test/resources/org/move/lang/parser/complete/macros.txt b/src/test/resources/org/move/lang/parser/complete/macros.txt index 25b89f30b..c5a0117ea 100644 --- a/src/test/resources/org/move/lang/parser/complete/macros.txt +++ b/src/test/resources/org/move/lang/parser/complete/macros.txt @@ -33,37 +33,35 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('v') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace('\n ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('f') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvLambdaTypeImpl(LAMBDA_TYPE) - PsiElement(|)('|') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(|)('|') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvLambdaTypeImpl(LAMBDA_TYPE) + PsiElement(|)('|') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) MvPathTypeImpl(PATH_TYPE) MvPathImpl(PATH) - PsiElement(IDENTIFIER)('NewElement') + PsiElement(IDENTIFIER)('Element') + PsiElement(|)('|') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('NewElement') PsiElement(,)(',') PsiWhiteSpace('\n ') PsiElement())(')') @@ -157,19 +155,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('p') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvLambdaTypeImpl(LAMBDA_TYPE) - PsiElement(|)('|') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(|)('|') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvLambdaTypeImpl(LAMBDA_TYPE) + PsiElement(|)('|') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement(|)('|') PsiWhiteSpace('\n ') PsiElement())(')') PsiWhiteSpace(' ') @@ -264,73 +261,70 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvParensTypeImpl(PARENS_TYPE) - PsiElement(()('(') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement())(')') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement())(')') PsiElement(,)(',') PsiWhiteSpace('\n ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('f') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvParensTypeImpl(PARENS_TYPE) - PsiElement(()('(') - MvLambdaTypeImpl(LAMBDA_TYPE) - PsiElement(|)('|') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(|)('|') - PsiWhiteSpace(' ') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') + MvLambdaTypeImpl(LAMBDA_TYPE) + PsiElement(|)('|') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) MvPathTypeImpl(PATH_TYPE) MvPathImpl(PATH) PsiElement(IDENTIFIER)('Element') - PsiElement())(')') + PsiElement(|)('|') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement())(')') PsiElement(,)(',') PsiWhiteSpace('\n ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('g') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvLambdaTypeImpl(LAMBDA_TYPE) + PsiElement(|)('|') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement(,)(',') PsiWhiteSpace(' ') - MvLambdaTypeImpl(LAMBDA_TYPE) - PsiElement(|)('|') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(,)(',') - PsiWhiteSpace(' ') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvParensTypeImpl(PARENS_TYPE) - PsiElement(()('(') - MvLambdaTypeImpl(LAMBDA_TYPE) - PsiElement(|)('|') - MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') - PsiElement(|)('|') - PsiWhiteSpace(' ') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) + MvParensTypeImpl(PARENS_TYPE) + PsiElement(()('(') + MvLambdaTypeImpl(LAMBDA_TYPE) + PsiElement(|)('|') + MvLambdaTypeParamImpl(LAMBDA_TYPE_PARAM) MvPathTypeImpl(PATH_TYPE) MvPathImpl(PATH) PsiElement(IDENTIFIER)('Element') - PsiElement())(')') - PsiElement(|)('|') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Element') + PsiElement(|)('|') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') + PsiElement())(')') + PsiElement(|)('|') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Element') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/complete/match.txt b/src/test/resources/org/move/lang/parser/complete/match.txt index 5981c7453..4ac388fab 100644 --- a/src/test/resources/org/move/lang/parser/complete/match.txt +++ b/src/test/resources/org/move/lang/parser/complete/match.txt @@ -18,12 +18,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -144,12 +143,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -278,12 +276,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -410,12 +407,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -541,15 +537,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('m') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('Color') + PsiElement(IDENTIFIER)('m') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -679,15 +674,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) MvPathImpl(PATH) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('m') - PsiElement(::)('::') - PsiElement(IDENTIFIER)('Color') + PsiElement(IDENTIFIER)('m') + PsiElement(::)('::') + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -822,12 +816,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -928,12 +921,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -1042,12 +1034,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -1154,12 +1145,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -1283,12 +1273,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -1406,12 +1395,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('self') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Color') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Color') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/complete/positional_fields.txt b/src/test/resources/org/move/lang/parser/complete/positional_fields.txt index 3acec0532..2472b7d80 100644 --- a/src/test/resources/org/move/lang/parser/complete/positional_fields.txt +++ b/src/test/resources/org/move/lang/parser/complete/positional_fields.txt @@ -183,23 +183,21 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('x') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('S') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('S') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('y') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('E') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('E') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) diff --git a/src/test/resources/org/move/lang/parser/complete/public_package.txt b/src/test/resources/org/move/lang/parser/complete/public_package.txt index 36b3d01a9..01e00813f 100644 --- a/src/test/resources/org/move/lang/parser/complete/public_package.txt +++ b/src/test/resources/org/move/lang/parser/complete/public_package.txt @@ -24,12 +24,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('package') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt b/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt index db3508108..75ce904f9 100644 --- a/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt +++ b/src/test/resources/org/move/lang/parser/complete/struct_declarations.txt @@ -56,29 +56,27 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('val1') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('val2') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace('\n ') PsiElement(})('}') @@ -103,66 +101,62 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('val1') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('val2') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('T') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('T') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('operator_account') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Option') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Option') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('operator_account2') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('Option') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('signer') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('Option') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('signer') + PsiElement(>)('>') PsiElement(,)(',') PsiWhiteSpace('\n ') PsiElement(})('}') diff --git a/src/test/resources/org/move/lang/parser/complete/vectors.txt b/src/test/resources/org/move/lang/parser/complete/vectors.txt index ca26e48cf..13f8c5ff1 100644 --- a/src/test/resources/org/move/lang/parser/complete/vectors.txt +++ b/src/test/resources/org/move/lang/parser/complete/vectors.txt @@ -29,19 +29,18 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('vector') - MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) - PsiElement(<)('<') - MvTypeArgumentImpl(TYPE_ARGUMENT) - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') - PsiElement(>)('>') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('vector') + MvTypeArgumentListImpl(TYPE_ARGUMENT_LIST) + PsiElement(<)('<') + MvTypeArgumentImpl(TYPE_ARGUMENT) + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') + PsiElement(>)('>') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) diff --git a/src/test/resources/org/move/lang/parser/partial/assignments.txt b/src/test/resources/org/move/lang/parser/partial/assignments.txt index 4ed51569d..aee2df077 100644 --- a/src/test/resources/org/move/lang/parser/partial/assignments.txt +++ b/src/test/resources/org/move/lang/parser/partial/assignments.txt @@ -33,10 +33,9 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got '=' - + PsiElement(:)(':') + PsiErrorElement: expected, got '=' + PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') @@ -50,12 +49,11 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiErrorElement:'::', ';', or '=' expected, got '1' PsiWhiteSpace(' ') diff --git a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt index c0957d30e..9623e6538 100644 --- a/src/test/resources/org/move/lang/parser/partial/function_signatures.txt +++ b/src/test/resources/org/move/lang/parser/partial/function_signatures.txt @@ -18,7 +18,7 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - PsiErrorElement: expected, got ',' + PsiErrorElement:':' expected, got ',' PsiElement(,)(',') PsiElement())(')') @@ -36,18 +36,17 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - PsiErrorElement: expected, got ')' + PsiErrorElement:':' expected, got ')' PsiElement())(')') PsiWhiteSpace(' ') @@ -64,21 +63,19 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got ')' - + PsiElement(:)(':') + PsiErrorElement: expected, got ')' + PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) @@ -238,18 +235,17 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - PsiErrorElement: expected, got 'b' + PsiErrorElement:':' expected, got 'b' PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) @@ -269,12 +265,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) @@ -290,25 +285,23 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - PsiErrorElement: or mut expected, got ',' - + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + PsiErrorElement: or mut expected, got ',' + PsiElement(,)(',') PsiWhiteSpace(' ') MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') PsiWhiteSpace(' ') MvCodeBlockImpl(CODE_BLOCK) diff --git a/src/test/resources/org/move/lang/parser/partial/module_const.txt b/src/test/resources/org/move/lang/parser/partial/module_const.txt index 1e97c60b5..4d2814eba 100644 --- a/src/test/resources/org/move/lang/parser/partial/module_const.txt +++ b/src/test/resources/org/move/lang/parser/partial/module_const.txt @@ -10,28 +10,26 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - PsiErrorElement: expected, got 'const' + PsiErrorElement:':' expected, got 'const' PsiWhiteSpace('\n\n ') MvConstImpl(CONST) PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got 'const' - + PsiElement(:)(':') + PsiErrorElement: expected, got 'const' + PsiWhiteSpace('\n\n ') MvConstImpl(CONST) PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiErrorElement:'::', or '=' expected, got 'const' PsiWhiteSpace('\n\n ') @@ -39,12 +37,11 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') @@ -55,12 +52,11 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('MY_CONST') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') @@ -74,7 +70,7 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('CONST_NO_TYPE') - PsiErrorElement: expected, got '=' + PsiErrorElement:':' expected, got '=' PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) @@ -88,10 +84,9 @@ FILE PsiElement(const_kw)('const') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('CONST_NO_TYPE_WITH_COMMA') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got '=' - + PsiElement(:)(':') + PsiErrorElement: expected, got '=' + PsiWhiteSpace(' ') MvInitializerImpl(INITIALIZER) PsiElement(=)('=') diff --git a/src/test/resources/org/move/lang/parser/partial/spec.txt b/src/test/resources/org/move/lang/parser/partial/spec.txt index f5b8dec5e..bc354fd39 100644 --- a/src/test/resources/org/move/lang/parser/partial/spec.txt +++ b/src/test/resources/org/move/lang/parser/partial/spec.txt @@ -143,7 +143,7 @@ FILE MvSpecExprStmtImpl(SPEC_EXPR_STMT) MvAssumeSpecExprImpl(ASSUME_SPEC_EXPR) PsiElement(assume_kw)('assume') - PsiErrorElement:, or '[' expected, got ';' + PsiErrorElement:':', or '[' expected, got ';' PsiElement(;)(';') PsiWhiteSpace('\n ') diff --git a/src/test/resources/org/move/lang/parser/partial/struct_fields.txt b/src/test/resources/org/move/lang/parser/partial/struct_fields.txt index 930301451..5083ea47c 100644 --- a/src/test/resources/org/move/lang/parser/partial/struct_fields.txt +++ b/src/test/resources/org/move/lang/parser/partial/struct_fields.txt @@ -20,18 +20,17 @@ FILE PsiWhiteSpace(' ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('u8') - PsiErrorElement: expected, got ',' + PsiErrorElement:':' expected, got ',' PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('my_field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace('\n ') PsiElement(})('}') PsiWhiteSpace('\n ') @@ -45,21 +44,19 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('my_field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got ',' - + PsiElement(:)(':') + PsiErrorElement: expected, got ',' + PsiWhiteSpace(' ') PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('my_field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace('\n ') PsiElement(})('}') PsiWhiteSpace('\n ') @@ -73,23 +70,21 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('my_field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiErrorElement:',', '::', or '}' expected, got 'my_field' PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('my_field') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace('\n ') PsiElement(})('}') PsiWhiteSpace('\n\n ') @@ -103,21 +98,20 @@ FILE PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('field1') - PsiErrorElement: expected, got ',' + PsiErrorElement:':' expected, got ',' PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('field2') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiErrorElement: expected, got ',' - + PsiElement(:)(':') + PsiErrorElement: expected, got ',' + PsiElement(,)(',') PsiWhiteSpace('\n ') MvNamedFieldDeclImpl(NAMED_FIELD_DECL) PsiElement(IDENTIFIER)('field3') - PsiErrorElement: expected, got '}' + PsiErrorElement:':' expected, got '}' PsiWhiteSpace('\n ') PsiElement(})('}') diff --git a/src/test/resources/org/move/lang/parser/specs/conditions.txt b/src/test/resources/org/move/lang/parser/specs/conditions.txt index d7916c1a3..e7cadd9bb 100644 --- a/src/test/resources/org/move/lang/parser/specs/conditions.txt +++ b/src/test/resources/org/move/lang/parser/specs/conditions.txt @@ -20,28 +20,26 @@ FILE MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('sending') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + PsiElement(mut)('mut') PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - PsiElement(mut)('mut') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('signer') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('signer') PsiElement(;)(';') PsiWhiteSpace('\n\n ') MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('amount') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(;)(';') PsiWhiteSpace('\n ') MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) @@ -49,24 +47,22 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('amount') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(;)(';') PsiWhiteSpace('\n ') MvGlobalVariableStmtImpl(GLOBAL_VARIABLE_STMT) PsiElement(global_kw)('global') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('amount') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u64') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u64') PsiElement(;)(';') PsiWhiteSpace('\n\n ') MvSpecExprStmtImpl(SPEC_EXPR_STMT) diff --git a/src/test/resources/org/move/lang/parser/specs/scopes.txt b/src/test/resources/org/move/lang/parser/specs/scopes.txt index fb70d5e12..2fea7cfe2 100644 --- a/src/test/resources/org/move/lang/parser/specs/scopes.txt +++ b/src/test/resources/org/move/lang/parser/specs/scopes.txt @@ -72,12 +72,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('addr') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') PsiElement())(')') PsiElement(;)(';') PsiWhiteSpace('\n\n ') @@ -100,15 +99,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('v') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('MvValue') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('MvValue') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') @@ -148,12 +146,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('addr') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') PsiElement())(')') PsiWhiteSpace(' ') MvSpecCodeBlockImpl(SPEC_CODE_BLOCK) @@ -171,12 +168,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('addr') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') PsiElement())(')') PsiElement(;)(';') PsiWhiteSpace('\n ') @@ -193,12 +189,11 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('addr') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('address') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('address') PsiElement())(')') PsiElement(;)(';') PsiWhiteSpace('\n\n ') @@ -271,22 +266,20 @@ FILE PsiElement(()('(') MvItemSpecFunctionParameterImpl(ITEM_SPEC_FUNCTION_PARAMETER) PsiElement(IDENTIFIER)('a') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(,)(',') PsiWhiteSpace(' ') MvItemSpecFunctionParameterImpl(ITEM_SPEC_FUNCTION_PARAMETER) PsiElement(IDENTIFIER)('b') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement())(')') PsiWhiteSpace(' ') MvSpecCodeBlockImpl(SPEC_CODE_BLOCK) @@ -335,12 +328,11 @@ FILE MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('supply') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('num') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('num') PsiElement(;)(';') PsiWhiteSpace('\n ') MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) @@ -348,12 +340,11 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('ensures') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('num') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('num') PsiElement(;)(';') PsiWhiteSpace('\n ') PsiElement(})('}') diff --git a/src/test/resources/org/move/lang/parser/specs/spec_statements.txt b/src/test/resources/org/move/lang/parser/specs/spec_statements.txt index 683ff718f..568896c58 100644 --- a/src/test/resources/org/move/lang/parser/specs/spec_statements.txt +++ b/src/test/resources/org/move/lang/parser/specs/spec_statements.txt @@ -628,15 +628,14 @@ FILE MvFunctionParameterImpl(FUNCTION_PARAMETER) MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('v') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvRefTypeImpl(REF_TYPE) - MvRefTypeStartImpl(REF_TYPE_START) - PsiElement(&)('&') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('MoveValue') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvRefTypeImpl(REF_TYPE) + MvRefTypeStartImpl(REF_TYPE_START) + PsiElement(&)('&') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('MoveValue') PsiElement())(')') MvReturnTypeImpl(RETURN_TYPE) PsiElement(:)(':') diff --git a/src/test/resources/org/move/lang/parser/specs/spec_variables.txt b/src/test/resources/org/move/lang/parser/specs/spec_variables.txt index 18c14dadc..0ba119165 100644 --- a/src/test/resources/org/move/lang/parser/specs/spec_variables.txt +++ b/src/test/resources/org/move/lang/parser/specs/spec_variables.txt @@ -22,12 +22,11 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('two') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(;)(';') PsiWhiteSpace('\n ') MvSchemaFieldStmtImpl(SCHEMA_FIELD_STMT) @@ -35,24 +34,22 @@ FILE PsiWhiteSpace(' ') MvPatBindingImpl(PAT_BINDING) PsiElement(IDENTIFIER)('two_with_params') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(;)(';') PsiWhiteSpace('\n ') MvGlobalVariableStmtImpl(GLOBAL_VARIABLE_STMT) PsiElement(global_kw)('global') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('three') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiElement(;)(';') PsiWhiteSpace('\n ') MvGlobalVariableStmtImpl(GLOBAL_VARIABLE_STMT) @@ -68,12 +65,11 @@ FILE MvTypeParameterImpl(TYPE_PARAMETER) PsiElement(IDENTIFIER)('Y') PsiElement(>)('>') - MvTypeAnnotationImpl(TYPE_ANNOTATION) - PsiElement(:)(':') - PsiWhiteSpace(' ') - MvPathTypeImpl(PATH_TYPE) - MvPathImpl(PATH) - PsiElement(IDENTIFIER)('u8') + PsiElement(:)(':') + PsiWhiteSpace(' ') + MvPathTypeImpl(PATH_TYPE) + MvPathImpl(PATH) + PsiElement(IDENTIFIER)('u8') PsiWhiteSpace(' ') PsiElement(=)('=') PsiWhiteSpace(' ') From aac0785c3aac00c5d297318587a17cb31b9de606 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Tue, 27 Aug 2024 01:05:46 +0300 Subject: [PATCH 05/13] simplify address handling --- src/main/grammars/MoveParser.bnf | 1 + src/main/kotlin/org/move/cli/MoveProject.kt | 19 +++--- .../aptos/CommandConfigurationHandler.kt | 5 +- .../runConfigurations/aptos/FunctionCall.kt | 3 +- .../aptos/FunctionCallConfigurationEditor.kt | 2 +- .../test/AptosTestLocator.kt | 3 +- ... NamedAddressFromTestAnnotationService.kt} | 13 ++-- src/main/kotlin/org/move/ide/MoveIcons.kt | 3 + .../move/ide/annotator/MvErrorAnnotator.kt | 6 +- .../move/ide/docs/MvDocumentationProvider.kt | 4 +- .../org/move/lang/core/psi/ext/MvFieldDecl.kt | 2 + .../org/move/lang/core/psi/ext/MvFunction.kt | 2 +- .../move/lang/core/psi/ext/MvMethodCall.kt | 34 ++-------- .../lang/core/psi/ext/MvTupleFieldDecl.kt | 17 +++++ .../org/move/lang/core/resolve2/PathKind.kt | 4 +- .../resolve2/ref/MvMethodCallReferenceImpl.kt | 24 +++++++ .../kotlin/org/move/lang/core/stubs/Stubs.kt | 2 +- .../org/move/lang/core/types/Address.kt | 67 +++++-------------- .../org/move/lang/core/types/ItemQualName.kt | 4 +- src/main/resources/META-INF/plugin.xml | 2 +- src/main/resources/icons/nodes/constant.svg | 4 ++ src/main/resources/icons/nodes/enum.svg | 4 ++ .../resources/icons/nodes/enumVariant.svg | 4 ++ src/main/resources/icons/nodes/field.svg | 4 ++ src/main/resources/icons/nodes/function.svg | 4 ++ src/main/resources/icons/nodes/method.svg | 4 ++ src/main/resources/icons/nodes/method@2x.svg | 4 ++ src/main/resources/icons/nodes/module.svg | 4 ++ src/main/resources/icons/nodes/struct.svg | 4 ++ .../CommandConfigurationHandlerTest.kt | 2 +- .../move/lang/NamedModulePathValuesTest.kt | 2 +- .../kotlin/org/move/utils/tests/MvTestBase.kt | 4 +- 32 files changed, 137 insertions(+), 124 deletions(-) rename src/main/kotlin/org/move/cli/tests/{NamedAddressService.kt => NamedAddressFromTestAnnotationService.kt} (62%) create mode 100644 src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt create mode 100644 src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt create mode 100644 src/main/resources/icons/nodes/constant.svg create mode 100644 src/main/resources/icons/nodes/enum.svg create mode 100644 src/main/resources/icons/nodes/enumVariant.svg create mode 100644 src/main/resources/icons/nodes/field.svg create mode 100644 src/main/resources/icons/nodes/function.svg create mode 100644 src/main/resources/icons/nodes/method.svg create mode 100644 src/main/resources/icons/nodes/method@2x.svg create mode 100644 src/main/resources/icons/nodes/module.svg create mode 100644 src/main/resources/icons/nodes/struct.svg diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 1cc4fa281..8e5a278a6 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -598,6 +598,7 @@ TupleFieldDecl ::= Attr* Type implements = [ "org.move.lang.core.psi.ext.MvFieldDecl" ] + mixin = "org.move.lang.core.psi.ext.MvTupleFieldDeclMixin" hooks = [ leftBinder = "ADJACENT_LINE_COMMENTS" ] } diff --git a/src/main/kotlin/org/move/cli/MoveProject.kt b/src/main/kotlin/org/move/cli/MoveProject.kt index 6e4064326..bb835e572 100644 --- a/src/main/kotlin/org/move/cli/MoveProject.kt +++ b/src/main/kotlin/org/move/cli/MoveProject.kt @@ -16,7 +16,7 @@ import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import org.move.cli.manifest.AptosConfigYaml import org.move.cli.manifest.MoveToml -import org.move.cli.tests.NamedAddressService +import org.move.cli.tests.NamedAddressFromTestAnnotationService import org.move.lang.MoveFile import org.move.lang.core.psi.MvModule import org.move.lang.core.types.Address @@ -87,23 +87,20 @@ data class MoveProject( return map } - fun getNamedAddressValue(name: String): String? = addressValues()[name]?.value - - fun getNamedAddress(name: String): Address.Named? { - val value = getNamedAddressValue(name) ?: return null - return Address.Named(name, value, this) - } - fun getNamedAddressTestAware(name: String): Address.Named? { - val namedAddress = getNamedAddress(name) - if (namedAddress != null) return namedAddress + val declaredNamedValue = getValueOfDeclaredNamedAddress(name) + if (declaredNamedValue != null) { + return Address.Named(name, declaredNamedValue) + } if (isUnitTestMode) { - val namedAddressService = project.service() + val namedAddressService = project.service() return namedAddressService.getNamedAddress(this, name) } return null } + fun getValueOfDeclaredNamedAddress(name: String): String? = addressValues()[name]?.value + fun getAddressNamesForValue(addressValue: String): List { val addressLit = AddressLit(addressValue) val names = mutableListOf() diff --git a/src/main/kotlin/org/move/cli/runConfigurations/aptos/CommandConfigurationHandler.kt b/src/main/kotlin/org/move/cli/runConfigurations/aptos/CommandConfigurationHandler.kt index 2dc338754..702759de2 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/aptos/CommandConfigurationHandler.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/aptos/CommandConfigurationHandler.kt @@ -28,7 +28,7 @@ abstract class CommandConfigurationHandler { ?: return null val moveProject = function.moveProject ?: return null - val functionId = function.functionId(moveProject) ?: return null + val functionId = function.functionId() ?: return null val profileName = moveProject.profiles.firstOrNull() val workingDirectory = moveProject.contentRootPath @@ -55,11 +55,10 @@ abstract class CommandConfigurationHandler { abstract fun getFunctionParameters(function: MvFunction): List fun generateCommand( - moveProject: MoveProject, functionCall: FunctionCall, signerAccount: String?, ): RsResult { - val functionId = functionCall.functionId(moveProject) ?: return RsResult.Err("FunctionId is null") + val functionId = functionCall.functionId() ?: return RsResult.Err("FunctionId is null") val typeParams = functionCall.typeParams .mapNotNull { it.value }.flatMap { listOf("--type-args", it) } diff --git a/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCall.kt b/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCall.kt index faad55249..6a1a97683 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCall.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCall.kt @@ -1,7 +1,6 @@ package org.move.cli.runConfigurations.aptos import com.intellij.psi.SmartPsiElementPointer -import org.move.cli.MoveProject import org.move.lang.core.psi.MvFunction import org.move.lang.core.psi.parametersAsBindings import org.move.lang.core.psi.ext.* @@ -31,7 +30,7 @@ data class FunctionCall( val valueParams: MutableMap ) { fun itemName(): String? = item?.element?.qualName?.editorText() - fun functionId(moveProject: MoveProject): String? = item?.element?.functionId(moveProject) + fun functionId(): String? = item?.element?.functionId() fun parametersRequired(): Boolean { val fn = item?.element ?: return false diff --git a/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCallConfigurationEditor.kt b/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCallConfigurationEditor.kt index 3773b6f50..3bc732f50 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCallConfigurationEditor.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/aptos/FunctionCallConfigurationEditor.kt @@ -84,7 +84,7 @@ class FunctionCallConfigurationEditor( // editor.functionCall = functionCall editor.rawCommandField.text = - commandHandler.generateCommand(mp, functionCall, accountTextField.text).unwrapOrNull() ?: "" + commandHandler.generateCommand(functionCall, accountTextField.text).unwrapOrNull() ?: "" } }) diff --git a/src/main/kotlin/org/move/cli/runConfigurations/test/AptosTestLocator.kt b/src/main/kotlin/org/move/cli/runConfigurations/test/AptosTestLocator.kt index ccd0c0ee9..f65857a1b 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/test/AptosTestLocator.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/test/AptosTestLocator.kt @@ -29,8 +29,7 @@ object AptosTestLocator : SMTestLocator { val name = qualifiedName.substringAfterLast(NAME_SEPARATOR) for (element in MvNamedElementIndex.getElementsByName(project, name, scope)) { if (element is MvFunction) { - val moveProject = element.moveProject ?: continue - if (element.qualName?.cmdText(moveProject) == qualifiedName) { + if (element.qualName?.cmdText() == qualifiedName) { add(PsiLocation.fromPsiElement(element)) } } diff --git a/src/main/kotlin/org/move/cli/tests/NamedAddressService.kt b/src/main/kotlin/org/move/cli/tests/NamedAddressFromTestAnnotationService.kt similarity index 62% rename from src/main/kotlin/org/move/cli/tests/NamedAddressService.kt rename to src/main/kotlin/org/move/cli/tests/NamedAddressFromTestAnnotationService.kt index 8725dcf25..2714990cd 100644 --- a/src/main/kotlin/org/move/cli/tests/NamedAddressService.kt +++ b/src/main/kotlin/org/move/cli/tests/NamedAddressFromTestAnnotationService.kt @@ -1,23 +1,22 @@ package org.move.cli.tests import org.move.cli.MoveProject -import org.move.lang.core.types.Address import org.move.lang.core.types.Address.Named -interface NamedAddressService { - fun getNamedAddress(moveProject: MoveProject, name: String): Address.Named? +interface NamedAddressFromTestAnnotationService { + fun getNamedAddress(moveProject: MoveProject, name: String): Named? } -class NamedAddressServiceImpl: NamedAddressService { - override fun getNamedAddress(moveProject: MoveProject, name: String): Address.Named? = null +class NamedAddressServiceImpl: NamedAddressFromTestAnnotationService { + override fun getNamedAddress(moveProject: MoveProject, name: String): Named? = null } -class NamedAddressServiceTestImpl: NamedAddressService { +class NamedAddressServiceTestImpl: NamedAddressFromTestAnnotationService { val namedAddresses: MutableMap = mutableMapOf() override fun getNamedAddress(moveProject: MoveProject, name: String): Named? { val value = namedAddresses[name] ?: return null - return Named(name, value, moveProject) + return Named(name, value) } } \ No newline at end of file diff --git a/src/main/kotlin/org/move/ide/MoveIcons.kt b/src/main/kotlin/org/move/ide/MoveIcons.kt index e848df5c7..3a30b8e10 100644 --- a/src/main/kotlin/org/move/ide/MoveIcons.kt +++ b/src/main/kotlin/org/move/ide/MoveIcons.kt @@ -23,6 +23,9 @@ object MoveIcons { val STRUCT_FIELD = AllIcons.Nodes.Field val SCHEMA = AllIcons.Nodes.Static + val FIELD = load("/icons/nodes/field.svg") + val ENUM_VARIANT = load("/icons/nodes/enumVariant.svg") + val CONST = AllIcons.Nodes.Constant val FUNCTION = AllIcons.Nodes.Function diff --git a/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt b/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt index c9533e7ce..eb55a7140 100644 --- a/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt +++ b/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt @@ -179,14 +179,14 @@ class MvErrorAnnotator: MvAnnotatorBase() { private fun checkModuleDef(moveHolder: MvAnnotationHolder, mod: MvModule) { val modName = mod.name ?: return - val moveProj = mod.moveProject ?: return - val addressIdent = mod.address(moveProj) ?: return + val moveProject = mod.moveProject ?: return + val addressIdent = mod.address(moveProject) ?: return val modIdent = Pair(addressIdent.text(), modName) val file = mod.containingMoveFile ?: return val duplicateIdents = file.modules() .filter { it.name != null } - .groupBy { Pair(it.address(moveProj)?.text(), it.name) } + .groupBy { Pair(it.address(moveProject)?.text(), it.name) } .filter { it.value.size > 1 } .map { it.key } .toSet() diff --git a/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt b/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt index 8fe94b945..524f7bf2f 100644 --- a/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt +++ b/src/main/kotlin/org/move/ide/docs/MvDocumentationProvider.kt @@ -42,9 +42,9 @@ class MvDocumentationProvider : AbstractDocumentationProvider() { // TODO: add docs for both [addresses] and [dev-addresses] val moveProject = docElement.moveProject ?: return null val refName = docElement.referenceName - val named = moveProject.getNamedAddress(refName) ?: return null + val named = moveProject.getNamedAddressTestAware(refName) ?: return null val address = - named.addressLit(moveProject)?.original ?: angleWrapped("unassigned") + named.addressLit()?.original ?: angleWrapped("unassigned") return "$refName = \"$address\"" } is MvDocAndAttributeOwner -> generateOwnerDoc(docElement, buffer) diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt index 9439d7a35..3e4d4e59c 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt @@ -2,6 +2,8 @@ package org.move.lang.core.psi.ext import org.move.lang.core.psi.MvType +val MvFieldDecl.owner: MvFieldsOwner? get() = ancestorStrict() + interface MvFieldDecl: MvDocAndAttributeOwner { val type: MvType? } \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt index a8888353b..a6a081e87 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt @@ -35,7 +35,7 @@ val MvFunction.isView: Boolean return stub?.isView ?: queryAttributes.isView } -fun MvFunction.functionId(moveProject: MoveProject): String? = qualName?.cmdText(moveProject) +fun MvFunction.functionId(): String? = qualName?.cmdText() val MvFunction.testAttrItem: MvAttrItem? get() = queryAttributes.getAttrItem("test") diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvMethodCall.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvMethodCall.kt index 8167fc03d..37d0b20be 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvMethodCall.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvMethodCall.kt @@ -6,6 +6,7 @@ import org.move.cli.MoveProject import org.move.lang.core.psi.* import org.move.lang.core.resolve.ref.MvPolyVariantReference import org.move.lang.core.resolve.ref.MvPolyVariantReferenceBase +import org.move.lang.core.resolve2.ref.MvMethodCallReferenceImpl import org.move.lang.core.types.address import org.move.lang.core.types.infer.inference import org.move.lang.core.types.ty.Ty @@ -13,14 +14,6 @@ import org.move.lang.core.types.ty.TyAdt import org.move.lang.core.types.ty.TyVector import org.move.stdext.wrapWithList -//typealias MatchSequence = Sequence> - -//fun MatchSequence.filterByName(refName: String): Sequence { -// return this -// .filter { it.name == refName } -// .map { it.element } -//} - fun Ty.itemModule(moveProject: MoveProject): MvModule? { val norefTy = this.derefIfNeeded() return when (norefTy) { @@ -34,29 +27,10 @@ fun Ty.itemModule(moveProject: MoveProject): MvModule? { } } -fun MvModule.is0x1Address(moveProject: MoveProject): Boolean { - val moduleAddress = this.address(moveProject)?.canonicalValue(moveProject) - return moduleAddress == "0x00000000000000000000000000000001" -} - -class MvMethodCallReferenceImpl( - element: MvMethodCall -): - MvPolyVariantReferenceBase(element) { +fun MvModule.is0x1Address(moveProject: MoveProject): Boolean = this.address(moveProject)?.is0x1 ?: false - override fun multiResolve(): List { - val msl = element.isMsl() - val receiverExpr = element.receiverExpr - val inference = receiverExpr.inference(msl) ?: return emptyList() - return inference.getResolvedMethod(element).wrapWithList() - } +abstract class MvMethodCallMixin(node: ASTNode): MvElementImpl(node), MvMethodCall { - override fun isReferenceTo(element: PsiElement): Boolean = - element is MvFunction && super.isReferenceTo(element) + override fun getReference(): MvPolyVariantReference = MvMethodCallReferenceImpl(this) } -abstract class MvMethodCallMixin(node: ASTNode): MvElementImpl(node), - MvMethodCall { - - override fun getReference(): MvPolyVariantReference = MvMethodCallReferenceImpl(this) -} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt new file mode 100644 index 000000000..95ddbbc8b --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt @@ -0,0 +1,17 @@ +package org.move.lang.core.psi.ext + +import com.intellij.lang.ASTNode +import org.move.ide.MoveIcons +import org.move.lang.core.psi.MvElementImpl +import org.move.lang.core.psi.MvTupleFieldDecl +import javax.swing.Icon + +val MvTupleFieldDecl.position: Int? + get() = owner?.positionalFields?.withIndex()?.firstOrNull { it.value === this }?.index + +abstract class MvTupleFieldDeclMixin(node: ASTNode): MvElementImpl(node), MvTupleFieldDecl { + + override fun getIcon(flags: Int): Icon? = MoveIcons.FIELD + + override fun getName(): String? = position?.toString() +} diff --git a/src/main/kotlin/org/move/lang/core/resolve2/PathKind.kt b/src/main/kotlin/org/move/lang/core/resolve2/PathKind.kt index 97827d883..37c10a7da 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/PathKind.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/PathKind.kt @@ -87,7 +87,7 @@ fun MvPath.pathKind(isCompletion: Boolean = false): PathKind { return PathKind.NamedAddress(namedAddress) } // and it can be with null value if absent, still a named address - return PathKind.NamedAddress(Address.Named(referenceName, null, moveProject)) + return PathKind.NamedAddress(Address.Named(referenceName, null)) } // outside use stmt context @@ -131,7 +131,7 @@ fun MvPath.pathKind(isCompletion: Boolean = false): PathKind { // ^ // , where std is the unknown named address if (this.isUseSpeck) { - val address = Address.Named(qualifierItemName, null, moveProject) + val address = Address.Named(qualifierItemName, null) return PathKind.QualifiedPath.Module(this, qualifier, MODULES, address) } } diff --git a/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt new file mode 100644 index 000000000..e573264da --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt @@ -0,0 +1,24 @@ +package org.move.lang.core.resolve2.ref + +import com.intellij.psi.PsiElement +import org.move.lang.core.psi.MvFunction +import org.move.lang.core.psi.MvMethodCall +import org.move.lang.core.psi.MvNamedElement +import org.move.lang.core.psi.ext.isMsl +import org.move.lang.core.resolve.ref.MvPolyVariantReferenceBase +import org.move.lang.core.types.infer.inference +import org.move.stdext.wrapWithList + +class MvMethodCallReferenceImpl( + element: MvMethodCall +): MvPolyVariantReferenceBase(element) { + + override fun multiResolve(): List { + val msl = element.isMsl() + val inference = element.inference(msl) ?: return emptyList() + return inference.getResolvedMethod(element).wrapWithList() + } + + override fun isReferenceTo(element: PsiElement): Boolean = + element is MvFunction && super.isReferenceTo(element) +} diff --git a/src/main/kotlin/org/move/lang/core/stubs/Stubs.kt b/src/main/kotlin/org/move/lang/core/stubs/Stubs.kt index 983bedc2c..76e2a8288 100644 --- a/src/main/kotlin/org/move/lang/core/stubs/Stubs.kt +++ b/src/main/kotlin/org/move/lang/core/stubs/Stubs.kt @@ -141,7 +141,7 @@ class MvFunctionStub( fun resolvedQualName(moveProject: MoveProject): String? { val addressText = when (address) { is StubAddress.Value -> address.value - is StubAddress.Named -> moveProject.getNamedAddressValue(address.name) ?: return null + is StubAddress.Named -> moveProject.getValueOfDeclaredNamedAddress(address.name) ?: return null else -> return null } val moduleName = this.moduleName ?: return null diff --git a/src/main/kotlin/org/move/lang/core/types/Address.kt b/src/main/kotlin/org/move/lang/core/types/Address.kt index a98ac3743..bcd10dcab 100644 --- a/src/main/kotlin/org/move/lang/core/types/Address.kt +++ b/src/main/kotlin/org/move/lang/core/types/Address.kt @@ -8,9 +8,7 @@ import org.move.lang.core.psi.MvModule import org.move.lang.core.psi.ext.addressRef import org.move.lang.core.psi.ext.greenStub import org.move.lang.core.types.Address.Named -import org.move.lang.core.types.Address.Value import org.move.lang.core.types.AddressLit.Companion.normalizeValue -import org.move.lang.moveProject const val MAX_LENGTH = 32 @@ -44,62 +42,30 @@ class AddressLit(val original: String) { sealed class Address { abstract fun text(): String - abstract fun canonicalValue(moveProject: MoveProject): String? + abstract fun canonicalValue(): String? val is0x0 get() = this is Value && this.addressLit().original == "0x0" + val is0x1 get() = canonicalValue() == "0x00000000000000000000000000000001" class Value(private val value: String): Address() { fun addressLit(): AddressLit = AddressLit(value) - override fun canonicalValue(moveProject: MoveProject): String = this.addressLit().canonical() + override fun canonicalValue(): String = this.addressLit().canonical() override fun text(): String = this.addressLit().original -// override fun equals(other: Any?): Boolean { -// if (this === other) return true -// if (other !is Value) return false -// if (this.hashCode() != other.hashCode()) return false -// return eq(this, other) -// } - -// override fun hashCode(): Int = normalizeValue(value).hashCode() - override fun toString(): String = "Address.Value($value)" } - class Named( - val name: String, - val value: String?, - private val declMoveProject: MoveProject? - ): Address() { - fun value(moveProject: MoveProject? = null): String { - return value - ?: this.declMoveProject?.getNamedAddressValue(name) - ?: moveProject?.getNamedAddressValue(name) - ?: UNKNOWN - } - - fun addressLit(moveProject: MoveProject): AddressLit? = - moveProject.getNamedAddressValue(this.name)?.let { AddressLit(it) } + class Named(val name: String, val value: String?): Address() { + fun addressLit(): AddressLit? = this.value?.let { AddressLit(it) } - override fun canonicalValue(moveProject: MoveProject): String? = - this.addressLit(moveProject)?.canonical() + override fun canonicalValue(): String? = this.addressLit()?.canonical() - override fun text(): String = "$name = ${value()}" - -// override fun equals(other: Any?): Boolean { -// if (this === other) return true -// if (other !is Named) return false -//// if (this.hashCode() != other.hashCode()) return false -// return eq(this, other) -// } - -// override fun hashCode(): Int = name.hashCode() + override fun text(): String = "$name = $value" } companion object { - const val UNKNOWN: String = "0x0" - fun equals(left: Address?, right: Address?): Boolean { if (left === right) return true if (left == null && right == null) return true @@ -130,7 +96,7 @@ sealed class Address { } sealed class StubAddress { - object Unknown: StubAddress() + data object Unknown: StubAddress() data class Value(val value: String): StubAddress() data class Named(val name: String): StubAddress() @@ -146,13 +112,10 @@ sealed class StubAddress { return when (this) { is Named -> { if (moveProject == null) { - Named(this.name, null, null) + Named(this.name, null) } else { - moveProject.getNamedAddressTestAware(this.name) ?: Named( - this.name, - null, - moveProject - ) + moveProject.getNamedAddressTestAware(this.name) + ?: Named(this.name, null) } } is Value -> Address.Value(this.value) @@ -193,12 +156,12 @@ val MvModule.stubAddress: StubAddress return stub?.address ?: this.psiStubAddress() } -fun MvModule.addressAsCanonicalValue(moveProject: MoveProject): String? = - this.address(moveProject)?.canonicalValue(moveProject) +//fun MvModule.addressAsCanonicalValue(moveProject: MoveProject): String? = +// this.address(moveProject)?.canonicalValue(moveProject) -fun MvModule.address(proj: MoveProject?): Address? = this.stubAddress.asAddress(proj) +fun MvModule.address(moveProject: MoveProject?): Address? = this.stubAddress.asAddress(moveProject) -fun MvAddressRef.address(proj: MoveProject?): Address? = psiStubAddress().asAddress(proj) +fun MvAddressRef.address(moveProject: MoveProject?): Address? = psiStubAddress().asAddress(moveProject) fun MvModule.psiStubAddress(): StubAddress = this.addressRef()?.psiStubAddress() ?: StubAddress.Unknown diff --git a/src/main/kotlin/org/move/lang/core/types/ItemQualName.kt b/src/main/kotlin/org/move/lang/core/types/ItemQualName.kt index 5590c1eaa..0e921f5a9 100644 --- a/src/main/kotlin/org/move/lang/core/types/ItemQualName.kt +++ b/src/main/kotlin/org/move/lang/core/types/ItemQualName.kt @@ -18,9 +18,9 @@ data class ItemQualName( return listOfNotNull(addressText, moduleName, itemName).joinToString("::") } - fun cmdText(moveProject: MoveProject): String { + fun cmdText(): String { val addressText = when (address) { - is Address.Named -> address.addressLit(moveProject)?.short() + is Address.Named -> address.addressLit()?.short() is Address.Value -> address.addressLit().short() } return listOfNotNull(addressText, moduleName, itemName).joinToString("::") diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 275806012..8acc24838 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -46,7 +46,7 @@ - diff --git a/src/main/resources/icons/nodes/constant.svg b/src/main/resources/icons/nodes/constant.svg new file mode 100644 index 000000000..4fef7c925 --- /dev/null +++ b/src/main/resources/icons/nodes/constant.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/enum.svg b/src/main/resources/icons/nodes/enum.svg new file mode 100644 index 000000000..6b0b556f1 --- /dev/null +++ b/src/main/resources/icons/nodes/enum.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/enumVariant.svg b/src/main/resources/icons/nodes/enumVariant.svg new file mode 100644 index 000000000..2c2acee2f --- /dev/null +++ b/src/main/resources/icons/nodes/enumVariant.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/field.svg b/src/main/resources/icons/nodes/field.svg new file mode 100644 index 000000000..981133494 --- /dev/null +++ b/src/main/resources/icons/nodes/field.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/function.svg b/src/main/resources/icons/nodes/function.svg new file mode 100644 index 000000000..4b38659f3 --- /dev/null +++ b/src/main/resources/icons/nodes/function.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/method.svg b/src/main/resources/icons/nodes/method.svg new file mode 100644 index 000000000..058ef1cff --- /dev/null +++ b/src/main/resources/icons/nodes/method.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/method@2x.svg b/src/main/resources/icons/nodes/method@2x.svg new file mode 100644 index 000000000..1b747bd17 --- /dev/null +++ b/src/main/resources/icons/nodes/method@2x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/module.svg b/src/main/resources/icons/nodes/module.svg new file mode 100644 index 000000000..9f404fce1 --- /dev/null +++ b/src/main/resources/icons/nodes/module.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/resources/icons/nodes/struct.svg b/src/main/resources/icons/nodes/struct.svg new file mode 100644 index 000000000..8e7f43351 --- /dev/null +++ b/src/main/resources/icons/nodes/struct.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/test/kotlin/org/move/cli/runConfigurations/CommandConfigurationHandlerTest.kt b/src/test/kotlin/org/move/cli/runConfigurations/CommandConfigurationHandlerTest.kt index 076dd81a3..4ef9be85e 100644 --- a/src/test/kotlin/org/move/cli/runConfigurations/CommandConfigurationHandlerTest.kt +++ b/src/test/kotlin/org/move/cli/runConfigurations/CommandConfigurationHandlerTest.kt @@ -79,7 +79,7 @@ profiles: check(profile == expectedProfile) { "Unexpected profile $profile" } - val generatedCommand = handler.generateCommand(moveProject, functionCall, profile).unwrap() + val generatedCommand = handler.generateCommand(functionCall, profile).unwrap() check(command == generatedCommand) { "Commands are not equal. \n" + "Original: $command\n" + diff --git a/src/test/kotlin/org/move/lang/NamedModulePathValuesTest.kt b/src/test/kotlin/org/move/lang/NamedModulePathValuesTest.kt index 0ef81edf7..1610b101a 100644 --- a/src/test/kotlin/org/move/lang/NamedModulePathValuesTest.kt +++ b/src/test/kotlin/org/move/lang/NamedModulePathValuesTest.kt @@ -209,7 +209,7 @@ class NamedModulePathValuesTest: MvProjectTestBase() { val expectedValue = data.trim() val moveProject = project.moveProjectsService.findMoveProjectForPsiElement(address)!! - val actualValue = moveProject.getNamedAddress(address.referenceName)!!.text() + val actualValue = moveProject.getNamedAddressTestAware(address.referenceName)!!.text() check(actualValue == expectedValue) { "Value mismatch. Expected $expectedValue, found: $actualValue" diff --git a/src/test/kotlin/org/move/utils/tests/MvTestBase.kt b/src/test/kotlin/org/move/utils/tests/MvTestBase.kt index a5ef879e1..552f3605d 100644 --- a/src/test/kotlin/org/move/utils/tests/MvTestBase.kt +++ b/src/test/kotlin/org/move/utils/tests/MvTestBase.kt @@ -13,7 +13,7 @@ import com.intellij.testFramework.UsefulTestCase import com.intellij.testFramework.enableInspectionTool import org.intellij.lang.annotations.Language import org.move.cli.settings.moveSettings -import org.move.cli.tests.NamedAddressService +import org.move.cli.tests.NamedAddressFromTestAnnotationService import org.move.cli.tests.NamedAddressServiceTestImpl import org.move.ide.inspections.fixes.CompilerV2Feat import org.move.ide.inspections.fixes.CompilerV2Feat.* @@ -63,7 +63,7 @@ fun UsefulTestCase.handleCompilerV2Annotations(project: Project) { fun UsefulTestCase.handleNamedAddressAnnotations(project: Project) { val namedAddresses = this.findAnnotationInstances() - val namedAddressService = project.service() as NamedAddressServiceTestImpl + val namedAddressService = project.service() as NamedAddressServiceTestImpl for (namedAddress in namedAddresses) { namedAddressService.namedAddresses[namedAddress.name] = namedAddress.value } From cd0e6e9b50e3b9b7c140e4d933eb61e0f64b0a9c Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Tue, 27 Aug 2024 23:11:26 +0300 Subject: [PATCH 06/13] tuple field decl name resolution --- .../inspections/MvAbilityCheckInspection.kt | 7 ++--- .../PhantomTypeParameterInspection.kt | 13 ++++------ .../navigation/goto/MvNamedElementsVisitor.kt | 2 +- .../move/ide/refactoring/MvRenameProcessor.kt | 3 ++- .../MvStructureViewTreeElement.kt | 2 +- .../StructFieldsCompletionProvider.kt | 2 +- .../org/move/lang/core/psi/MvElement.kt | 3 +-- .../org/move/lang/core/psi/ext/MvFieldDecl.kt | 3 ++- .../{MvStructDotField.kt => MvFieldLookup.kt} | 5 +++- .../move/lang/core/psi/ext/MvFieldsOwner.kt | 7 +++-- .../core/psi/ext/MvStructOrEnumItemElement.kt | 22 ++++++++-------- .../lang/core/psi/ext/MvTupleFieldDecl.kt | 6 +++++ .../core/resolve2/LexicalDeclarations2.kt | 10 +++---- .../lang/core/resolve2/NameResolution2.kt | 26 +++++++++++++++++++ .../resolve2/ref/MvMethodCallReferenceImpl.kt | 24 +++++++++++++++++ .../core/types/infer/TypeInferenceWalker.kt | 7 +++-- .../lang/resolve/ResolveStructFieldsTest.kt | 21 +++++++++++++++ .../org/move/lang/resolve/ResolveTypesTest.kt | 2 +- .../move/lang/types/ExpressionTypesTest.kt | 2 +- 19 files changed, 124 insertions(+), 43 deletions(-) rename src/main/kotlin/org/move/lang/core/psi/ext/{MvStructDotField.kt => MvFieldLookup.kt} (94%) diff --git a/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt index 83b818720..8fce01ace 100644 --- a/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt @@ -6,10 +6,7 @@ import org.move.ide.annotator.pluralise import org.move.ide.presentation.name import org.move.ide.presentation.text import org.move.lang.core.psi.* -import org.move.lang.core.psi.ext.abilities -import org.move.lang.core.psi.ext.fields -import org.move.lang.core.psi.ext.isMsl -import org.move.lang.core.psi.ext.fieldOwner +import org.move.lang.core.psi.ext.* import org.move.lang.core.types.infer.inferExpectedTypeArgumentTy import org.move.lang.core.types.infer.inference import org.move.lang.core.types.infer.loweredType @@ -78,7 +75,7 @@ class MvAbilityCheckInspection: MvLocalInspectionTool() { val message = "The type '${fieldTy.name()}' does not have the ability '${requiredAbility.label()}' " + "required by the declared ability '${ability.label()}' " + - "of the struct '${field.fieldOwner.name}'" + "of the struct '${field.owner?.name}'" holder.registerProblem(field, message, ProblemHighlightType.GENERIC_ERROR) } } diff --git a/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt b/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt index 7e996b2e7..08b496bf4 100644 --- a/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt +++ b/src/main/kotlin/org/move/ide/inspections/PhantomTypeParameterInspection.kt @@ -4,21 +4,18 @@ import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.util.descendantsOfType import org.move.ide.inspections.fixes.PhantomFix import org.move.lang.core.psi.* -import org.move.lang.core.psi.ext.fields -import org.move.lang.core.psi.ext.isPhantom -import org.move.lang.core.psi.ext.moveReference -import org.move.lang.core.psi.ext.typeArguments +import org.move.lang.core.psi.ext.* -class PhantomTypeParameterInspection : MvLocalInspectionTool() { +class PhantomTypeParameterInspection: MvLocalInspectionTool() { override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): MvVisitor { - return object : MvVisitor() { + return object: MvVisitor() { override fun visitStruct(o: MvStruct) { val usedTypeParams = mutableSetOf() - for (structField in o.fields) { + for (field in o.fields) { val fieldUsedTypeParams = mutableSetOf() - val fieldType = structField.type ?: continue + val fieldType = field.type ?: continue for (path in fieldType.descendantsOfType()) { if (path.typeArguments.isNotEmpty()) continue val typeParam = path.reference?.resolve() as? MvTypeParameter ?: continue diff --git a/src/main/kotlin/org/move/ide/navigation/goto/MvNamedElementsVisitor.kt b/src/main/kotlin/org/move/ide/navigation/goto/MvNamedElementsVisitor.kt index eae841514..f002b6329 100644 --- a/src/main/kotlin/org/move/ide/navigation/goto/MvNamedElementsVisitor.kt +++ b/src/main/kotlin/org/move/ide/navigation/goto/MvNamedElementsVisitor.kt @@ -26,7 +26,7 @@ abstract class MvNamedElementsVisitor : MvVisitor(), PsiRecursiveVisitor { override fun visitStruct(o: MvStruct) { processNamedElement(o) - o.fields.forEach { processNamedElement(it) } + o.namedFields.forEach { processNamedElement(it) } } override fun visitConst(o: MvConst) = processNamedElement(o) diff --git a/src/main/kotlin/org/move/ide/refactoring/MvRenameProcessor.kt b/src/main/kotlin/org/move/ide/refactoring/MvRenameProcessor.kt index 7fb64099a..5f079ce18 100644 --- a/src/main/kotlin/org/move/ide/refactoring/MvRenameProcessor.kt +++ b/src/main/kotlin/org/move/ide/refactoring/MvRenameProcessor.kt @@ -13,7 +13,8 @@ import org.move.lang.core.psi.ext.owner class MvRenameProcessor: RenamePsiElementProcessor() { - override fun canProcessElement(element: PsiElement): Boolean = element is MvNamedElement + override fun canProcessElement(element: PsiElement): Boolean = + element is MvNamedElement && element !is MvTupleFieldDecl override fun renameElement( element: PsiElement, diff --git a/src/main/kotlin/org/move/ide/structureView/MvStructureViewTreeElement.kt b/src/main/kotlin/org/move/ide/structureView/MvStructureViewTreeElement.kt index 9a7a55b22..5ff359216 100644 --- a/src/main/kotlin/org/move/ide/structureView/MvStructureViewTreeElement.kt +++ b/src/main/kotlin/org/move/ide/structureView/MvStructureViewTreeElement.kt @@ -52,7 +52,7 @@ class MvStructureViewTreeElement(val element: NavigatablePsiElement): StructureV element.specFunctions(), ).flatten() } - is MvStruct -> element.fields + is MvStruct -> element.namedFields else -> emptyList() } return items.map { MvStructureViewTreeElement(it) }.toTypedArray() diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/StructFieldsCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/StructFieldsCompletionProvider.kt index 06c426a77..1e62f2ca5 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/StructFieldsCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/StructFieldsCompletionProvider.kt @@ -68,7 +68,7 @@ object StructFieldsCompletionProvider: MvCompletionProvider() { result: CompletionResultSet, completionContext: CompletionContext, ) { - for (field in referredStruct.fields.filter { it.name !in providedFieldNames }) { + for (field in referredStruct.namedFields.filter { it.name !in providedFieldNames }) { result.addElement( field.createLookupElement(completionContext) ) diff --git a/src/main/kotlin/org/move/lang/core/psi/MvElement.kt b/src/main/kotlin/org/move/lang/core/psi/MvElement.kt index 9d519b937..a99d0572d 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvElement.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvElement.kt @@ -11,8 +11,7 @@ import org.move.lang.core.psi.ext.* interface MvElement : PsiElement -abstract class MvElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), - MvElement +abstract class MvElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), MvElement val MvElement.containingMoveFile: MoveFile? get() = this.containingFile as? MoveFile diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt index 3e4d4e59c..98de36199 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldDecl.kt @@ -1,9 +1,10 @@ package org.move.lang.core.psi.ext +import org.move.lang.core.psi.MvNamedElement import org.move.lang.core.psi.MvType val MvFieldDecl.owner: MvFieldsOwner? get() = ancestorStrict() -interface MvFieldDecl: MvDocAndAttributeOwner { +interface MvFieldDecl: MvDocAndAttributeOwner, MvNamedElement { val type: MvType? } \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt similarity index 94% rename from src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt rename to src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt index 94896ef5c..b53e404b1 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructDotField.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt @@ -1,6 +1,7 @@ package org.move.lang.core.psi.ext import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement import org.move.lang.core.psi.* import org.move.lang.core.resolve.RsResolveProcessor import org.move.lang.core.resolve.process @@ -44,7 +45,7 @@ fun processNamedFieldVariants( } // todo: change into VisibilityFilter -private fun isFieldsAccessible( +fun isFieldsAccessible( element: MvElement, item: MvStructOrEnumItemElement, msl: Boolean @@ -72,5 +73,7 @@ class MvFieldLookupReferenceImpl( abstract class MvFieldLookupMixin(node: ASTNode): MvElementImpl(node), MvFieldLookup { + override val referenceNameElement: PsiElement get() = (identifier ?: integerLiteral)!! + override fun getReference(): MvPolyVariantReference = MvFieldLookupReferenceImpl(this) } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt index 1e952c4a2..834ca1930 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldsOwner.kt @@ -22,8 +22,11 @@ val MvFieldsOwner.itemElement: MvStructOrEnumItemElement // } //} -val MvFieldsOwner.fields: List - get() = namedFields //+ positionalFields +//val MvFieldsOwner.fields: List +// get() = namedFields //+ positionalFields + +val MvFieldsOwner.fields: List + get() = namedFields + positionalFields val MvFieldsOwner.namedFields: List get() = blockFields?.namedFieldDeclList.orEmpty() diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt index 7456b2ec5..94b1b479b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt @@ -15,17 +15,17 @@ interface MvStructOrEnumItemElement: MvQualNamedElement, override fun declaredType(msl: Boolean): Ty { val typeParameters = this.tyTypeParams val itemTy = TyAdt(this, typeParameters, this.generics) - if (this is MvFieldsOwner && this.tupleFields != null) { - // tuple struct or tuple enum variant - val paramTypes = this.positionalFields.map { it.type.loweredType(msl) } - return TyFunction( - this, - typeParameters, - paramTypes, - returnType = itemTy, - acquiresTypes = emptyList(), - ) - } +// if (this is MvFieldsOwner && this.tupleFields != null) { +// // tuple struct or tuple enum variant +// val paramTypes = this.positionalFields.map { it.type.loweredType(msl) } +// return TyFunction( +// this, +// typeParameters, +// paramTypes, +// returnType = itemTy, +// acquiresTypes = emptyList(), +// ) +// } return itemTy } } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt index 95ddbbc8b..f5cc5f6d7 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvTupleFieldDecl.kt @@ -1,6 +1,8 @@ package org.move.lang.core.psi.ext import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement +import com.intellij.util.IncorrectOperationException import org.move.ide.MoveIcons import org.move.lang.core.psi.MvElementImpl import org.move.lang.core.psi.MvTupleFieldDecl @@ -14,4 +16,8 @@ abstract class MvTupleFieldDeclMixin(node: ASTNode): MvElementImpl(node), MvTupl override fun getIcon(flags: Int): Icon? = MoveIcons.FIELD override fun getName(): String? = position?.toString() + + override fun setName(name: String): PsiElement { + throw IncorrectOperationException("Cannot rename fake named element") + } } 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 ef49ed7d4..7295fa672 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt @@ -62,16 +62,16 @@ fun processItemsInScope( false } is MvItemSpec -> { - val specItem = scope.item - when (specItem) { + val referredItem = scope.item + when (referredItem) { is MvFunction -> { processor.processAll( elementNs, - specItem.valueParamsAsBindings, - specItem.specFunctionResultParameters.map { it.patBinding }, + referredItem.valueParamsAsBindings, + referredItem.specFunctionResultParameters.map { it.patBinding }, ) } - is MvStruct -> processor.processAll(elementNs, specItem.fields) + is MvStruct -> processor.processAll(elementNs, referredItem.namedFields) else -> false } } 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 0452475c3..65dabd811 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt @@ -4,12 +4,32 @@ import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* import org.move.lang.core.resolve.* import org.move.lang.core.resolve.ref.* +import org.move.lang.core.resolve2.ref.FieldResolveVariant import org.move.lang.core.resolve2.ref.ResolutionContext import org.move.lang.core.types.Address import org.move.lang.core.types.Address.Named import org.move.lang.core.types.address +import org.move.lang.core.types.ty.Ty +import org.move.lang.core.types.ty.TyAdt import org.move.lang.index.MvModuleIndex +fun processFieldLookupResolveVariants( + fieldLookup: MvFieldLookup, + receiverTy: TyAdt, + msl: Boolean, + originalProcessor: RsResolveProcessorBase, +): Boolean { + val receiverItem = receiverTy.item + if (!isFieldsAccessible(fieldLookup, receiverItem, msl)) return false + + val processor = originalProcessor.wrapWithMapper { it: ScopeEntry -> + FieldResolveVariant(it.name, it.element) +// FieldResolveVariant(it.name, it.element, ty, autoderef.steps(), autoderef.obligations()) + } + val structItem = receiverTy.item as? MvStruct ?: return false + + return processFieldDeclarations(structItem, processor) +} fun processStructLitFieldResolveVariants( litField: MvStructLitField, @@ -218,6 +238,12 @@ fun walkUpThroughScopes( return false } +private fun processFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean = + struct.fields.any { field -> + val name = field.name ?: return@any false + processor.process(name, NAMES, field) + } + private fun processNamedFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean = struct.namedFields.any { field -> val name = field.name diff --git a/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt index e573264da..39a0c29ba 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/ref/MvMethodCallReferenceImpl.kt @@ -1,11 +1,15 @@ package org.move.lang.core.resolve2.ref import com.intellij.psi.PsiElement +import org.move.lang.core.psi.MvElement import org.move.lang.core.psi.MvFunction import org.move.lang.core.psi.MvMethodCall import org.move.lang.core.psi.MvNamedElement import org.move.lang.core.psi.ext.isMsl +import org.move.lang.core.resolve.ScopeEntry import org.move.lang.core.resolve.ref.MvPolyVariantReferenceBase +import org.move.lang.core.resolve.ref.NAMES +import org.move.lang.core.resolve.ref.Namespace import org.move.lang.core.types.infer.inference import org.move.stdext.wrapWithList @@ -22,3 +26,23 @@ class MvMethodCallReferenceImpl( override fun isReferenceTo(element: PsiElement): Boolean = element is MvFunction && super.isReferenceTo(element) } + +interface DotExprResolveVariant : ScopeEntry { + /** The receiver type after possible derefs performed */ +// val selfTy: Ty + /** The number of `*` dereferences should be performed on receiver to match `selfTy` */ +// val derefCount: Int + + override val namespaces: Set + get() = NAMES // Namespace does not matter in the case of dot expression + + override fun doCopyWithNs(namespaces: Set): ScopeEntry = this +} + +data class FieldResolveVariant( + override val name: String, + override val element: MvNamedElement, +// override val selfTy: Ty, +// val derefSteps: List, +// val obligations: List, +): DotExprResolveVariant \ No newline at end of file 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 35f6a0a88..74032e4a7 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 @@ -13,6 +13,7 @@ import org.move.lang.core.resolve.collectMethodOrPathResolveVariants import org.move.lang.core.resolve.processAll 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 @@ -460,10 +461,12 @@ class TypeInferenceWalker( fun inferFieldLookupTy(receiverTy: Ty, fieldLookup: MvFieldLookup): Ty { val tyAdt = receiverTy.derefIfNeeded() as? TyAdt ?: return TyUnknown + val field = resolveSingleResolveVariant(fieldLookup.referenceName) { - processNamedFieldVariants(fieldLookup, tyAdt, msl, it) - } as? MvNamedFieldDecl + processFieldLookupResolveVariants(fieldLookup, tyAdt, msl, it) +// processNamedFieldVariants(fieldLookup, tyAdt, msl, it) + } as? MvFieldDecl ctx.resolvedFields[fieldLookup] = field val fieldTy = field?.type?.loweredType(msl)?.substitute(tyAdt.typeParameterValues) diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveStructFieldsTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveStructFieldsTest.kt index 272b71b53..8510bec61 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveStructFieldsTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveStructFieldsTest.kt @@ -275,4 +275,25 @@ class ResolveStructFieldsTest : ResolveTestCase() { } } """) + + fun `test positional struct type as a type`() = checkByCode(""" + module 0x1::m { + struct S(u8); + //X + fun main(s: S) { + //^ + } + } + """) + + fun `test positional field lookup type`() = checkByCode(""" + module 0x1::m { + struct S(u8); + //X + fun main(s: S) { + s.0; + //^ + } + } + """) } diff --git a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt index 109c1b31e..f883ead3d 100644 --- a/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt +++ b/src/test/kotlin/org/move/lang/resolve/ResolveTypesTest.kt @@ -817,7 +817,7 @@ module 0x1::m { } """) - fun `test resolve tuple struct`() = checkByCode(""" + fun `test resolve tuple struct as a name`() = checkByCode(""" module 0x1::m { struct S(u8); //X diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt index 18fac9f42..de24b9c53 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt @@ -2061,7 +2061,7 @@ module 0x1::main { fun `test positional field lookup type`() = testExpr(""" module 0x1::m { - struct S(u8) + struct S(u8); fun main(s: S) { s.0; //^ u8 From 58506032ebd45b20bac615ab76a17693843657b2 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Tue, 27 Aug 2024 23:12:31 +0300 Subject: [PATCH 07/13] TypeParameterOwner -> GenericDeclaration --- src/main/grammars/MoveParser.bnf | 4 ++-- .../org/move/ide/annotator/MvErrorAnnotator.kt | 2 +- .../org/move/ide/hints/TypeParameterInfoHandler.kt | 2 +- .../kotlin/org/move/lang/core/psi/MvFunctionLike.kt | 2 +- ...ypeParametersOwner.kt => MvGenericDeclaration.kt} | 12 ++++++------ .../lang/core/psi/ext/MvStructOrEnumItemElement.kt | 3 +-- .../move/lang/core/resolve2/LexicalDeclarations2.kt | 2 +- .../org/move/lang/core/types/infer/ExpectedType.kt | 2 +- .../move/lang/core/types/infer/InferenceContext.kt | 2 +- .../kotlin/org/move/lang/core/types/infer/Paths.kt | 2 +- .../org/move/lang/core/types/infer/Patterns.kt | 2 +- .../org/move/lang/core/types/infer/TyLowering.kt | 4 ++-- src/main/kotlin/org/move/lang/core/types/ty/Ty.kt | 4 ++-- .../kotlin/org/move/lang/core/types/ty/TyFunction.kt | 4 ++-- 14 files changed, 23 insertions(+), 24 deletions(-) rename src/main/kotlin/org/move/lang/core/psi/{MvTypeParametersOwner.kt => MvGenericDeclaration.kt} (67%) diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 8e5a278a6..5ea1869b7 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -1428,7 +1428,7 @@ ItemSpecRef ::= IDENTIFIER Schema ::= Attr* (spec schema) IDENTIFIER TypeParameterList? <> { pin = 2 implements = [ - "org.move.lang.core.psi.MvTypeParametersOwner" + "org.move.lang.core.psi.MvGenericDeclaration" "org.move.lang.core.psi.MvQualNamedElement" "org.move.lang.core.types.infer.MvInferenceContextOwner" "org.move.lang.core.psi.ScopeMslOnlyElement" @@ -1657,7 +1657,7 @@ AxiomSpecExpr ::= axiom TypeParameterList? SpecPropertyList? Expr { pin = 1 implements = [ "org.move.lang.core.psi.MvBoolSpecExpr" - "org.move.lang.core.psi.MvTypeParametersOwner" + "org.move.lang.core.psi.MvGenericDeclaration" "org.move.lang.core.psi.MslOnlyElement" ] } diff --git a/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt b/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt index eb55a7140..e6cd38d68 100644 --- a/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt +++ b/src/main/kotlin/org/move/ide/annotator/MvErrorAnnotator.kt @@ -310,7 +310,7 @@ class MvErrorAnnotator: MvAnnotatorBase() { private fun checkTypeArgumentList( typeArgumentList: MvTypeArgumentList, - item: MvTypeParametersOwner, + item: MvGenericDeclaration, holder: MvAnnotationHolder, ) { val qualName = (item as? MvQualNamedElement)?.qualName ?: return diff --git a/src/main/kotlin/org/move/ide/hints/TypeParameterInfoHandler.kt b/src/main/kotlin/org/move/ide/hints/TypeParameterInfoHandler.kt index d5b42e2a6..ac6ebc0e7 100644 --- a/src/main/kotlin/org/move/ide/hints/TypeParameterInfoHandler.kt +++ b/src/main/kotlin/org/move/ide/hints/TypeParameterInfoHandler.kt @@ -21,7 +21,7 @@ class TypeParameterInfoHandler : val parentPath = element.parent as? MvPath ?: return null val owner = parentPath.reference?.resolveFollowingAliases() ?: return null // if zero type parameters - if (owner !is MvTypeParametersOwner) return null + if (owner !is MvGenericDeclaration) return null return arrayOf(typeParamsDescription(owner.typeParameters)) } 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 6f558a6d0..dec67d866 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -18,7 +18,7 @@ import org.move.lang.core.types.ty.TyLambda import org.move.lang.core.types.ty.TyUnknown interface MvFunctionLike: MvNameIdentifierOwner, - MvTypeParametersOwner, + MvGenericDeclaration, MvDocAndAttributeOwner { val functionParameterList: MvFunctionParameterList? diff --git a/src/main/kotlin/org/move/lang/core/psi/MvTypeParametersOwner.kt b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt similarity index 67% rename from src/main/kotlin/org/move/lang/core/psi/MvTypeParametersOwner.kt rename to src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt index 65428262e..2c43e909b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvTypeParametersOwner.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt @@ -7,22 +7,22 @@ import org.move.lang.core.types.ty.TyInfer import org.move.lang.core.types.ty.TyTypeParameter import org.move.lang.core.types.ty.TyUnknown -interface MvTypeParametersOwner : MvElement { +interface MvGenericDeclaration : MvElement { val typeParameterList: MvTypeParameterList? // override for generic items fun declaredType(msl: Boolean): Ty = TyUnknown } -val MvTypeParametersOwner.typeParameters: List +val MvGenericDeclaration.typeParameters: List get() = typeParameterList?.typeParameterList.orEmpty() -val MvTypeParametersOwner.generics: List +val MvGenericDeclaration.generics: List get() = typeParameters.map { TyTypeParameter(it) } -val MvTypeParametersOwner.tyTypeParams: Substitution get() = Substitution(generics.associateWith { it }) +val MvGenericDeclaration.tyTypeParams: Substitution get() = Substitution(generics.associateWith { it }) -val MvTypeParametersOwner.tyInfers: Substitution +val MvGenericDeclaration.tyInfers: Substitution get() { val typeSubst = this .generics @@ -30,6 +30,6 @@ val MvTypeParametersOwner.tyInfers: Substitution return typeSubst.toTypeSubst() } -val MvTypeParametersOwner.hasTypeParameters: Boolean +val MvGenericDeclaration.hasTypeParameters: Boolean get() = typeParameters.isNotEmpty() diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt index 94b1b479b..26b177466 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt @@ -3,12 +3,11 @@ package org.move.lang.core.psi.ext import com.intellij.psi.StubBasedPsiElement import org.move.lang.core.psi.* import org.move.lang.core.stubs.MvModuleStub -import org.move.lang.core.types.infer.loweredType import org.move.lang.core.types.ty.* interface MvStructOrEnumItemElement: MvQualNamedElement, MvItemElement, - MvTypeParametersOwner { + MvGenericDeclaration { val abilitiesList: MvAbilitiesList? 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 7295fa672..50674eb1a 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/LexicalDeclarations2.kt @@ -187,7 +187,7 @@ fun processItemsInScope( } Namespace.TYPE -> { - if (scope is MvTypeParametersOwner) { + if (scope is MvGenericDeclaration) { if (processor.processAll(elementNs, scope.typeParameters)) return true } val found = when (scope) { diff --git a/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt b/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt index fbc26f792..afd02aa07 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt @@ -27,7 +27,7 @@ fun inferExpectedTypeArgumentTy(typeArgument: MvTypeArgument): Ty? { if (paramIndex == -1) return null val path = typeArgumentList.parent as MvPath - val genericItem = path.reference?.resolveFollowingAliases() as? MvTypeParametersOwner ?: return null + val genericItem = path.reference?.resolveFollowingAliases() as? MvGenericDeclaration ?: return null genericItem.typeParameters .getOrNull(paramIndex) ?.let { TyInfer.TyVar(TyTypeParameter(it)) } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index 7a0547083..cd95b39b4 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -351,7 +351,7 @@ class InferenceContext( @Suppress("UNCHECKED_CAST") fun instantiateMethodOrPath( methodOrPath: MvMethodOrPath, - genericItem: MvTypeParametersOwner + genericItem: MvGenericDeclaration ): Pair? { var itemTy = this.methodOrPathTypes.getOrPut(methodOrPath) { diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt b/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt index 291727b0b..e484df0cd 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt @@ -6,7 +6,7 @@ import org.move.lang.core.types.infer.RsPsiSubstitution.Value fun pathPsiSubst( methodOrPath: MvMethodOrPath, - resolved: MvTypeParametersOwner, + resolved: MvGenericDeclaration, ): RsPsiSubstitution { val typeParameters = resolved.typeParameters val parent = methodOrPath.parent diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt index 4d9edfb8a..a17ffe51a 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt @@ -47,7 +47,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode ?: (expected as? TyAdt)?.item as? MvStruct ?: return - if (item is MvTypeParametersOwner) { + if (item is MvGenericDeclaration) { val (patTy, _) = fcx.ctx.instantiateMethodOrPath(this.path, item) ?: return if (!isCompatible(expected, patTy, fcx.msl)) { fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index 59b555370..00a331a2a 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -54,7 +54,7 @@ class TyLowering { } return when (namedItem) { is MvTypeParameter -> TyTypeParameter(namedItem) - is MvTypeParametersOwner -> { + is MvGenericDeclaration -> { val baseTy = namedItem.declaredType(msl) val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) // val (_, explicits) = instantiatePathGenerics(path, namedItem, msl) @@ -93,7 +93,7 @@ class TyLowering { namedItem: T, msl: Boolean ): Substitution { - if (namedItem !is MvTypeParametersOwner) return emptySubstitution + if (namedItem !is MvGenericDeclaration) return emptySubstitution val psiSubstitution = pathPsiSubst(methodOrPath, namedItem) diff --git a/src/main/kotlin/org/move/lang/core/types/ty/Ty.kt b/src/main/kotlin/org/move/lang/core/types/ty/Ty.kt index 438d63aae..d9fa49981 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/Ty.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/Ty.kt @@ -1,6 +1,6 @@ package org.move.lang.core.types.ty -import org.move.lang.core.psi.MvTypeParametersOwner +import org.move.lang.core.psi.MvGenericDeclaration import org.move.lang.core.types.infer.* import org.move.lang.core.types.infer.HasTypeFlagVisitor.Companion.HAS_TY_ADT_VISITOR import org.move.lang.core.types.infer.HasTypeFlagVisitor.Companion.HAS_TY_INFER_VISITOR @@ -88,7 +88,7 @@ fun Ty.mslScopeRefined(msl: Boolean): Ty { } abstract class GenericTy( - open val item: MvTypeParametersOwner, + open val item: MvGenericDeclaration, open val substitution: Substitution, flags: TypeFlags, ) : Ty(mergeFlags(substitution.types) or flags) diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt index 55899a5ae..c6676e73e 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt @@ -2,12 +2,12 @@ package org.move.lang.core.types.ty import com.intellij.openapi.project.Project import org.move.ide.presentation.tyToString -import org.move.lang.core.psi.MvTypeParametersOwner +import org.move.lang.core.psi.MvGenericDeclaration import org.move.lang.core.psi.psiFactory import org.move.lang.core.types.infer.* data class TyFunction( - override val item: MvTypeParametersOwner, + override val item: MvGenericDeclaration, override val substitution: Substitution, override val paramTypes: List, override val returnType: Ty, From fbf7d393a3df069ddb4554f781d05606273b108b Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Thu, 29 Aug 2024 03:10:57 +0300 Subject: [PATCH 08/13] extract function type creation from other types --- src/main/grammars/MoveParser.bnf | 2 + .../inspections/MvAbilityCheckInspection.kt | 3 +- .../lang/core/completion/FuncSignature.kt | 3 +- .../lang/core/completion/MvLookupElement.kt | 3 +- .../MethodOrFieldCompletionProvider.kt | 2 +- .../org/move/lang/core/psi/MvFunctionLike.kt | 24 ++-------- .../lang/core/psi/MvGenericDeclaration.kt | 8 +--- .../org/move/lang/core/psi/ext/MvEnum.kt | 4 ++ .../org/move/lang/core/psi/ext/MvFunction.kt | 16 ------- .../org/move/lang/core/psi/ext/MvSchema.kt | 14 +++--- .../org/move/lang/core/psi/ext/MvStruct.kt | 4 ++ .../core/psi/ext/MvStructOrEnumItemElement.kt | 33 +++++++------- .../core/psi/ext/MvTypeDeclarationElement.kt | 15 +++++++ .../move/lang/core/psi/ext/MvTypeParameter.kt | 14 +++--- .../move/lang/core/types/MvPsiTypeImplUtil.kt | 19 ++++++++ .../lang/core/types/infer/ExpectedType.kt | 2 +- .../lang/core/types/infer/InferenceContext.kt | 5 +-- .../lang/core/types/infer/Substitution.kt | 2 +- .../move/lang/core/types/infer/TyLowering.kt | 44 +++++++++---------- .../core/types/infer/TypeInferenceWalker.kt | 2 +- .../org/move/lang/core/types/ty/TyAdt.kt | 19 ++++++-- .../org/move/lang/core/types/ty/TyFunction.kt | 22 ++++++++++ .../lang/core/types/ty/TyTypeParameter.kt | 14 +++++- 23 files changed, 161 insertions(+), 113 deletions(-) create mode 100644 src/main/kotlin/org/move/lang/core/psi/ext/MvTypeDeclarationElement.kt create mode 100644 src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt diff --git a/src/main/grammars/MoveParser.bnf b/src/main/grammars/MoveParser.bnf index 5ea1869b7..a266bd94f 100644 --- a/src/main/grammars/MoveParser.bnf +++ b/src/main/grammars/MoveParser.bnf @@ -685,6 +685,7 @@ private TypeParameter_recover ::= !('>' | '(' | '{' | phantom | IDENTIFIER) fake TypeParameter ::= phantom? IDENTIFIER? TypeParamBound? { pin = 2 implements = [ + "org.move.lang.core.psi.ext.MvTypeDeclarationElement" "org.move.lang.core.psi.MvNameIdentifierOwner" ] mixin = "org.move.lang.core.psi.ext.MvTypeParameterMixin" @@ -1433,6 +1434,7 @@ Schema ::= Attr* (spec schema) IDENTIFIER TypeParameterList? <, @@ -50,7 +51,7 @@ data class FuncSignature( companion object { fun fromFunction(function: MvFunction, msl: Boolean): FuncSignature { - val declaredType = function.declaredType(msl) + val declaredType = function.functionTy(msl) val params = function.parameters.zip(declaredType.paramTypes) .associate { (param, paramTy) -> Pair(param.name, paramTy) } val retType = declaredType.returnType diff --git a/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt b/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt index 3a2bbf3a1..7e2fc6f33 100644 --- a/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt +++ b/src/main/kotlin/org/move/lang/core/completion/MvLookupElement.kt @@ -5,6 +5,7 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator import org.move.lang.core.psi.* import org.move.lang.core.types.infer.* import org.move.lang.core.types.ty.TyUnknown +import org.move.lang.core.types.ty.functionTy fun LookupElement.toMvLookupElement(properties: LookupElementProperties): MvLookupElement = MvLookupElement(this, properties) @@ -63,7 +64,7 @@ fun getLookupElementProperties( val msl = context.msl val declaredTy = when (element) { - is MvFunctionLike -> element.declaredType(msl).returnType + is MvFunctionLike -> element.functionTy(msl).returnType is MvStruct -> element.declaredType(msl) is MvConst -> element.type?.loweredType(msl) ?: TyUnknown is MvPatBinding -> { diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt index 4aa5c82df..bb0e7c99f 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt @@ -56,7 +56,7 @@ object MethodOrFieldCompletionProvider: MvCompletionProvider() { processMethodResolveVariants(element, receiverTy, ctx.msl, createProcessor { e -> val function = e.element as? MvFunction ?: return@createProcessor val subst = function.tyInfers - val declaredFuncTy = function.declaredType(msl).substitute(subst) as TyFunction + val declaredFuncTy = function.functionTy(msl).substitute(subst) as TyFunction val declaredSelfTy = declaredFuncTy.paramTypes.first() val autoborrowedReceiverTy = TyReference.autoborrow(receiverTy, declaredSelfTy) 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 dec67d866..36965f52b 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -12,10 +12,7 @@ import org.move.lang.core.types.infer.InferenceContext import org.move.lang.core.types.infer.deepFoldTyInferWith import org.move.lang.core.types.infer.loweredType import org.move.lang.core.types.infer.substitute -import org.move.lang.core.types.ty.Ty -import org.move.lang.core.types.ty.TyFunction -import org.move.lang.core.types.ty.TyLambda -import org.move.lang.core.types.ty.TyUnknown +import org.move.lang.core.types.ty.* interface MvFunctionLike: MvNameIdentifierOwner, MvGenericDeclaration, @@ -24,20 +21,6 @@ interface MvFunctionLike: MvNameIdentifierOwner, val functionParameterList: MvFunctionParameterList? val returnType: MvReturnType? - - override fun declaredType(msl: Boolean): TyFunction { - val typeParameters = this.tyTypeParams - val paramTypes = parameters.map { it.type?.loweredType(msl) ?: TyUnknown } - val acquiredTypes = this.acquiresPathTypes.map { it.loweredType(msl) } - val retType = returnTypeTy(msl) - return TyFunction( - this, - typeParameters, - paramTypes, - retType, - acquiredTypes, - ) - } } val MvFunctionLike.functionItemPresentation: PresentationData? @@ -136,17 +119,18 @@ val MvFunction.selfSignatureText: String fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: CompletionContext?): Boolean { val msl = this.isMslOnlyItem - val callTy = this.declaredType(msl).substitute(this.tyInfers) as TyFunction + val callTy = this.functionTy(msl).substitute(this.tyInfers) as TyFunction val inferenceCtx = InferenceContext(msl) - callTy.paramTypes.forEach { inferenceCtx.combineTypes(it, it.deepFoldTyInferWith { TyUnknown }) } + val expectedTy = completionContext?.expectedTy if (expectedTy != null && expectedTy !is TyUnknown) { inferenceCtx.combineTypes(callTy.returnType, expectedTy) } val resolvedCallTy = inferenceCtx.resolveTypeVarsIfPossible(callTy) as TyFunction + return resolvedCallTy.needsTypeAnnotation() } \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt index 2c43e909b..51959a628 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt @@ -2,15 +2,11 @@ package org.move.lang.core.psi import org.move.lang.core.types.infer.Substitution import org.move.lang.core.types.infer.toTypeSubst -import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyInfer import org.move.lang.core.types.ty.TyTypeParameter -import org.move.lang.core.types.ty.TyUnknown -interface MvGenericDeclaration : MvElement { +interface MvGenericDeclaration: MvElement { val typeParameterList: MvTypeParameterList? - // override for generic items - fun declaredType(msl: Boolean): Ty = TyUnknown } val MvGenericDeclaration.typeParameters: List @@ -18,7 +14,7 @@ val MvGenericDeclaration.typeParameters: List typeParameterList?.typeParameterList.orEmpty() val MvGenericDeclaration.generics: List - get() = typeParameters.map { TyTypeParameter(it) } + get() = typeParameters.map { TyTypeParameter.named(it) } val MvGenericDeclaration.tyTypeParams: Substitution get() = Substitution(generics.associateWith { it }) diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt index 91899210f..7084b24b7 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvEnum.kt @@ -8,6 +8,8 @@ import org.move.lang.core.psi.MvEnumVariant import org.move.lang.core.stubs.MvEnumStub import org.move.lang.core.stubs.MvStubbedNamedElementImpl import org.move.lang.core.types.ItemQualName +import org.move.lang.core.types.MvPsiTypeImplUtil +import org.move.lang.core.types.ty.Ty import javax.swing.Icon val MvEnum.variants: List get() = enumBody?.enumVariantList.orEmpty() @@ -24,6 +26,8 @@ abstract class MvEnumMixin: MvStubbedNamedElementImpl, constructor(stub: MvEnumStub, nodeType: IStubElementType<*, *>): super(stub, nodeType) + override fun declaredType(msl: Boolean): Ty = MvPsiTypeImplUtil.declaredType(this) + override fun getIcon(flags: Int): Icon = MoveIcons.STRUCT override val qualName: ItemQualName? diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt index a6a081e87..5a156e884 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFunction.kt @@ -74,14 +74,6 @@ fun MvFunction.outerItemSpecs(): List { val MvFunction.transactionParameters: List get() = this.parameters.drop(1) -//fun MvFunctionLike.declaredType(msl: Boolean): TyFunction2 { -// val subst = typeParameters ?: this.instantiateTypeParameters() -// val paramTypes = parameters.map { it.type?.loweredType(msl) ?: TyUnknown } -// val acquiresTypes = this.acquiresPathTypes.map { it.loweredType(msl) } -// val retType = rawReturnType(msl) -// return TyFunction2(subst, paramTypes, acquiresTypes, retType) -//} - fun MvFunctionLike.returnTypeTy(msl: Boolean): Ty { val retType = this.returnType ?: return TyUnit return retType.type?.loweredType(msl) ?: TyUnknown @@ -129,14 +121,6 @@ abstract class MvFunctionMixin : MvStubbedNamedElementImpl, return ItemQualName(this, moduleFQName.address, moduleFQName.itemName, itemName) } -// override fun declaredType(msl: Boolean): TyFunction2 { -// val subst = this.instantiateTypeParameters() -// val paramTypes = parameters.map { it.type?.loweredType(msl) ?: TyUnknown } -// val acquiresTypes = this.acquiresPathTypes.map { it.loweredType(msl) } -// val retType = rawReturnType(msl) -// return TyFunction2(subst, paramTypes, acquiresTypes, retType) -// } - override val modificationTracker = MvModificationTracker(this) override fun incModificationCount(element: PsiElement): Boolean { diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvSchema.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvSchema.kt index 56a11df2c..ed28342e6 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvSchema.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvSchema.kt @@ -7,9 +7,10 @@ import org.move.lang.core.psi.* import org.move.lang.core.stubs.MvSchemaStub import org.move.lang.core.stubs.MvStubbedNamedElementImpl import org.move.lang.core.types.ItemQualName +import org.move.lang.core.types.MvPsiTypeImplUtil import org.move.lang.core.types.infer.deepFoldTyTypeParameterWith import org.move.lang.core.types.infer.loweredType -import org.move.lang.core.types.ty.TySchema +import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyUnknown val MvSchema.specBlock: MvSpecCodeBlock? get() = this.childOfType() @@ -33,12 +34,12 @@ val MvSchema.fieldsAsBindings get() = this.fieldStmts.map { it.patBinding } val MvIncludeStmt.expr: MvExpr? get() = this.childOfType() -abstract class MvSchemaMixin : MvStubbedNamedElementImpl, - MvSchema { +abstract class MvSchemaMixin: MvStubbedNamedElementImpl, + MvSchema { - constructor(node: ASTNode) : super(node) + constructor(node: ASTNode): super(node) - constructor(stub: MvSchemaStub, nodeType: IStubElementType<*, *>) : super(stub, nodeType) + constructor(stub: MvSchemaStub, nodeType: IStubElementType<*, *>): super(stub, nodeType) override fun getIcon(flags: Int) = MoveIcons.SCHEMA @@ -49,6 +50,5 @@ abstract class MvSchemaMixin : MvStubbedNamedElementImpl, return ItemQualName(this, moduleFQName.address, moduleFQName.itemName, itemName) } - override fun declaredType(msl: Boolean): TySchema = - TySchema(this, this.tyTypeParams, this.generics) + override fun declaredType(msl: Boolean): Ty = MvPsiTypeImplUtil.declaredType(this) } diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt index dc53d074b..84dc7fde1 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStruct.kt @@ -13,7 +13,9 @@ import org.move.lang.core.psi.typeParameters import org.move.lang.core.stubs.MvStructStub import org.move.lang.core.stubs.MvStubbedNamedElementImpl import org.move.lang.core.types.ItemQualName +import org.move.lang.core.types.MvPsiTypeImplUtil import org.move.lang.core.types.ty.Ability +import org.move.lang.core.types.ty.Ty import org.move.stdext.withAdded import javax.swing.Icon @@ -95,6 +97,8 @@ abstract class MvStructMixin: MvStubbedNamedElementImpl, return ItemQualName(this, moduleFQName.address, moduleFQName.itemName, itemName) } + override fun declaredType(msl: Boolean): Ty = MvPsiTypeImplUtil.declaredType(this) + override fun getIcon(flags: Int): Icon = MoveIcons.STRUCT override fun getPresentation(): ItemPresentation? { diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt index 26b177466..503b598a5 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvStructOrEnumItemElement.kt @@ -7,26 +7,27 @@ import org.move.lang.core.types.ty.* interface MvStructOrEnumItemElement: MvQualNamedElement, MvItemElement, + MvTypeDeclarationElement, MvGenericDeclaration { val abilitiesList: MvAbilitiesList? - override fun declaredType(msl: Boolean): Ty { - val typeParameters = this.tyTypeParams - val itemTy = TyAdt(this, typeParameters, this.generics) -// if (this is MvFieldsOwner && this.tupleFields != null) { -// // tuple struct or tuple enum variant -// val paramTypes = this.positionalFields.map { it.type.loweredType(msl) } -// return TyFunction( -// this, -// typeParameters, -// paramTypes, -// returnType = itemTy, -// acquiresTypes = emptyList(), -// ) -// } - return itemTy - } +// override fun declaredType(msl: Boolean): Ty { +// val typeParameters = this.tyTypeParams +// val itemTy = TyAdt(this, typeParameters, this.generics) +//// if (this is MvFieldsOwner && this.tupleFields != null) { +//// // tuple struct or tuple enum variant +//// val paramTypes = this.positionalFields.map { it.type.loweredType(msl) } +//// return TyFunction( +//// this, +//// typeParameters, +//// paramTypes, +//// returnType = itemTy, +//// acquiresTypes = emptyList(), +//// ) +//// } +// return itemTy +// } } val MvStructOrEnumItemElement.psiAbilities: List diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeDeclarationElement.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeDeclarationElement.kt new file mode 100644 index 000000000..844164b70 --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeDeclarationElement.kt @@ -0,0 +1,15 @@ +package org.move.lang.core.psi.ext + +import org.move.lang.core.psi.MvElement +import org.move.lang.core.types.ty.Ty + +/** + * Psi element that defines a type and thus lives in types namespace. + * Archetypal inheritors are structs an enums. Type aliases are type + * declarations, while constants and statics are not. Notably, traits + * are type declarations: a bare trait denotes a trait object type. + * + */ +interface MvTypeDeclarationElement: MvElement { + fun declaredType(msl: Boolean): Ty +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeParameter.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeParameter.kt index a13297df8..385de258a 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeParameter.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvTypeParameter.kt @@ -5,21 +5,19 @@ import org.move.lang.MvElementTypes import org.move.lang.core.psi.MvAbility import org.move.lang.core.psi.MvTypeParameter import org.move.lang.core.psi.impl.MvNameIdentifierOwnerImpl +import org.move.lang.core.types.MvPsiTypeImplUtil +import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyTypeParameter val MvTypeParameter.isPhantom get() = hasChild(MvElementTypes.PHANTOM) -val MvTypeParameter.typeParamType: TyTypeParameter - get() { - return TyTypeParameter(this) - } - val MvTypeParameter.abilityBounds: List get() { return typeParamBound?.abilityList.orEmpty() } -//fun MvTypeParameter.ty(): TyTypeParameter = TyTypeParameter(this) - abstract class MvTypeParameterMixin(node: ASTNode) : MvNameIdentifierOwnerImpl(node), - MvTypeParameter + MvTypeParameter { + + override fun declaredType(msl: Boolean): Ty = MvPsiTypeImplUtil.declaredType(this) +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt b/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt new file mode 100644 index 000000000..87aa48a8c --- /dev/null +++ b/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt @@ -0,0 +1,19 @@ +package org.move.lang.core.types + +import org.move.lang.core.psi.MvEnum +import org.move.lang.core.psi.MvSchema +import org.move.lang.core.psi.MvStruct +import org.move.lang.core.psi.MvTypeParameter +import org.move.lang.core.psi.generics +import org.move.lang.core.psi.tyTypeParams +import org.move.lang.core.types.ty.Ty +import org.move.lang.core.types.ty.TyAdt +import org.move.lang.core.types.ty.TySchema +import org.move.lang.core.types.ty.TyTypeParameter + +object MvPsiTypeImplUtil { + fun declaredType(psi: MvTypeParameter): Ty = TyTypeParameter.named(psi) + fun declaredType(psi: MvStruct): Ty = TyAdt.valueOf(psi) + fun declaredType(psi: MvEnum): Ty = TyAdt.valueOf(psi) + fun declaredType(psi: MvSchema): Ty = TySchema(psi, psi.tyTypeParams, psi.generics) +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt b/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt index afd02aa07..7fac89726 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/ExpectedType.kt @@ -30,7 +30,7 @@ fun inferExpectedTypeArgumentTy(typeArgument: MvTypeArgument): Ty? { val genericItem = path.reference?.resolveFollowingAliases() as? MvGenericDeclaration ?: return null genericItem.typeParameters .getOrNull(paramIndex) - ?.let { TyInfer.TyVar(TyTypeParameter(it)) } + ?.let { TyInfer.TyVar(TyTypeParameter.named(it)) } } else -> error("invalid MvTypeArgument parent ${parent.elementType}") } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index cd95b39b4..08b061358 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -357,7 +357,7 @@ class InferenceContext( this.methodOrPathTypes.getOrPut(methodOrPath) { // can only be method or path, both are resolved to MvNamedElement val genericNamedItem = genericItem as MvNamedElement - TyLowering.lowerPath(methodOrPath, genericNamedItem, msl) as? T ?: return null + TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T ?: return null } val typeParameters = genericItem.tyInfers @@ -377,9 +377,6 @@ class InferenceContext( } } -// fun compareTypes(ty1: Ty, ty2: Ty): RelateResult = -// this.freezeUnification { this.combineTypes(ty1, ty2) } - fun combineTypes(ty1: Ty, ty2: Ty): RelateResult { val resolvedTy1 = resolveIfTyInfer(ty1) val resolvedTy2 = resolveIfTyInfer(ty2) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt index 0ff2266a2..8a111f6ca 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt @@ -13,7 +13,7 @@ open class Substitution(val typeSubst: Map = emptyMap()) : Substitution(mergeMaps(typeSubst, other.typeSubst)) operator fun get(key: TyTypeParameter): Ty? = typeSubst[key] - operator fun get(psi: MvTypeParameter): Ty? = typeSubst[TyTypeParameter(psi)] + operator fun get(psi: MvTypeParameter): Ty? = typeSubst[TyTypeParameter.named(psi)] // fun typeParameterByName(name: String): TyTypeParameter? = // typeSubst.keys.find { it.toString() == name } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index 00a331a2a..f4b2bbcad 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -7,10 +7,10 @@ import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.* import org.move.lang.core.types.ty.* -fun MvType.loweredType(msl: Boolean): Ty = TyLowering.lowerType(this, msl) +fun MvType.loweredType(msl: Boolean): Ty = TyLowering().lowerType(this, msl) class TyLowering { - fun lowerTy(moveType: MvType, msl: Boolean): Ty { + fun lowerType(moveType: MvType, msl: Boolean): Ty { return when (moveType) { is MvPathType -> { val genericItem = moveType.path.reference?.resolveFollowingAliases() @@ -19,22 +19,22 @@ class TyLowering { is MvRefType -> { val mutability = Mutability.valueOf(moveType.mutable) val refInnerType = moveType.type ?: return TyReference(TyUnknown, mutability, msl) - val innerTy = lowerTy(refInnerType, msl) + val innerTy = lowerType(refInnerType, msl) TyReference(innerTy, mutability, msl) } is MvTupleType -> { - val innerTypes = moveType.typeList.map { lowerTy(it, msl) } + val innerTypes = moveType.typeList.map { lowerType(it, msl) } TyTuple(innerTypes) } is MvUnitType -> TyUnit - is MvParensType -> lowerTy(moveType.type, msl) + is MvParensType -> lowerType(moveType.type, msl) is MvLambdaType -> { - val paramTys = moveType.paramTypes.map { lowerTy(it, msl) } + val paramTys = moveType.paramTypes.map { lowerType(it, msl) } val returnType = moveType.returnType val retTy = if (returnType == null) { TyUnit } else { - lowerTy(returnType, msl) + lowerType(returnType, msl) } TyLambda(paramTys, retTy) } @@ -45,7 +45,7 @@ class TyLowering { } } - private fun lowerPath(methodOrPath: MvMethodOrPath, namedItem: MvNamedElement?, msl: Boolean): Ty { + fun lowerPath(methodOrPath: MvMethodOrPath, namedItem: MvNamedElement?, msl: Boolean): Ty { // cannot do resolve() here due to circular caching for MethodCall, need to pass namedItem explicitly, // namedItem can be null if it's a primitive type // val namedItem = methodOrPath.reference?.resolveWithAliases() @@ -53,13 +53,19 @@ class TyLowering { return if (methodOrPath is MvPath) lowerPrimitiveTy(methodOrPath, msl) else TyUnknown } return when (namedItem) { - is MvTypeParameter -> TyTypeParameter(namedItem) - is MvGenericDeclaration -> { + is MvTypeDeclarationElement -> { val baseTy = namedItem.declaredType(msl) val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) -// val (_, explicits) = instantiatePathGenerics(path, namedItem, msl) baseTy.substitute(explicitSubst) } + is MvFunctionLike -> { + val baseTy = namedItem.functionTy(msl) + val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) + baseTy.substitute(explicitSubst) + } +// is MvTypeParameter -> TyTypeParameter(namedItem) +// is MvGenericDeclaration -> { +// } is MvEnumVariant -> lowerPath(methodOrPath, namedItem.enumItem, msl) else -> debugErrorOrFallback( "${namedItem.elementType} path cannot be inferred into type", @@ -80,7 +86,7 @@ class TyLowering { "signer" -> TySigner "vector" -> { val argType = path.typeArguments.firstOrNull()?.type - val itemTy = argType?.let { lowerTy(it, msl) } ?: TyUnknown + val itemTy = argType?.let { lowerType(it, msl) } ?: TyUnknown return TyVector(itemTy) } else -> TyUnknown @@ -99,9 +105,9 @@ class TyLowering { val typeSubst = hashMapOf() for ((param, value) in psiSubstitution.typeSubst.entries) { - val paramTy = TyTypeParameter(param) + val paramTy = TyTypeParameter.named(param) val valueTy = when (value) { - is RsPsiSubstitution.Value.Present -> lowerTy(value.value, msl) + is RsPsiSubstitution.Value.Present -> lowerType(value.value, msl) is RsPsiSubstitution.Value.OptionalAbsent -> paramTy is RsPsiSubstitution.Value.RequiredAbsent -> TyUnknown } @@ -109,14 +115,4 @@ class TyLowering { } return Substitution(typeSubst) } - - companion object { - fun lowerType(type: MvType, msl: Boolean): Ty { - return TyLowering().lowerTy(type, msl) - } - - fun lowerPath(path: MvMethodOrPath, namedItem: MvNamedElement?, msl: Boolean): Ty { - return TyLowering().lowerPath(path, namedItem, msl) - } - } } 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 74032e4a7..5f49a4ff2 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 @@ -327,7 +327,7 @@ class TypeInferenceWalker( is MvNamedFieldDecl -> item.type?.loweredType(msl) ?: TyUnknown is MvStruct -> { if (project.moveSettings.enableIndexExpr && pathExpr.parent is MvIndexExpr) { - TyLowering.lowerPath(pathExpr.path, item, ctx.msl) + TyLowering().lowerPath(pathExpr.path, item, ctx.msl) } else { // invalid statements 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 7f52ee019..b7664c117 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 @@ -1,11 +1,10 @@ package org.move.lang.core.types.ty +import com.intellij.codeInsight.completion.CompletionUtil import org.move.ide.presentation.tyToString -import org.move.lang.core.psi.MvEnum -import org.move.lang.core.psi.MvStruct +import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.MvStructOrEnumItemElement import org.move.lang.core.psi.ext.abilities -import org.move.lang.core.psi.typeParameters import org.move.lang.core.types.infer.* data class TyAdt( @@ -34,10 +33,22 @@ data class TyAdt( override val typeParameterValues: Substitution get() { val typeSubst = item.typeParameters.withIndex().associate { (i, param) -> - TyTypeParameter(param) to typeArguments.getOrElse(i) { TyUnknown } + TyTypeParameter.named(param) to typeArguments.getOrElse(i) { TyUnknown } } return Substitution(typeSubst) } + + companion object { + fun valueOf(struct: MvStructOrEnumItemElement): TyAdt { + val typeParameters = struct.tyTypeParams + return TyAdt( + struct, +// CompletionUtil.getOriginalOrSelf(struct), + typeParameters, + struct.generics + ) + } + } } val TyAdt.enumItem: MvEnum? get() = this.item as? MvEnum diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt index c6676e73e..033263281 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt @@ -2,9 +2,15 @@ package org.move.lang.core.types.ty import com.intellij.openapi.project.Project import org.move.ide.presentation.tyToString +import org.move.lang.core.psi.MvFunctionLike import org.move.lang.core.psi.MvGenericDeclaration +import org.move.lang.core.psi.acquiresPathTypes +import org.move.lang.core.psi.ext.returnTypeTy +import org.move.lang.core.psi.parameters import org.move.lang.core.psi.psiFactory +import org.move.lang.core.psi.tyTypeParams import org.move.lang.core.types.infer.* +import org.move.lang.core.types.infer.loweredType data class TyFunction( override val item: MvGenericDeclaration, @@ -53,3 +59,19 @@ data class TyFunction( } } } + +fun MvFunctionLike.functionTy(msl: Boolean): TyFunction = callableTy(this, msl) + +fun callableTy(item: MvFunctionLike, msl: Boolean): TyFunction { + val typeParameters = item.tyTypeParams + val paramTypes = item.parameters.map { it.type?.loweredType(msl) ?: TyUnknown } + val acquiredTypes = item.acquiresPathTypes.map { it.loweredType(msl) } + val retType = item.returnTypeTy(msl) + return TyFunction( + item, + typeParameters, + paramTypes, + retType, + acquiredTypes, + ) +} 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 66780c919..aca9c362b 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 @@ -1,5 +1,6 @@ package org.move.lang.core.types.ty +import com.intellij.codeInsight.completion.CompletionUtil import org.move.ide.presentation.tyToString import org.move.lang.core.psi.MvStruct import org.move.lang.core.psi.MvTypeParameter @@ -9,7 +10,9 @@ import org.move.lang.core.psi.ext.requiredAbilitiesForTypeParam import org.move.lang.core.types.infer.HAS_TY_TYPE_PARAMETER_MASK -data class TyTypeParameter(val origin: MvTypeParameter) : Ty(HAS_TY_TYPE_PARAMETER_MASK) { +class TyTypeParameter private constructor( + val origin: MvTypeParameter +) : Ty(HAS_TY_TYPE_PARAMETER_MASK) { val name: String? get() = origin.name @@ -26,4 +29,13 @@ data class TyTypeParameter(val origin: MvTypeParameter) : Ty(HAS_TY_TYPE_PARAMET override fun hashCode(): Int = origin.hashCode() override fun toString(): String = tyToString(this) + + 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) + } + } } From f701357808f36d1002e2280afa1de10c8673226e Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Thu, 29 Aug 2024 03:50:46 +0300 Subject: [PATCH 09/13] refactor instantiate path functions a bit --- .../lang/core/types/infer/InferenceContext.kt | 33 +------ .../move/lang/core/types/infer/Patterns.kt | 2 +- .../core/types/infer/TypeInferenceWalker.kt | 85 ++++++++++++------- 3 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index 08b061358..061510754 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -86,7 +86,7 @@ data class InferenceResult( private val exprTypes: Map, private val exprExpectedTypes: Map, - private val methodOrPathTypes: Map, + val methodOrPathTypes: Map, private val resolvedPaths: Map>, private val resolvedFields: Map, @@ -192,7 +192,7 @@ class InferenceContext( private val callableTypes = mutableMapOf() // private val pathTypes = mutableMapOf() - private val methodOrPathTypes = mutableMapOf() + val methodOrPathTypes = mutableMapOf() val resolvedPaths = mutableMapOf>() val resolvedFields = mutableMapOf() @@ -348,35 +348,6 @@ class InferenceContext( return exprTypes[expr] ?: TyUnknown } - @Suppress("UNCHECKED_CAST") - fun instantiateMethodOrPath( - methodOrPath: MvMethodOrPath, - genericItem: MvGenericDeclaration - ): Pair? { - var itemTy = - this.methodOrPathTypes.getOrPut(methodOrPath) { - // can only be method or path, both are resolved to MvNamedElement - val genericNamedItem = genericItem as MvNamedElement - TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T ?: return null - } - - val typeParameters = genericItem.tyInfers - itemTy = itemTy.substitute(typeParameters) as? T ?: return null - - unifySubst(typeParameters, itemTy.substitution) - return Pair(itemTy, typeParameters) - } - - fun unifySubst(subst1: Substitution, subst2: Substitution) { - subst1.typeSubst.forEach { (k, v1) -> - subst2[k]?.let { v2 -> - if (k != v1 && v1 !is TyTypeParameter && v1 !is TyUnknown) { - combineTypes(v2, v1) - } - } - } - } - fun combineTypes(ty1: Ty, ty2: Ty): RelateResult { val resolvedTy1 = resolveIfTyInfer(ty1) val resolvedTy2 = resolveIfTyInfer(ty2) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt index a17ffe51a..6402cc6c4 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt @@ -48,7 +48,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode ?: return if (item is MvGenericDeclaration) { - val (patTy, _) = fcx.ctx.instantiateMethodOrPath(this.path, item) ?: return + val (patTy, _) = fcx.instantiateMethodOrPath(this.path, item) ?: return if (!isCompatible(expected, patTy, fcx.msl)) { fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) } 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 5f49a4ff2..5875b8534 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 @@ -401,13 +401,13 @@ class TypeInferenceWalker( val baseTy = when (namedItem) { is MvFunctionLike -> { - val (itemTy, _) = ctx.instantiateMethodOrPath(path, namedItem) + val (itemTy, _) = instantiateMethodOrPath(path, namedItem) ?: return TyUnknown itemTy } is MvStruct -> { if (namedItem.tupleFields == null) return TyUnknown - val (itemTy, _) = ctx.instantiateMethodOrPath(path, namedItem) + val (itemTy, _) = instantiateMethodOrPath(path, namedItem) ?: return TyUnknown itemTy } @@ -487,8 +487,8 @@ class TypeInferenceWalker( val baseTy = when (genericItem) { is MvFunction -> { - val (itemTy, _) = - ctx.instantiateMethodOrPath(methodCall, genericItem) ?: return TyUnknown + val (itemTy, _) = instantiateMethodOrPath(methodCall, genericItem) + ?: return TyUnknown itemTy } else -> { @@ -533,46 +533,71 @@ class TypeInferenceWalker( is InferArg.ArgExpr -> { val argExpr = inferArg.expr ?: continue val argExprTy = argExpr.inferType(expected = expectation) -// val argExprTy = inferExprTy(argExpr, expectation) -// val coercedTy = -// resolveTypeVarsWithObligations(expectation.onlyHasTy(ctx) ?: formalInputTy) coerce(argExpr, argExprTy, expectedTy) // retrieve obligations ctx.combineTypes(formalInputTy, expectedTy) -// coercedTy } is InferArg.SelfType -> { -// val actualSelfTy = inferArg.selfTy -// val coercedTy = -// resolveTypeVarsWithObligations(expectation.onlyHasTy(ctx) ?: formalInputTy) -// ctx.combineTypes( -// resolveTypeVarsWithObligations(actualTy), -// resolveTypeVarsWithObligations(expectedTy) -// ) - // method already resolved, so autoborrow() should always succeed val actualSelfTy = autoborrow(inferArg.selfTy, expectedTy) ?: error("unreachable, as method call cannot be resolved if autoborrow fails") ctx.combineTypes(actualSelfTy, expectedTy) -// coercedTy - } } // retrieve obligations ctx.combineTypes(formalInputTy, expectedTy) -// if (inferArg == null) continue - -// val actualTy = inferExprTy(inferArg, expectation) -// val coercedTy = -// resolveTypeVarsWithObligations(expectation.onlyHasTy(ctx) ?: formalInputTy) -// coerce(inferArg, actualTy, coercedTy) -// -// // retrieve obligations -// ctx.combineTypes(formalInputTy, coercedTy) } } + @Suppress("UNCHECKED_CAST") + fun instantiateMethodOrPath( + methodOrPath: MvMethodOrPath, + genericItem: MvGenericDeclaration + ): Pair? { + var itemTy = + this.ctx.methodOrPathTypes.getOrPut(methodOrPath) { + // can only be method or path, both are resolved to MvNamedElement + val genericNamedItem = genericItem as MvNamedElement + TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T + ?: return null + } + + val typeParameters = genericItem.tyInfers + itemTy = itemTy.substitute(typeParameters) as? T ?: return null + + unifySubst(typeParameters, itemTy.substitution) + return Pair(itemTy, typeParameters) + } + + private fun unifySubst(subst1: Substitution, subst2: Substitution) { + subst1.typeSubst.forEach { (k, v1) -> + subst2[k]?.let { v2 -> + if (k != v1 && v1 !is TyTypeParameter && v1 !is TyUnknown) { + ctx.combineTypes(v2, v1) + } + } + } + } + + private fun callableTy(tupleFields: MvTupleFields, item: MvFieldsOwner): TyFunction { + val parameterTypes = tupleFields.tupleFieldDeclList.map { it.type.loweredType(msl) } + val returnType = when (item) { + is MvStruct -> item.declaredType(msl) + is MvEnumVariant -> item.enumItem.declaredType(msl) + else -> error("exhaustive") + } + val typeParams = (item as MvGenericDeclaration).tyTypeParams + return TyFunction( + item as MvGenericDeclaration, + typeParams, + paramTypes = parameterTypes, + returnType = returnType, + acquiresTypes = emptyList(), + ) + .substitute(typeParams) as TyFunction + } + fun inferMacroCallExprTy(macroExpr: MvAssertMacroExpr): Ty { val ident = macroExpr.identifier if (ident.text == "assert") { @@ -668,10 +693,10 @@ class TypeInferenceWalker( } val genericItem = if (item is MvEnumVariant) item.enumItem else (item as MvStruct) - val (tyAdt, typeParameters) = ctx.instantiateMethodOrPath(path, genericItem) + val (tyAdt, typeParameters) = instantiateMethodOrPath(path, genericItem) ?: return TyUnknown expectedType?.let { expectedTy -> - ctx.unifySubst(typeParameters, expectedTy.typeParameterValues) + unifySubst(typeParameters, expectedTy.typeParameterValues) } litExpr.fields.forEach { field -> @@ -706,7 +731,7 @@ class TypeInferenceWalker( return TyUnknown } - val (schemaTy, _) = ctx.instantiateMethodOrPath(path, schemaItem) ?: return TyUnknown + val (schemaTy, _) = instantiateMethodOrPath(path, schemaItem) ?: return TyUnknown // expected.onlyHasTy(ctx)?.let { expectedTy -> // ctx.unifySubst(typeParameters, expectedTy.typeParameterValues) // } From 4900d1c72acf4bfe7bf7faad66a87188a02a54f1 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Thu, 29 Aug 2024 03:52:51 +0300 Subject: [PATCH 10/13] remove ability check inspection --- .../inspections/MvAbilityCheckInspection.kt | 86 ------- .../lang/core/types/infer/InferenceContext.kt | 8 - .../move/lang/core/types/infer/TyLowering.kt | 3 - .../core/types/infer/TypeInferenceWalker.kt | 22 +- src/main/resources/META-INF/plugin.xml | 4 - .../MvAbilityCheckInspectionTest.kt | 216 ------------------ 6 files changed, 4 insertions(+), 335 deletions(-) delete mode 100644 src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt delete mode 100644 src/test/kotlin/org/move/ide/inspections/MvAbilityCheckInspectionTest.kt diff --git a/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt b/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt deleted file mode 100644 index dd20b0cef..000000000 --- a/src/main/kotlin/org/move/ide/inspections/MvAbilityCheckInspection.kt +++ /dev/null @@ -1,86 +0,0 @@ -package org.move.ide.inspections - -import com.intellij.codeInspection.ProblemHighlightType -import com.intellij.codeInspection.ProblemsHolder -import org.move.ide.annotator.pluralise -import org.move.ide.presentation.name -import org.move.ide.presentation.text -import org.move.lang.core.psi.* -import org.move.lang.core.psi.ext.* -import org.move.lang.core.types.infer.inferExpectedTypeArgumentTy -import org.move.lang.core.types.infer.inference -import org.move.lang.core.types.infer.loweredType -import org.move.lang.core.types.ty.GenericTy -import org.move.lang.core.types.ty.TyUnknown -import org.move.lang.core.types.ty.functionTy - -class MvAbilityCheckInspection: MvLocalInspectionTool() { - override fun buildMvVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = - object: MvVisitor() { - override fun visitValueArgumentList(o: MvValueArgumentList) { - if (o.isMsl()) return - - val callExpr = o.parent as? MvCallExpr ?: return - val funcItem = (callExpr.path.reference?.resolve() as? MvFunctionLike) ?: return - val funcTy = funcItem.functionTy(false) - val inference = callExpr.inference(false) ?: return - - for ((i, valueArgument) in o.valueArgumentList.withIndex()) { - val argumentExpr = valueArgument.expr ?: continue - val actualType = inference.getExprType(argumentExpr) - val expectedType = funcTy.paramTypes.getOrNull(i) ?: TyUnknown - val missingAbilities = expectedType.abilities() - actualType.abilities() - if (missingAbilities.isNotEmpty()) { - val abilitiesText = - missingAbilities.joinToString(prefix = "", postfix = "") { it.label() } - val message = "The type '${actualType.text()}' does not have required " + - "${pluralise(missingAbilities.size, "ability", "abilities")} " + - "'$abilitiesText'" - holder.registerProblem(argumentExpr, message, ProblemHighlightType.GENERIC_ERROR) - } - } - } - - override fun visitTypeArgumentList(o: MvTypeArgumentList) { - if (o.isMsl()) return - - val path = o.parent as? MvPath ?: return - val pathType = o.inference(false)?.getMethodOrPathType(path) as? GenericTy ?: return - val generics = pathType.item.generics - - for ((i, typeArgument) in o.typeArgumentList.withIndex()) { - val expectedType = inferExpectedTypeArgumentTy(typeArgument) ?: continue - val actualType = generics.getOrNull(i)?.let { pathType.substitution[it] } ?: continue - - val missingAbilities = expectedType.abilities() - actualType.abilities() - if (missingAbilities.isNotEmpty()) { - val abilitiesText = - missingAbilities.joinToString(prefix = "", postfix = "") { it.label() } - val message = "The type '${actualType.text()}' does not have required " + - "${pluralise(missingAbilities.size, "ability", "abilities")} " + - "'$abilitiesText'" - holder.registerProblem(typeArgument, message, ProblemHighlightType.GENERIC_ERROR) - } - } - } - - override fun visitStruct(o: MvStruct) { - val structAbilities = o.abilities - if (structAbilities.isEmpty()) return - for (field in o.fields) { - val fieldTy = field.type?.loweredType(false) ?: continue - val fieldAbilities = fieldTy.abilities() - for (ability in structAbilities) { - val requiredAbility = ability.requires() - if (requiredAbility !in fieldAbilities) { - val message = - "The type '${fieldTy.name()}' does not have the ability '${requiredAbility.label()}' " + - "required by the declared ability '${ability.label()}' " + - "of the struct '${field.owner?.name}'" - holder.registerProblem(field, message, ProblemHighlightType.GENERIC_ERROR) - } - } - } - } - } -} diff --git a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt index 061510754..6dede10c1 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/InferenceContext.kt @@ -86,7 +86,6 @@ data class InferenceResult( private val exprTypes: Map, private val exprExpectedTypes: Map, - val methodOrPathTypes: Map, private val resolvedPaths: Map>, private val resolvedFields: Map, @@ -108,7 +107,6 @@ data class InferenceResult( fun getExpectedType(expr: MvExpr): Ty = exprExpectedTypes[expr] ?: TyUnknown fun getCallableType(callable: MvCallable): Ty? = callableTypes[callable] - fun getMethodOrPathType(methodOrPath: MvMethodOrPath): Ty? = methodOrPathTypes[methodOrPath] fun getResolvedPath(path: MvPath): List? = resolvedPaths[path] ?: inferenceErrorOrFallback(path, null) @@ -191,9 +189,6 @@ class InferenceContext( private val exprExpectedTypes = mutableMapOf() private val callableTypes = mutableMapOf() - // private val pathTypes = mutableMapOf() - val methodOrPathTypes = mutableMapOf() - val resolvedPaths = mutableMapOf>() val resolvedFields = mutableMapOf() val resolvedMethodCalls = mutableMapOf() @@ -258,8 +253,6 @@ class InferenceContext( exprExpectedTypes.replaceAll { _, ty -> fullyResolveTypeVarsWithOrigins(ty) } typeErrors.replaceAll { err -> fullyResolveTypeVarsWithOrigins(err) } -// pathTypes.replaceAll { _, ty -> fullyResolveWithOrigins(ty) } - methodOrPathTypes.replaceAll { _, ty -> fullyResolveTypeVarsWithOrigins(ty) } resolvedPaths.values.asSequence().flatten() .forEach { it.subst = it.subst.foldValues(fullTypeWithOriginsResolver) } @@ -269,7 +262,6 @@ class InferenceContext( patFieldTypes, exprTypes, exprExpectedTypes, - methodOrPathTypes, resolvedPaths, resolvedFields, resolvedMethodCalls, diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index f4b2bbcad..2fd1d7687 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -63,9 +63,6 @@ class TyLowering { val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) baseTy.substitute(explicitSubst) } -// is MvTypeParameter -> TyTypeParameter(namedItem) -// is MvGenericDeclaration -> { -// } is MvEnumVariant -> lowerPath(methodOrPath, namedItem.enumItem, msl) else -> debugErrorOrFallback( "${namedItem.elementType} path cannot be inferred into type", 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 5875b8534..b6100b882 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 @@ -306,16 +306,6 @@ class TypeInferenceWalker( } private fun inferPathExprTy(pathExpr: MvPathExpr, expected: Expectation): Ty { - // special-case `result` inside item spec -// if (msl && refExpr.path.text == "result") { -// val funcItem = refExpr.ancestorStrict()?.funcItem -// if (funcItem != null) { -// return funcItem.rawReturnType(true) -// } -// } -// val path = pathExpr.path -// val resolveVariants = resolvePathRaw(path) -// ctx.writePath(path, resolveVariants.map { ResolvedPath.from(it, path)}) val expectedType = expected.onlyHasTy(ctx) val item = resolvePathElement(pathExpr, expectedType) ?: return TyUnknown @@ -369,7 +359,6 @@ class TypeInferenceWalker( val hint = Expectation.maybeHasType(expectedInnerTy) val innerExprTy = innerExpr.inferType(expected = hint) -// val innerExprTy = inferExprTy(innerExpr, hint) val innerRefTy = when (innerExprTy) { is TyReference, is TyTuple -> { ctx.reportTypeError(TypeError.ExpectedNonReferenceType(innerExpr, innerExprTy)) @@ -555,13 +544,10 @@ class TypeInferenceWalker( methodOrPath: MvMethodOrPath, genericItem: MvGenericDeclaration ): Pair? { - var itemTy = - this.ctx.methodOrPathTypes.getOrPut(methodOrPath) { - // can only be method or path, both are resolved to MvNamedElement - val genericNamedItem = genericItem as MvNamedElement - TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T - ?: return null - } + // can only be method or path, both are resolved to MvNamedElement + val genericNamedItem = genericItem as MvNamedElement + var itemTy = TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T + ?: return null val typeParameters = genericItem.tyInfers itemTy = itemTy.substitute(typeParameters) as? T ?: return null diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 8acc24838..388b1e5c8 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -245,10 +245,6 @@ displayName="Type checking" enabledByDefault="true" level="ERROR" implementationClass="org.move.ide.inspections.MvTypeCheckInspection" /> - (r: T) {} - fun main(r: Res) { - save(r) - } - } - """ - ) - - fun `test no required ability 'key' for move_to argument`() = checkByText( - """ - module 0x1::M { - struct Res {} - fun main(s: &signer, r: Res) { - move_to(s, r) - } - } - """ - ) - - fun `test pass primitive type to generic with required abilities`() = checkByText( - """ - module 0x1::M { - fun balance(k: Token) {} - fun m() { - balance(@0x1); - } - } - """ - ) - - fun `test no ability error in call expr mut ref inference`() = checkByText( - """ - module 0x1::m { - struct AVLqueue { } - fun new(): AVLqueue { AVLqueue {}} - fun compute(q: &mut AVLqueue, v: ComputeV) {} - fun main() { - let avlq = new(); - compute(&mut avlq, 10u64); - } - } - """ - ) - - fun `test fields of struct should have abilities of struct`() = checkByText( - """ - module 0x1::M { - struct A {} - - struct B has copy { - a: A - } - } - """ - ) - - fun `test key struct requires store fields`() = checkByText( - """ - module 0x1::M { - struct A {} - - struct B has key { - a: A - } - } - """ - ) - - fun `test store struct requires store fields`() = checkByText( - """ - module 0x1::M { - struct A {} - - struct B has store { - a: A - } - } - """ - ) - - fun `test copy struct requires copy fields`() = checkByText( - """ - module 0x1::M { - struct A {} - - struct B has copy { - a: A - } - } - """ - ) - - fun `test drop struct requires drop fields`() = checkByText( - """ - module 0x1::M { - struct A {} - - struct B has drop { - a: A - } - } - """ - ) - - fun `test function invocation with explicitly provided generic type`() = checkByText( - """ - module 0x1::Event { - struct Message has drop {} - - public fun emit_event() {} - - public fun main() { - emit_event<Message>() - } - } - """ - ) - - fun `test struct constructor with explicitly provided generic type`() = checkByText( - """ - module 0x1::Event { - struct Message has drop {} - - struct Event {} - - public fun main() { - Event<Message> {}; - } - } - """ - ) - - fun `test type param`() = checkByText( - """ - module 0x1::Event { - struct Message has drop {} - - public fun emit_event() {} - - public fun main() { - emit_event<M>() - } - } - """ - ) - - fun `test no error in move_to with resource`() = checkByText( - """ - module 0x1::M { - struct Res has key {} - fun main(s: &signer, r: Res) { - move_to(s, r) - } - } - """ - ) - - fun `test no error in type param if structure has required abilities`() = checkByText( - """ - module 0x1::M { - struct Res has key {} - fun save(r: T) {} - fun main(r: Res) { - save(r) - } - } - """ - ) - - fun `test no error in specs`() = checkByText( - """ - module 0x1::M { - fun balance() {} - spec schema PayFromEnsures { - ensures balance(); - } - } - """ - ) - - fun `test no ability error on generic parameter in struct`() = checkByText(""" - module 0x1::m { - struct SmartVector has store { - inner_item: T, - } - } - """) - - fun `test no required ability on vector of type T`() = checkByText(""" - module 0x1::m { - struct SmartVector has store { - inline_vec: vector, - } - } - """) - - fun `test field T requires store if struct has key ability`() = checkByText(""" - module 0x1::m { - struct S has key { val: T } - struct M {} - fun main() { - let m = M {}; - S { val: m }; - } - } - """) -} From ede73daf39eef6224dde73fef3d34a10414df6dc Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Thu, 29 Aug 2024 16:53:27 +0300 Subject: [PATCH 11/13] renames --- .../MethodOrFieldCompletionProvider.kt | 4 +- .../org/move/lang/core/psi/MvFunctionLike.kt | 2 +- .../lang/core/psi/MvGenericDeclaration.kt | 14 +++--- .../move/lang/core/types/MvPsiTypeImplUtil.kt | 4 +- .../org/move/lang/core/types/infer/Paths.kt | 24 +++++----- .../move/lang/core/types/infer/Patterns.kt | 1 + .../core/types/infer/RsPsiSubstitution.kt | 4 +- .../lang/core/types/infer/Substitution.kt | 6 +-- .../move/lang/core/types/infer/TyLowering.kt | 31 +++++++++---- .../core/types/infer/TypeInferenceWalker.kt | 44 +++++++++++++------ .../org/move/lang/core/types/ty/TyAdt.kt | 5 +-- .../org/move/lang/core/types/ty/TyFunction.kt | 4 +- 12 files changed, 87 insertions(+), 56 deletions(-) diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt index bb0e7c99f..b0cbbad32 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt @@ -11,7 +11,7 @@ import org.move.lang.core.completion.CompletionContext import org.move.lang.core.completion.createLookupElement import org.move.lang.core.psi.MvFunction import org.move.lang.core.psi.ext.* -import org.move.lang.core.psi.tyInfers +import org.move.lang.core.psi.typeParamsToTyVarsSubst import org.move.lang.core.resolve.collectCompletionVariants import org.move.lang.core.resolve.createProcessor import org.move.lang.core.resolve2.processMethodResolveVariants @@ -55,7 +55,7 @@ object MethodOrFieldCompletionProvider: MvCompletionProvider() { processMethodResolveVariants(element, receiverTy, ctx.msl, createProcessor { e -> val function = e.element as? MvFunction ?: return@createProcessor - val subst = function.tyInfers + val subst = function.typeParamsToTyVarsSubst val declaredFuncTy = function.functionTy(msl).substitute(subst) as TyFunction val declaredSelfTy = declaredFuncTy.paramTypes.first() val autoborrowedReceiverTy = 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 36965f52b..fd2c26d52 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -119,7 +119,7 @@ val MvFunction.selfSignatureText: String fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: CompletionContext?): Boolean { val msl = this.isMslOnlyItem - val callTy = this.functionTy(msl).substitute(this.tyInfers) as TyFunction + val callTy = this.functionTy(msl).substitute(this.typeParamsToTyVarsSubst) as TyFunction val inferenceCtx = InferenceContext(msl) callTy.paramTypes.forEach { diff --git a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt index 51959a628..61e709d73 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt @@ -1,7 +1,6 @@ package org.move.lang.core.psi import org.move.lang.core.types.infer.Substitution -import org.move.lang.core.types.infer.toTypeSubst import org.move.lang.core.types.ty.TyInfer import org.move.lang.core.types.ty.TyTypeParameter @@ -13,17 +12,16 @@ val MvGenericDeclaration.typeParameters: List get() = typeParameterList?.typeParameterList.orEmpty() -val MvGenericDeclaration.generics: List +val MvGenericDeclaration.tyTypeParams: List get() = typeParameters.map { TyTypeParameter.named(it) } -val MvGenericDeclaration.tyTypeParams: Substitution get() = Substitution(generics.associateWith { it }) +val MvGenericDeclaration.typeParamsToTypeParamsSubst: Substitution get() = + Substitution(tyTypeParams.associateWith { it }) -val MvGenericDeclaration.tyInfers: Substitution +val MvGenericDeclaration.typeParamsToTyVarsSubst: Substitution get() { - val typeSubst = this - .generics - .associateWith { TyInfer.TyVar(it) } - return typeSubst.toTypeSubst() + val typeSubst = this.tyTypeParams.associateWith { TyInfer.TyVar(it) } + return Substitution(typeSubst) } val MvGenericDeclaration.hasTypeParameters: Boolean diff --git a/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt b/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt index 87aa48a8c..e015845ea 100644 --- a/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt +++ b/src/main/kotlin/org/move/lang/core/types/MvPsiTypeImplUtil.kt @@ -4,8 +4,8 @@ import org.move.lang.core.psi.MvEnum import org.move.lang.core.psi.MvSchema import org.move.lang.core.psi.MvStruct import org.move.lang.core.psi.MvTypeParameter -import org.move.lang.core.psi.generics import org.move.lang.core.psi.tyTypeParams +import org.move.lang.core.psi.typeParamsToTypeParamsSubst import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyAdt import org.move.lang.core.types.ty.TySchema @@ -15,5 +15,5 @@ object MvPsiTypeImplUtil { fun declaredType(psi: MvTypeParameter): Ty = TyTypeParameter.named(psi) fun declaredType(psi: MvStruct): Ty = TyAdt.valueOf(psi) fun declaredType(psi: MvEnum): Ty = TyAdt.valueOf(psi) - fun declaredType(psi: MvSchema): Ty = TySchema(psi, psi.tyTypeParams, psi.generics) + fun declaredType(psi: MvSchema): Ty = TySchema(psi, psi.typeParamsToTypeParamsSubst, psi.tyTypeParams) } \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt b/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt index e484df0cd..1bbc2453b 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Paths.kt @@ -4,12 +4,13 @@ import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.MvMethodOrPath import org.move.lang.core.types.infer.RsPsiSubstitution.Value -fun pathPsiSubst( +fun pathTypeParamsSubst( methodOrPath: MvMethodOrPath, - resolved: MvGenericDeclaration, + genericItem: MvGenericDeclaration, ): RsPsiSubstitution { - val typeParameters = resolved.typeParameters + val typeParameters = genericItem.typeParameters val parent = methodOrPath.parent + // Generic arguments are optional in expression context, e.g. // `let a = Foo::::bar::();` can be written as `let a = Foo::bar();` // if it is possible to infer `u8` and `u16` during type inference @@ -22,19 +23,20 @@ fun pathPsiSubst( return RsPsiSubstitution(typeSubst) } -private fun associateSubst( +private fun associateSubst( parameters: List, arguments: List

?, areOptionalArgs: Boolean, ): Map> { return parameters.withIndex().associate { (i, param) -> - val value = if (areOptionalArgs && arguments == null) { - Value.OptionalAbsent - } else if (arguments != null && i < arguments.size) { - Value.Present(arguments[i]) - } else { - Value.RequiredAbsent - } + val value = + if (areOptionalArgs && arguments == null) { + Value.OptionalAbsent + } else if (arguments != null && i < arguments.size) { + Value.Present(arguments[i]) + } else { + Value.RequiredAbsent + } param to value } } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt index 6402cc6c4..8dd3ecc91 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt @@ -48,6 +48,7 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode ?: return if (item is MvGenericDeclaration) { +// val patTy = fcx.instantiatePath(this.path, item) ?: return val (patTy, _) = fcx.instantiateMethodOrPath(this.path, item) ?: return if (!isCompatible(expected, patTy, fcx.msl)) { fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/RsPsiSubstitution.kt b/src/main/kotlin/org/move/lang/core/types/infer/RsPsiSubstitution.kt index fb1b7be61..4b8deed38 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/RsPsiSubstitution.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/RsPsiSubstitution.kt @@ -8,8 +8,8 @@ class RsPsiSubstitution( val typeSubst: Map> = emptyMap(), ) { sealed class Value { - object RequiredAbsent : Value() - object OptionalAbsent : Value() + data object RequiredAbsent : Value() + data object OptionalAbsent : Value() class Present

(val value: P) : Value

() } } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt index 8a111f6ca..631452388 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt @@ -13,7 +13,9 @@ open class Substitution(val typeSubst: Map = emptyMap()) : Substitution(mergeMaps(typeSubst, other.typeSubst)) operator fun get(key: TyTypeParameter): Ty? = typeSubst[key] - operator fun get(psi: MvTypeParameter): Ty? = typeSubst[TyTypeParameter.named(psi)] + + fun getPsi(psi: MvTypeParameter): Ty? = typeSubst[TyTypeParameter.named(psi)] +// operator fun get(psi: MvTypeParameter): Ty? = typeSubst[TyTypeParameter.named(psi)] // fun typeParameterByName(name: String): TyTypeParameter? = // typeSubst.keys.find { it.toString() == name } @@ -59,8 +61,6 @@ private object EmptySubstitution : Substitution() val emptySubstitution: Substitution = EmptySubstitution -fun Map.toTypeSubst(): Substitution = Substitution(typeSubst = this) - /** * Deeply replace any [TyTypeParameter] by [subst] mapping. */ diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index 2fd1d7687..d3c829d78 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -9,6 +9,18 @@ import org.move.lang.core.types.ty.* fun MvType.loweredType(msl: Boolean): Ty = TyLowering().lowerType(this, msl) + +/** + * Returns type from the explicit instantiation of the item, like + * ``` + * struct Option {} + * fun main() { + * Option{}; + * //^ + * } + * ``` + * will return TyAdt(Option, Element -> u8) + */ class TyLowering { fun lowerType(moveType: MvType, msl: Boolean): Ty { return when (moveType) { @@ -45,23 +57,24 @@ class TyLowering { } } - fun lowerPath(methodOrPath: MvMethodOrPath, namedItem: MvNamedElement?, msl: Boolean): Ty { + fun lowerPath(methodOrPath: MvMethodOrPath, namedItem: MvElement?, msl: Boolean): Ty { // cannot do resolve() here due to circular caching for MethodCall, need to pass namedItem explicitly, // namedItem can be null if it's a primitive type -// val namedItem = methodOrPath.reference?.resolveWithAliases() if (namedItem == null) { return if (methodOrPath is MvPath) lowerPrimitiveTy(methodOrPath, msl) else TyUnknown } return when (namedItem) { is MvTypeDeclarationElement -> { - val baseTy = namedItem.declaredType(msl) - val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) - baseTy.substitute(explicitSubst) + val baseItemTy = namedItem.declaredType(msl) + val substFromExplicitTypeArguments = + instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) + baseItemTy.substitute(substFromExplicitTypeArguments) } is MvFunctionLike -> { val baseTy = namedItem.functionTy(msl) - val explicitSubst = instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) - baseTy.substitute(explicitSubst) + val explicitTypeParamsSubst = + instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) + baseTy.substitute(explicitTypeParamsSubst) } is MvEnumVariant -> lowerPath(methodOrPath, namedItem.enumItem, msl) else -> debugErrorOrFallback( @@ -98,10 +111,10 @@ class TyLowering { ): Substitution { if (namedItem !is MvGenericDeclaration) return emptySubstitution - val psiSubstitution = pathPsiSubst(methodOrPath, namedItem) + val explicitTypeParamsSubst = pathTypeParamsSubst(methodOrPath, namedItem) val typeSubst = hashMapOf() - for ((param, value) in psiSubstitution.typeSubst.entries) { + for ((param, value) in explicitTypeParamsSubst.typeSubst.entries) { val paramTy = TyTypeParameter.named(param) val valueTy = when (value) { is RsPsiSubstitution.Value.Present -> lowerType(value.value, msl) 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 b6100b882..09cb37042 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 @@ -463,7 +463,6 @@ class TypeInferenceWalker( } fun inferMethodCallTy(receiverTy: Ty, methodCall: MvMethodCall, expected: Expectation): Ty { - val resolutionCtx = ResolutionContext(methodCall, isCompletion = false) val resolvedMethods = collectMethodOrPathResolveVariants(methodCall, resolutionCtx) { @@ -539,29 +538,48 @@ class TypeInferenceWalker( } } +// fun instantiatePath( +// methodOrPath: MvMethodOrPath, +// genericItem: MvGenericDeclaration +// ): T? { +// // can only be method or path, both are resolved to MvNamedElement +// val genericNamedItem = genericItem as MvNamedElement +// // item type from explicit type parameters +// @Suppress("UNCHECKED_CAST") +// val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T +// ?: return null +// +// return explicitPathTy +// } + @Suppress("UNCHECKED_CAST") fun instantiateMethodOrPath( methodOrPath: MvMethodOrPath, genericItem: MvGenericDeclaration ): Pair? { - // can only be method or path, both are resolved to MvNamedElement - val genericNamedItem = genericItem as MvNamedElement - var itemTy = TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T + // item type from explicit type parameters + val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericItem, msl) as? T ?: return null + val typeParamToVarSubst = genericItem.typeParamsToTyVarsSubst - val typeParameters = genericItem.tyInfers - itemTy = itemTy.substitute(typeParameters) as? T ?: return null + // replace type params which weren't explicitly specified with TyVar + val explicitPathTyWithTyVars = explicitPathTy.substitute(typeParamToVarSubst) as? T ?: return null - unifySubst(typeParameters, itemTy.substitution) - return Pair(itemTy, typeParameters) + // adds associations of ?Element -> (type of ?Element from explicitly set types) + /// Option: ?Element -> u8 + /// Option: ?Element -> ?Element + unifySubst(typeParamToVarSubst, explicitPathTyWithTyVars.substitution) + + return Pair(explicitPathTyWithTyVars, typeParamToVarSubst) } private fun unifySubst(subst1: Substitution, subst2: Substitution) { subst1.typeSubst.forEach { (k, v1) -> - subst2[k]?.let { v2 -> - if (k != v1 && v1 !is TyTypeParameter && v1 !is TyUnknown) { - ctx.combineTypes(v2, v1) - } + if (k == v1) return@forEach + if (v1 is TyTypeParameter || v1 is TyUnknown) return@forEach + subst2[k]?.let { + // perform unification for every value type of `subst` for the same TyTypeParameter + ctx.combineTypes(it, v1) } } } @@ -573,7 +591,7 @@ class TypeInferenceWalker( is MvEnumVariant -> item.enumItem.declaredType(msl) else -> error("exhaustive") } - val typeParams = (item as MvGenericDeclaration).tyTypeParams + val typeParams = (item as MvGenericDeclaration).typeParamsToTypeParamsSubst return TyFunction( item as MvGenericDeclaration, typeParams, 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 b7664c117..8cada9887 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 @@ -1,6 +1,5 @@ package org.move.lang.core.types.ty -import com.intellij.codeInsight.completion.CompletionUtil import org.move.ide.presentation.tyToString import org.move.lang.core.psi.* import org.move.lang.core.psi.ext.MvStructOrEnumItemElement @@ -40,12 +39,12 @@ data class TyAdt( companion object { fun valueOf(struct: MvStructOrEnumItemElement): TyAdt { - val typeParameters = struct.tyTypeParams + val typeParameters = struct.typeParamsToTypeParamsSubst return TyAdt( struct, // CompletionUtil.getOriginalOrSelf(struct), typeParameters, - struct.generics + struct.tyTypeParams ) } } diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt index 033263281..254e5a0c6 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt @@ -8,7 +8,7 @@ import org.move.lang.core.psi.acquiresPathTypes import org.move.lang.core.psi.ext.returnTypeTy import org.move.lang.core.psi.parameters import org.move.lang.core.psi.psiFactory -import org.move.lang.core.psi.tyTypeParams +import org.move.lang.core.psi.typeParamsToTypeParamsSubst import org.move.lang.core.types.infer.* import org.move.lang.core.types.infer.loweredType @@ -63,7 +63,7 @@ data class TyFunction( fun MvFunctionLike.functionTy(msl: Boolean): TyFunction = callableTy(this, msl) fun callableTy(item: MvFunctionLike, msl: Boolean): TyFunction { - val typeParameters = item.tyTypeParams + val typeParameters = item.typeParamsToTypeParamsSubst val paramTypes = item.parameters.map { it.type?.loweredType(msl) ?: TyUnknown } val acquiredTypes = item.acquiresPathTypes.map { it.loweredType(msl) } val retType = item.returnTypeTy(msl) From cfa00fe63891eda1ee20d0ad5a88e674c56c7ccc Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Thu, 29 Aug 2024 17:40:09 +0300 Subject: [PATCH 12/13] extract instantiatePath --- .../move/lang/core/types/infer/Patterns.kt | 4 +- .../lang/core/types/infer/Substitution.kt | 2 +- .../move/lang/core/types/infer/TyLowering.kt | 12 ++-- .../core/types/infer/TypeInferenceWalker.kt | 63 ++++++++++--------- .../org/move/lang/types/ExpectedTypeTest.kt | 26 ++++++++ .../lang/types/ExpressionTypeInferenceTest.kt | 4 +- 6 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt index 8dd3ecc91..7f2107974 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Patterns.kt @@ -48,8 +48,8 @@ fun MvPat.extractBindings(fcx: TypeInferenceWalker, ty: Ty, defBm: RsBindingMode ?: return if (item is MvGenericDeclaration) { -// val patTy = fcx.instantiatePath(this.path, item) ?: return - val (patTy, _) = fcx.instantiateMethodOrPath(this.path, item) ?: return + val patTy = fcx.instantiatePath(this.path, item) ?: return +// val (patTy, _) = fcx.instantiateMethodOrPath(this.path, item) ?: return if (!isCompatible(expected, patTy, fcx.msl)) { fcx.reportTypeError(TypeError.InvalidUnpacking(this, ty)) } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt index 631452388..bddfe42c8 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/Substitution.kt @@ -64,7 +64,7 @@ val emptySubstitution: Substitution = EmptySubstitution /** * Deeply replace any [TyTypeParameter] by [subst] mapping. */ -fun > TypeFoldable.substitute(subst: Substitution): T = +fun > T.substitute(subst: Substitution): T = foldWith(object : TypeFolder() { override fun fold(ty: Ty): Ty { return when { diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index d3c829d78..8fd6c9f80 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -66,15 +66,13 @@ class TyLowering { return when (namedItem) { is MvTypeDeclarationElement -> { val baseItemTy = namedItem.declaredType(msl) - val substFromExplicitTypeArguments = - instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) - baseItemTy.substitute(substFromExplicitTypeArguments) + val explicitTypeParams = explicitTypeParamsSubst(methodOrPath, namedItem, msl) + baseItemTy.substitute(explicitTypeParams) } is MvFunctionLike -> { val baseTy = namedItem.functionTy(msl) - val explicitTypeParamsSubst = - instantiateTypeParamsSubstitution(methodOrPath, namedItem, msl) - baseTy.substitute(explicitTypeParamsSubst) + val explicitTypeParams = explicitTypeParamsSubst(methodOrPath, namedItem, msl) + baseTy.substitute(explicitTypeParams) } is MvEnumVariant -> lowerPath(methodOrPath, namedItem.enumItem, msl) else -> debugErrorOrFallback( @@ -104,7 +102,7 @@ class TyLowering { return ty } - private fun instantiateTypeParamsSubstitution( + private fun explicitTypeParamsSubst( methodOrPath: MvMethodOrPath, namedItem: T, msl: Boolean 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 09cb37042..edf92ce58 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 @@ -387,17 +387,19 @@ class TypeInferenceWalker( private fun inferCallExprTy(callExpr: MvCallExpr, expected: Expectation): Ty { val path = callExpr.path val namedItem = resolvePathElement(callExpr, expectedType = null) - val baseTy = + val baseFuncTy = when (namedItem) { is MvFunctionLike -> { - val (itemTy, _) = instantiateMethodOrPath(path, namedItem) - ?: return TyUnknown + val itemTy = instantiatePath(path, namedItem) ?: return TyUnknown +// val (itemTy, _) = instantiateMethodOrPath(path, namedItem) +// ?: return TyUnknown itemTy } is MvStruct -> { if (namedItem.tupleFields == null) return TyUnknown - val (itemTy, _) = instantiateMethodOrPath(path, namedItem) - ?: return TyUnknown +// val (itemTy, _) = instantiateMethodOrPath(path, namedItem) +// ?: return TyUnknown + val itemTy = instantiatePath(path, namedItem) ?: return TyUnknown itemTy } is MvPatBinding -> { @@ -406,7 +408,7 @@ class TypeInferenceWalker( } else -> TyFunction.unknownTyFunction(callExpr.project, callExpr.valueArguments.size) } - val funcTy = ctx.resolveTypeVarsIfPossible(baseTy) as TyCallable + val funcTy = ctx.resolveTypeVarsIfPossible(baseFuncTy) as TyCallable val expectedInputTys = expectedInputsForExpectedOutput(expected, funcTy.returnType, funcTy.paramTypes) @@ -475,8 +477,10 @@ class TypeInferenceWalker( val baseTy = when (genericItem) { is MvFunction -> { - val (itemTy, _) = instantiateMethodOrPath(methodCall, genericItem) + val itemTy = instantiatePath(methodCall, genericItem) ?: return TyUnknown +// val (itemTy, _) = instantiateMethodOrPath(methodCall, genericItem) +// ?: return TyUnknown itemTy } else -> { @@ -538,19 +542,20 @@ class TypeInferenceWalker( } } -// fun instantiatePath( -// methodOrPath: MvMethodOrPath, -// genericItem: MvGenericDeclaration -// ): T? { -// // can only be method or path, both are resolved to MvNamedElement -// val genericNamedItem = genericItem as MvNamedElement -// // item type from explicit type parameters -// @Suppress("UNCHECKED_CAST") -// val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericNamedItem, msl) as? T -// ?: return null -// -// return explicitPathTy -// } + fun instantiatePath( + methodOrPath: MvMethodOrPath, + genericItem: MvGenericDeclaration + ): T? { + // item type from explicit type parameters + @Suppress("UNCHECKED_CAST") + val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericItem, msl) as? T + ?: return null + + val tyVarsSubst = genericItem.typeParamsToTyVarsSubst + @Suppress("UNCHECKED_CAST") + // TyTypeParameter -> TyVar for every TypeParameter which is not explicit set + return explicitPathTy.substitute(tyVarsSubst) as T + } @Suppress("UNCHECKED_CAST") fun instantiateMethodOrPath( @@ -626,9 +631,6 @@ class TypeInferenceWalker( ): List { val resolvedFormalRet = resolveTypeVarsIfPossible(formalRet) val retTy = expectedRet.onlyHasTy(ctx) ?: return emptyList() - // Rustc does `fudge` instead of `probe` here. But `fudge` seems useless in our simplified type inference - // because we don't produce new type variables during unification - // https://github.com/rust-lang/rust/blob/50cf76c24bf6f266ca6d253a/compiler/rustc_infer/src/infer/fudge.rs#L98 return ctx.freezeUnification { if (ctx.combineTypes(retTy, resolvedFormalRet).isOk) { formalArgs.map { ctx.resolveTypeVarsIfPossible(it) } @@ -695,12 +697,16 @@ class TypeInferenceWalker( } return TyUnknown } - val genericItem = if (item is MvEnumVariant) item.enumItem else (item as MvStruct) - val (tyAdt, typeParameters) = instantiateMethodOrPath(path, genericItem) - ?: return TyUnknown + val (tyAdt, tyVarsSubst) = + instantiateMethodOrPath(path, genericItem) ?: return TyUnknown +// val tyAdt = instantiatePath(path, genericItem) ?: return TyUnknown +// val tyVarsSubst = genericItem.typeParamsToTyVarsSubst + expectedType?.let { expectedTy -> - unifySubst(typeParameters, expectedTy.typeParameterValues) + val expectedTyTypeParams = expectedTy.typeParameterValues + // set TyVars from expected type substitution + unifySubst(tyVarsSubst, expectedTyTypeParams) } litExpr.fields.forEach { field -> @@ -735,7 +741,8 @@ class TypeInferenceWalker( return TyUnknown } - val (schemaTy, _) = instantiateMethodOrPath(path, schemaItem) ?: return TyUnknown + val schemaTy = instantiatePath(path, schemaItem) ?: return TyUnknown +// val (schemaTy, _) = instantiateMethodOrPath(path, schemaItem) ?: return TyUnknown // expected.onlyHasTy(ctx)?.let { expectedTy -> // ctx.unifySubst(typeParameters, expectedTy.typeParameterValues) // } diff --git a/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt b/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt index 51cb65358..813e7ac9a 100644 --- a/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt @@ -111,6 +111,32 @@ class ExpectedTypeTest : TypificationTestCase() { """ ) + fun `test let statement struct pattern field explicit incompatible type`() = testExpectedTyExpr( + """ + module 0x1::Main { + struct S { val: Type } + fun main() { + let val: S = S { val: my_ref }; + //^ u32 + } + } + """ + ) + + fun `test let statement struct pattern field explicit type nested inference`() = testExpectedTyExpr( + """ + module 0x1::Main { + struct Option { item: Type } + struct S { opt: Option, val: Type } + fun main() { + let a = 1u8; + S { opt: Option { item: a }, val: my_ref }; + //^ u8 + } + } + """ + ) + // fun `test let statement struct pattern field path type`() = testExpectedTyExpr( // """ // module 0x1::Main { diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypeInferenceTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypeInferenceTest.kt index bc813d555..6edc2a9ed 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypeInferenceTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypeInferenceTest.kt @@ -335,11 +335,11 @@ class ExpressionTypeInferenceTest: TypificationTestCase() { let a = 0; let b: u8 = identity(a); a; - //^ u8 + //^ u8 } } """ - ) + , allowErrors = false) // fun `test struct unpacking type inference`() = testExpr(""" //module 0x1::main { From 6ac8fc6555c8a210da76188c7e4ee3441616dff1 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Fri, 30 Aug 2024 01:39:16 +0300 Subject: [PATCH 13/13] type inference for positional callables --- .../lang/core/completion/FuncSignature.kt | 9 +-- .../MethodOrFieldCompletionProvider.kt | 4 +- .../org/move/lang/core/psi/MvFunctionLike.kt | 2 +- .../lang/core/psi/MvGenericDeclaration.kt | 2 +- .../move/lang/core/psi/ext/MvFieldLookup.kt | 5 +- .../lang/core/resolve2/NameResolution2.kt | 31 +++++++--- .../move/lang/core/types/infer/TyLowering.kt | 23 ++++++-- .../core/types/infer/TypeInferenceWalker.kt | 56 +++++++++++-------- .../org/move/lang/core/types/ty/TyFunction.kt | 9 +-- .../org/move/lang/types/ExpectedTypeTest.kt | 15 ++++- .../move/lang/types/ExpressionTypesTest.kt | 33 +++++++++++ 11 files changed, 140 insertions(+), 49 deletions(-) diff --git a/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt b/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt index 6fe5012b9..1d9cba7ab 100644 --- a/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt +++ b/src/main/kotlin/org/move/lang/core/completion/FuncSignature.kt @@ -51,11 +51,12 @@ data class FuncSignature( companion object { fun fromFunction(function: MvFunction, msl: Boolean): FuncSignature { - val declaredType = function.functionTy(msl) - val params = function.parameters.zip(declaredType.paramTypes) + val functionType = function.functionTy(msl) + val parameters = function.parameters + .zip(functionType.paramTypes) .associate { (param, paramTy) -> Pair(param.name, paramTy) } - val retType = declaredType.returnType - return FuncSignature(params, retType) + val returnType = functionType.returnType + return FuncSignature(parameters, returnType) } } } \ No newline at end of file diff --git a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt index b0cbbad32..734e889c6 100644 --- a/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt +++ b/src/main/kotlin/org/move/lang/core/completion/providers/MethodOrFieldCompletionProvider.kt @@ -11,7 +11,7 @@ import org.move.lang.core.completion.CompletionContext import org.move.lang.core.completion.createLookupElement import org.move.lang.core.psi.MvFunction import org.move.lang.core.psi.ext.* -import org.move.lang.core.psi.typeParamsToTyVarsSubst +import org.move.lang.core.psi.tyVarsSubst import org.move.lang.core.resolve.collectCompletionVariants import org.move.lang.core.resolve.createProcessor import org.move.lang.core.resolve2.processMethodResolveVariants @@ -55,7 +55,7 @@ object MethodOrFieldCompletionProvider: MvCompletionProvider() { processMethodResolveVariants(element, receiverTy, ctx.msl, createProcessor { e -> val function = e.element as? MvFunction ?: return@createProcessor - val subst = function.typeParamsToTyVarsSubst + val subst = function.tyVarsSubst val declaredFuncTy = function.functionTy(msl).substitute(subst) as TyFunction val declaredSelfTy = declaredFuncTy.paramTypes.first() val autoborrowedReceiverTy = 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 fd2c26d52..9e92f0ecd 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvFunctionLike.kt @@ -119,7 +119,7 @@ val MvFunction.selfSignatureText: String fun MvFunctionLike.requiresExplicitlyProvidedTypeArguments(completionContext: CompletionContext?): Boolean { val msl = this.isMslOnlyItem - val callTy = this.functionTy(msl).substitute(this.typeParamsToTyVarsSubst) as TyFunction + val callTy = this.functionTy(msl).substitute(this.tyVarsSubst) as TyFunction val inferenceCtx = InferenceContext(msl) callTy.paramTypes.forEach { diff --git a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt index 61e709d73..2c0a6c443 100644 --- a/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt +++ b/src/main/kotlin/org/move/lang/core/psi/MvGenericDeclaration.kt @@ -18,7 +18,7 @@ val MvGenericDeclaration.tyTypeParams: List val MvGenericDeclaration.typeParamsToTypeParamsSubst: Substitution get() = Substitution(tyTypeParams.associateWith { it }) -val MvGenericDeclaration.typeParamsToTyVarsSubst: Substitution +val MvGenericDeclaration.tyVarsSubst: Substitution get() { val typeSubst = this.tyTypeParams.associateWith { TyInfer.TyVar(it) } return Substitution(typeSubst) diff --git a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt index b53e404b1..adfc18799 100644 --- a/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt +++ b/src/main/kotlin/org/move/lang/core/psi/ext/MvFieldLookup.kt @@ -3,12 +3,11 @@ package org.move.lang.core.psi.ext import com.intellij.lang.ASTNode import com.intellij.psi.PsiElement import org.move.lang.core.psi.* -import org.move.lang.core.resolve.RsResolveProcessor -import org.move.lang.core.resolve.process -import org.move.lang.core.resolve.processAll +import org.move.lang.core.resolve.* import org.move.lang.core.resolve.ref.MvPolyVariantReference import org.move.lang.core.resolve.ref.MvPolyVariantReferenceBase import org.move.lang.core.resolve.ref.NONE +import org.move.lang.core.resolve2.ref.FieldResolveVariant import org.move.lang.core.types.infer.inference import org.move.lang.core.types.ty.TyAdt import org.move.stdext.wrapWithList 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 65dabd811..118683d54 100644 --- a/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt +++ b/src/main/kotlin/org/move/lang/core/resolve2/NameResolution2.kt @@ -9,7 +9,6 @@ import org.move.lang.core.resolve2.ref.ResolutionContext import org.move.lang.core.types.Address import org.move.lang.core.types.Address.Named import org.move.lang.core.types.address -import org.move.lang.core.types.ty.Ty import org.move.lang.core.types.ty.TyAdt import org.move.lang.index.MvModuleIndex @@ -17,18 +16,36 @@ fun processFieldLookupResolveVariants( fieldLookup: MvFieldLookup, receiverTy: TyAdt, msl: Boolean, - originalProcessor: RsResolveProcessorBase, + originalProcessor: RsResolveProcessorBase ): Boolean { val receiverItem = receiverTy.item if (!isFieldsAccessible(fieldLookup, receiverItem, msl)) return false val processor = originalProcessor.wrapWithMapper { it: ScopeEntry -> FieldResolveVariant(it.name, it.element) -// FieldResolveVariant(it.name, it.element, ty, autoderef.steps(), autoderef.obligations()) } - val structItem = receiverTy.item as? MvStruct ?: return false - return processFieldDeclarations(structItem, processor) + return when (receiverItem) { + is MvStruct -> processFieldDeclarations(receiverItem, processor) +// is MvStruct -> processor.processAll(NONE, receiverItem.fields) + is MvEnum -> { + val visitedFields = mutableSetOf() + for (variant in receiverItem.variants) { + val visitedVariantFields = mutableSetOf() + for (field in variant.fields) { + val fieldName = field.name ?: continue + if (fieldName in visitedFields) continue + if (processor.process(NONE, field)) return true + // collect all names for the variant + visitedVariantFields.add(fieldName) + } + // add variant fields to the global fields list to skip them in the next variants + visitedFields.addAll(visitedVariantFields) + } + false + } + else -> error("unreachable") + } } fun processStructLitFieldResolveVariants( @@ -238,8 +255,8 @@ fun walkUpThroughScopes( return false } -private fun processFieldDeclarations(struct: MvFieldsOwner, processor: RsResolveProcessor): Boolean = - struct.fields.any { field -> +private fun processFieldDeclarations(item: MvFieldsOwner, processor: RsResolveProcessor): Boolean = + item.fields.any { field -> val name = field.name ?: return@any false processor.process(name, NAMES, field) } diff --git a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt index 8fd6c9f80..11fa37a58 100644 --- a/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt +++ b/src/main/kotlin/org/move/lang/core/types/infer/TyLowering.kt @@ -82,6 +82,21 @@ class TyLowering { } } + fun lowerCallable( + methodOrPath: MvMethodOrPath, + item: MvGenericDeclaration, + parameterTypes: List, + returnType: Ty, + msl: Boolean + ): TyFunction { + val typeParamsSubst = item.typeParamsToTypeParamsSubst + val acqTypes = (item as? MvFunctionLike)?.acquiresPathTypes.orEmpty().map { it.loweredType(msl) } + val baseTy = TyFunction(item, typeParamsSubst, parameterTypes, returnType, acqTypes) + + val explicitTypeParams = explicitTypeParamsSubst(methodOrPath, item, msl) + return baseTy.substitute(explicitTypeParams) as TyFunction + } + private fun lowerPrimitiveTy(path: MvPath, msl: Boolean): Ty { val refName = path.referenceName ?: return TyUnknown if (msl && refName in SPEC_INTEGER_TYPE_IDENTIFIERS) return TyInteger.fromName("num") @@ -102,14 +117,14 @@ class TyLowering { return ty } - private fun explicitTypeParamsSubst( + private fun explicitTypeParamsSubst( methodOrPath: MvMethodOrPath, - namedItem: T, + genericItem: MvElement, msl: Boolean ): Substitution { - if (namedItem !is MvGenericDeclaration) return emptySubstitution + if (genericItem !is MvGenericDeclaration) return emptySubstitution - val explicitTypeParamsSubst = pathTypeParamsSubst(methodOrPath, namedItem) + val explicitTypeParamsSubst = pathTypeParamsSubst(methodOrPath, genericItem) val typeSubst = hashMapOf() for ((param, value) in explicitTypeParamsSubst.typeSubst.entries) { 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 edf92ce58..291d7a524 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 @@ -395,11 +395,10 @@ class TypeInferenceWalker( // ?: return TyUnknown itemTy } - is MvStruct -> { - if (namedItem.tupleFields == null) return TyUnknown -// val (itemTy, _) = instantiateMethodOrPath(path, namedItem) -// ?: return TyUnknown - val itemTy = instantiatePath(path, namedItem) ?: return TyUnknown + is MvFieldsOwner -> { + val tupleFields = namedItem.tupleFields + if (tupleFields == null) return TyUnknown + val itemTy = instantiateTupleCallable(tupleFields, path, namedItem) itemTy } is MvPatBinding -> { @@ -456,7 +455,6 @@ class TypeInferenceWalker( val field = resolveSingleResolveVariant(fieldLookup.referenceName) { processFieldLookupResolveVariants(fieldLookup, tyAdt, msl, it) -// processNamedFieldVariants(fieldLookup, tyAdt, msl, it) } as? MvFieldDecl ctx.resolvedFields[fieldLookup] = field @@ -551,7 +549,7 @@ class TypeInferenceWalker( val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericItem, msl) as? T ?: return null - val tyVarsSubst = genericItem.typeParamsToTyVarsSubst + val tyVarsSubst = genericItem.tyVarsSubst @Suppress("UNCHECKED_CAST") // TyTypeParameter -> TyVar for every TypeParameter which is not explicit set return explicitPathTy.substitute(tyVarsSubst) as T @@ -565,7 +563,7 @@ class TypeInferenceWalker( // item type from explicit type parameters val explicitPathTy = TyLowering().lowerPath(methodOrPath, genericItem, msl) as? T ?: return null - val typeParamToVarSubst = genericItem.typeParamsToTyVarsSubst + val typeParamToVarSubst = genericItem.tyVarsSubst // replace type params which weren't explicitly specified with TyVar val explicitPathTyWithTyVars = explicitPathTy.substitute(typeParamToVarSubst) as? T ?: return null @@ -589,22 +587,36 @@ class TypeInferenceWalker( } } - private fun callableTy(tupleFields: MvTupleFields, item: MvFieldsOwner): TyFunction { - val parameterTypes = tupleFields.tupleFieldDeclList.map { it.type.loweredType(msl) } - val returnType = when (item) { - is MvStruct -> item.declaredType(msl) - is MvEnumVariant -> item.enumItem.declaredType(msl) + private fun instantiateTupleCallable( + tupleFields: MvTupleFields, + methodOrPath: MvMethodOrPath, + item: MvFieldsOwner + ): TyFunction { + val genericItem = when (item) { + is MvStruct -> item + is MvEnumVariant -> item.enumItem else -> error("exhaustive") } - val typeParams = (item as MvGenericDeclaration).typeParamsToTypeParamsSubst - return TyFunction( - item as MvGenericDeclaration, - typeParams, - paramTypes = parameterTypes, - returnType = returnType, - acquiresTypes = emptyList(), - ) - .substitute(typeParams) as TyFunction +// + val parameterTypes = tupleFields.tupleFieldDeclList.map { it.type.loweredType(msl) } + val returnType = genericItem.declaredType(msl) + + val funcTy = TyLowering().lowerCallable(methodOrPath, genericItem, parameterTypes, returnType, msl) +// +// val baseTy = TyFunction( +// genericItem, +// genericItem.typeParamsToTypeParamsSubst, +// paramTypes = parameterTypes, +// returnType = returnType, +// acquiresTypes = emptyList(), +// ) +// +// val explicitTypeParamsSubst = TyLowering().explicitTypeParamsSubst(methodOrPath, genericItem, msl) +// val funcTy = baseTy.substitute(explicitTypeParamsSubst) + +// val baseTy = TyLowering().lowerTupleCallable(methodOrPath, item, tupleFields, msl) + val tyVarsSubst = genericItem.tyVarsSubst + return funcTy.substitute(tyVarsSubst) as TyFunction } fun inferMacroCallExprTy(macroExpr: MvAssertMacroExpr): Ty { diff --git a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt index 254e5a0c6..59104ad07 100644 --- a/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt +++ b/src/main/kotlin/org/move/lang/core/types/ty/TyFunction.kt @@ -60,16 +60,17 @@ data class TyFunction( } } -fun MvFunctionLike.functionTy(msl: Boolean): TyFunction = callableTy(this, msl) +// do not account for explicit type arguments +fun MvFunctionLike.functionTy(msl: Boolean): TyFunction = rawFunctionTy(this, msl) -fun callableTy(item: MvFunctionLike, msl: Boolean): TyFunction { - val typeParameters = item.typeParamsToTypeParamsSubst +private fun rawFunctionTy(item: MvFunctionLike, msl: Boolean): TyFunction { + val typeParamsSubst = item.typeParamsToTypeParamsSubst val paramTypes = item.parameters.map { it.type?.loweredType(msl) ?: TyUnknown } val acquiredTypes = item.acquiresPathTypes.map { it.loweredType(msl) } val retType = item.returnTypeTy(msl) return TyFunction( item, - typeParameters, + typeParamsSubst, paramTypes, retType, acquiredTypes, diff --git a/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt b/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt index 813e7ac9a..b49e1319f 100644 --- a/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpectedTypeTest.kt @@ -99,7 +99,7 @@ class ExpectedTypeTest : TypificationTestCase() { // """ // ) - fun `test let statement struct pattern field explicit type`() = testExpectedTyExpr( + fun `test let statement struct lit field explicit type`() = testExpectedTyExpr( """ module 0x1::Main { struct S { val: Type } @@ -111,6 +111,19 @@ class ExpectedTypeTest : TypificationTestCase() { """ ) + fun `test function returning generic struct`() = testExpectedTyExpr( + """ + module 0x1::Main { + struct S { val: Type } + fun return_s(t: Type): S { S { val: t }} + fun main() { + let val: S = return_s(my_ref); + //^ u8 + } + } + """ + ) + fun `test let statement struct pattern field explicit incompatible type`() = testExpectedTyExpr( """ module 0x1::Main { diff --git a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt index de24b9c53..f3b662374 100644 --- a/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt +++ b/src/test/kotlin/org/move/lang/types/ExpressionTypesTest.kt @@ -2059,6 +2059,17 @@ module 0x1::main { } """) + fun `test type for tuple struct literal with multiple type parameters and explicit type`() = testExpr(""" + module 0x1::m { + struct S(T, T); + fun main() { + let s = S(1, 1); + s; + //^ 0x1::m::S + } + } + """) + fun `test positional field lookup type`() = testExpr(""" module 0x1::m { struct S(u8); @@ -2079,4 +2090,26 @@ module 0x1::main { } } """) + + fun `test enum variant for tuple struct literal`() = testExpr(""" + module 0x1::m { + enum S { One(T) } + fun main() { + let s = S::One(true); + s; + //^ 0x1::m::S + } + } + """) + + fun `test enum variant for tuple struct literal field`() = testExpr(""" + module 0x1::m { + enum S { One(T) } + fun main() { + let s = S::One(true); + s.0; + //^ bool + } + } + """) }