From 9e7c0d248364fdd662b333bd369157615b1e068c Mon Sep 17 00:00:00 2001 From: peefy Date: Fri, 19 Jul 2024 21:29:54 +0800 Subject: [PATCH] feat: support multiple assign target including member access `a.b` and index `a[b]` Signed-off-by: peefy --- .../api/src/testdata/parse-file.response.json | 2 +- kclvm/ast/src/ast.rs | 94 +++++- kclvm/ast/src/path.rs | 54 ++++ kclvm/ast/src/tests.rs | 35 +- kclvm/ast/src/token.rs | 7 + kclvm/ast/src/walker.rs | 45 ++- kclvm/ast_pretty/src/node.rs | 22 +- .../ast_pretty/src/test_data/codelayout.input | 10 +- .../src/test_data/codelayout.output | 7 + kclvm/compiler/src/codegen/llvm/context.rs | 118 +++++-- kclvm/compiler/src/codegen/llvm/module.rs | 17 +- kclvm/compiler/src/codegen/llvm/node.rs | 130 +++++++- kclvm/compiler/src/codegen/llvm/schema.rs | 4 +- kclvm/evaluator/src/lazy.rs | 4 +- kclvm/evaluator/src/module.rs | 13 +- kclvm/evaluator/src/node.rs | 102 +++++- kclvm/evaluator/src/scope.rs | 141 ++++++--- ...kclvm_evaluator__tests__assign_stmt_5.snap | 7 + ...kclvm_evaluator__tests__assign_stmt_6.snap | 7 + ...kclvm_evaluator__tests__assign_stmt_7.snap | 13 + ..._evaluator__tests__aug_assign_stmt_12.snap | 10 + ..._evaluator__tests__aug_assign_stmt_13.snap | 10 + ..._evaluator__tests__aug_assign_stmt_14.snap | 25 ++ .../kclvm_evaluator__tests__if_stmt_6.snap | 6 + kclvm/evaluator/src/tests.rs | 33 ++ kclvm/parser/src/parser/expr.rs | 79 ++++- kclvm/parser/src/parser/stmt.rs | 89 +++--- kclvm/parser/src/tests/error_recovery.rs | 8 + ...kclvm_parser__tests__ast__assign_stmt.snap | 22 +- .../kclvm_parser__tests__ast__basic_stmt.snap | 66 ++-- .../kclvm_parser__tests__ast__if_stmt_0.snap | 132 ++++---- .../kclvm_parser__tests__ast__if_stmt_1.snap | 22 +- ...rror_recovery__assign_stmt_recovery_0.snap | 24 +- ...ror_recovery__assign_stmt_recovery_10.snap | 32 +- ...ror_recovery__assign_stmt_recovery_11.snap | 87 +++++ ...ror_recovery__assign_stmt_recovery_12.snap | 89 ++++++ ...ror_recovery__assign_stmt_recovery_13.snap | 41 +++ ...ror_recovery__assign_stmt_recovery_14.snap | 41 +++ ...ror_recovery__assign_stmt_recovery_15.snap | 41 +++ ...ror_recovery__assign_stmt_recovery_16.snap | 115 +++++++ ...ror_recovery__assign_stmt_recovery_17.snap | 126 ++++++++ ...ror_recovery__assign_stmt_recovery_18.snap | 120 +++++++ ...rror_recovery__assign_stmt_recovery_2.snap | 24 +- ...rror_recovery__assign_stmt_recovery_3.snap | 24 +- ...rror_recovery__assign_stmt_recovery_4.snap | 24 +- ...rror_recovery__assign_stmt_recovery_5.snap | 46 ++- ...rror_recovery__assign_stmt_recovery_6.snap | 53 ++-- ...rror_recovery__assign_stmt_recovery_7.snap | 24 +- ...rror_recovery__assign_stmt_recovery_8.snap | 24 +- ...rror_recovery__assign_stmt_recovery_9.snap | 43 +-- ...recovery__fn_ty_annotation_recovery_0.snap | 24 +- ...recovery__fn_ty_annotation_recovery_1.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_10.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_11.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_12.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_13.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_14.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_15.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_16.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_17.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_18.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_19.snap | 24 +- ...recovery__fn_ty_annotation_recovery_2.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_20.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_21.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_22.snap | 24 +- ...ecovery__fn_ty_annotation_recovery_23.snap | 24 +- ...recovery__fn_ty_annotation_recovery_3.snap | 24 +- ...recovery__fn_ty_annotation_recovery_4.snap | 24 +- ...recovery__fn_ty_annotation_recovery_5.snap | 24 +- ...recovery__fn_ty_annotation_recovery_6.snap | 24 +- ...recovery__fn_ty_annotation_recovery_7.snap | 24 +- ...recovery__fn_ty_annotation_recovery_8.snap | 24 +- ...recovery__fn_ty_annotation_recovery_9.snap | 24 +- ...s__error_recovery__if_stmt_recovery_0.snap | 17 +- ...s__error_recovery__if_stmt_recovery_1.snap | 37 +-- ...s__error_recovery__if_stmt_recovery_2.snap | 24 +- ...s__error_recovery__if_stmt_recovery_3.snap | 39 +-- ...s__error_recovery__if_stmt_recovery_4.snap | 24 +- ...s__error_recovery__if_stmt_recovery_8.snap | 37 +-- ...s__error_recovery__if_stmt_recovery_9.snap | 39 +-- ...ror_recovery__schema_stmt_recovery_10.snap | 17 +- ...ror_recovery__schema_stmt_recovery_11.snap | 17 +- ...ror_recovery__schema_stmt_recovery_12.snap | 17 +- ...ror_recovery__schema_stmt_recovery_13.snap | 17 +- ...ror_recovery__schema_stmt_recovery_17.snap | 24 +- ...rror_recovery__schema_stmt_recovery_7.snap | 24 +- ...rror_recovery__schema_stmt_recovery_8.snap | 24 +- ...rror_recovery__schema_stmt_recovery_9.snap | 17 +- ...vm_parser__tests__expr__lambda_expr_3.snap | 46 ++- .../kclvm_parser__tests__file__assert_2.snap | 22 +- .../kclvm_parser__tests__file__assert_3.snap | 22 +- ...clvm_parser__tests__file__assert_if_0.snap | 22 +- ...clvm_parser__tests__file__assert_if_1.snap | 22 +- ...clvm_parser__tests__file__assert_if_2.snap | 44 ++- .../kclvm_parser__tests__file__assign_1.snap | 66 ++-- ...vm_parser__tests__file__config_expr_1.snap | 22 +- ...vm_parser__tests__file__config_expr_2.snap | 22 +- ...vm_parser__tests__file__config_expr_3.snap | 22 +- ...vm_parser__tests__file__config_expr_4.snap | 44 ++- .../kclvm_parser__tests__file__hello_win.snap | 22 +- .../kclvm_parser__tests__file__if_1.snap | 44 ++- .../kclvm_parser__tests__file__if_2.snap | 132 ++++---- .../kclvm_parser__tests__file__if_3.snap | 22 +- kclvm/query/src/node.rs | 28 +- kclvm/query/src/override.rs | 39 +-- kclvm/query/src/selector.rs | 24 +- kclvm/runtime/src/_kclvm.bc | Bin 14484 -> 14528 bytes kclvm/runtime/src/_kclvm.h | 2 + kclvm/runtime/src/_kclvm.ll | 2 + kclvm/runtime/src/_kclvm.rs | 1 + kclvm/runtime/src/_kclvm_addr.rs | 1 + kclvm/runtime/src/_kclvm_api_spec.rs | 4 + kclvm/runtime/src/value/api.rs | 15 + kclvm/runtime/src/value/val_as_val.rs | 8 + kclvm/runtime/src/value/val_bin.rs | 31 +- kclvm/runtime/src/value/val_list.rs | 7 + kclvm/runtime/src/value/val_str.rs | 8 - kclvm/sema/src/advanced_resolver/node.rs | 299 +++++++++++++++++- kclvm/sema/src/lint/mod.rs | 23 +- kclvm/sema/src/namer/node.rs | 14 +- kclvm/sema/src/pre_process/config.rs | 4 +- kclvm/sema/src/pre_process/identifier.rs | 54 ++-- kclvm/sema/src/pre_process/tests.rs | 4 +- kclvm/sema/src/resolver/attr.rs | 120 +++++++ kclvm/sema/src/resolver/global.rs | 9 +- kclvm/sema/src/resolver/node.rs | 224 ++++++------- kclvm/sema/src/resolver/ty.rs | 7 +- kclvm/sema/src/resolver/var.rs | 40 +++ kclvm/tools/src/LSP/src/util.rs | 22 +- kclvm/tools/src/testing/suite.rs | 2 +- kclvm/tools/src/vet/validator.rs | 10 +- test/grammar/assign/assign_0/main.k | 4 + test/grammar/assign/assign_0/stdout.golden | 5 + test/grammar/assign/assign_1/main.k | 4 + test/grammar/assign/assign_1/stdout.golden | 9 + test/grammar/assign/assign_fail_0/main.k | 3 + .../assign/assign_fail_0/stderr.golden | 1 + test/grammar/assign/assign_fail_1/main.k | 3 + .../assign/assign_fail_1/stderr.golden | 1 + .../syntax/else_if_token/stderr.golden | 56 ---- 141 files changed, 3111 insertions(+), 1813 deletions(-) create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_5.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_6.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_7.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_12.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_13.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_14.snap create mode 100644 kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__if_stmt_6.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_11.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_12.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_13.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_14.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_15.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_16.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_17.snap create mode 100644 kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_18.snap create mode 100644 test/grammar/assign/assign_0/main.k create mode 100644 test/grammar/assign/assign_0/stdout.golden create mode 100644 test/grammar/assign/assign_1/main.k create mode 100644 test/grammar/assign/assign_1/stdout.golden create mode 100644 test/grammar/assign/assign_fail_0/main.k create mode 100644 test/grammar/assign/assign_fail_0/stderr.golden create mode 100644 test/grammar/assign/assign_fail_1/main.k create mode 100644 test/grammar/assign/assign_fail_1/stderr.golden diff --git a/kclvm/api/src/testdata/parse-file.response.json b/kclvm/api/src/testdata/parse-file.response.json index fee977ddd..2382b6be7 100644 --- a/kclvm/api/src/testdata/parse-file.response.json +++ b/kclvm/api/src/testdata/parse-file.response.json @@ -1,5 +1,5 @@ { - "ast_json": "{\"filename\":\"source.k\",\"pkg\":\"__main__\",\"doc\":null,\"name\":\"__main__\",\"body\":[{\"node\":{\"type\":\"Import\",\"path\":{\"node\":\"units\",\"filename\":\"source.k\",\"line\":1,\"column\":7,\"end_line\":1,\"end_column\":12},\"rawpath\":\"units\",\"name\":\"units\",\"asname\":null,\"pkg_name\":\"__main__\"},\"filename\":\"source.k\",\"line\":1,\"column\":0,\"end_line\":1,\"end_column\":12},{\"node\":{\"type\":\"Import\",\"path\":{\"node\":\"data.cloud\",\"filename\":\"source.k\",\"line\":2,\"column\":7,\"end_line\":2,\"end_column\":17},\"rawpath\":\"data.cloud\",\"name\":\"cloud_pkg\",\"asname\":{\"node\":\"cloud_pkg\",\"filename\":\"source.k\",\"line\":2,\"column\":21,\"end_line\":2,\"end_column\":30},\"pkg_name\":\"__main__\"},\"filename\":\"source.k\",\"line\":2,\"column\":0,\"end_line\":2,\"end_column\":30},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"names\":[{\"node\":\"data1\",\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Store\"},\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":5}],\"value\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"NumberLit\",\"binary_suffix\":null,\"value\":{\"type\":\"Int\",\"value\":32}},\"filename\":\"source.k\",\"line\":4,\"column\":8,\"end_line\":4,\"end_column\":10},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"units\",\"filename\":\"source.k\",\"line\":4,\"column\":13,\"end_line\":4,\"end_column\":18},{\"node\":\"Ki\",\"filename\":\"source.k\",\"line\":4,\"column\":19,\"end_line\":4,\"end_column\":21}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":4,\"column\":13,\"end_line\":4,\"end_column\":21}},\"filename\":\"source.k\",\"line\":4,\"column\":8,\"end_line\":4,\"end_column\":21},\"ty\":null},\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":21},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"names\":[{\"node\":\"Data2\",\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Store\"},\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":5}],\"value\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"NumberLit\",\"binary_suffix\":null,\"value\":{\"type\":\"Int\",\"value\":42}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":10},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"units\",\"filename\":\"source.k\",\"line\":5,\"column\":13,\"end_line\":5,\"end_column\":18},{\"node\":\"Ki\",\"filename\":\"source.k\",\"line\":5,\"column\":19,\"end_line\":5,\"end_column\":21}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":5,\"column\":13,\"end_line\":5,\"end_column\":21}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":21},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"cloud_pkg\",\"filename\":\"source.k\",\"line\":5,\"column\":24,\"end_line\":5,\"end_column\":33},{\"node\":\"Foo\",\"filename\":\"source.k\",\"line\":5,\"column\":34,\"end_line\":5,\"end_column\":37}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":5,\"column\":24,\"end_line\":5,\"end_column\":37}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":37},\"ty\":null},\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":37},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"names\":[{\"node\":\"lambda1\",\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":7,\"end_column\":7}],\"pkgpath\":\"\",\"ctx\":\"Store\"},\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":7,\"end_column\":7}],\"value\":{\"node\":{\"type\":\"Lambda\",\"args\":{\"node\":{\"args\":[{\"node\":{\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":18}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":18},{\"node\":{\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":7,\"column\":25,\"end_line\":7,\"end_column\":26}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":7,\"column\":25,\"end_line\":7,\"end_column\":26}],\"defaults\":[null,null],\"ty_list\":[{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":20,\"end_line\":7,\"end_column\":23},{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":28,\"end_line\":7,\"end_column\":31}]},\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":31},\"body\":[{\"node\":{\"type\":\"Expr\",\"exprs\":[{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":5},\"op\":\"Sub\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":8,\"column\":8,\"end_line\":8,\"end_column\":9}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":8,\"column\":8,\"end_line\":8,\"end_column\":9}},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":9}]},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":9}],\"return_ty\":{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":35,\"end_line\":7,\"end_column\":38}},\"filename\":\"source.k\",\"line\":7,\"column\":10,\"end_line\":9,\"end_column\":1},\"ty\":null},\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":9,\"end_column\":1},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"names\":[{\"node\":\"Lambda2\",\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":10,\"end_column\":7}],\"pkgpath\":\"\",\"ctx\":\"Store\"},\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":10,\"end_column\":7}],\"value\":{\"node\":{\"type\":\"Lambda\",\"args\":{\"node\":{\"args\":[{\"node\":{\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":18}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":18},{\"node\":{\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":10,\"column\":25,\"end_line\":10,\"end_column\":26}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":10,\"column\":25,\"end_line\":10,\"end_column\":26}],\"defaults\":[null,null],\"ty_list\":[{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":20,\"end_line\":10,\"end_column\":23},{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":28,\"end_line\":10,\"end_column\":31}]},\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":31},\"body\":[{\"node\":{\"type\":\"Expr\",\"exprs\":[{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":5},\"op\":\"Add\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":11,\"column\":8,\"end_line\":11,\"end_column\":9}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":11,\"column\":8,\"end_line\":11,\"end_column\":9}},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":9}]},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":9}],\"return_ty\":{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":35,\"end_line\":10,\"end_column\":38}},\"filename\":\"source.k\",\"line\":10,\"column\":10,\"end_line\":12,\"end_column\":1},\"ty\":null},\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":12,\"end_column\":1}],\"comments\":[]}", + "ast_json": "{\"filename\":\"source.k\",\"pkg\":\"__main__\",\"doc\":null,\"name\":\"__main__\",\"body\":[{\"node\":{\"type\":\"Import\",\"path\":{\"node\":\"units\",\"filename\":\"source.k\",\"line\":1,\"column\":7,\"end_line\":1,\"end_column\":12},\"rawpath\":\"units\",\"name\":\"units\",\"asname\":null,\"pkg_name\":\"__main__\"},\"filename\":\"source.k\",\"line\":1,\"column\":0,\"end_line\":1,\"end_column\":12},{\"node\":{\"type\":\"Import\",\"path\":{\"node\":\"data.cloud\",\"filename\":\"source.k\",\"line\":2,\"column\":7,\"end_line\":2,\"end_column\":17},\"rawpath\":\"data.cloud\",\"name\":\"cloud_pkg\",\"asname\":{\"node\":\"cloud_pkg\",\"filename\":\"source.k\",\"line\":2,\"column\":21,\"end_line\":2,\"end_column\":30},\"pkg_name\":\"__main__\"},\"filename\":\"source.k\",\"line\":2,\"column\":0,\"end_line\":2,\"end_column\":30},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"name\":{\"node\":\"data1\",\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":5},\"paths\":[]},\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":5}],\"value\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"NumberLit\",\"binary_suffix\":null,\"value\":{\"type\":\"Int\",\"value\":32}},\"filename\":\"source.k\",\"line\":4,\"column\":8,\"end_line\":4,\"end_column\":10},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"units\",\"filename\":\"source.k\",\"line\":4,\"column\":13,\"end_line\":4,\"end_column\":18},{\"node\":\"Ki\",\"filename\":\"source.k\",\"line\":4,\"column\":19,\"end_line\":4,\"end_column\":21}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":4,\"column\":13,\"end_line\":4,\"end_column\":21}},\"filename\":\"source.k\",\"line\":4,\"column\":8,\"end_line\":4,\"end_column\":21},\"ty\":null},\"filename\":\"source.k\",\"line\":4,\"column\":0,\"end_line\":4,\"end_column\":21},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"name\":{\"node\":\"Data2\",\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":5},\"paths\":[]},\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":5}],\"value\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"NumberLit\",\"binary_suffix\":null,\"value\":{\"type\":\"Int\",\"value\":42}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":10},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"units\",\"filename\":\"source.k\",\"line\":5,\"column\":13,\"end_line\":5,\"end_column\":18},{\"node\":\"Ki\",\"filename\":\"source.k\",\"line\":5,\"column\":19,\"end_line\":5,\"end_column\":21}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":5,\"column\":13,\"end_line\":5,\"end_column\":21}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":21},\"op\":\"Mul\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"cloud_pkg\",\"filename\":\"source.k\",\"line\":5,\"column\":24,\"end_line\":5,\"end_column\":33},{\"node\":\"Foo\",\"filename\":\"source.k\",\"line\":5,\"column\":34,\"end_line\":5,\"end_column\":37}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":5,\"column\":24,\"end_line\":5,\"end_column\":37}},\"filename\":\"source.k\",\"line\":5,\"column\":8,\"end_line\":5,\"end_column\":37},\"ty\":null},\"filename\":\"source.k\",\"line\":5,\"column\":0,\"end_line\":5,\"end_column\":37},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"name\":{\"node\":\"lambda1\",\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":7,\"end_column\":7},\"paths\":[]},\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":7,\"end_column\":7}],\"value\":{\"node\":{\"type\":\"Lambda\",\"args\":{\"node\":{\"args\":[{\"node\":{\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":18}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":18},{\"node\":{\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":7,\"column\":25,\"end_line\":7,\"end_column\":26}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":7,\"column\":25,\"end_line\":7,\"end_column\":26}],\"defaults\":[null,null],\"ty_list\":[{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":20,\"end_line\":7,\"end_column\":23},{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":28,\"end_line\":7,\"end_column\":31}]},\"filename\":\"source.k\",\"line\":7,\"column\":17,\"end_line\":7,\"end_column\":31},\"body\":[{\"node\":{\"type\":\"Expr\",\"exprs\":[{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":5},\"op\":\"Sub\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":8,\"column\":8,\"end_line\":8,\"end_column\":9}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":8,\"column\":8,\"end_line\":8,\"end_column\":9}},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":9}]},\"filename\":\"source.k\",\"line\":8,\"column\":4,\"end_line\":8,\"end_column\":9}],\"return_ty\":{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":7,\"column\":35,\"end_line\":7,\"end_column\":38}},\"filename\":\"source.k\",\"line\":7,\"column\":10,\"end_line\":9,\"end_column\":1},\"ty\":null},\"filename\":\"source.k\",\"line\":7,\"column\":0,\"end_line\":9,\"end_column\":1},{\"node\":{\"type\":\"Assign\",\"targets\":[{\"node\":{\"name\":{\"node\":\"Lambda2\",\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":10,\"end_column\":7},\"paths\":[]},\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":10,\"end_column\":7}],\"value\":{\"node\":{\"type\":\"Lambda\",\"args\":{\"node\":{\"args\":[{\"node\":{\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":18}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":18},{\"node\":{\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":10,\"column\":25,\"end_line\":10,\"end_column\":26}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":10,\"column\":25,\"end_line\":10,\"end_column\":26}],\"defaults\":[null,null],\"ty_list\":[{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":20,\"end_line\":10,\"end_column\":23},{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":28,\"end_line\":10,\"end_column\":31}]},\"filename\":\"source.k\",\"line\":10,\"column\":17,\"end_line\":10,\"end_column\":31},\"body\":[{\"node\":{\"type\":\"Expr\",\"exprs\":[{\"node\":{\"type\":\"Binary\",\"left\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"x\",\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":5}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":5},\"op\":\"Add\",\"right\":{\"node\":{\"type\":\"Identifier\",\"names\":[{\"node\":\"y\",\"filename\":\"source.k\",\"line\":11,\"column\":8,\"end_line\":11,\"end_column\":9}],\"pkgpath\":\"\",\"ctx\":\"Load\"},\"filename\":\"source.k\",\"line\":11,\"column\":8,\"end_line\":11,\"end_column\":9}},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":9}]},\"filename\":\"source.k\",\"line\":11,\"column\":4,\"end_line\":11,\"end_column\":9}],\"return_ty\":{\"node\":{\"type\":\"Basic\",\"value\":\"Int\"},\"filename\":\"source.k\",\"line\":10,\"column\":35,\"end_line\":10,\"end_column\":38}},\"filename\":\"source.k\",\"line\":10,\"column\":10,\"end_line\":12,\"end_column\":1},\"ty\":null},\"filename\":\"source.k\",\"line\":10,\"column\":0,\"end_line\":12,\"end_column\":1}],\"comments\":[]}", "deps": [], "errors": [ { diff --git a/kclvm/ast/src/ast.rs b/kclvm/ast/src/ast.rs index 8cac4f1f7..59cbcd083 100644 --- a/kclvm/ast/src/ast.rs +++ b/kclvm/ast/src/ast.rs @@ -84,6 +84,8 @@ impl From for Range { } } +/// The unique index of AST, used for KCL semantic analysis to record AST +/// node semantic information. #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct AstIndex(uuid::Uuid); @@ -487,10 +489,16 @@ pub struct UnificationStmt { /// AssignStmt represents an assignment, e.g. /// ```kcl /// a: int = 1 +/// a["key"] = "value" +/// a.b["key"].c = "value" +/// a[0] = 1 /// ``` +/// Valid left-hand side of an assignment expressions: +/// - Expr::Identifier a +/// - Expr::Subscript e.g. `a[0]`, `b["k"]` #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct AssignStmt { - pub targets: Vec>, + pub targets: Vec>, pub value: NodeRef, pub ty: Option>, } @@ -498,10 +506,11 @@ pub struct AssignStmt { /// AugAssignStmt represents an argument assignment, e.g. /// ```kcl /// a += 1 +/// a[0] += 2 /// ``` #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct AugAssignStmt { - pub target: NodeRef, + pub target: NodeRef, pub value: NodeRef, pub op: AugOp, } @@ -606,24 +615,20 @@ impl SchemaStmt { } Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - if !target.node.names.is_empty() { - attr_list.push(( - target.line, - target.column, - target.node.names[0].node.to_string(), - )); - } - } - } - Stmt::AugAssign(aug_assign_stmt) => { - if !aug_assign_stmt.target.node.names.is_empty() { attr_list.push(( - aug_assign_stmt.target.line, - aug_assign_stmt.target.column, - aug_assign_stmt.target.node.names[0].node.to_string(), + target.line, + target.column, + target.node.name.node.to_string(), )); } } + Stmt::AugAssign(aug_assign_stmt) => { + attr_list.push(( + aug_assign_stmt.target.line, + aug_assign_stmt.target.column, + aug_assign_stmt.target.node.name.node.to_string(), + )); + } Stmt::If(if_stmt) => { loop_body(&if_stmt.body, attr_list); loop_body(&if_stmt.orelse, attr_list); @@ -715,6 +720,7 @@ pub struct RuleStmt { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(tag = "type")] pub enum Expr { + Target(Target), Identifier(Identifier), Unary(UnaryExpr), Binary(BinaryExpr), @@ -750,6 +756,7 @@ pub enum Expr { impl Expr { pub fn get_expr_name(&self) -> String { match self { + Expr::Target(_) => "TargetExpression", Expr::Identifier(_) => "IdentifierExpression", Expr::Unary(_) => "UnaryExpression", Expr::Binary(_) => "BinaryExpression", @@ -784,6 +791,46 @@ impl Expr { } } +/// Target, e.g. +/// ```kcl +/// a.b.c +/// b +/// _c +/// a["b"][0].c +/// ``` +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct Target { + pub name: Node, + pub paths: Vec, + pub pkgpath: String, +} + +impl Target { + #[inline] + pub fn get_name(&self) -> &str { + self.name.node.as_str() + } +} + +/// Member or index expression +/// - `a.` +/// - `b[]` +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum MemberOrIndex { + Member(NodeRef), + Index(NodeRef), +} + +impl MemberOrIndex { + #[inline] + pub fn id(&self) -> AstIndex { + match self { + MemberOrIndex::Member(member) => member.id.clone(), + MemberOrIndex::Index(index) => index.id.clone(), + } + } +} + /// Identifier, e.g. /// ```kcl /// a @@ -799,10 +846,12 @@ pub struct Identifier { } impl Identifier { + #[inline] pub fn get_name(&self) -> String { self.get_names().join(".") } + #[inline] pub fn get_names(&self) -> Vec { self.names .iter() @@ -1260,6 +1309,19 @@ pub struct NumberLit { pub value: NumberLitValue, } +impl ToString for NumberLit { + fn to_string(&self) -> String { + let mut result = match self.value { + NumberLitValue::Int(v) => v.to_string(), + NumberLitValue::Float(v) => v.to_string(), + }; + if let Some(suffix) = &self.binary_suffix { + result.push_str(&suffix.value()); + } + result + } +} + /// StringLit, e.g. /// ```kcl /// "string literal" diff --git a/kclvm/ast/src/path.rs b/kclvm/ast/src/path.rs index f3c3043d2..617a9468d 100644 --- a/kclvm/ast/src/path.rs +++ b/kclvm/ast/src/path.rs @@ -34,6 +34,60 @@ pub fn get_key_path(key: &Option>) -> String { } } +/// Get assign target path from the AST key node and convert string-based AST nodes including +/// `ast::Expr::Identifier` and `ast::Expr::StringLit` to strings. +/// +/// # Examples +/// +/// ``` +/// use kclvm_ast::ast; +/// use kclvm_ast::path::get_target_path; +/// +/// let target = ast::Target { +/// name: ast::Node::dummy_node("alice".to_string()), +/// paths: vec![], +/// pkgpath: "".to_string(), +/// }; +/// assert_eq!(get_target_path(&target), "alice"); +/// ``` +#[inline] +pub fn get_target_path(key: &ast::Target) -> String { + let mut result = key.name.node.to_string(); + for path in &key.paths { + match path { + ast::MemberOrIndex::Member(member) => { + result.push('.'); + result.push_str(&member.node); + } + ast::MemberOrIndex::Index(index) => { + result.push('['); + match &index.node { + ast::Expr::Unary(unary_expr) => match &unary_expr.operand.node { + ast::Expr::NumberLit(number) => { + result.push_str(&unary_expr.op.symbol()); + result.push_str(&number.to_string()); + } + _ => { + result.push_str("..."); + } + }, + ast::Expr::NumberLit(number) => { + result.push_str(&number.to_string()); + } + ast::Expr::StringLit(string_lit) => { + result.push_str(&format!("{:?}", string_lit.value)); + } + _ => { + result.push_str("..."); + } + } + result.push(']'); + } + } + } + result +} + /// Get all attribute paths recursively from a config expression AST node. /// /// # Examples diff --git a/kclvm/ast/src/tests.rs b/kclvm/ast/src/tests.rs index ebaa19797..cdc5f903e 100644 --- a/kclvm/ast/src/tests.rs +++ b/kclvm/ast/src/tests.rs @@ -4,15 +4,15 @@ use crate::{ast, ast::*}; /// Construct an AssignStmt node with assign_value as value fn build_assign_node(attr_name: &str, assign_value: NodeRef) -> NodeRef { - let iden = node_ref!(Identifier { - names: vec![Node::dummy_node(attr_name.to_string())], - pkgpath: String::new(), - ctx: ExprContext::Store + let target = node_ref!(Target { + name: Node::dummy_node(attr_name.to_string()), + paths: vec![], + pkgpath: "".to_string() }); node_ref!(Stmt::Assign(AssignStmt { value: assign_value, - targets: vec![iden], + targets: vec![target], ty: None })) } @@ -26,10 +26,10 @@ fn get_dummy_assign_ast() -> ast::Node { ast::Node::new( ast::AssignStmt { targets: vec![Box::new(ast::Node::new( - ast::Identifier { - names: vec![Node::dummy_node(String::from("a"))], - pkgpath: String::from(filename), - ctx: ast::ExprContext::Load, + ast::Target { + name: Node::dummy_node(String::from("a")), + paths: vec![], + pkgpath: "".to_string(), }, String::from(filename), line, @@ -68,10 +68,10 @@ fn get_dummy_assign_binary_ast() -> ast::Node { ast::Node::new( ast::AssignStmt { targets: vec![Box::new(ast::Node::new( - ast::Identifier { - names: vec![Node::dummy_node(String::from("a"))], - pkgpath: String::from(filename), - ctx: ast::ExprContext::Load, + ast::Target { + name: Node::dummy_node(String::from("a")), + paths: vec![], + pkgpath: "".to_string(), }, String::from(filename), line, @@ -143,16 +143,15 @@ fn test_ast_print_assign_binary() { fn test_mut_walker() { pub struct VarMutSelfMutWalker; impl<'ctx> MutSelfMutWalker<'ctx> for VarMutSelfMutWalker { - fn walk_identifier(&mut self, identifier: &'ctx mut ast::Identifier) { - if identifier.names[0].node == "a" { - let id_mut = identifier.names.get_mut(0).unwrap(); - id_mut.node = "x".to_string(); + fn walk_target(&mut self, target: &'ctx mut ast::Target) { + if target.name.node == "a" { + target.name.node = "x".to_string(); } } } let mut assign_stmt = get_dummy_assign_ast(); VarMutSelfMutWalker {}.walk_assign_stmt(&mut assign_stmt.node); - assert_eq!(assign_stmt.node.targets[0].node.names[0].node, "x") + assert_eq!(assign_stmt.node.targets[0].node.name.node, "x") } #[test] diff --git a/kclvm/ast/src/token.rs b/kclvm/ast/src/token.rs index 59b5ea7a1..d375b4c07 100644 --- a/kclvm/ast/src/token.rs +++ b/kclvm/ast/src/token.rs @@ -313,16 +313,20 @@ impl From for String { } impl Token { + /// New a token using the kind and span. + #[inline] pub fn new(kind: TokenKind, span: Span) -> Self { Token { kind, span } } /// Some token that will be thrown away later. + #[inline] pub fn dummy() -> Self { Token::new(TokenKind::Dummy, DUMMY_SP) } /// Returns an identifier if this token is an identifier. + #[inline] pub fn ident(&self) -> Option { match self.kind { Ident(name) => Some(Ident::new(name, self.span)), @@ -330,11 +334,14 @@ impl Token { } } + /// Whether the token is keyword. + #[inline] pub fn is_keyword(&self, kw: Symbol) -> bool { self.run_on_ident(|id| id.name == kw) } /// Whether the token is a string literal token. + #[inline] pub fn is_string_lit(&self) -> bool { match self.kind { TokenKind::Literal(lit) => { diff --git a/kclvm/ast/src/walker.rs b/kclvm/ast/src/walker.rs index 49932e4b8..916eb1b9a 100644 --- a/kclvm/ast/src/walker.rs +++ b/kclvm/ast/src/walker.rs @@ -110,6 +110,7 @@ pub trait TypedResultWalker<'ctx>: Sized { fn walk_arguments(&self, arguments: &'ctx ast::Arguments) -> Self::Result; fn walk_compare(&self, compare: &'ctx ast::Compare) -> Self::Result; fn walk_identifier(&self, identifier: &'ctx ast::Identifier) -> Self::Result; + fn walk_target(&self, target: &'ctx ast::Target) -> Self::Result; fn walk_number_lit(&self, number_lit: &'ctx ast::NumberLit) -> Self::Result; fn walk_string_lit(&self, string_lit: &'ctx ast::StringLit) -> Self::Result; fn walk_name_constant_lit(&self, name_constant_lit: &'ctx ast::NameConstantLit) @@ -174,6 +175,7 @@ pub trait MutSelfTypedResultWalker<'ctx>: Sized { fn walk_expr(&mut self, expr: &'ctx ast::Expr) -> Self::Result { match expr { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), @@ -243,6 +245,7 @@ pub trait MutSelfTypedResultWalker<'ctx>: Sized { fn walk_arguments(&mut self, arguments: &'ctx ast::Arguments) -> Self::Result; fn walk_compare(&mut self, compare: &'ctx ast::Compare) -> Self::Result; fn walk_identifier(&mut self, identifier: &'ctx ast::Identifier) -> Self::Result; + fn walk_target(&mut self, target: &'ctx ast::Target) -> Self::Result; fn walk_number_lit(&mut self, number_lit: &'ctx ast::NumberLit) -> Self::Result; fn walk_string_lit(&mut self, string_lit: &'ctx ast::StringLit) -> Self::Result; fn walk_name_constant_lit( @@ -274,13 +277,13 @@ pub trait MutSelfMutWalker<'ctx> { } fn walk_assign_stmt(&mut self, assign_stmt: &'ctx mut ast::AssignStmt) { for target in assign_stmt.targets.iter_mut() { - self.walk_identifier(&mut target.node) + self.walk_target(&mut target.node) } self.walk_expr(&mut assign_stmt.value.node); walk_if_mut!(self, walk_type, assign_stmt.ty); } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx mut ast::AugAssignStmt) { - self.walk_identifier(&mut aug_assign_stmt.target.node); + self.walk_target(&mut aug_assign_stmt.target.node); self.walk_expr(&mut aug_assign_stmt.value.node); } fn walk_assert_stmt(&mut self, assert_stmt: &'ctx mut ast::AssertStmt) { @@ -471,6 +474,13 @@ pub trait MutSelfMutWalker<'ctx> { // Nothing to do. let _ = identifier; } + fn walk_target(&mut self, target: &'ctx mut ast::Target) { + for path in target.paths.iter_mut() { + if let ast::MemberOrIndex::Index(index) = path { + self.walk_expr(&mut index.node) + } + } + } fn walk_number_lit(&mut self, number_lit: &'ctx mut ast::NumberLit) { let _ = number_lit; } @@ -518,6 +528,7 @@ pub trait MutSelfMutWalker<'ctx> { } fn walk_expr(&mut self, expr: &'ctx mut ast::Expr) { match expr { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), @@ -671,6 +682,9 @@ pub trait Walker<'ctx>: TypedResultWalker<'ctx> { fn walk_identifier(&mut self, identifier: &'ctx ast::Identifier) { walk_identifier(self, identifier); } + fn walk_target(&mut self, target: &'ctx ast::Target) { + walk_target(self, target); + } fn walk_number_lit(&mut self, number_lit: &'ctx ast::NumberLit) { walk_number_lit(self, number_lit); } @@ -703,6 +717,7 @@ pub trait Walker<'ctx>: TypedResultWalker<'ctx> { pub fn walk_expr<'ctx, V: Walker<'ctx>>(walker: &mut V, expr: &'ctx ast::Expr) { match expr { + ast::Expr::Target(target) => walker.walk_target(target), ast::Expr::Identifier(identifier) => walker.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => walker.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => walker.walk_binary_expr(binary_expr), @@ -777,7 +792,9 @@ pub fn walk_type_alias_stmt<'ctx, V: Walker<'ctx>>( } pub fn walk_assign_stmt<'ctx, V: Walker<'ctx>>(walker: &mut V, assign_stmt: &'ctx ast::AssignStmt) { - walk_list!(walker, walk_identifier, assign_stmt.targets); + for target in &assign_stmt.targets { + walker.walk_target(&target.node) + } walker.walk_expr(&assign_stmt.value.node); } @@ -785,7 +802,7 @@ pub fn walk_aug_assign_stmt<'ctx, V: Walker<'ctx>>( walker: &mut V, aug_assign_stmt: &'ctx ast::AugAssignStmt, ) { - walker.walk_identifier(&aug_assign_stmt.target.node); + walker.walk_target(&aug_assign_stmt.target.node); walker.walk_expr(&aug_assign_stmt.value.node); } @@ -991,6 +1008,14 @@ pub fn walk_identifier<'ctx, V: Walker<'ctx>>(walker: &mut V, identifier: &'ctx let _ = identifier; } +pub fn walk_target<'ctx, V: Walker<'ctx>>(walker: &mut V, target: &'ctx ast::Target) { + for path in target.paths.iter() { + if let ast::MemberOrIndex::Index(index) = path { + walk_expr(walker, &index.node); + } + } +} + pub fn walk_number_lit<'ctx, V: Walker<'ctx>>(walker: &mut V, number_lit: &'ctx ast::NumberLit) { // Nothing to do. let _ = walker; @@ -1055,12 +1080,12 @@ pub trait MutSelfWalker { } fn walk_assign_stmt(&mut self, assign_stmt: &ast::AssignStmt) { for target in &assign_stmt.targets { - self.walk_identifier(&target.node) + self.walk_target(&target.node) } self.walk_expr(&assign_stmt.value.node); } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &ast::AugAssignStmt) { - self.walk_identifier(&aug_assign_stmt.target.node); + self.walk_target(&aug_assign_stmt.target.node); self.walk_expr(&aug_assign_stmt.value.node); } fn walk_assert_stmt(&mut self, assert_stmt: &ast::AssertStmt) { @@ -1213,6 +1238,13 @@ pub trait MutSelfWalker { // Nothing to do. let _ = identifier; } + fn walk_target(&mut self, target: &ast::Target) { + for path in target.paths.iter() { + if let ast::MemberOrIndex::Index(index) = path { + self.walk_expr(&index.node) + } + } + } fn walk_number_lit(&mut self, number_lit: &ast::NumberLit) { let _ = number_lit; } @@ -1260,6 +1292,7 @@ pub trait MutSelfWalker { } fn walk_expr(&mut self, expr: &ast::Expr) { match expr { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), diff --git a/kclvm/ast_pretty/src/node.rs b/kclvm/ast_pretty/src/node.rs index 96dfc58b6..eff710ee3 100644 --- a/kclvm/ast_pretty/src/node.rs +++ b/kclvm/ast_pretty/src/node.rs @@ -74,7 +74,7 @@ impl<'p, 'ctx> MutSelfTypedResultWalker<'ctx> for Printer<'p> { fn walk_assign_stmt(&mut self, assign_stmt: &'ctx ast::AssignStmt) -> Self::Result { for (i, target) in assign_stmt.targets.iter().enumerate() { - self.walk_identifier(&target.node); + self.walk_target(&target.node); if i == 0 { if let Some(ty) = &assign_stmt.ty { self.write(": "); @@ -91,7 +91,7 @@ impl<'p, 'ctx> MutSelfTypedResultWalker<'ctx> for Printer<'p> { } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx ast::AugAssignStmt) -> Self::Result { - self.walk_identifier(&aug_assign_stmt.target.node); + self.walk_target(&aug_assign_stmt.target.node); self.write_space(); self.write(aug_assign_stmt.op.symbol()); self.write_space(); @@ -749,6 +749,24 @@ impl<'p, 'ctx> MutSelfTypedResultWalker<'ctx> for Printer<'p> { self.write(&identifier.get_name()); } + #[inline] + fn walk_target(&mut self, target: &'ctx ast::Target) -> Self::Result { + self.write(target.get_name()); + for path in &target.paths { + match path { + ast::MemberOrIndex::Member(member) => { + self.write("."); + self.write(&member.node) + } + ast::MemberOrIndex::Index(index) => { + self.write("["); + self.walk_expr(&index.node); + self.write("]"); + } + } + } + } + fn walk_number_lit(&mut self, number_lit: &'ctx ast::NumberLit) -> Self::Result { match &number_lit.value { ast::NumberLitValue::Int(int_val) => self.write(&int_val.to_string()), diff --git a/kclvm/ast_pretty/src/test_data/codelayout.input b/kclvm/ast_pretty/src/test_data/codelayout.input index d36aeb3cb..45fc4d46b 100644 --- a/kclvm/ast_pretty/src/test_data/codelayout.input +++ b/kclvm/ast_pretty/src/test_data/codelayout.input @@ -99,4 +99,12 @@ joined_data_3 = '''\ ''' joined_data_4 = '''\ \${CC} -''' \ No newline at end of file +''' + +# Member access and index assign targets +a[0].b -= 1 +a.b[0] += 1 +a.b[1].c /= 1 +a.b[c.d].e == 1 +a.b[1 + 1].e = 1 +a.b[f()].e = 1 diff --git a/kclvm/ast_pretty/src/test_data/codelayout.output b/kclvm/ast_pretty/src/test_data/codelayout.output index b2338351d..04b62f351 100644 --- a/kclvm/ast_pretty/src/test_data/codelayout.output +++ b/kclvm/ast_pretty/src/test_data/codelayout.output @@ -105,3 +105,10 @@ joined_data_3 = '''\ joined_data_4 = '''\ \${CC} ''' +# Member access and index assign targets +a[0].b -= 1 +a.b[0] += 1 +a.b[1].c /= 1 +a.b[c.d].e == 1 +a.b[1 + 1].e = 1 +a.b[f()].e = 1 diff --git a/kclvm/compiler/src/codegen/llvm/context.rs b/kclvm/compiler/src/codegen/llvm/context.rs index 0bc28f3f4..6cf99d5db 100644 --- a/kclvm/compiler/src/codegen/llvm/context.rs +++ b/kclvm/compiler/src/codegen/llvm/context.rs @@ -22,6 +22,7 @@ use std::rc::Rc; use std::str; use kclvm_ast::ast; +use kclvm_ast::walker::TypedResultWalker; use kclvm_error::*; use kclvm_runtime::{ApiFunc, MAIN_PKG_PATH, PKG_PATH_PREFIX}; use kclvm_sema::builtin; @@ -2222,37 +2223,11 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { }); } let name = names[0]; - // Get variable from the scope. - let get = |name: &str| { - match ( - self.is_in_schema(), - self.is_in_lambda(), - self.is_local_var(name), - ) { - // Get from local or global scope - (false, _, _) | (_, _, true) => self.get_variable(name), - // Get variable from the current schema scope. - (true, false, false) => self.get_variable_in_schema(name), - // Get from local scope including lambda arguments, lambda variables, - // loop variables or global variables. - (true, true, _) => - // Get from local scope including lambda arguments, lambda variables, - // loop variables or global variables. - { - match self.resolve_variable_level(name) { - // Closure variable or local variables - Some(level) if level > GLOBAL_LEVEL => self.get_variable(name), - // Schema closure or global variables - _ => self.get_variable_in_schema(name), - } - } - } - }; if names.len() == 1 { - get(name) + self.load_name(name) } else { let mut value = if pkgpath.is_empty() { - get(name) + self.load_name(name) } else { self.ok_result() } @@ -2278,6 +2253,93 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } } + /// Load global or local value from name. + pub fn load_name(&self, name: &str) -> CompileResult<'ctx> { + match ( + self.is_in_schema(), + self.is_in_lambda(), + self.is_local_var(name), + ) { + // Get from local or global scope + (false, _, _) | (_, _, true) => self.get_variable(name), + // Get variable from the current schema scope. + (true, false, false) => self.get_variable_in_schema(name), + // Get from local scope including lambda arguments, lambda variables, + // loop variables or global variables. + (true, true, _) => + // Get from local scope including lambda arguments, lambda variables, + // loop variables or global variables. + { + match self.resolve_variable_level(name) { + // Closure variable or local variables + Some(level) if level > GLOBAL_LEVEL => self.get_variable(name), + // Schema closure or global variables + _ => self.get_variable_in_schema(name), + } + } + } + } + + /// Load value from assignment target. + pub fn load_target(&self, target: &'ctx ast::Target) -> CompileResult<'ctx> { + let mut value = self.load_name(target.get_name())?; + for path in &target.paths { + value = self.load_target_path(value, path)?; + } + Ok(value) + } + + /// Load value from assignment target path. + pub fn load_target_path( + &self, + value: BasicValueEnum<'ctx>, + path: &'ctx ast::MemberOrIndex, + ) -> CompileResult<'ctx> { + Ok(match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + let attr = self.native_global_string(attr, "").into(); + self.build_call( + &ApiFunc::kclvm_value_load_attr.name(), + &[self.current_runtime_ctx_ptr(), value, attr], + ) + } + ast::MemberOrIndex::Index(index) => { + let index = self.walk_expr(index)?; + self.build_call( + &ApiFunc::kclvm_value_subscr.name(), + &[self.current_runtime_ctx_ptr(), value, index], + ) + } + }) + } + + pub fn store_target_path( + &self, + value: BasicValueEnum<'ctx>, + path: &'ctx ast::MemberOrIndex, + right_value: BasicValueEnum<'ctx>, + ) -> CompileResult<'ctx> { + match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + let attr = self.native_global_string(attr, "").into(); + self.build_void_call( + &ApiFunc::kclvm_dict_set_value.name(), + &[self.current_runtime_ctx_ptr(), value, attr, right_value], + ); + } + ast::MemberOrIndex::Index(index) => { + let index = self.walk_expr(index)?; + self.build_void_call( + &ApiFunc::kclvm_value_subscr_set.name(), + &[self.current_runtime_ctx_ptr(), value, index, right_value], + ); + } + } + self.ok_result() + } + /// Push a lambda definition scope into the lambda stack #[inline] pub fn push_lambda(&self, scope: usize) { diff --git a/kclvm/compiler/src/codegen/llvm/module.rs b/kclvm/compiler/src/codegen/llvm/module.rs index 761b4be34..7b9adc451 100644 --- a/kclvm/compiler/src/codegen/llvm/module.rs +++ b/kclvm/compiler/src/codegen/llvm/module.rs @@ -139,14 +139,11 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } ast::Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - let names = &target.node.names; - if names.len() == 1 { - self.add_or_update_global_variable( - &names[0].node, - self.undefined_value(), - false, - ); - } + self.add_or_update_global_variable( + target.node.get_name(), + self.undefined_value(), + false, + ); } } ast::Stmt::If(if_stmt) => { @@ -319,7 +316,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } ast::Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - let name = &target.node.names[0].node; + let name = &target.node.name.node; if is_in_if { in_if_names.push(name.to_string()); } else { @@ -335,7 +332,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } ast::Stmt::AugAssign(aug_assign_stmt) => { let target = &aug_assign_stmt.target; - let name = &target.node.names[0].node; + let name = &target.node.name.node; if is_in_if { in_if_names.push(name.to_string()); } else { diff --git a/kclvm/compiler/src/codegen/llvm/node.rs b/kclvm/compiler/src/codegen/llvm/node.rs index 2e73694d9..24f392f43 100644 --- a/kclvm/compiler/src/codegen/llvm/node.rs +++ b/kclvm/compiler/src/codegen/llvm/node.rs @@ -150,7 +150,7 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { for name in &assign_stmt.targets { self.target_vars .borrow_mut() - .push(name.node.names[0].node.clone()); + .push(name.node.name.node.clone()); } // Load the right value let mut value = self @@ -172,13 +172,13 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { if assign_stmt.targets.len() == 1 { // Store the single target let name = &assign_stmt.targets[0]; - self.walk_identifier_with_ctx(&name.node, &name.node.ctx, Some(value)) + self.walk_target_with_value(&name.node, value) .expect(kcl_error::COMPILE_ERROR_MSG); } else { // Store multiple targets for name in &assign_stmt.targets { let value = self.value_deep_copy(value); - self.walk_identifier_with_ctx(&name.node, &name.node.ctx, Some(value)) + self.walk_target_with_value(&name.node, value) .expect(kcl_error::COMPILE_ERROR_MSG); } } @@ -189,14 +189,14 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { check_backtrack_stop!(self); self.target_vars .borrow_mut() - .push(aug_assign_stmt.target.node.names[0].node.clone()); + .push(aug_assign_stmt.target.node.name.node.clone()); // Load the right value let right_value = self .walk_expr(&aug_assign_stmt.value) .expect(kcl_error::COMPILE_ERROR_MSG); - // Load the identifier value + // Load the value let org_value = self - .walk_identifier_with_ctx(&aug_assign_stmt.target.node, &ast::ExprContext::Load, None) + .load_target(&aug_assign_stmt.target.node) .expect(kcl_error::COMPILE_ERROR_MSG); let fn_name = match aug_assign_stmt.op { ast::AugOp::Add => ApiFunc::kclvm_value_op_aug_add, @@ -219,13 +219,9 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { &fn_name.name(), &[self.current_runtime_ctx_ptr(), org_value, right_value], ); - // Store the identifier value - self.walk_identifier_with_ctx( - &aug_assign_stmt.target.node, - &ast::ExprContext::Store, - Some(value), - ) - .expect(kcl_error::COMPILE_ERROR_MSG); + // Store the target value + self.walk_target_with_value(&aug_assign_stmt.target.node, value) + .expect(kcl_error::COMPILE_ERROR_MSG); Ok(value) } @@ -1269,6 +1265,7 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { utils::update_ctx_filename(self, expr); utils::update_ctx_line_col(self, expr); match &expr.node { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), @@ -2298,6 +2295,12 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> { self.walk_identifier_with_ctx(identifier, &identifier.ctx, None) } + #[inline] + fn walk_target(&self, target: &'ctx ast::Target) -> Self::Result { + check_backtrack_stop!(self); + self.load_target(target) + } + fn walk_number_lit(&self, number_lit: &'ctx ast::NumberLit) -> Self::Result { check_backtrack_stop!(self); match number_lit.value { @@ -2421,6 +2424,107 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { result } + pub fn walk_target_with_value( + &self, + target: &'ctx ast::Target, + right_value: BasicValueEnum<'ctx>, + ) -> CompileResult<'ctx> { + check_backtrack_stop!(self); + let is_in_schema = self.is_in_schema(); + if target.paths.is_empty() { + let name = target.get_name(); + let tpe = self.value_ptr_type(); + // Global variables + if self.scope_level() == GLOBAL_LEVEL { + self.add_or_update_global_variable(name, right_value, true); + // Lambda local variables. + } else if self.is_in_lambda() { + let value = right_value; + // If variable exists in the scope and update it, if not, add it to the scope. + if !self.store_variable_in_current_scope(name, value) { + let cur_bb = self.builder.get_insert_block().unwrap(); + let lambda_func = cur_bb.get_parent().unwrap(); + let entry_bb = lambda_func.get_first_basic_block().unwrap(); + match entry_bb.get_first_instruction() { + Some(inst) => self.builder.position_before(&inst), + None => self.builder.position_at_end(entry_bb), + }; + let var = self.builder.build_alloca(tpe, name); + let undefined_val = self.undefined_value(); + self.builder.build_store(var, undefined_val); + self.add_variable(name, var); + self.builder.position_at_end(cur_bb); + self.store_variable(name, value); + } + } else { + let is_local_var = self.is_local_var(name); + let value = right_value; + // Store schema attribute + if is_in_schema { + let schema_value = self.get_variable(value::SCHEMA_SELF_NAME)?; + // Schema config + let config_value = self.get_variable(value::SCHEMA_CONFIG_NAME)?; + // If is in the backtrack, return the schema value. + if self.update_schema_scope_value(schema_value, config_value, name, Some(value)) + { + return Ok(schema_value); + } + } + // Store loop variable + if is_local_var || !is_in_schema { + let var = self.builder.build_alloca(tpe, name); + self.builder.build_store(var, value); + self.add_variable(name, var); + } + } + } else { + let name = target.get_name(); + // In KCL, we cannot modify global variables in other packages, + // so pkgpath is empty here. + let mut value = self + .load_value("", &[name]) + .expect(kcl_error::INTERNAL_ERROR_MSG); + // Convert `store a.b.c = 1` -> `%t = load &a; %t = load_attr %t %b; store_attr %t %c with 1` + for (i, path) in target.paths.iter().enumerate() { + let ctx = if i < target.paths.len() - 1 { + ast::ExprContext::Load + } else { + ast::ExprContext::Store + }; + match ctx { + ast::ExprContext::Load => { + value = self.load_target_path(value, path)?; + } + ast::ExprContext::Store => { + self.store_target_path(value, path, right_value)?; + + let is_local_var = self.is_local_var(name); + let is_in_lambda = self.is_in_lambda(); + // Set config value for the schema attribute if the attribute is in the schema and + // it is not a local variable in the lambda function. + if self.scope_level() >= INNER_LEVEL + && is_in_schema + && !is_in_lambda + && !is_local_var + { + let schema_value = self.get_variable(value::SCHEMA_SELF_NAME)?; + let config_value = self.get_variable(value::SCHEMA_CONFIG_NAME)?; + if self.update_schema_scope_value( + schema_value, + config_value, + name, + None, + ) { + return Ok(schema_value); + } + } + } + } + } + } + Ok(right_value) + } + pub fn walk_identifier_with_ctx( &self, identifier: &'ctx ast::Identifier, diff --git a/kclvm/compiler/src/codegen/llvm/schema.rs b/kclvm/compiler/src/codegen/llvm/schema.rs index 24fe35198..5d53dc6eb 100644 --- a/kclvm/compiler/src/codegen/llvm/schema.rs +++ b/kclvm/compiler/src/codegen/llvm/schema.rs @@ -104,7 +104,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } ast::Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - let name = &target.node.names[0].node; + let name = &target.node.name.node; self.dict_merge(schema_value, name, value, 0, None); if is_in_if { in_if_names.push(name.to_string()); @@ -121,7 +121,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> { } ast::Stmt::AugAssign(aug_assign_stmt) => { let target = &aug_assign_stmt.target; - let name = &target.node.names[0].node; + let name = &target.node.name.node; self.dict_merge(schema_value, name, value, 0, None); if is_in_if { in_if_names.push(name.to_string()); diff --git a/kclvm/evaluator/src/lazy.rs b/kclvm/evaluator/src/lazy.rs index e911a1a72..9fb24f230 100644 --- a/kclvm/evaluator/src/lazy.rs +++ b/kclvm/evaluator/src/lazy.rs @@ -209,7 +209,7 @@ impl<'ctx> Evaluator<'ctx> { } ast::Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - let name = &target.node.names[0].node; + let name = &target.node.name.node; if is_in_if { in_if_names.push((name.to_string(), stmt.id.clone())); } else { @@ -219,7 +219,7 @@ impl<'ctx> Evaluator<'ctx> { } ast::Stmt::AugAssign(aug_assign_stmt) => { let target = &aug_assign_stmt.target; - let name = &target.node.names[0].node; + let name = &target.node.name.node; if is_in_if { in_if_names.push((name.to_string(), stmt.id.clone())); } else { diff --git a/kclvm/evaluator/src/module.rs b/kclvm/evaluator/src/module.rs index 50012e149..613c78524 100644 --- a/kclvm/evaluator/src/module.rs +++ b/kclvm/evaluator/src/module.rs @@ -60,14 +60,11 @@ impl<'ctx> Evaluator<'ctx> { } ast::Stmt::Assign(assign_stmt) => { for target in &assign_stmt.targets { - let names = &target.node.names; - if names.len() == 1 { - self.add_or_update_global_variable( - &names[0].node, - self.undefined_value(), - false, - ); - } + self.add_or_update_global_variable( + &target.node.get_name(), + self.undefined_value(), + false, + ); } } ast::Stmt::If(if_stmt) => { diff --git a/kclvm/evaluator/src/node.rs b/kclvm/evaluator/src/node.rs index cfb16a89b..70ea3b52b 100644 --- a/kclvm/evaluator/src/node.rs +++ b/kclvm/evaluator/src/node.rs @@ -132,7 +132,7 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { self.clear_local_vars(); // Set target vars. for name in &assign_stmt.targets { - self.add_target_var(&name.node.names[0].node) + self.add_target_var(&name.node.name.node) } // Load the right value let mut value = self.walk_expr(&assign_stmt.value)?; @@ -143,12 +143,12 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { if assign_stmt.targets.len() == 1 { // Store the single target let name = &assign_stmt.targets[0]; - self.walk_identifier_with_ctx(&name.node, &name.node.ctx, Some(value.clone()))?; + self.walk_target_with_value(&name.node, value.clone())?; } else { // Store multiple targets for name in &assign_stmt.targets { let value = self.value_deep_copy(&value); - self.walk_identifier_with_ctx(&name.node, &name.node.ctx, Some(value.clone()))?; + self.walk_target_with_value(&name.node, value.clone())?; } } // Pop target vars. @@ -159,15 +159,11 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { } fn walk_aug_assign_stmt(&self, aug_assign_stmt: &'ctx ast::AugAssignStmt) -> Self::Result { - self.add_target_var(&aug_assign_stmt.target.node.names[0].node); + self.add_target_var(&aug_assign_stmt.target.node.name.node); // Load the right value let right_value = self.walk_expr(&aug_assign_stmt.value)?; // Load the identifier value - let org_value = self.walk_identifier_with_ctx( - &aug_assign_stmt.target.node, - &ast::ExprContext::Load, - None, - )?; + let org_value = self.load_target(&aug_assign_stmt.target.node)?; let value = match aug_assign_stmt.op { ast::AugOp::Add => self.add(org_value, right_value), ast::AugOp::Sub => self.sub(org_value, right_value), @@ -185,12 +181,8 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { return Err(anyhow::anyhow!(kcl_error::INVALID_OPERATOR_MSG)); } }; - // Store the identifier value - self.walk_identifier_with_ctx( - &aug_assign_stmt.target.node, - &ast::ExprContext::Store, - Some(value.clone()), - )?; + // Store the target value + self.walk_target_with_value(&aug_assign_stmt.target.node, value.clone())?; self.pop_target_var(); Ok(value) } @@ -334,6 +326,7 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { fn walk_expr(&self, expr: &'ctx ast::Node) -> Self::Result { self.update_ctx_panic_info(expr); match &expr.node { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), @@ -1058,10 +1051,16 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> { } } + #[inline] fn walk_identifier(&self, identifier: &'ctx ast::Identifier) -> Self::Result { self.walk_identifier_with_ctx(identifier, &identifier.ctx, None) } + #[inline] + fn walk_target(&self, target: &'ctx ast::Target) -> Self::Result { + self.load_target(target) + } + fn walk_number_lit(&self, number_lit: &'ctx ast::NumberLit) -> Self::Result { match number_lit.value { ast::NumberLitValue::Int(int_value) => match &number_lit.binary_suffix { @@ -1226,6 +1225,79 @@ impl<'ctx> Evaluator<'ctx> { } } + pub fn walk_target_with_value( + &self, + target: &'ctx ast::Target, + right_value: ValueRef, + ) -> EvalResult { + let is_in_schema = self.is_in_schema(); + if target.paths.is_empty() { + let name = target.get_name(); + // Global variables + if self.scope_level() == GLOBAL_LEVEL { + self.add_or_update_global_variable(name, right_value.clone(), true); + // Lambda local variables. + } else if self.is_in_lambda() { + let value = right_value.clone(); + // schema frame in the lambda + if self.is_schema_scope() { + let is_local_var = self.is_local_var(name); + let value = right_value.clone(); + match (is_local_var, is_in_schema) { + (false, true) => self.update_schema_or_rule_scope_value(name, Some(&value)), + _ => self.add_variable(name, value), + } + } else { + // If variable exists in the scope and update it, if not, add it to the scope. + if !self.store_variable_in_current_scope(name, value.clone()) { + self.add_variable(name, self.undefined_value()); + self.store_variable(name, value); + } + } + } else { + let is_local_var = self.is_local_var(name); + let value = right_value.clone(); + match (is_local_var, is_in_schema) { + (false, true) => self.update_schema_or_rule_scope_value(name, Some(&value)), + _ => self.add_variable(name, value), + } + } + } else { + let name = target.get_name(); + // In KCL, we cannot modify global variables in other packages, + // so pkgpath is empty here. + let mut value = self.load_value("", &[name]); + // Convert `store a.b.c = 1` -> `%t = load &a; %t = load_attr %t %b; store_attr %t %c with 1` + for (i, path) in target.paths.iter().enumerate() { + let ctx = if i < target.paths.len() - 1 { + ast::ExprContext::Load + } else { + ast::ExprContext::Store + }; + match ctx { + ast::ExprContext::Load => { + value = self.load_target_path(&value, path)?; + } + ast::ExprContext::Store => { + self.store_target_path(&mut value, path, &right_value)?; + let is_local_var = self.is_local_var(name); + let is_in_lambda = self.is_in_lambda(); + // Set config value for the schema attribute if the attribute is in the schema and + // it is not a local variable in the lambda function. + if self.scope_level() >= INNER_LEVEL + && is_in_schema + && !is_in_lambda + && !is_local_var + { + self.update_schema_or_rule_scope_value(name, None); + } + } + } + } + } + Ok(right_value) + } + pub fn walk_identifier_with_ctx( &self, identifier: &'ctx ast::Identifier, diff --git a/kclvm/evaluator/src/scope.rs b/kclvm/evaluator/src/scope.rs index 2bb0aea8c..1bce530c0 100644 --- a/kclvm/evaluator/src/scope.rs +++ b/kclvm/evaluator/src/scope.rs @@ -5,10 +5,11 @@ use crate::{ }; use indexmap::{IndexMap, IndexSet}; use kclvm_ast::ast; +use kclvm_ast::walker::TypedResultWalker; use kclvm_runtime::{ValueRef, _kclvm_get_fn_ptr_by_name, MAIN_PKG_PATH}; use kclvm_sema::{builtin, plugin}; -use crate::{Evaluator, GLOBAL_LEVEL, INNER_LEVEL}; +use crate::{EvalResult, Evaluator, GLOBAL_LEVEL, INNER_LEVEL}; /// The evaluator scope. #[derive(Debug, Default)] @@ -496,52 +497,11 @@ impl<'ctx> Evaluator<'ctx> { return self.undefined_value(); } let name = names[0]; - // Get variable from the scope. - let get = |name: &str| { - match ( - self.is_in_schema(), - self.is_in_lambda(), - self.is_local_var(name), - ) { - // Get variable from the global lazy scope. - (false, false, false) => { - let variable = self.get_variable(name); - match self.resolve_variable_level(name) { - // Closure variable or local variables - Some(level) if level <= GLOBAL_LEVEL => self.get_value_from_lazy_scope( - &self.current_pkgpath(), - name, - &self.get_target_var(), - variable, - ), - // Schema closure or global variables - _ => variable, - } - } - // Get variable from the local or global scope. - (false, _, _) | (_, _, true) => self.get_variable(name), - // Get variable from the current schema scope. - (true, false, false) => self.get_variable_in_schema_or_rule(name), - // Get from local scope including lambda arguments, lambda variables, - // loop variables or global variables. - (true, true, _) => - // Get from local scope including lambda arguments, lambda variables, - // loop variables or global variables. - { - match self.resolve_variable_level(name) { - // Closure variable or local variables - Some(level) if level > GLOBAL_LEVEL => self.get_variable(name), - // Schema closure or global variables - _ => self.get_variable_in_schema_or_rule(name), - } - } - } - }; if names.len() == 1 { - get(name) + self.load_name(name) } else { let mut value = if pkgpath.is_empty() { - get(name) + self.load_name(name) } else { self.undefined_value() }; @@ -582,4 +542,97 @@ impl<'ctx> Evaluator<'ctx> { value } } + + /// Load global or local value from name. + pub fn load_name(&self, name: &str) -> ValueRef { + match ( + self.is_in_schema(), + self.is_in_lambda(), + self.is_local_var(name), + ) { + // Get variable from the global lazy scope. + (false, false, false) => { + let variable = self.get_variable(name); + match self.resolve_variable_level(name) { + // Closure variable or local variables + Some(level) if level <= GLOBAL_LEVEL => self.get_value_from_lazy_scope( + &self.current_pkgpath(), + name, + &self.get_target_var(), + variable, + ), + // Schema closure or global variables + _ => variable, + } + } + // Get variable from the local or global scope. + (false, _, _) | (_, _, true) => self.get_variable(name), + // Get variable from the current schema scope. + (true, false, false) => self.get_variable_in_schema_or_rule(name), + // Get from local scope including lambda arguments, lambda variables, + // loop variables or global variables. + (true, true, _) => + // Get from local scope including lambda arguments, lambda variables, + // loop variables or global variables. + { + match self.resolve_variable_level(name) { + // Closure variable or local variables + Some(level) if level > GLOBAL_LEVEL => self.get_variable(name), + // Schema closure or global variables + _ => self.get_variable_in_schema_or_rule(name), + } + } + } + } + + /// Load assignment target value. + pub fn load_target(&self, target: &'ctx ast::Target) -> EvalResult { + let mut value = self.load_name(target.get_name()); + for path in &target.paths { + match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + value = value.load_attr(attr); + } + ast::MemberOrIndex::Index(index) => { + let index = self.walk_expr(index)?; + value = value.bin_subscr(&index); + } + } + } + Ok(value) + } + + /// Load value from assignment target path. + pub fn load_target_path(&self, value: &ValueRef, path: &'ctx ast::MemberOrIndex) -> EvalResult { + Ok(match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + value.load_attr(attr) + } + ast::MemberOrIndex::Index(index) => { + let index = self.walk_expr(index)?; + value.bin_subscr(&index) + } + }) + } + + pub fn store_target_path( + &self, + value: &mut ValueRef, + path: &'ctx ast::MemberOrIndex, + right_value: &ValueRef, + ) -> EvalResult { + match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + self.dict_set_value(value, attr, &right_value); + } + ast::MemberOrIndex::Index(index) => { + let index = self.walk_expr(index)?; + value.bin_subscr_set(&mut self.runtime_ctx.borrow_mut(), &index, &right_value); + } + } + self.ok_result() + } } diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_5.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_5.snap new file mode 100644 index 000000000..e56d37d9b --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_5.snap @@ -0,0 +1,7 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- 1 +- 0 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_6.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_6.snap new file mode 100644 index 000000000..5a0777795 --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_6.snap @@ -0,0 +1,7 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- key: 1 +- key: 0 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_7.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_7.snap new file mode 100644 index 000000000..9b744ff8d --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__assign_stmt_7.snap @@ -0,0 +1,13 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- key: + key: + - 1 + - 0 +- key: + key: + - 0 + - 0 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_12.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_12.snap new file mode 100644 index 000000000..1f84c9b2b --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_12.snap @@ -0,0 +1,10 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- 1 +- 0 +- 0 +- 0 +- 0 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_13.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_13.snap new file mode 100644 index 000000000..1afd0a31d --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_13.snap @@ -0,0 +1,10 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- key: 2 +- key: 1 +- key: 1 +- key: 1 +- key: 1 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_14.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_14.snap new file mode 100644 index 000000000..eecfa14bb --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__aug_assign_stmt_14.snap @@ -0,0 +1,25 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +a: +- key: + key: + - 1 + - 0 +- key: + key: + - 0 + - 0 +- key: + key: + - 0 + - 0 +- key: + key: + - 0 + - 0 +- key: + key: + - 0 + - 0 diff --git a/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__if_stmt_6.snap b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__if_stmt_6.snap new file mode 100644 index 000000000..fe81f5423 --- /dev/null +++ b/kclvm/evaluator/src/snapshots/kclvm_evaluator__tests__if_stmt_6.snap @@ -0,0 +1,6 @@ +--- +source: evaluator/src/tests.rs +expression: "format!(\"{}\", evaluator.run().unwrap().1)" +--- +b: 1 +c: 1 diff --git a/kclvm/evaluator/src/tests.rs b/kclvm/evaluator/src/tests.rs index a4de7bd93..17630d48a 100644 --- a/kclvm/evaluator/src/tests.rs +++ b/kclvm/evaluator/src/tests.rs @@ -40,6 +40,18 @@ b = a + 1 evaluator_snapshot! {assign_stmt_4, r#"a: int = 1 b: int = a + 1 "#} +evaluator_snapshot! {assign_stmt_5, r#"_a = [0] * 2 +_a[0] = 1 +a = _a +"#} +evaluator_snapshot! {assign_stmt_6, r#"_a = [{"key": 0}] * 2 +_a[0].key = 1 +a = _a +"#} +evaluator_snapshot! {assign_stmt_7, r#"_a = [{key.key = [0] * 2}] * 2 +_a[0].key.key[0] = 1 +a = _a +"#} evaluator_snapshot! {aug_assign_stmt_0, r#"_a = 1 _a += 1 @@ -89,6 +101,18 @@ evaluator_snapshot! {aug_assign_stmt_11, r#"_a = 3 _a //= 2 a = _a "#} +evaluator_snapshot! {aug_assign_stmt_12, r#"_a = [0] * 5 +_a[0] += 1 +a = _a +"#} +evaluator_snapshot! {aug_assign_stmt_13, r#"_a = [{"key": 1}] * 5 +_a[0].key += 1 +a = _a +"#} +evaluator_snapshot! {aug_assign_stmt_14, r#"_a = [{key.key = [0, 0]}] * 5 +_a[0].key.key[0] += 1 +a = _a +"#} evaluator_snapshot! {assert_stmt_0, r#"assert True, "msg" a = 1 @@ -130,6 +154,15 @@ else: else: c = 3 "#} +evaluator_snapshot! {if_stmt_6, r#" +if False: + a = 1 +else: + if True: + b = 1 + if True: + c = 1 +"#} evaluator_snapshot! {import_stmt_0, r#"import math a = 1 diff --git a/kclvm/parser/src/parser/expr.rs b/kclvm/parser/src/parser/expr.rs index 11813bd7f..3b0b04155 100644 --- a/kclvm/parser/src/parser/expr.rs +++ b/kclvm/parser/src/parser/expr.rs @@ -7,12 +7,14 @@ use std::vec; use super::int::bytes_to_int; use super::Parser; +use anyhow::bail; use either::{self, Either}; -use kclvm_ast::node_ref; use crate::parser::precedence::Precedence; +use anyhow::Result; use compiler_base_error::unit_type::{TypeWithUnit, UnitUsize}; use kclvm_ast::ast::*; +use kclvm_ast::node_ref; use kclvm_ast::token; use kclvm_ast::token::{BinOpToken, DelimToken, TokenKind, VALID_SPACES_LENGTH}; use kclvm_span::symbol::kw; @@ -2428,4 +2430,79 @@ impl<'a> Parser<'a> { expr.into_missing_identifier().node } } + + /// Cast an expression into an assign target. + pub(crate) fn expr_as_assign_target(&self, expr: &NodeRef) -> Result { + let mut paths = self.expr_as_assign_target_paths(expr)?; + if paths.len() >= 1 { + let first = paths.remove(0); + match first { + MemberOrIndex::Member(member) => Ok(Target { + name: *member, + paths: paths.to_vec(), + pkgpath: "".to_string(), + }), + MemberOrIndex::Index(_) => bail!( + "'{}' is an illegal expression for assignment", + expr.node.get_expr_name() + ), + } + } else { + bail!( + "'{}' is an illegal expression for assignment", + expr.node.get_expr_name() + ); + } + } + + /// Cast an expression into an assign target paths. + pub(crate) fn expr_as_assign_target_paths( + &self, + expr: &NodeRef, + ) -> Result> { + match &expr.node { + Expr::Identifier(identifier) => Ok(self.identifier_as_assign_target_paths(identifier)), + Expr::Selector(selector) => { + if selector.has_question { + bail!("'{}' is an illegal expression for assignment, because the left-hand side of an assignment expression may not be an optional attribute access.", expr.node.get_expr_name()); + } else { + let mut value_paths = self.expr_as_assign_target_paths(&selector.value)?; + let mut attr_values = + self.identifier_as_assign_target_paths(&selector.attr.node); + value_paths.append(&mut attr_values); + Ok(value_paths) + } + } + Expr::Subscript(subscript) => { + if subscript.has_question { + bail!("'{}' is an illegal expression for assignment, because the left-hand side of an assignment expression may not be an optional subscript access.", expr.node.get_expr_name()); + } else { + let mut value_paths = self.expr_as_assign_target_paths(&subscript.value)?; + if let Some(index) = &subscript.index { + value_paths.push(MemberOrIndex::Index(index.clone())); + Ok(value_paths) + } else { + bail!("'{}' is an illegal expression for assignment, because the left-hand side of an assignment expression may not be a slice access.", expr.node.get_expr_name()); + } + } + } + _ => bail!( + "'{}' is an illegal expression for assignment", + expr.node.get_expr_name() + ), + } + } + + /// Cast a identifier into an assign target paths. + #[inline] + pub(crate) fn identifier_as_assign_target_paths( + &self, + identifier: &Identifier, + ) -> Vec { + identifier + .names + .iter() + .map(|i| MemberOrIndex::Member(Box::new(i.clone()))) + .collect() + } } diff --git a/kclvm/parser/src/parser/stmt.rs b/kclvm/parser/src/parser/stmt.rs index 3c60027e8..dc31323c6 100644 --- a/kclvm/parser/src/parser/stmt.rs +++ b/kclvm/parser/src/parser/stmt.rs @@ -193,7 +193,7 @@ impl<'a> Parser<'a> { fn parse_expr_or_assign_stmt(&mut self, is_in_schema_stmt: bool) -> Option> { let token = self.token; let mut targets = vec![self.parse_expr()]; - + let mut target_spans = vec![Span::new(token.span.lo(), self.prev_token.span.hi())]; let mut value_or_target = None; let mut type_annotation = None; let mut ty = None; @@ -226,33 +226,42 @@ impl<'a> Parser<'a> { } else if let TokenKind::BinOpEq(x) = self.token.kind { let op = AugOp::from(x); self.bump_token(self.token.kind); - - let value = self.parse_expr(); - let mut ident = self.expr_as_identifier(targets[0].clone(), token); - ident.ctx = ExprContext::Store; - - let t = node_ref!( - Stmt::AugAssign(AugAssignStmt { - target: Box::new(Node::node_with_pos(ident, targets[0].pos())), - value, - op, - }), - self.token_span_pos(token, self.prev_token) - ); - - self.skip_newlines(); - - return Some(t); + let target = self.expr_as_assign_target(&targets[0]); + match target { + Ok(target) => { + let value = self.parse_expr(); + let t = node_ref!( + Stmt::AugAssign(AugAssignStmt { + target: Box::new(Node::node_with_pos(target, targets[0].pos())), + value, + op, + }), + self.token_span_pos(token, self.prev_token) + ); + self.skip_newlines(); + return Some(t); + } + // 'expression' is an illegal expression for augmented assignment and drop the whole statement. + Err(err) => { + self.sess + .struct_span_error(&err.to_string(), target_spans[0]); + self.parse_expr(); + self.skip_newlines(); + return None; + } + } } while let TokenKind::Assign = self.token.kind { self.bump_token(TokenKind::Assign); - + let token = self.token; let expr = self.parse_expr(); + let expr_token = self.prev_token; if let Some(target) = value_or_target { targets.push(target); } - + // Put the `target = target = value` spans in the target_spans. + target_spans.push(Span::new(token.span.lo(), expr_token.span.hi())); value_or_target = Some(expr); } @@ -288,18 +297,16 @@ impl<'a> Parser<'a> { let targets = targets .iter() - .map(|expr| match &expr.node { - Expr::Identifier(x) => { - let mut x = x.clone(); - x.ctx = ExprContext::Store; - Box::new(Node::node_with_pos(x, expr.pos())) - } - _ => { + .enumerate() + .map(|(i, expr)| match self.expr_as_assign_target(expr) { + Ok(target) => Some(Box::new(Node::node_with_pos(target, expr.pos()))), + Err(err) => { self.sess - .struct_token_error(&[TokenKind::ident_value()], self.token); - Box::new(expr.into_missing_identifier()) + .struct_span_error(&err.to_string(), target_spans[i]); + None } }) + .flatten() .collect(); self.skip_newlines(); @@ -351,24 +358,22 @@ impl<'a> Parser<'a> { pos.3 = targets.last().unwrap().end_line; pos.4 = targets.last().unwrap().end_column; - let targets: Vec<_> = targets + let targets = targets .iter() - .map(|expr| match &expr.node { - Expr::Identifier(x) => { - let mut x = x.clone(); - x.ctx = ExprContext::Store; - Box::new(Node::node_with_pos(x, expr.pos())) - } - _ => { + .enumerate() + .map(|(i, expr)| match self.expr_as_assign_target(expr) { + Ok(target) => Some(Box::new(Node::node_with_pos(target, expr.pos()))), + Err(err) => { self.sess - .struct_token_error(&[TokenKind::ident_value()], self.token); - Box::new(expr.into_missing_identifier()) + .struct_span_error(&err.to_string(), target_spans[i]); + None } }) + .flatten() .collect(); Some(Box::new(Node::node_with_pos( Stmt::Assign(AssignStmt { - targets: targets.clone(), + targets, value: miss_expr, ty, }), @@ -1071,13 +1076,13 @@ impl<'a> Parser<'a> { if let Stmt::Assign(assign) = x.node.clone() { if assign.targets.len() == 1 { - let ident = assign.targets[0].clone().node; + let target = assign.targets[0].clone().node; if assign.ty.is_some() { body_body.push(node_ref!( Stmt::SchemaAttr(SchemaAttr { doc: "".to_string(), name: node_ref!( - ident.get_names().join("."), + target.get_name().to_string(), assign.targets[0].pos() ), ty: assign.ty.unwrap(), diff --git a/kclvm/parser/src/tests/error_recovery.rs b/kclvm/parser/src/tests/error_recovery.rs index fe61588e5..0dc571c0e 100644 --- a/kclvm/parser/src/tests/error_recovery.rs +++ b/kclvm/parser/src/tests/error_recovery.rs @@ -242,6 +242,14 @@ parse_module_snapshot! { assign_stmt_recovery_7, r#"a: () = 0"#} parse_module_snapshot! { assign_stmt_recovery_8, r#"a: () = 0"#} parse_module_snapshot! { assign_stmt_recovery_9, r#"a ++= 1"#} parse_module_snapshot! { assign_stmt_recovery_10, r#"a[0] -= 1"#} +parse_module_snapshot! { assign_stmt_recovery_11, r#"a[0].b -= 1"#} +parse_module_snapshot! { assign_stmt_recovery_12, r#"a.b[0] = 1"#} +parse_module_snapshot! { assign_stmt_recovery_13, r#"a().b = 1"#} +parse_module_snapshot! { assign_stmt_recovery_14, r#"a.b[1:2] = 1"#} +parse_module_snapshot! { assign_stmt_recovery_15, r#"a.b[1::2].c = 1"#} +parse_module_snapshot! { assign_stmt_recovery_16, r#"a.b[c.d].e = 1"#} +parse_module_snapshot! { assign_stmt_recovery_17, r#"a.b[1 + 1].e = 1"#} +parse_module_snapshot! { assign_stmt_recovery_18, r#"a.b[f()].e = 1"#} parse_module_snapshot! { assert_stmt_recovery_0, r#"assert"#} parse_module_snapshot! { assert_stmt_recovery_1, r#"assert a."#} parse_module_snapshot! { assert_stmt_recovery_2, r#"assert True,,, 'msg'"#} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__assign_stmt.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__assign_stmt.snap index 28e67a473..c2e9055ec 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__assign_stmt.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__assign_stmt.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\", r####\"a=123\"#### "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "hello.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "hello.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 1, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__basic_stmt.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__basic_stmt.snap index 84642f4ef..c5263f21d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__basic_stmt.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__basic_stmt.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\n# co "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "hello.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "hello.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 3, @@ -63,18 +61,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\n# co "targets": [ { "node": { - "names": [ - { - "node": "b", - "filename": "hello.k", - "line": 5, - "column": 0, - "end_line": 5, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "b", + "filename": "hello.k", + "line": 5, + "column": 0, + "end_line": 5, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 5, @@ -112,18 +108,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\n# co "targets": [ { "node": { - "names": [ - { - "node": "c", - "filename": "hello.k", - "line": 7, - "column": 0, - "end_line": 7, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "c", + "filename": "hello.k", + "line": 7, + "column": 0, + "end_line": 7, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 7, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_0.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_0.snap index d7cc9954f..319091997 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_0.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_0.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "hello.k", - "line": 2, - "column": 0, - "end_line": 2, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "hello.k", + "line": 2, + "column": 0, + "end_line": 2, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 2, @@ -63,18 +61,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "b", - "filename": "hello.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "b", + "filename": "hello.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 3, @@ -112,18 +108,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "_condition", - "filename": "hello.k", - "line": 4, - "column": 0, - "end_line": 4, - "end_column": 10 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_condition", + "filename": "hello.k", + "line": 4, + "column": 0, + "end_line": 4, + "end_column": 10 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 4, @@ -165,18 +159,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "_condition", - "filename": "hello.k", - "line": 5, - "column": 23, - "end_line": 5, - "end_column": 33 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_condition", + "filename": "hello.k", + "line": 5, + "column": 23, + "end_line": 5, + "end_column": 33 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 5, @@ -335,18 +327,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "_condition", - "filename": "hello.k", - "line": 6, - "column": 26, - "end_line": 6, - "end_column": 36 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_condition", + "filename": "hello.k", + "line": 6, + "column": 26, + "end_line": 6, + "end_column": 36 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 6, @@ -516,18 +506,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\na = "targets": [ { "node": { - "names": [ - { - "node": "condition", - "filename": "hello.k", - "line": 7, - "column": 0, - "end_line": 7, - "end_column": 9 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "condition", + "filename": "hello.k", + "line": 7, + "column": 0, + "end_line": 7, + "end_column": 9 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 7, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_1.snap index cdc8b4b70..d159e1068 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__ast__if_stmt_1.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_ast_json(\"hello.k\",\n r####\"\ndata "targets": [ { "node": { - "names": [ - { - "node": "data2", - "filename": "hello.k", - "line": 2, - "column": 0, - "end_line": 2, - "end_column": 5 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "data2", + "filename": "hello.k", + "line": 2, + "column": 0, + "end_line": 2, + "end_column": 5 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello.k", "line": 2, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_0.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_0.snap index de7843857..8f6eff69f 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_0.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_0.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 170 expression: "crate::tests::parsing_module_string(r#\"a = \"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -57,4 +54,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_10.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_10.snap index bc681b829..b45793928 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_10.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_10.snap @@ -12,10 +12,35 @@ Module { node: AugAssign( AugAssignStmt { target: Node { - node: Identifier { - names: [], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Index( + Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 0, + ), + }, + ), + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + ], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -50,4 +75,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_11.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_11.snap new file mode 100644 index 000000000..20489eadc --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_11.snap @@ -0,0 +1,87 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a[0].b -= 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: AugAssign( + AugAssignStmt { + target: Node { + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Index( + Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 0, + ), + }, + ), + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + Member( + Node { + node: "b", + filename: "", + line: 1, + column: 5, + end_line: 1, + end_column: 6, + }, + ), + ], + pkgpath: "", + }, + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 6, + }, + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 10, + end_line: 1, + end_column: 11, + }, + op: Sub, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 11, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_12.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_12.snap new file mode 100644 index 000000000..39573c11a --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_12.snap @@ -0,0 +1,89 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[0] = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [ + Node { + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Member( + Node { + node: "b", + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + Index( + Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 0, + ), + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + ), + ], + pkgpath: "", + }, + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 6, + }, + ], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 10, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_13.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_13.snap new file mode 100644 index 000000000..af11fd921 --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_13.snap @@ -0,0 +1,41 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a().b = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 8, + end_line: 1, + end_column: 9, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 9, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_14.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_14.snap new file mode 100644 index 000000000..9a756dd9c --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_14.snap @@ -0,0 +1,41 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[1:2] = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 11, + end_line: 1, + end_column: 12, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 12, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_15.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_15.snap new file mode 100644 index 000000000..9572b43f4 --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_15.snap @@ -0,0 +1,41 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[1::2].c = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 14, + end_line: 1, + end_column: 15, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 15, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_16.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_16.snap new file mode 100644 index 000000000..5986cb533 --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_16.snap @@ -0,0 +1,115 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[c.d].e = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [ + Node { + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Member( + Node { + node: "b", + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + Index( + Node { + node: Identifier( + Identifier { + names: [ + Node { + node: "c", + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + Node { + node: "d", + filename: "", + line: 1, + column: 6, + end_line: 1, + end_column: 7, + }, + ], + pkgpath: "", + ctx: Load, + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 7, + }, + ), + Member( + Node { + node: "e", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + ), + ], + pkgpath: "", + }, + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 10, + }, + ], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 13, + end_line: 1, + end_column: 14, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 14, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_17.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_17.snap new file mode 100644 index 000000000..0f4c80099 --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_17.snap @@ -0,0 +1,126 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[1 + 1].e = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [ + Node { + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Member( + Node { + node: "b", + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + Index( + Node { + node: Binary( + BinaryExpr { + left: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + op: Add, + right: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 8, + end_line: 1, + end_column: 9, + }, + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 9, + }, + ), + Member( + Node { + node: "e", + filename: "", + line: 1, + column: 11, + end_line: 1, + end_column: 12, + }, + ), + ], + pkgpath: "", + }, + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 12, + }, + ], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 15, + end_line: 1, + end_column: 16, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 16, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_18.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_18.snap new file mode 100644 index 000000000..c816ff096 --- /dev/null +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_18.snap @@ -0,0 +1,120 @@ +--- +source: parser/src/tests/error_recovery.rs +expression: "crate::tests::parsing_module_string(r#\"a.b[f()].e = 1\"#)" +--- +Module { + filename: "", + pkg: "", + doc: None, + name: "", + body: [ + Node { + node: Assign( + AssignStmt { + targets: [ + Node { + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [ + Member( + Node { + node: "b", + filename: "", + line: 1, + column: 2, + end_line: 1, + end_column: 3, + }, + ), + Index( + Node { + node: Call( + CallExpr { + func: Node { + node: Identifier( + Identifier { + names: [ + Node { + node: "f", + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + ], + pkgpath: "", + ctx: Load, + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + args: [], + keywords: [], + }, + ), + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 7, + }, + ), + Member( + Node { + node: "e", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + ), + ], + pkgpath: "", + }, + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 10, + }, + ], + value: Node { + node: NumberLit( + NumberLit { + binary_suffix: None, + value: Int( + 1, + ), + }, + ), + filename: "", + line: 1, + column: 13, + end_line: 1, + end_column: 14, + }, + ty: None, + }, + ), + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 14, + }, + ], + comments: [], +} diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_2.snap index c14a848ec..c0d2f3cfa 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_2.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 172 expression: "crate::tests::parsing_module_string(r#\"a: int =\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -68,4 +65,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_3.snap index ae525294e..666b30721 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_3.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 173 expression: "crate::tests::parsing_module_string(r#\"a: a = 1\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -86,4 +83,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_4.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_4.snap index 713264e42..9f974cf44 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_4.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_4.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 174 expression: "crate::tests::parsing_module_string(r#\"a:\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -66,4 +63,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_5.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_5.snap index a269227ee..34efcb2b2 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_5.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_5.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 175 expression: "crate::tests::parsing_module_string(r#\"a = b = \"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -35,19 +32,17 @@ Module { end_column: 1, }, Node { - node: Identifier { - names: [ - Node { - node: "b", - filename: "", - line: 1, - column: 4, - end_line: 1, - end_column: 5, - }, - ], + node: Target { + name: Node { + node: "b", + filename: "", + line: 1, + column: 4, + end_line: 1, + end_column: 5, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -78,4 +73,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_6.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_6.snap index 0a9b5bada..b7f3b05bf 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_6.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_6.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 176 expression: "crate::tests::parsing_module_string(r#\"a() = b. = c\"#)" --- Module { @@ -14,39 +13,28 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 3, - }, - Node { - node: Identifier { - names: [ - Node { - node: "b", - filename: "", - line: 1, - column: 6, - end_line: 1, - end_column: 7, - }, - Node { - node: "", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 9, - }, + node: Target { + name: Node { + node: "b", + filename: "", + line: 1, + column: 6, + end_line: 1, + end_column: 7, + }, + paths: [ + Member( + Node { + node: "", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 9, + }, + ), ], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -90,4 +78,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_7.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_7.snap index 80ef40aef..8bf85e696 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_7.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_7.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 177 expression: "crate::tests::parsing_module_string(r#\"a: () = 0\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -76,4 +73,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_8.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_8.snap index 40632b2db..8bf85e696 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_8.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_8.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 178 expression: "crate::tests::parsing_module_string(r#\"a: () = 0\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -76,4 +73,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_9.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_9.snap index cdf76703f..9d03b317d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_9.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__assign_stmt_recovery_9.snap @@ -7,47 +7,6 @@ Module { pkg: "", doc: None, name: "", - body: [ - Node { - node: AugAssign( - AugAssignStmt { - target: Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Store, - }, - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 3, - }, - value: Node { - node: NumberLit( - NumberLit { - binary_suffix: None, - value: Int( - 1, - ), - }, - ), - filename: "", - line: 1, - column: 6, - end_line: 1, - end_column: 7, - }, - op: Add, - }, - ), - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 7, - }, - ], + body: [], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_0.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_0.snap index cc0ed2331..057379397 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_0.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_0.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 303 expression: "crate::tests::parsing_module_string(r#\"a:(\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -82,4 +79,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_1.snap index e49b03b5b..c3c8d8e96 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_1.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 304 expression: "crate::tests::parsing_module_string(r#\"a:(i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -105,4 +102,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_10.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_10.snap index 73cb8778e..9feb547ef 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_10.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_10.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 313 expression: "crate::tests::parsing_module_string(r#\"a:({\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -105,4 +102,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_11.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_11.snap index 5cfbba9c7..6df6a93be 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_11.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_11.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 314 expression: "crate::tests::parsing_module_string(r#\"a:({i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -120,4 +117,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_12.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_12.snap index 0eb248a85..d16a4a19d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_12.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_12.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 315 expression: "crate::tests::parsing_module_string(r#\"a:({i:\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -120,4 +117,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_13.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_13.snap index 68ec7d35f..eaa9a0fff 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_13.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_13.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 316 expression: "crate::tests::parsing_module_string(r#\"a:({i:i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -135,4 +132,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_14.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_14.snap index 31246010e..4c9c34dc5 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_14.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_14.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 317 expression: "crate::tests::parsing_module_string(r#\"a:({i:int\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -122,4 +119,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_15.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_15.snap index 3731cbe38..4404f5c0c 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_15.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_15.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 318 expression: "crate::tests::parsing_module_string(r#\"a:({i:int]\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -130,4 +127,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_16.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_16.snap index 02ae0f14a..6a4d6fe27 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_16.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_16.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 319 expression: "crate::tests::parsing_module_string(r#\"a:({str:int]\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -117,4 +114,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_17.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_17.snap index 99eba5b4a..4416f2323 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_17.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_17.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 320 expression: "crate::tests::parsing_module_string(r#\"a:({str:int}\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -117,4 +114,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_18.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_18.snap index fd30dc8de..3a844ef56 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_18.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_18.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 321 expression: "crate::tests::parsing_module_string(r#\"a:({str:int} ->\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -125,4 +122,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_19.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_19.snap index fafafc948..8ec647cfe 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_19.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_19.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 322 expression: "crate::tests::parsing_module_string(r#\"a:({str:int}) -> i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -133,4 +130,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_2.snap index 9886a7c98..d3e0422bf 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_2.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 305 expression: "crate::tests::parsing_module_string(r#\"a:(int\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -92,4 +89,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_20.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_20.snap index 4643f67e5..6d1b1e3fb 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_20.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_20.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 323 expression: "crate::tests::parsing_module_string(r#\"a:(str|int) -> i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -131,4 +128,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_21.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_21.snap index b3ccd5a8a..add4ff92d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_21.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_21.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 324 expression: "crate::tests::parsing_module_string(r#\"a:(str|int, int) -> i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -141,4 +138,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_22.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_22.snap index 7cf0505a3..c8530dec9 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_22.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_22.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 325 expression: "crate::tests::parsing_module_string(r#\"a:(str|int, int|\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -138,4 +135,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_23.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_23.snap index 27c647d88..bb3ecd599 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_23.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_23.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 326 expression: "crate::tests::parsing_module_string(r#\"a:(str|int, int|) ->\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -154,4 +151,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_3.snap index 089985ad5..2fb839279 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_3.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 306 expression: "crate::tests::parsing_module_string(r#\"a:i)\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -81,4 +78,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_4.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_4.snap index 7090fb529..1ce3daeef 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_4.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_4.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 307 expression: "crate::tests::parsing_module_string(r#\"a:([i\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -110,4 +107,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_5.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_5.snap index dce820c2b..ab1f9884f 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_5.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_5.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 308 expression: "crate::tests::parsing_module_string(r#\"a:([i:\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -118,4 +115,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_6.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_6.snap index 1958b3b5d..792e25934 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_6.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_6.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 309 expression: "crate::tests::parsing_module_string(r#\"a:([i]\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -118,4 +115,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_7.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_7.snap index 0c72fe05e..3135b60f2 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_7.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_7.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 310 expression: "crate::tests::parsing_module_string(r#\"a:([int]\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -105,4 +102,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_8.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_8.snap index 98a37fc95..a31c8371d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_8.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_8.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 311 expression: "crate::tests::parsing_module_string(r#\"a:([int\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -97,4 +94,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_9.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_9.snap index 0105b2ad3..0e19ecb2d 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_9.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__fn_ty_annotation_recovery_9.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 312 expression: "crate::tests::parsing_module_string(r#\"a:({}\"#)" --- Module { @@ -14,19 +13,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 0, - end_line: 1, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 0, + end_line: 1, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -105,4 +102,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_0.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_0.snap index 2a542bb56..cd4937e56 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_0.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_0.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 199 expression: "crate::tests::parsing_module_string(r#\"if True a = 1\"#)" --- Module { @@ -16,20 +15,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 1, - column: 10, - end_line: 1, - end_column: 11, - }, - ], + targets: [], value: Node { node: NumberLit( NumberLit { @@ -79,4 +65,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_1.snap index 9521800ff..42e15e952 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_1.snap @@ -17,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -79,20 +77,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 1, - column: 25, - end_line: 1, - end_column: 26, - }, - ], + targets: [], value: Node { node: NumberLit( NumberLit { diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_2.snap index 0825e61de..e56ef7c74 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_2.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 201 expression: "crate::tests::parsing_module_string(r#\"if : a = 1\"#)" --- Module { @@ -18,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 5, - end_line: 1, - end_column: 6, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 5, + end_line: 1, + end_column: 6, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -86,4 +83,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_3.snap index 08649b203..df366c9dd 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_3.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 202 expression: "crate::tests::parsing_module_string(r#\"if True: a = 1 else b = 2\"#)" --- Module { @@ -18,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -80,20 +77,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 1, - column: 22, - end_line: 1, - end_column: 23, - }, - ], + targets: [], value: Node { node: NumberLit( NumberLit { @@ -130,4 +114,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_4.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_4.snap index 1919ee82f..f9533f5b9 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_4.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_4.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 203 expression: "crate::tests::parsing_module_string(r#\"if True: else: b = 2\"#)" --- Module { @@ -18,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "else", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 13, - }, - ], + node: Target { + name: Node { + node: "else", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 13, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -112,4 +109,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_8.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_8.snap index 81634ac43..a870f260e 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_8.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_8.snap @@ -17,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -79,20 +77,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 13, - end_line: 2, - end_column: 14, - }, - ], + targets: [], value: Node { node: NumberLit( NumberLit { diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_9.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_9.snap index 44c97c538..f9b49cdb6 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_9.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__if_stmt_recovery_9.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 209 expression: "crate::tests::parsing_module_string(r#\"if True: a = 1\nelse False: b = 1\"#)" --- Module { @@ -18,19 +17,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 1, - column: 9, - end_line: 1, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 1, + column: 9, + end_line: 1, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 1, @@ -80,20 +77,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 10, - end_line: 2, - end_column: 11, - }, - ], + targets: [], value: Node { node: NumberLit( NumberLit { @@ -154,4 +138,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_10.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_10.snap index 1b41e73ba..604699848 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_10.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_10.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 220 expression: "crate::tests::parsing_module_string(r#\"schema A:\n[str:]: []\"#)" --- Module { @@ -42,20 +41,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 6, - }, - ], + targets: [], value: Node { node: Missing( MissingExpr, @@ -91,4 +77,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_11.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_11.snap index dedaa1e66..3508d6663 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_11.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_11.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 222 expression: "crate::tests::parsing_module_string(r#\"schema A:\n[str]: str = \"#)" --- Module { @@ -42,20 +41,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 5, - }, - ], + targets: [], value: Node { node: Missing( MissingExpr, @@ -89,4 +75,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_12.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_12.snap index fd8aa72d7..cbf860fab 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_12.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_12.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 224 expression: "crate::tests::parsing_module_string(r#\"schema A:\n[str]: = \"#)" --- Module { @@ -42,20 +41,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 5, - }, - ], + targets: [], value: Node { node: Missing( MissingExpr, @@ -87,4 +73,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_13.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_13.snap index b20085b14..2b5561ebc 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_13.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_13.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 226 expression: "crate::tests::parsing_module_string(r#\"schema A:\n[str]: ''= \"#)" --- Module { @@ -42,20 +41,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 5, - }, - ], + targets: [], value: Node { node: Missing( MissingExpr, @@ -91,4 +77,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_17.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_17.snap index 9841b3f98..14dbf639f 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_17.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_17.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 234 expression: "crate::tests::parsing_module_string(r#\"schema A:\na: \"#)" --- Module { @@ -44,19 +43,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 2, + column: 0, + end_line: 2, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 2, @@ -96,4 +93,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_7.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_7.snap index a235208a7..657cae7ba 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_7.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_7.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 214 expression: "crate::tests::parsing_module_string(r#\"schema A:\na:: int\"#)" --- Module { @@ -44,19 +43,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 2, + column: 0, + end_line: 2, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 2, @@ -132,4 +129,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_8.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_8.snap index 4e7515c44..413bea2c2 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_8.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_8.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 216 expression: "crate::tests::parsing_module_string(r#\"schema A:\na: int =\"#)" --- Module { @@ -44,19 +43,17 @@ Module { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "a", - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 1, - }, - ], + node: Target { + name: Node { + node: "a", + filename: "", + line: 2, + column: 0, + end_line: 2, + end_column: 1, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 2, @@ -98,4 +95,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_9.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_9.snap index 7cc92559f..b54777efe 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_9.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__error_recovery__schema_stmt_recovery_9.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/error_recovery.rs -assertion_line: 218 expression: "crate::tests::parsing_module_string(r#\"schema A:\n[]: []\"#)" --- Module { @@ -42,20 +41,7 @@ Module { Node { node: Assign( AssignStmt { - targets: [ - Node { - node: Identifier { - names: [], - pkgpath: "", - ctx: Load, - }, - filename: "", - line: 2, - column: 0, - end_line: 2, - end_column: 2, - }, - ], + targets: [], value: Node { node: Missing( MissingExpr, @@ -91,4 +77,3 @@ Module { ], comments: [], } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__expr__lambda_expr_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__expr__lambda_expr_3.snap index db438a698..e8f968626 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__expr__lambda_expr_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__expr__lambda_expr_3.snap @@ -1,6 +1,5 @@ --- source: parser/src/tests/expr.rs -assertion_line: 82 expression: "crate::tests::parsing_expr_string(r####\"lambda {\n if True:\n _a = 1\n else:\n _a = 2\n _a\n}\"####)" --- Node { @@ -17,19 +16,17 @@ Node { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "_a", - filename: "", - line: 3, - column: 8, - end_line: 3, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "_a", + filename: "", + line: 3, + column: 8, + end_line: 3, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 3, @@ -81,19 +78,17 @@ Node { AssignStmt { targets: [ Node { - node: Identifier { - names: [ - Node { - node: "_a", - filename: "", - line: 5, - column: 8, - end_line: 5, - end_column: 10, - }, - ], + node: Target { + name: Node { + node: "_a", + filename: "", + line: 5, + column: 8, + end_line: 5, + end_column: 10, + }, + paths: [], pkgpath: "", - ctx: Store, }, filename: "", line: 5, @@ -181,4 +176,3 @@ Node { end_line: 7, end_column: 1, } - diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_2.snap index e24e18208..f5dca473f 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_2.snap @@ -94,18 +94,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_x", - "filename": "assert-02.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 2 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_x", + "filename": "assert-02.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 2 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-02.k", "line": 3, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_3.snap index 59faefaf9..945e0e24c 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_3.snap @@ -122,18 +122,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-03.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_x", - "filename": "assert-03.k", - "line": 4, - "column": 4, - "end_line": 4, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_x", + "filename": "assert-03.k", + "line": 4, + "column": 4, + "end_line": 4, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-03.k", "line": 4, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_0.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_0.snap index 0495e654d..a79d07a3c 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_0.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_0.snap @@ -104,18 +104,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-if-0.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_x", - "filename": "assert-if-0.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 2 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_x", + "filename": "assert-if-0.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 2 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-if-0.k", "line": 3, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_1.snap index 110f9d077..eeb5a50bf 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_1.snap @@ -114,18 +114,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-if-1.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_x", - "filename": "assert-if-1.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 2 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_x", + "filename": "assert-if-1.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 2 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-if-1.k", "line": 3, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_2.snap index 592458159..b8a3bd858 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assert_if_2.snap @@ -133,18 +133,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-if-2.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_x", - "filename": "assert-if-2.k", - "line": 4, - "column": 4, - "end_line": 4, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_x", + "filename": "assert-if-2.k", + "line": 4, + "column": 4, + "end_line": 4, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-if-2.k", "line": 4, @@ -297,18 +295,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assert-if-2.k\")" "targets": [ { "node": { - "names": [ - { - "node": "data", - "filename": "assert-if-2.k", - "line": 7, - "column": 0, - "end_line": 7, - "end_column": 4 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "data", + "filename": "assert-if-2.k", + "line": 7, + "column": 0, + "end_line": 7, + "end_column": 4 + }, + "paths": [], + "pkgpath": "" }, "filename": "assert-if-2.k", "line": 7, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assign_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assign_1.snap index 56467d8a7..d59a6e793 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assign_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__assign_1.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assign-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "assign-01.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "assign-01.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "assign-01.k", "line": 1, @@ -63,18 +61,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assign-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "b", - "filename": "assign-01.k", - "line": 2, - "column": 0, - "end_line": 2, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "b", + "filename": "assign-01.k", + "line": 2, + "column": 0, + "end_line": 2, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "assign-01.k", "line": 2, @@ -138,18 +134,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/assign-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "c", - "filename": "assign-01.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "c", + "filename": "assign-01.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "assign-01.k", "line": 3, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_1.snap index af4a785c8..43e25d6e6 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_1.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/config_expr-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "config", - "filename": "config_expr-01.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "config", + "filename": "config_expr-01.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "config_expr-01.k", "line": 1, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_2.snap index 94dd32d33..ddbe3a471 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_2.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/config_expr-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "config", - "filename": "config_expr-02.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "config", + "filename": "config_expr-02.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "config_expr-02.k", "line": 1, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_3.snap index b47332dbf..e322721d3 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_3.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/config_expr-03.k\")" "targets": [ { "node": { - "names": [ - { - "node": "config", - "filename": "config_expr-03.k", - "line": 3, - "column": 0, - "end_line": 3, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "config", + "filename": "config_expr-03.k", + "line": 3, + "column": 0, + "end_line": 3, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "config_expr-03.k", "line": 3, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_4.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_4.snap index df3482775..3f774c6f9 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_4.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__config_expr_4.snap @@ -278,18 +278,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/config_expr-04.k\")" "targets": [ { "node": { - "names": [ - { - "node": "_main", - "filename": "config_expr-04.k", - "line": 13, - "column": 0, - "end_line": 13, - "end_column": 5 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "_main", + "filename": "config_expr-04.k", + "line": 13, + "column": 0, + "end_line": 13, + "end_column": 5 + }, + "paths": [], + "pkgpath": "" }, "filename": "config_expr-04.k", "line": 13, @@ -504,18 +502,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/config_expr-04.k\")" "targets": [ { "node": { - "names": [ - { - "node": "config", - "filename": "config_expr-04.k", - "line": 19, - "column": 0, - "end_line": 19, - "end_column": 6 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "config", + "filename": "config_expr-04.k", + "line": 19, + "column": 0, + "end_line": 19, + "end_column": 6 + }, + "paths": [], + "pkgpath": "" }, "filename": "config_expr-04.k", "line": 19, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__hello_win.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__hello_win.snap index 760a592b0..4c1b0cbcf 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__hello_win.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__hello_win.snap @@ -90,18 +90,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/hello_win.k\")" "targets": [ { "node": { - "names": [ - { - "node": "x0", - "filename": "hello_win.k", - "line": 5, - "column": 0, - "end_line": 5, - "end_column": 2 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "x0", + "filename": "hello_win.k", + "line": 5, + "column": 0, + "end_line": 5, + "end_column": 2 + }, + "paths": [], + "pkgpath": "" }, "filename": "hello_win.k", "line": 5, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_1.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_1.snap index b5c56d05a..022175f39 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_1.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_1.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "if-01.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "if-01.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-01.k", "line": 1, @@ -67,18 +65,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-01.k\")" "targets": [ { "node": { - "names": [ - { - "node": "bbb", - "filename": "if-01.k", - "line": 4, - "column": 4, - "end_line": 4, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "bbb", + "filename": "if-01.k", + "line": 4, + "column": 4, + "end_line": 4, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-01.k", "line": 4, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_2.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_2.snap index eb9612718..8bd23ab8b 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_2.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_2.snap @@ -14,18 +14,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "if-02.k", - "line": 1, - "column": 0, - "end_line": 1, - "end_column": 1 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "if-02.k", + "line": 1, + "column": 0, + "end_line": 1, + "end_column": 1 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 1, @@ -67,18 +65,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "bbb", - "filename": "if-02.k", - "line": 4, - "column": 4, - "end_line": 4, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "bbb", + "filename": "if-02.k", + "line": 4, + "column": 4, + "end_line": 4, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 4, @@ -144,18 +140,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "ccc", - "filename": "if-02.k", - "line": 6, - "column": 4, - "end_line": 6, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "ccc", + "filename": "if-02.k", + "line": 6, + "column": 4, + "end_line": 6, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 6, @@ -247,18 +241,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "ddd", - "filename": "if-02.k", - "line": 8, - "column": 4, - "end_line": 8, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "ddd", + "filename": "if-02.k", + "line": 8, + "column": 4, + "end_line": 8, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 8, @@ -346,18 +338,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "eee", - "filename": "if-02.k", - "line": 10, - "column": 4, - "end_line": 10, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "eee", + "filename": "if-02.k", + "line": 10, + "column": 4, + "end_line": 10, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 10, @@ -395,18 +385,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-02.k\")" "targets": [ { "node": { - "names": [ - { - "node": "fff", - "filename": "if-02.k", - "line": 11, - "column": 4, - "end_line": 11, - "end_column": 7 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "fff", + "filename": "if-02.k", + "line": 11, + "column": 4, + "end_line": 11, + "end_column": 7 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-02.k", "line": 11, diff --git a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_3.snap b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_3.snap index d1db8d1b4..20cd7d244 100644 --- a/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_3.snap +++ b/kclvm/parser/src/tests/snapshots/kclvm_parser__tests__file__if_3.snap @@ -18,18 +18,16 @@ expression: "crate::tests::parsing_file_string(\"testdata/if-03.k\")" "targets": [ { "node": { - "names": [ - { - "node": "a", - "filename": "if-03.k", - "line": 1, - "column": 9, - "end_line": 1, - "end_column": 10 - } - ], - "pkgpath": "", - "ctx": "Store" + "name": { + "node": "a", + "filename": "if-03.k", + "line": 1, + "column": 9, + "end_line": 1, + "end_column": 10 + }, + "paths": [], + "pkgpath": "" }, "filename": "if-03.k", "line": 1, diff --git a/kclvm/query/src/node.rs b/kclvm/query/src/node.rs index 2dba35a95..3439db732 100644 --- a/kclvm/query/src/node.rs +++ b/kclvm/query/src/node.rs @@ -60,7 +60,7 @@ impl<'ctx> MutSelfMutWalker<'ctx> for AstNodeMover { } for target in assign_stmt.targets.iter_mut() { - self.walk_identifier(&mut target.node) + self.walk_target(&mut target.node) } self.walk_expr(&mut assign_stmt.value.node); walk_if_mut!(self, walk_type, assign_stmt.ty) @@ -72,7 +72,7 @@ impl<'ctx> MutSelfMutWalker<'ctx> for AstNodeMover { aug_assign_stmt.value.line += self.line_offset as u64; aug_assign_stmt.value.end_line += self.line_offset as u64; - self.walk_identifier(&mut aug_assign_stmt.target.node); + self.walk_target(&mut aug_assign_stmt.target.node); self.walk_expr(&mut aug_assign_stmt.value.node); } fn walk_assert_stmt(&mut self, assert_stmt: &'ctx mut ast::AssertStmt) { @@ -672,21 +672,6 @@ impl<'ctx> MutSelfMutWalker<'ctx> for AstNodeMover { self.walk_expr(&mut compare.left.node); walk_list_mut!(self, walk_expr, compare.comparators); } - fn walk_identifier(&mut self, identifier: &'ctx mut ast::Identifier) { - // Nothing to do. - let _ = identifier; - } - fn walk_number_lit(&mut self, number_lit: &'ctx mut ast::NumberLit) { - let _ = number_lit; - } - fn walk_string_lit(&mut self, string_lit: &'ctx mut ast::StringLit) { - // Nothing to do. - let _ = string_lit; - } - fn walk_name_constant_lit(&mut self, name_constant_lit: &'ctx mut ast::NameConstantLit) { - // Nothing to do. - let _ = name_constant_lit; - } fn walk_joined_string(&mut self, joined_string: &'ctx mut ast::JoinedString) { joined_string.values.iter_mut().for_each(|v| { v.line += self.line_offset as u64; @@ -701,14 +686,6 @@ impl<'ctx> MutSelfMutWalker<'ctx> for AstNodeMover { self.walk_expr(&mut formatted_value.value.node); } - fn walk_comment(&mut self, comment: &'ctx mut ast::Comment) { - // Nothing to do. - let _ = comment; - } - fn walk_missing_expr(&mut self, missing_expr: &'ctx mut ast::MissingExpr) { - // Nothing to do. - let _ = missing_expr; - } fn walk_module(&mut self, module: &'ctx mut ast::Module) { module.comments.iter_mut().for_each(|c| { c.line += self.line_offset as u64; @@ -745,6 +722,7 @@ impl<'ctx> MutSelfMutWalker<'ctx> for AstNodeMover { } fn walk_expr(&mut self, expr: &'ctx mut ast::Expr) { match expr { + ast::Expr::Target(target) => self.walk_target(target), ast::Expr::Identifier(identifier) => self.walk_identifier(identifier), ast::Expr::Unary(unary_expr) => self.walk_unary_expr(unary_expr), ast::Expr::Binary(binary_expr) => self.walk_binary_expr(binary_expr), diff --git a/kclvm/query/src/override.rs b/kclvm/query/src/override.rs index 350bc2ccf..9dfd0b823 100644 --- a/kclvm/query/src/override.rs +++ b/kclvm/query/src/override.rs @@ -3,12 +3,12 @@ use std::collections::HashSet; use anyhow::{anyhow, Result}; use compiler_base_macros::bug; -use kclvm_ast::ast; use kclvm_ast::config::try_get_config_expr_mut; use kclvm_ast::path::get_key_path; use kclvm_ast::walk_list_mut; use kclvm_ast::walker::MutSelfMutWalker; use kclvm_ast::MAIN_PKG; +use kclvm_ast::{ast, path::get_target_path}; use kclvm_ast_pretty::print_ast_module; use kclvm_parser::parse_expr; use kclvm_sema::pre_process::{fix_config_expr_nest_attr, transform_multi_assign}; @@ -323,11 +323,8 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { module.body.iter_mut().for_each(|stmt| { if let ast::Stmt::Assign(assign_stmt) = &mut stmt.node { if assign_stmt.targets.len() == 1 && self.field_paths.len() == 0 { - let target = - &Some(Box::new(ast::Node::dummy_node(ast::Expr::Identifier( - assign_stmt.targets.get(0).unwrap().node.clone(), - )))); - let target = get_key_path(target); + let target = assign_stmt.targets.get(0).unwrap().node.clone(); + let target = get_target_path(&target); if target == self.target_id { let item = assign_stmt.value.clone(); @@ -372,11 +369,7 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { module.body.retain(|stmt| { if let ast::Stmt::Assign(assign_stmt) = &stmt.node { if assign_stmt.targets.len() == 1 && self.field_paths.len() == 0 { - let target = - &Some(Box::new(ast::Node::dummy_node(ast::Expr::Identifier( - assign_stmt.targets.get(0).unwrap().node.clone(), - )))); - let target = get_key_path(target); + let target = get_target_path(&assign_stmt.targets.get(0).unwrap().node); if target == self.target_id { self.has_override = true; return false; @@ -433,9 +426,9 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { match &self.operation { ast::ConfigEntryOperation::Override => { let assign = ast::AssignStmt { - targets: vec![Box::new(ast::Node::dummy_node(ast::Identifier { - names: vec![ast::Node::dummy_node(self.target_id.clone())], - ctx: ast::ExprContext::Store, + targets: vec![Box::new(ast::Node::dummy_node(ast::Target { + name: ast::Node::dummy_node(self.target_id.clone()), + paths: vec![], pkgpath: "".to_string(), }))], ty: None, @@ -467,11 +460,9 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { Err(_) => { let stmt = ast::AssignStmt { targets: vec![Box::new(ast::Node::dummy_node( - ast::Identifier { - names: vec![ast::Node::dummy_node( - self.target_id.clone(), - )], - ctx: ast::ExprContext::Store, + ast::Target { + name: ast::Node::dummy_node(self.target_id.clone()), + paths: vec![], pkgpath: "".to_string(), }, ))], @@ -486,9 +477,9 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { } ast::ConfigEntryOperation::Insert => { let stmt = ast::AugAssignStmt { - target: Box::new(ast::Node::dummy_node(ast::Identifier { - names: vec![ast::Node::dummy_node(self.target_id.clone())], - ctx: ast::ExprContext::Store, + target: Box::new(ast::Node::dummy_node(ast::Target { + name: ast::Node::dummy_node(self.target_id.clone()), + paths: vec![], pkgpath: "".to_string(), })), op: ast::AugOp::Add, @@ -534,10 +525,10 @@ impl<'ctx> MutSelfMutWalker<'ctx> for OverrideTransformer { if let ast::Expr::Schema(_) | ast::Expr::Config(_) = &assign_stmt.value.node { self.override_target_count = 0; for target in &assign_stmt.targets { - if target.node.names.len() != 1 { + if !target.node.paths.is_empty() { continue; } - if target.node.names[0].node != self.target_id { + if target.node.name.node != self.target_id { continue; } self.override_target_count += 1; diff --git a/kclvm/query/src/selector.rs b/kclvm/query/src/selector.rs index 8ba5318fe..6914c66e8 100644 --- a/kclvm/query/src/selector.rs +++ b/kclvm/query/src/selector.rs @@ -2,7 +2,7 @@ use crate::r#override::build_expr_from_string; use super::util::{invalid_symbol_selector_spec_error, split_field_path}; use anyhow::Result; -use kclvm_ast::ast; +use kclvm_ast::{ast, path::get_target_path}; use kclvm_error::diagnostic::Errors; use kclvm_parser::ParseSession; use serde::{Deserialize, Serialize}; @@ -359,14 +359,11 @@ impl<'ctx> MutSelfWalker for Selector { "".to_string() }; // The length of name for variable in top level is 1 - if assign_stmt.targets.len() == 1 { - let target = &assign_stmt.targets[0]; - let target = &Some(Box::new(ast::Node::dummy_node(ast::Expr::Identifier( - target.node.clone(), - )))); - let key = get_key_path(&target); + for target in &assign_stmt.targets { + let key = get_target_path(&target.node); + let mut variable = variable.clone(); variable.name = key.to_string(); - variable.type_name = type_name; + variable.type_name = type_name.clone(); variable.op_sym = ast::ConfigEntryOperation::Override.symbol().to_string(); self.switch_top_variable(variable.clone()); self.push_variable(variable); @@ -375,20 +372,17 @@ impl<'ctx> MutSelfWalker for Selector { } } else { // Compare the target with the spec - if assign_stmt.targets.len() == 1 { - let target = &assign_stmt.targets[0]; - let target = &Some(Box::new(ast::Node::dummy_node(ast::Expr::Identifier( - target.node.clone(), - )))); - let target = get_key_path(target); + for target in &assign_stmt.targets { + let target = get_target_path(&target.node); let selector = self.inner.pop_front(); if let Some(selector) = selector { - if selector == target.to_string() { + if selector == target { let type_name = if let ast::Expr::Schema(schema) = &assign_stmt.value.node { schema.name.node.get_name() } else { "".to_string() }; + let mut variable = variable.clone(); variable.name = selector.to_string(); variable.type_name = type_name; variable.op_sym = ast::ConfigEntryOperation::Override.symbol().to_string(); diff --git a/kclvm/runtime/src/_kclvm.bc b/kclvm/runtime/src/_kclvm.bc index 2c3c25798572c0157b7819d5f26444e332c91180..e6ed679004714d6ca99e8dd2ba51520f7950c6af 100644 GIT binary patch delta 474 zcmbPIc%X2C3ghIBs*5D+6TdPEFdzUk&&r5PCtfgcAcPti+d@(^dl+RI7!iU72PSZt z^7imGAcPns5coDM#k{Fvr(7_dj7a2kJ*2Bbs7N5Ja0>k2( ztcVf@7MLOih64=FT9KxUSkT<}I4gt`%^M%Cb_gjTG%^5fUAiVv)d5Ke=(ze%k;&c- zNMb-wOx=ELD!O0GdNmlC5Xur76hnVVg)*VJ?6>JMbeC!7#MmQ+8_)wn(kxwZatsVd zl7QxIHjw_uB;c&eBE`qT4CFu4R`}EKce0(FxcFYC9)75eu{;b66WJITgqWw4ZqAWw cli(^YO)5?Z<7~7BrVV$o4^Z*|Y0A>X6I=dO*dDLu9HA14GBr&5qKH%y!JW zEK+ u64 { "kclvm_value_slice_option" => crate::kclvm_value_slice_option as *const () as u64, "kclvm_value_subscr" => crate::kclvm_value_subscr as *const () as u64, "kclvm_value_subscr_option" => crate::kclvm_value_subscr_option as *const () as u64, + "kclvm_value_subscr_set" => crate::kclvm_value_subscr_set as *const () as u64, "kclvm_value_to_json_value" => crate::kclvm_value_to_json_value as *const () as u64, "kclvm_value_to_json_value_with_null" => { crate::kclvm_value_to_json_value_with_null as *const () as u64 diff --git a/kclvm/runtime/src/_kclvm_api_spec.rs b/kclvm/runtime/src/_kclvm_api_spec.rs index 93defc117..326c2d554 100644 --- a/kclvm/runtime/src/_kclvm_api_spec.rs +++ b/kclvm/runtime/src/_kclvm_api_spec.rs @@ -566,6 +566,10 @@ // api-spec(c): kclvm_value_ref_t* kclvm_value_subscr(kclvm_context_t* ctx, kclvm_value_ref_t* a, kclvm_value_ref_t* b); // api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_subscr(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %a, %kclvm_value_ref_t* %b); +// api-spec: kclvm_value_subscr_set +// api-spec(c): void kclvm_value_subscr_set(kclvm_context_t* ctx, kclvm_value_ref_t* p, kclvm_value_ref_t* index, kclvm_value_ref_t* val); +// api-spec(llvm): declare void @kclvm_value_subscr_set(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %p, %kclvm_value_ref_t* %index, %kclvm_value_ref_t* %val); + // api-spec: kclvm_value_subscr_option // api-spec(c): kclvm_value_ref_t* kclvm_value_subscr_option(kclvm_context_t* ctx, kclvm_value_ref_t* a, kclvm_value_ref_t* b); // api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_subscr_option(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %a, %kclvm_value_ref_t* %b); diff --git a/kclvm/runtime/src/value/api.rs b/kclvm/runtime/src/value/api.rs index 25c694d01..8c9f693ca 100644 --- a/kclvm/runtime/src/value/api.rs +++ b/kclvm/runtime/src/value/api.rs @@ -1898,6 +1898,21 @@ pub unsafe extern "C" fn kclvm_value_subscr( a.bin_subscr(b).into_raw(mut_ptr_as_ref(ctx)) } +#[no_mangle] +#[runtime_fn] +pub unsafe extern "C" fn kclvm_value_subscr_set( + ctx: *mut kclvm_context_t, + p: *mut kclvm_value_ref_t, + index: *const kclvm_value_ref_t, + val: *const kclvm_value_ref_t, +) { + let ctx = mut_ptr_as_ref(ctx); + let p = mut_ptr_as_ref(p); + let index = ptr_as_ref(index); + let val = ptr_as_ref(val); + p.bin_subscr_set(ctx, index, val); +} + #[no_mangle] #[runtime_fn] pub unsafe extern "C" fn kclvm_value_subscr_option( diff --git a/kclvm/runtime/src/value/val_as_val.rs b/kclvm/runtime/src/value/val_as_val.rs index a6cdeb92e..f118822fa 100644 --- a/kclvm/runtime/src/value/val_as_val.rs +++ b/kclvm/runtime/src/value/val_as_val.rs @@ -19,6 +19,14 @@ impl ValueRef { } } + #[inline] + pub fn must_as_strict_int(&self) -> i64 { + match *self.rc.borrow() { + Value::int_value(ref v) => *v, + _ => panic!("invalid int value"), + } + } + #[inline] pub fn as_float(&self) -> f64 { match *self.rc.borrow() { diff --git a/kclvm/runtime/src/value/val_bin.rs b/kclvm/runtime/src/value/val_bin.rs index fe2e07767..38fb862ad 100644 --- a/kclvm/runtime/src/value/val_bin.rs +++ b/kclvm/runtime/src/value/val_bin.rs @@ -135,7 +135,7 @@ impl ValueRef { let mut list = ListValue::default(); for _ in 0..(*b as usize) { for x in a.values.iter() { - list.values.push(x.clone()); + list.values.push(x.deep_copy()); } } Self::from(Value::list_value(Box::new(list))) @@ -144,7 +144,7 @@ impl ValueRef { let mut list = ListValue::default(); for _ in 0..(*b as usize) { for x in a.values.iter() { - list.values.push(x.clone()); + list.values.push(x.deep_copy()); } } Self::from(Value::list_value(Box::new(list))) @@ -298,11 +298,7 @@ impl ValueRef { (Value::str_value(a), Value::int_value(b)) => { let str_len = a.chars().count(); let index = *b; - let index = if index < 0 { - (index + str_len as i64) as usize - } else { - index as usize - }; + let index = must_normalize_index(index as i32, str_len); if index < a.len() { let ch = a.chars().nth(index).unwrap(); Self::str(ch.to_string().as_ref()) @@ -312,11 +308,7 @@ impl ValueRef { } (Value::list_value(a), Value::int_value(b)) => { let index = *b; - let index = if index < 0 { - (index + a.values.len() as i64) as usize - } else { - index as usize - }; + let index = must_normalize_index(index as i32, a.values.len()); if index < a.values.len() { a.values[index].clone() } else { @@ -347,6 +339,21 @@ impl ValueRef { Self::none() } } + + pub fn bin_subscr_set(&mut self, ctx: &mut Context, x: &Self, v: &Self) { + if self.is_list() && x.is_int() { + self.list_set_value(x, v); + } else if self.is_config() && x.is_str() { + let key = x.as_str(); + self.dict_set_value(ctx, &key, v); + } else { + panic!( + "'{}' object is not subscriptable with '{}'", + self.type_str(), + x.type_str() + ); + } + } } #[cfg(test)] diff --git a/kclvm/runtime/src/value/val_list.rs b/kclvm/runtime/src/value/val_list.rs index 3f4399572..9b9f11238 100644 --- a/kclvm/runtime/src/value/val_list.rs +++ b/kclvm/runtime/src/value/val_list.rs @@ -103,6 +103,13 @@ impl ValueRef { } } + /// Set list element value `v` with the index `i`. + pub fn list_set_value(&mut self, i: &Self, v: &Self) { + let index = i.must_as_strict_int(); + let index = must_normalize_index(index as i32, self.len()); + self.list_must_set(index, v); + } + pub fn list_set(&mut self, i: usize, v: &Self) { match &mut *self.rc.borrow_mut() { Value::list_value(list) => { diff --git a/kclvm/runtime/src/value/val_str.rs b/kclvm/runtime/src/value/val_str.rs index f961adceb..f9f2c9766 100644 --- a/kclvm/runtime/src/value/val_str.rs +++ b/kclvm/runtime/src/value/val_str.rs @@ -77,14 +77,6 @@ impl ValueRef { _ => panic!("Invalid str object in str len"), } } - pub fn str_resize(&mut self, n: usize) { - match &mut *self.rc.borrow_mut() { - Value::str_value(str) => { - *str = "?".repeat(n); - } - _ => panic!("Invalid str object in str resize"), - } - } pub fn str_lower(&self) -> ValueRef { match &*self.rc.borrow() { diff --git a/kclvm/sema/src/advanced_resolver/node.rs b/kclvm/sema/src/advanced_resolver/node.rs index e58aa43fd..32fa0411e 100644 --- a/kclvm/sema/src/advanced_resolver/node.rs +++ b/kclvm/sema/src/advanced_resolver/node.rs @@ -89,11 +89,8 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { fn walk_assign_stmt(&mut self, assign_stmt: &'ctx ast::AssignStmt) -> Self::Result { for target in &assign_stmt.targets { - if target.node.names.is_empty() { - continue; - } self.ctx.maybe_def = true; - self.walk_identifier_expr_with_hint(target, assign_stmt.ty.is_none())?; + self.walk_target_expr_with_hint(target, assign_stmt.ty.is_none())?; self.ctx.maybe_def = false; } self.walk_type_expr(assign_stmt.ty.as_ref().map(|ty| ty.as_ref()))?; @@ -103,7 +100,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx ast::AugAssignStmt) -> Self::Result { self.ctx.maybe_def = true; - self.walk_identifier_expr(&aug_assign_stmt.target)?; + self.walk_target_expr(&aug_assign_stmt.target)?; self.ctx.maybe_def = false; self.expr(&aug_assign_stmt.value)?; Ok(None) @@ -830,6 +827,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { Ok(symbol_ref) } + fn walk_target(&mut self, target: &'ctx ast::Target) -> Self::Result { + let symbol_ref = self.resolve_target(&target)?; + Ok(symbol_ref) + } + fn walk_number_lit(&mut self, _number_lit: &'ctx ast::NumberLit) -> Self::Result { Ok(None) } @@ -974,10 +976,10 @@ impl<'ctx> AdvancedResolver<'ctx> { &first_name.node, cur_scope, self.get_current_module_info(), - self.ctx.maybe_def, + maybe_def, ); if first_symbol.is_none() { - //maybe import package symbol + // Maybe import package symbol let module_info = self.get_current_module_info().unwrap(); let import_info = module_info.get_import_info(&first_name.node); @@ -1021,7 +1023,7 @@ impl<'ctx> AdvancedResolver<'ctx> { .ok_or(anyhow!("first name symbol not found"))? .get_range(); - // get an unresolved symbol + // Get an unresolved symbol if def_start_pos != start_pos || def_end_pos != end_pos { let ast_id = first_name.id.clone(); let mut first_unresolved = @@ -1173,6 +1175,287 @@ impl<'ctx> AdvancedResolver<'ctx> { } } + fn resolve_target(&mut self, target: &'ctx ast::Target) -> ResolvedResult { + let first_name = &target.name; + let cur_scope = *self.ctx.scopes.last().unwrap(); + + let first_symbol = self.gs.look_up_symbol( + &first_name.node, + cur_scope, + self.get_current_module_info(), + true, + ); + match first_symbol { + Some(symbol_ref) => { + let (start_pos, end_pos): Range = first_name.get_span_pos(); + let (def_start_pos, def_end_pos) = self + .gs + .get_symbols() + .get_symbol(symbol_ref) + .ok_or(anyhow!("first name symbol not found"))? + .get_range(); + + // Get an unresolved symbol + if def_start_pos != start_pos || def_end_pos != end_pos { + let ast_id = first_name.id.clone(); + let mut first_unresolved = + UnresolvedSymbol::new(first_name.node.clone(), start_pos, end_pos, None); + first_unresolved.def = Some(symbol_ref); + let first_unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + first_unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); + let cur_scope = *self.ctx.scopes.last().unwrap(); + self.gs + .get_scopes_mut() + .add_ref_to_scope(cur_scope, first_unresolved_ref); + } + if !target.paths.is_empty() { + let mut parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&first_name.id)) + { + Some(ty) => ty.clone(), + None => return Ok(None), + }; + + for (index, path) in target.paths.iter().enumerate() { + match path { + ast::MemberOrIndex::Member(member) => { + let name = member; + let def_symbol_ref = match self.gs.get_symbols().get_type_attribute( + &parent_ty, + &name.node, + self.get_current_module_info(), + ) { + Some(symbol) => symbol, + None => return Ok(None), + }; + + let (start_pos, end_pos): Range = name.get_span_pos(); + let ast_id = name.id.clone(); + let mut unresolved = UnresolvedSymbol::new( + name.node.clone(), + start_pos, + end_pos, + None, + ); + unresolved.def = Some(def_symbol_ref); + unresolved.sema_info = SymbolSemanticInfo { + ty: self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + .map(|ty| ty.clone()), + doc: None, + }; + + let unresolved_ref = + self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); + + let cur_scope = *self.ctx.scopes.last().unwrap(); + self.gs + .get_scopes_mut() + .add_ref_to_scope(cur_scope, unresolved_ref); + + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + { + Some(ty) => ty.clone(), + None => return Ok(None), + }; + if index == target.paths.len() - 1 { + return Ok(Some(unresolved_ref)); + } + } + ast::MemberOrIndex::Index(index_expr) => { + let last_maybe_def = self.ctx.maybe_def; + self.ctx.maybe_def = false; + let symbol = self.expr(index_expr); + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&index_expr.id)) + { + Some(ty) => ty.clone(), + None => return Ok(None), + }; + self.ctx.maybe_def = last_maybe_def; + if index == target.paths.len() { + return symbol; + } + } + } + } + } + Ok(Some(symbol_ref)) + } + None => { + let (start_pos, end_pos): Range = first_name.get_span_pos(); + let ast_id = first_name.id.clone(); + let first_value = self.gs.get_symbols_mut().alloc_value_symbol( + ValueSymbol::new(first_name.node.clone(), start_pos, end_pos, None, false), + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); + self.gs.get_scopes_mut().add_def_to_scope( + cur_scope, + first_name.node.clone(), + first_value, + ); + + if let Some(symbol) = self + .gs + .get_symbols_mut() + .values + .get_mut(first_value.get_id()) + { + symbol.sema_info = SymbolSemanticInfo { + ty: self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&first_name.id)) + .map(|ty| ty.clone()), + doc: None, + }; + } + + for (index, path) in target.paths.iter().enumerate() { + match path { + ast::MemberOrIndex::Member(member) => { + let name = member; + let (start_pos, end_pos): Range = name.get_span_pos(); + let ast_id = name.id.clone(); + let value = self.gs.get_symbols_mut().alloc_value_symbol( + ValueSymbol::new( + name.node.clone(), + start_pos, + end_pos, + None, + false, + ), + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); + + self.gs.get_scopes_mut().add_def_to_scope( + cur_scope, + name.node.clone(), + value, + ); + + if let Some(symbol) = + self.gs.get_symbols_mut().values.get_mut(value.get_id()) + { + symbol.sema_info = SymbolSemanticInfo { + ty: self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + .map(|ty| ty.clone()), + doc: None, + }; + } + if index == target.paths.len() { + return Ok(Some(value)); + } + } + ast::MemberOrIndex::Index(index_expr) => { + let last_maybe_def = self.ctx.maybe_def; + self.ctx.maybe_def = false; + let symbol = self.expr(index_expr); + self.ctx.maybe_def = last_maybe_def; + if index == target.paths.len() { + return symbol; + } + } + } + } + Ok(None) + } + } + } + + #[inline] + pub fn walk_target_expr(&mut self, target: &'ctx ast::NodeRef) -> ResolvedResult { + self.walk_target_expr_with_hint(target, false) + } + + pub fn walk_target_expr_with_hint( + &mut self, + target: &'ctx ast::NodeRef, + with_hint: bool, + ) -> ResolvedResult { + let symbol_ref = if let Some(identifier_symbol) = self + .gs + .get_symbols() + .symbols_info + .node_symbol_map + .get(&self.ctx.get_node_key(&&target.id)) + .map(|symbol_ref| *symbol_ref) + { + if let Some(symbol) = self + .gs + .get_symbols_mut() + .values + .get_mut(identifier_symbol.get_id()) + { + let id = if let Some(last) = target.node.paths.last() { + last.id() + } else { + target.node.name.id.clone() + }; + let ty = self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&id)) + .map(|ty| ty.clone()); + if with_hint { + symbol.hint = ty.as_ref().map(|ty| SymbolHint { + kind: SymbolHintKind::TypeHint(ty.ty_str()), + pos: symbol.get_range().1, + }); + } + symbol.sema_info = SymbolSemanticInfo { ty, doc: None }; + } + + let cur_scope = *self.ctx.scopes.last().unwrap(); + match cur_scope.kind { + crate::core::scope::ScopeKind::Local => { + self.gs.get_scopes_mut().add_def_to_scope( + cur_scope, + target.node.get_name().to_string(), + identifier_symbol, + ); + } + crate::core::scope::ScopeKind::Root => {} + } + identifier_symbol + } else { + match self.resolve_target(&target.node)? { + Some(symbol) => symbol, + None => return Ok(None), + } + }; + + Ok(Some(symbol_ref)) + } + #[inline] pub fn walk_identifier_expr( &mut self, diff --git a/kclvm/sema/src/lint/mod.rs b/kclvm/sema/src/lint/mod.rs index f60613a66..9ae492ce3 100644 --- a/kclvm/sema/src/lint/mod.rs +++ b/kclvm/sema/src/lint/mod.rs @@ -201,14 +201,14 @@ impl MutSelfWalker for Linter { fn walk_assign_stmt(&mut self, assign_stmt: &ast::AssignStmt) { for target in &assign_stmt.targets { set_pos!(self, &target); - self.walk_identifier(&target.node) + self.walk_target(&target.node) } set_pos!(self, &assign_stmt.value); self.walk_expr(&assign_stmt.value.node); } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &ast::AugAssignStmt) { set_pos!(self, &aug_assign_stmt.target); - self.walk_identifier(&aug_assign_stmt.target.node); + self.walk_target(&aug_assign_stmt.target.node); set_pos!(self, &aug_assign_stmt.value); self.walk_expr(&aug_assign_stmt.value.node); } @@ -392,21 +392,6 @@ impl MutSelfWalker for Linter { self.walk_expr(&compare.left.node); walk_set_list!(self, walk_expr, compare.comparators); } - fn walk_identifier(&mut self, identifier: &ast::Identifier) { - // Nothing to do. - let _ = identifier; - } - fn walk_number_lit(&mut self, number_lit: &ast::NumberLit) { - let _ = number_lit; - } - fn walk_string_lit(&mut self, string_lit: &ast::StringLit) { - // Nothing to do. - let _ = string_lit; - } - fn walk_name_constant_lit(&mut self, name_constant_lit: &ast::NameConstantLit) { - // Nothing to do. - let _ = name_constant_lit; - } fn walk_joined_string(&mut self, joined_string: &ast::JoinedString) { walk_set_list!(self, walk_expr, joined_string.values); } @@ -414,8 +399,4 @@ impl MutSelfWalker for Linter { set_pos!(self, &formatted_value.value); self.walk_expr(&formatted_value.value.node); } - fn walk_comment(&mut self, comment: &ast::Comment) { - // Nothing to do. - let _ = comment; - } } diff --git a/kclvm/sema/src/namer/node.rs b/kclvm/sema/src/namer/node.rs index e07af9545..d29496496 100644 --- a/kclvm/sema/src/namer/node.rs +++ b/kclvm/sema/src/namer/node.rs @@ -111,7 +111,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { for target in assign_stmt.targets.iter() { let (start_pos, end_pos): Range = target.get_span_pos(); let owner = self.ctx.owner_symbols.last().unwrap().clone(); - if target.node.names.len() == 1 { + if target.node.paths.is_empty() { let owner_fully_qualified_name = self .gs .get_symbols() @@ -125,7 +125,13 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { .contains(&value_fully_qualified_name) { let value_ref = self.gs.get_symbols_mut().alloc_value_symbol( - ValueSymbol::new(value_name, start_pos, end_pos, Some(owner), true), + ValueSymbol::new( + value_name.to_string(), + start_pos, + end_pos, + Some(owner), + true, + ), self.ctx.get_node_key(&target.id), self.ctx .current_package_info @@ -363,6 +369,10 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { None } + fn walk_target(&mut self, _target: &'ctx ast::Target) -> Self::Result { + None + } + fn walk_number_lit(&mut self, _number_lit: &'ctx ast::NumberLit) -> Self::Result { None } diff --git a/kclvm/sema/src/pre_process/config.rs b/kclvm/sema/src/pre_process/config.rs index fbdd099b2..eac973eb8 100644 --- a/kclvm/sema/src/pre_process/config.rs +++ b/kclvm/sema/src/pre_process/config.rs @@ -156,8 +156,8 @@ impl ConfigMergeTransformer { ast::Stmt::Assign(assign_stmt) => { if let ast::Expr::Schema(_) = assign_stmt.value.node { for target in &assign_stmt.targets { - if target.node.names.len() == 1 { - let name = &target.node.names[0].node; + if target.node.paths.is_empty() { + let name = &target.node.name.node; match name_declaration_mapping.get_mut(name) { Some(declarations) => { // A hidden var is mutable. diff --git a/kclvm/sema/src/pre_process/identifier.rs b/kclvm/sema/src/pre_process/identifier.rs index 7c3b5ff8f..5ff159dab 100644 --- a/kclvm/sema/src/pre_process/identifier.rs +++ b/kclvm/sema/src/pre_process/identifier.rs @@ -1,6 +1,5 @@ use crate::info::is_private_field; use indexmap::{IndexMap, IndexSet}; -use kclvm_ast::ast::Node; use kclvm_ast::pos::GetPos; use kclvm_ast::walker::MutSelfMutWalker; use kclvm_ast::{ast, walk_if_mut, walk_list_mut}; @@ -55,23 +54,18 @@ impl<'ctx> MutSelfMutWalker<'ctx> for QualifiedIdentifierTransformer { fn walk_assign_stmt(&mut self, assign_stmt: &'ctx mut ast::AssignStmt) { let is_config = matches!(assign_stmt.value.node, ast::Expr::Schema(_)); for target in &assign_stmt.targets { - if !target.node.names.is_empty() { - let name = &target.node.names[0].node; - if (is_private_field(name) || !self.global_names.contains_key(name) || is_config) - && self.scope_level == 0 - { - self.global_names.insert(name.to_string(), target.get_pos()); - } + let name = &target.node.name.node; + if (is_private_field(name) || !self.global_names.contains_key(name) || is_config) + && self.scope_level == 0 + { + self.global_names.insert(name.to_string(), target.get_pos()); } } self.walk_expr(&mut assign_stmt.value.node); } fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx mut ast::AugAssignStmt) { let is_config = matches!(aug_assign_stmt.value.node, ast::Expr::Schema(_)); - if aug_assign_stmt.target.node.names.is_empty() { - return; - } - let name = &aug_assign_stmt.target.node.names[0].node; + let name = &aug_assign_stmt.target.node.name.node; if is_private_field(name) || !self.global_names.contains_key(name) || is_config { if self.scope_level == 0 { self.global_names @@ -145,6 +139,17 @@ impl<'ctx> MutSelfMutWalker<'ctx> for QualifiedIdentifierTransformer { } } } + fn walk_target(&mut self, target: &'ctx mut ast::Target) { + if !target.paths.is_empty() { + // skip global name and generator local variables in list/dict comp and quant expression + let name = &target.name.node; + if !self.global_names.contains_key(name) && !self.local_vars.contains(name) { + if let Some(pkgpath) = self.import_names.get(name) { + target.pkgpath = pkgpath.clone() + } + } + } + } } #[inline] @@ -159,18 +164,21 @@ fn remove_raw_ident_prefix(name: &str) -> String { struct RawIdentifierTransformer; impl<'ctx> MutSelfMutWalker<'ctx> for RawIdentifierTransformer { + fn walk_target(&mut self, target: &'ctx mut ast::Target) { + target.name.node = remove_raw_ident_prefix(&target.name.node); + for path in target.paths.iter_mut() { + match path { + ast::MemberOrIndex::Member(member) => { + member.node = remove_raw_ident_prefix(&member.node); + } + ast::MemberOrIndex::Index(index) => self.walk_expr(&mut index.node), + } + } + } fn walk_identifier(&mut self, identifier: &'ctx mut ast::Identifier) { - identifier.names = identifier - .names - .iter() - .map(|name| { - Node::node_with_pos_and_id( - remove_raw_ident_prefix(&name.node), - name.pos(), - name.id.clone(), - ) - }) - .collect::>>(); + for name in identifier.names.iter_mut() { + name.node = remove_raw_ident_prefix(&name.node); + } } fn walk_schema_attr(&mut self, schema_attr: &'ctx mut ast::SchemaAttr) { // If the attribute is an identifier and then fix it. diff --git a/kclvm/sema/src/pre_process/tests.rs b/kclvm/sema/src/pre_process/tests.rs index f3f41d31c..5daabe220 100644 --- a/kclvm/sema/src/pre_process/tests.rs +++ b/kclvm/sema/src/pre_process/tests.rs @@ -27,13 +27,13 @@ fn test_fix_raw_identifier_prefix() { let mut module = parse_file_force_errors("./src/pre_process/test_data/raw_identifier.k", None).unwrap(); if let ast::Stmt::Assign(assign_stmt) = &module.body[0].node { - assert_eq!(assign_stmt.targets[0].node.names[0].node, "$schema") + assert_eq!(assign_stmt.targets[0].node.name.node, "$schema") } else { panic!("invalid assign statement") } fix_raw_identifier_prefix(&mut module); if let ast::Stmt::Assign(assign_stmt) = &module.body[0].node { - assert_eq!(assign_stmt.targets[0].node.names[0].node, "schema") + assert_eq!(assign_stmt.targets[0].node.name.node, "schema") } else { panic!("invalid assign statement") } diff --git a/kclvm/sema/src/resolver/attr.rs b/kclvm/sema/src/resolver/attr.rs index 4ace00539..6c8edf788 100644 --- a/kclvm/sema/src/resolver/attr.rs +++ b/kclvm/sema/src/resolver/attr.rs @@ -7,6 +7,7 @@ use crate::ty::TypeKind::Schema; use crate::ty::{ DictType, ModuleKind, Parameter, Type, TypeKind, TypeRef, SCHEMA_MEMBER_FUNCTIONS, }; +use kclvm_ast::ast; use kclvm_error::diagnostic::Range; use kclvm_error::*; @@ -157,4 +158,123 @@ impl<'ctx> Resolver<'ctx> { } return_ty } + + pub fn subscript_index( + &mut self, + value_ty: TypeRef, + index: &'ctx ast::NodeRef, + range: Range, + ) -> ResolvedResult { + if value_ty.is_any() { + value_ty + } else { + match &value_ty.kind { + TypeKind::Str | TypeKind::StrLit(_) | TypeKind::List(_) => { + self.must_be_type(index, self.int_ty()); + if value_ty.is_list() { + value_ty.list_item_ty() + } else { + self.str_ty() + } + } + TypeKind::Dict(DictType { + key_ty: _, val_ty, .. + }) => { + let index_key_ty = self.expr(index); + if index_key_ty.is_none_or_any() { + val_ty.clone() + } else if !index_key_ty.is_key() { + self.handler.add_compile_error( + &format!("invalid dict/schema key type: '{}'", index_key_ty.ty_str()), + range, + ); + self.any_ty() + } else if let TypeKind::StrLit(lit_value) = &index_key_ty.kind { + self.load_attr(value_ty, lit_value, range) + } else { + val_ty.clone() + } + } + TypeKind::Schema(schema_ty) => { + let index_key_ty = self.expr(index); + if index_key_ty.is_none_or_any() { + schema_ty.val_ty() + } else if !index_key_ty.is_key() { + self.handler.add_compile_error( + &format!("invalid dict/schema key type: '{}'", index_key_ty.ty_str()), + range, + ); + self.any_ty() + } else if let TypeKind::StrLit(lit_value) = &index_key_ty.kind { + self.load_attr(value_ty, lit_value, range) + } else { + schema_ty.val_ty() + } + } + _ => { + self.handler.add_compile_error( + &format!("'{}' object is not subscriptable", value_ty.ty_str()), + range, + ); + self.any_ty() + } + } + } + } + + pub fn subscript( + &mut self, + value_ty: TypeRef, + index: &'ctx Option>, + lower: &'ctx Option>, + upper: &'ctx Option>, + step: &'ctx Option>, + range: Range, + ) -> ResolvedResult { + if value_ty.is_any() { + value_ty + } else { + match &value_ty.kind { + TypeKind::Str | TypeKind::StrLit(_) | TypeKind::List(_) => { + if let Some(index) = &index { + self.subscript_index(value_ty, index, range) + } else { + for expr in [lower, upper, step].iter().copied().flatten() { + self.must_be_type(expr, self.int_ty()); + } + if value_ty.is_list() { + value_ty + } else { + self.str_ty() + } + } + } + TypeKind::Dict(DictType { key_ty: _, .. }) => { + if let Some(index) = &index { + self.subscript_index(value_ty, index, range) + } else { + self.handler + .add_compile_error("unhashable type: 'slice'", range); + self.any_ty() + } + } + TypeKind::Schema(_) => { + if let Some(index) = &index { + self.subscript_index(value_ty, index, range) + } else { + self.handler + .add_compile_error("unhashable type: 'slice'", range); + self.any_ty() + } + } + _ => { + self.handler.add_compile_error( + &format!("'{}' object is not subscriptable", value_ty.ty_str()), + range, + ); + self.any_ty() + } + } + } + } } diff --git a/kclvm/sema/src/resolver/global.rs b/kclvm/sema/src/resolver/global.rs index a115ea870..f103b65ce 100644 --- a/kclvm/sema/src/resolver/global.rs +++ b/kclvm/sema/src/resolver/global.rs @@ -234,14 +234,7 @@ impl<'ctx> Resolver<'ctx> { unique_check: bool, ) { for target in &assign_stmt.targets { - if target.node.names.is_empty() { - self.handler.add_compile_error( - "missing target in the assign statement", - target.get_span_pos(), - ); - continue; - } - let name = &target.node.names[0].node; + let name = &target.node.name.node; let (start, end) = target.get_span_pos(); if self.contains_object(name) && !is_private_field(name) && unique_check { self.handler.add_error( diff --git a/kclvm/sema/src/resolver/node.rs b/kclvm/sema/src/resolver/node.rs index b7627dac6..bd78ba69b 100644 --- a/kclvm/sema/src/resolver/node.rs +++ b/kclvm/sema/src/resolver/node.rs @@ -129,25 +129,24 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { fn walk_assign_stmt(&mut self, assign_stmt: &'ctx ast::AssignStmt) -> Self::Result { self.ctx.local_vars.clear(); let mut value_ty = self.any_ty(); - let start = assign_stmt.targets[0].get_pos(); - let end = assign_stmt.value.get_pos(); + let start = if assign_stmt.targets.is_empty() { + assign_stmt.value.get_pos() + } else { + assign_stmt.targets[0].get_pos() + }; + let end = assign_stmt.value.get_end_pos(); let is_config = matches!(assign_stmt.value.node, ast::Expr::Schema(_)); for target in &assign_stmt.targets { - // For invalid syntax assign statement, we just skip it - // and show a syntax error only. - if target.node.names.is_empty() { - continue; - } - let name = &target.node.names[0].node; + let name = &target.node.name.node; // Add global names. if (is_private_field(name) || is_config || !self.contains_global_name(name)) && self.scope_level == 0 { self.insert_global_name(name, &target.get_span_pos()); } - if target.node.names.len() == 1 { + if target.node.paths.is_empty() { self.ctx.l_value = true; - let expected_ty = self.walk_identifier_expr(target); + let expected_ty = self.walk_target_expr(target); self.ctx.l_value = false; match &expected_ty.kind { TypeKind::Schema(ty) => { @@ -197,7 +196,10 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); if !value_ty.is_any() && expected_ty.is_any() && assign_stmt.ty.is_none() { - self.set_infer_type_to_scope(name, value_ty.clone(), &target.node.names[0]); + // When the type is inferred and paths of target are empty, set the type to + // the whole AST node `target` and the first name of node `target.node.name` + self.set_infer_type_to_scope(name, value_ty.clone(), &target); + self.set_infer_type_to_scope(name, value_ty.clone(), &target.node.name); if let Some(schema_ty) = &self.ctx.schema { let mut schema_ty = schema_ty.borrow_mut(); schema_ty.set_type_of_attr( @@ -209,7 +211,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { } else { self.lookup_type_from_scope(name, target.get_span_pos()); self.ctx.l_value = true; - let expected_ty = self.walk_identifier_expr(target); + let expected_ty = self.walk_target_expr(target); self.ctx.l_value = false; value_ty = self.expr(&assign_stmt.value); // Check type annotation if exists. @@ -237,38 +239,37 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { fn walk_aug_assign_stmt(&mut self, aug_assign_stmt: &'ctx ast::AugAssignStmt) -> Self::Result { self.ctx.l_value = false; - if !aug_assign_stmt.target.node.names.is_empty() { - let is_config = matches!(aug_assign_stmt.value.node, ast::Expr::Schema(_)); - let name = &aug_assign_stmt.target.node.names[0].node; - // Add global names. - if is_private_field(name) || is_config || !self.contains_global_name(name) { - if self.scope_level == 0 { - self.insert_global_name(name, &aug_assign_stmt.target.get_span_pos()); - } - } else { - let mut msgs = vec![Message { - range: aug_assign_stmt.target.get_span_pos(), + let is_config = matches!(aug_assign_stmt.value.node, ast::Expr::Schema(_)); + let name = &aug_assign_stmt.target.node.name.node; + // Add global names. + if is_private_field(name) || is_config || !self.contains_global_name(name) { + if self.scope_level == 0 { + self.insert_global_name(name, &aug_assign_stmt.target.get_span_pos()); + } + } else { + let mut msgs = vec![Message { + range: aug_assign_stmt.target.get_span_pos(), + style: Style::LineAndColumn, + message: format!("Immutable variable '{}' is modified during compiling", name), + note: None, + suggested_replacement: None, + }]; + if let Some(pos) = self.get_global_name_pos(name) { + msgs.push(Message { + range: pos.clone(), style: Style::LineAndColumn, - message: format!("Immutable variable '{}' is modified during compiling", name), - note: None, + message: format!("The variable '{}' is declared here firstly", name), + note: Some(format!( + "change the variable name to '_{}' to make it mutable", + name + )), suggested_replacement: None, - }]; - if let Some(pos) = self.get_global_name_pos(name) { - msgs.push(Message { - range: pos.clone(), - style: Style::LineAndColumn, - message: format!("The variable '{}' is declared here firstly", name), - note: Some(format!( - "change the variable name to '_{}' to make it mutable", - name - )), - suggested_replacement: None, - }) - } - self.handler.add_error(ErrorKind::ImmutableError, &msgs); + }) } + self.handler.add_error(ErrorKind::ImmutableError, &msgs); } - let left_ty = self.walk_identifier_expr(&aug_assign_stmt.target); + + let left_ty = self.walk_target_expr(&aug_assign_stmt.target); let right_ty = self.expr(&aug_assign_stmt.value); let op = match aug_assign_stmt.op.clone().try_into() { Ok(op) => op, @@ -281,7 +282,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { aug_assign_stmt.target.get_span_pos(), ); self.ctx.l_value = true; - let expected_ty = self.walk_identifier_expr(&aug_assign_stmt.target); + let expected_ty = self.walk_target_expr(&aug_assign_stmt.target); self.must_assignable_to( new_target_ty.clone(), expected_ty, @@ -616,94 +617,14 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { fn walk_subscript(&mut self, subscript: &'ctx ast::Subscript) -> Self::Result { let value_ty = self.expr(&subscript.value); let range = subscript.value.get_span_pos(); - if value_ty.is_any() { - value_ty - } else { - match &value_ty.kind { - TypeKind::Str | TypeKind::StrLit(_) | TypeKind::List(_) => { - if let Some(index) = &subscript.index { - self.must_be_type(index, self.any_ty()); - if value_ty.is_list() { - value_ty.list_item_ty() - } else { - self.str_ty() - } - } else { - for expr in [&subscript.lower, &subscript.upper, &subscript.step] - .iter() - .copied() - .flatten() - { - self.must_be_type(expr, self.int_ty()); - } - if value_ty.is_list() { - value_ty - } else { - self.str_ty() - } - } - } - TypeKind::Dict(DictType { - key_ty: _, val_ty, .. - }) => { - if let Some(index) = &subscript.index { - let index_key_ty = self.expr(index); - if index_key_ty.is_none_or_any() { - val_ty.clone() - } else if !index_key_ty.is_key() { - self.handler.add_compile_error( - &format!( - "invalid dict/schema key type: '{}'", - index_key_ty.ty_str() - ), - range, - ); - self.any_ty() - } else if let TypeKind::StrLit(lit_value) = &index_key_ty.kind { - self.load_attr(value_ty, lit_value, range) - } else { - val_ty.clone() - } - } else { - self.handler - .add_compile_error("unhashable type: 'slice'", range); - self.any_ty() - } - } - TypeKind::Schema(schema_ty) => { - if let Some(index) = &subscript.index { - let index_key_ty = self.expr(index); - if index_key_ty.is_none_or_any() { - schema_ty.val_ty() - } else if !index_key_ty.is_key() { - self.handler.add_compile_error( - &format!( - "invalid dict/schema key type: '{}'", - index_key_ty.ty_str() - ), - range, - ); - self.any_ty() - } else if let TypeKind::StrLit(lit_value) = &index_key_ty.kind { - self.load_attr(value_ty, lit_value, range) - } else { - schema_ty.val_ty() - } - } else { - self.handler - .add_compile_error("unhashable type: 'slice'", range); - self.any_ty() - } - } - _ => { - self.handler.add_compile_error( - &format!("'{}' object is not subscriptable", value_ty.ty_str()), - subscript.value.get_span_pos(), - ); - self.any_ty() - } - } - } + self.subscript( + value_ty, + &subscript.index, + &subscript.lower, + &subscript.upper, + &subscript.step, + range, + ) } fn walk_paren_expr(&mut self, paren_expr: &'ctx ast::ParenExpr) -> Self::Result { @@ -1202,6 +1123,26 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { tys.last().unwrap().clone() } + fn walk_target(&mut self, target: &'ctx ast::Target) -> Self::Result { + let tys = self.resolve_target( + &target, + (self.ctx.start_pos.clone(), self.ctx.end_pos.clone()), + ); + if let Some(ty) = tys.first() { + self.node_ty_map + .borrow_mut() + .insert(self.get_node_key(target.name.id.clone()), ty.clone()); + } + for (index, name) in target.paths.iter().enumerate() { + self.node_ty_map.borrow_mut().insert( + self.get_node_key(name.id()), + tys.get(index + 1).unwrap_or(&self.any_ty()).clone(), + ); + } + let target_ty = tys.last().unwrap_or(&self.any_ty()).clone(); + target_ty + } + fn walk_number_lit(&mut self, number_lit: &'ctx ast::NumberLit) -> Self::Result { match &number_lit.binary_suffix { Some(binary_suffix) => { @@ -1276,7 +1217,6 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { } impl<'ctx> Resolver<'ctx> { - #[inline] pub fn stmts(&mut self, stmts: &'ctx [ast::NodeRef]) -> ResolvedResult { let stmt_types: Vec = stmts.iter().map(|stmt| self.stmt(&stmt)).collect(); match stmt_types.last() { @@ -1290,7 +1230,6 @@ impl<'ctx> Resolver<'ctx> { exprs.iter().map(|expr| self.expr(&expr)).collect() } - #[inline] pub fn expr(&mut self, expr: &'ctx ast::NodeRef) -> ResolvedResult { if let ast::Expr::Identifier(_) = &expr.node { let (start, end) = expr.get_span_pos(); @@ -1320,7 +1259,6 @@ impl<'ctx> Resolver<'ctx> { ty } - #[inline] pub fn stmt(&mut self, stmt: &'ctx ast::NodeRef) -> ResolvedResult { let (start, end) = stmt.get_span_pos(); self.ctx.start_pos = start; @@ -1332,7 +1270,6 @@ impl<'ctx> Resolver<'ctx> { ty } - #[inline] pub fn expr_or_any_type( &mut self, expr: &'ctx Option>, @@ -1349,7 +1286,6 @@ impl<'ctx> Resolver<'ctx> { } } - #[inline] pub fn walk_identifier_expr( &mut self, identifier: &'ctx ast::NodeRef, @@ -1371,4 +1307,24 @@ impl<'ctx> Resolver<'ctx> { ident_ty } + + pub fn walk_target_expr(&mut self, target: &'ctx ast::NodeRef) -> ResolvedResult { + let tys = self.resolve_target(&target.node, target.get_span_pos()); + if let Some(ty) = tys.first() { + self.node_ty_map + .borrow_mut() + .insert(self.get_node_key(target.node.name.id.clone()), ty.clone()); + } + for (index, name) in target.node.paths.iter().enumerate() { + self.node_ty_map.borrow_mut().insert( + self.get_node_key(name.id()), + tys.get(index + 1).unwrap_or(&self.any_ty()).clone(), + ); + } + let target_ty = tys.last().unwrap_or(&self.any_ty()).clone(); + self.node_ty_map + .borrow_mut() + .insert(self.get_node_key(target.id.clone()), target_ty.clone()); + target_ty + } } diff --git a/kclvm/sema/src/resolver/ty.rs b/kclvm/sema/src/resolver/ty.rs index 3f376552e..e0d88a146 100644 --- a/kclvm/sema/src/resolver/ty.rs +++ b/kclvm/sema/src/resolver/ty.rs @@ -194,10 +194,7 @@ impl<'ctx> Resolver<'ctx> { return; } for target in &assign_stmt.targets { - if target.node.names.is_empty() { - continue; - } - let name = &target.node.names[0].node; + let name = &target.node.name.node; // If the assignment statement has type annotation, check the type of value and the type annotation of target if let Some(ty_annotation) = &assign_stmt.ty { @@ -240,7 +237,7 @@ impl<'ctx> Resolver<'ctx> { annotation_ty }; - self.set_type_to_scope(name, target_ty.clone(), &target.node.names[0]); + self.set_type_to_scope(name, target_ty.clone(), &target.node.name); // Check the type of value and the type annotation of target self.must_assignable_to(value_ty.clone(), target_ty, target.get_span_pos(), None) diff --git a/kclvm/sema/src/resolver/var.rs b/kclvm/sema/src/resolver/var.rs index a45f29d93..765d81b9d 100644 --- a/kclvm/sema/src/resolver/var.rs +++ b/kclvm/sema/src/resolver/var.rs @@ -1,5 +1,6 @@ use crate::resolver::Resolver; use indexmap::IndexMap; +use kclvm_ast::ast; use kclvm_ast::pos::GetPos; use kclvm_error::diagnostic::Range; use kclvm_error::*; @@ -150,6 +151,45 @@ impl<'ctx> Resolver<'ctx> { } } + /// Resolve left-hand target in the assign statement. + pub fn resolve_target( + &mut self, + target: &'ctx ast::Target, + range: Range, + ) -> Vec { + let mut tys = self.resolve_var( + &[target.get_name().to_string()], + &target.pkgpath, + range.clone(), + ); + if target.paths.is_empty() { + tys + } else { + let mut ty = tys[0].clone(); + let last_ctx_l_value = self.ctx.l_value; + self.ctx.l_value = false; + for path in &target.paths { + match path { + ast::MemberOrIndex::Member(member) => { + let attr = &member.node; + self.must_check_config_attr(attr, &range, &ty); + ty = self.load_attr(ty, attr, range.clone()); + tys.push(ty.clone()); + } + ast::MemberOrIndex::Index(index) => { + if let ast::Expr::StringLit(string_lit) = &index.node { + self.must_check_config_attr(&string_lit.value, &range, &ty); + } + ty = self.subscript_index(ty, index, range.clone()); + tys.push(ty.clone()); + } + } + } + self.ctx.l_value = last_ctx_l_value; + tys + } + } + /// Resolve an unique key in the current package. pub(crate) fn resolve_unique_key(&mut self, name: &str, range: &Range) { if !self.contains_global_name(name) && self.scope_level == 0 { diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index 19954eecb..abab347da 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -1,6 +1,7 @@ use indexmap::IndexSet; use kclvm_ast::ast::{ - ConfigEntry, Expr, Identifier, Node, NodeRef, PosTuple, Program, SchemaStmt, Stmt, Type, + ConfigEntry, Expr, Identifier, MemberOrIndex, Node, NodeRef, PosTuple, Program, SchemaStmt, + Stmt, Type, }; use kclvm_ast::node_ref; use kclvm_ast::pos::ContainsPos; @@ -386,7 +387,7 @@ pub(crate) fn inner_most_expr_in_stmt( walk_if_contains!(assign_stmt.value, pos, schema_def); for expr in &assign_stmt.targets { - walk_if_contains_with_new_expr!(expr, pos, schema_def, Expr::Identifier); + walk_if_contains_with_new_expr!(expr, pos, schema_def, Expr::Target); } (None, schema_def) } @@ -417,12 +418,7 @@ pub(crate) fn inner_most_expr_in_stmt( } Stmt::AugAssign(aug_assign_stmt) => { walk_if_contains!(aug_assign_stmt.value, pos, schema_def); - walk_if_contains_with_new_expr!( - aug_assign_stmt.target, - pos, - schema_def, - Expr::Identifier - ); + walk_if_contains_with_new_expr!(aug_assign_stmt.target, pos, schema_def, Expr::Target); (None, schema_def) } Stmt::Assert(assert_stmt) => { @@ -554,6 +550,16 @@ pub(crate) fn inner_most_expr( } match &expr.node { Expr::Identifier(_) => (Some(expr.clone()), schema_def), + Expr::Target(target) => { + for path in &target.paths { + if let MemberOrIndex::Index(index) = path { + if index.contains_pos(pos) { + return (Some(*index.clone()), schema_def); + } + } + } + (Some(expr.clone()), schema_def) + } Expr::Selector(select_expr) => { walk_if_contains!(select_expr.value, pos, schema_def); (Some(expr.clone()), schema_def) diff --git a/kclvm/tools/src/testing/suite.rs b/kclvm/tools/src/testing/suite.rs index a7d882e06..499794167 100644 --- a/kclvm/tools/src/testing/suite.rs +++ b/kclvm/tools/src/testing/suite.rs @@ -169,7 +169,7 @@ pub fn load_test_suites>(path: P, opts: &TestOptions) -> Result Result { fn build_assign(attr_name: &str, node: NodeRef) -> NodeRef { node_ref!(Stmt::Assign(AssignStmt { - targets: vec![node_ref!(Identifier { - names: vec![Node::dummy_node(attr_name.to_string())], - pkgpath: String::new(), - ctx: ExprContext::Store, + targets: vec![node_ref!(Target { + name: Node::dummy_node(attr_name.to_string()), + paths: vec![], + pkgpath: "".to_string(), })], value: node, ty: None, diff --git a/test/grammar/assign/assign_0/main.k b/test/grammar/assign/assign_0/main.k new file mode 100644 index 000000000..860c26289 --- /dev/null +++ b/test/grammar/assign/assign_0/main.k @@ -0,0 +1,4 @@ +_a = [0, 1] * 2 +_a[0] = 2 +_a[1] += 2 +a = _a diff --git a/test/grammar/assign/assign_0/stdout.golden b/test/grammar/assign/assign_0/stdout.golden new file mode 100644 index 000000000..98515f468 --- /dev/null +++ b/test/grammar/assign/assign_0/stdout.golden @@ -0,0 +1,5 @@ +a: +- 2 +- 3 +- 0 +- 1 diff --git a/test/grammar/assign/assign_1/main.k b/test/grammar/assign/assign_1/main.k new file mode 100644 index 000000000..7e564c730 --- /dev/null +++ b/test/grammar/assign/assign_1/main.k @@ -0,0 +1,4 @@ +_a = [{key1.key2 = [0] * 2}, {key3.key4 = [0] * 2}] +_a[0].key1.key2[0] = 1 +_a[1].key3.key4[1] += 1 +a = _a diff --git a/test/grammar/assign/assign_1/stdout.golden b/test/grammar/assign/assign_1/stdout.golden new file mode 100644 index 000000000..9d37d64a7 --- /dev/null +++ b/test/grammar/assign/assign_1/stdout.golden @@ -0,0 +1,9 @@ +a: +- key1: + key2: + - 1 + - 0 +- key3: + key4: + - 0 + - 1 diff --git a/test/grammar/assign/assign_fail_0/main.k b/test/grammar/assign/assign_fail_0/main.k new file mode 100644 index 000000000..2b0f4bcb0 --- /dev/null +++ b/test/grammar/assign/assign_fail_0/main.k @@ -0,0 +1,3 @@ +_a = [0, 1] * 2 +_a[10] = 2 +a = _a diff --git a/test/grammar/assign/assign_fail_0/stderr.golden b/test/grammar/assign/assign_fail_0/stderr.golden new file mode 100644 index 000000000..707a6d2dc --- /dev/null +++ b/test/grammar/assign/assign_fail_0/stderr.golden @@ -0,0 +1 @@ +index out of bounds: the len is 4 but the index is 10 \ No newline at end of file diff --git a/test/grammar/assign/assign_fail_1/main.k b/test/grammar/assign/assign_fail_1/main.k new file mode 100644 index 000000000..54001b50a --- /dev/null +++ b/test/grammar/assign/assign_fail_1/main.k @@ -0,0 +1,3 @@ +_a = [{key1.key2 = [0] * 2}, {key3.key4 = [0] * 2}] +_a[1].key1.key2[1] += 1 +a = _a diff --git a/test/grammar/assign/assign_fail_1/stderr.golden b/test/grammar/assign/assign_fail_1/stderr.golden new file mode 100644 index 000000000..ee35051cd --- /dev/null +++ b/test/grammar/assign/assign_fail_1/stderr.golden @@ -0,0 +1 @@ +invalid value 'UndefinedType' to load attribute 'key2' \ No newline at end of file diff --git a/test/grammar/syntax/else_if_token/stderr.golden b/test/grammar/syntax/else_if_token/stderr.golden index 6a69a43f5..be7deb06e 100644 --- a/test/grammar/syntax/else_if_token/stderr.golden +++ b/test/grammar/syntax/else_if_token/stderr.golden @@ -4,59 +4,3 @@ error[E1001]: InvalidSyntax 3 | else if False: | 'else if' here is invalid in KCL, consider using the 'elif' keyword | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:3:9 - | -3 | else if False: - | ^ expected one of [":"] got identifier - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:3:14 - | -3 | else if False: - | ^ expected one of ["identifier", "literal", "(", "[", "{"] got : - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:3:14 - | -3 | else if False: - | ^ expected one of ["any", "bool", "int", "float", "str", "True", "False", "identifier", "literal", "[", "{", ")"] got newline - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:4:5 - | -4 | b = 1 - | ^ expected one of ["="] got indent - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:4:5 - | -4 | b = 1 - | ^ expected one of ["identifier"] got indent - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:4:5 - | -4 | b = 1 - | ^ unexpected token 'indent' - | - -error[E1001]: InvalidSyntax - --> ${CWD}/main.k:4:9 - | -4 | b = 1 - | ^ unexpected token 'dedent' - | - -error[E2L23]: CompileError - --> ${CWD}/main.k:3:14 - | -3 | else if False: - | ^ missing target in the assign statement - |