From 2e342ef3637543171644d5c6c090cd2e28e413bf Mon Sep 17 00:00:00 2001 From: Marko Mindek Date: Fri, 13 Sep 2024 12:28:35 +0200 Subject: [PATCH 1/3] failing testcase --- ...diagnostics_bound_var_in_pattern_maybe.erl | 20 +++++++++++++++++++ apps/els_lsp/test/els_diagnostics_SUITE.erl | 20 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl diff --git a/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl new file mode 100644 index 00000000..d6d87743 --- /dev/null +++ b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl @@ -0,0 +1,20 @@ +%% https://github.com/erlang-ls/erlang_ls/issues/1527 +%% Only valid for OTP25 or higher +-module(diagnostics_bound_var_in_pattern_maybe). + +-if(?OTP_RELEASE<27). +-feature(maybe_expr, enable). +-endif. + +-export([foo/0]). + +foo() -> + maybe + foo ?= bar() + else + e = Error -> Error + % ^- Bound variable in pattern: Error + end. + +bar() -> + foo. diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 1ae1cf2e..e718e2b3 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -14,6 +14,7 @@ -export([ atom_typo/1, bound_var_in_pattern/1, + bound_var_in_pattern_maybe/1, bound_var_in_pattern_cannot_parse/1, compiler/1, compiler_with_behaviour/1, @@ -193,6 +194,15 @@ init_per_testcase(TestCase, Config) when -> mock_refactorerl(), els_test_utils:init_per_testcase(TestCase, Config); +init_per_testcase(TestCase, Config) when + TestCase =:= bound_var_in_pattern_maybe +-> + case ?OTP_RELEASE < 25 of + true -> + {skip, "Maybe expressions are only supported from OTP 25"}; + false -> + Config + end; init_per_testcase(TestCase, Config) -> els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config). @@ -363,6 +373,16 @@ bound_var_in_pattern(_Config) -> end, els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). +%% #1527 +-spec bound_var_in_pattern_maybe(config()) -> ok. +bound_var_in_pattern_maybe(_Config) -> + Path = src_path("diagnostics_bound_var_in_pattern_maybe.erl"), + Source = <<"BoundVarInPattern">>, + Errors = [], + Warnings = [], + Hints = [], + els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). + -spec bound_var_in_pattern_cannot_parse(config()) -> ok. bound_var_in_pattern_cannot_parse(_Config) -> Path = src_path("diagnostics_bound_var_in_pattern_cannot_parse.erl"), From c0e3323e0e576912cd8b67ae4e92d23e0df8893c Mon Sep 17 00:00:00 2001 From: Marko Mindek Date: Fri, 13 Sep 2024 13:26:13 +0200 Subject: [PATCH 2/3] els_diagnostic_SUITE:bound_var_in_pattern/1 update --- .../diagnostics_bound_var_in_pattern_maybe.erl | 11 ++++++++++- apps/els_lsp/test/els_diagnostics_SUITE.erl | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl index d6d87743..18db9b25 100644 --- a/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl +++ b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl @@ -6,7 +6,7 @@ -feature(maybe_expr, enable). -endif. --export([foo/0]). +-export([foo/0, maybe_expr/0]). foo() -> maybe @@ -18,3 +18,12 @@ foo() -> bar() -> foo. + +maybe_expr() -> + X = 1, + Y = ok, + maybe + X ?= 1 + else + Y -> Y + end. diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index e718e2b3..38f9fc19 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -202,7 +202,9 @@ init_per_testcase(TestCase, Config) when {skip, "Maybe expressions are only supported from OTP 25"}; false -> Config - end; + end, + els_mock_diagnostics:setup(), + els_test_utils:init_per_testcase(TestCase, Config); init_per_testcase(TestCase, Config) -> els_mock_diagnostics:setup(), els_test_utils:init_per_testcase(TestCase, Config). @@ -380,7 +382,16 @@ bound_var_in_pattern_maybe(_Config) -> Source = <<"BoundVarInPattern">>, Errors = [], Warnings = [], - Hints = [], + Hints = [ + #{ + message => <<"Bound variable in pattern: X">>, + range => {{24, 9}, {24, 10}} + }, + #{ + message => <<"Bound variable in pattern: Y">>, + range => {{27, 9}, {27, 10}} + } + ], els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). -spec bound_var_in_pattern_cannot_parse(config()) -> ok. From 827bc107567084f26f02f23f55ab8a3179538e7c Mon Sep 17 00:00:00 2001 From: Marko Mindek Date: Sat, 14 Sep 2024 01:17:31 +0200 Subject: [PATCH 3/3] testcases update, erlfmt ast handle, maybe_match_expr --- ...diagnostics_bound_var_in_pattern_maybe.erl | 14 ++++++++++-- .../els_bound_var_in_pattern_diagnostics.erl | 4 ++++ apps/els_lsp/src/els_erlfmt_ast.erl | 2 ++ apps/els_lsp/test/els_diagnostics_SUITE.erl | 22 +++++++++++-------- rebar.config | 5 ++--- rebar.lock | 6 ++--- 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl index 18db9b25..39ddd60e 100644 --- a/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl +++ b/apps/els_lsp/priv/code_navigation/src/diagnostics_bound_var_in_pattern_maybe.erl @@ -6,11 +6,12 @@ -feature(maybe_expr, enable). -endif. --export([foo/0, maybe_expr/0]). +-export([foo/0, maybe_expr/0, no_else/0]). foo() -> maybe - foo ?= bar() + X ?= bar(), + X == foo else e = Error -> Error % ^- Bound variable in pattern: Error @@ -27,3 +28,12 @@ maybe_expr() -> else Y -> Y end. + +no_else() -> + Y = 1, + maybe + {ok, Y} ?= 2, + X = 4, + Z ?= 8, + X == Z + end. diff --git a/apps/els_lsp/src/els_bound_var_in_pattern_diagnostics.erl b/apps/els_lsp/src/els_bound_var_in_pattern_diagnostics.erl index 4e61a8ce..6154cec7 100644 --- a/apps/els_lsp/src/els_bound_var_in_pattern_diagnostics.erl +++ b/apps/els_lsp/src/els_bound_var_in_pattern_diagnostics.erl @@ -115,6 +115,10 @@ find_vars_in_tree(Tree, Acc) -> Pattern = erl_syntax:match_expr_pattern(Tree), NewAcc = fold_pattern(Pattern, Acc), find_vars_in_tree(erl_syntax:match_expr_body(Tree), NewAcc); + maybe_match_expr -> + Pattern = erl_syntax:maybe_match_expr_pattern(Tree), + NewAcc = fold_pattern(Pattern, Acc), + find_vars_in_tree(erl_syntax:maybe_match_expr_body(Tree), NewAcc); clause -> Patterns = erl_syntax:clause_patterns(Tree), NewAcc = fold_pattern_list(Patterns, Acc), diff --git a/apps/els_lsp/src/els_erlfmt_ast.erl b/apps/els_lsp/src/els_erlfmt_ast.erl index bbff5e11..5de4b3ce 100644 --- a/apps/els_lsp/src/els_erlfmt_ast.erl +++ b/apps/els_lsp/src/els_erlfmt_ast.erl @@ -46,6 +46,8 @@ erlfmt_to_st(Node) -> %% The special `match` node is encoded as a regular binary operator {op, Pos, '=', Left, Right} -> erlfmt_to_st_1({match, Pos, Left, Right}); + {op, Pos, '?=', Left, Right} -> + erlfmt_to_st_1({maybe_match, Pos, Left, Right}); %% The special `catch` node is encoded as a regular unary operator {op, Pos, 'catch', Expr} -> erlfmt_to_st_1({'catch', Pos, Expr}); diff --git a/apps/els_lsp/test/els_diagnostics_SUITE.erl b/apps/els_lsp/test/els_diagnostics_SUITE.erl index 38f9fc19..3f656352 100644 --- a/apps/els_lsp/test/els_diagnostics_SUITE.erl +++ b/apps/els_lsp/test/els_diagnostics_SUITE.erl @@ -383,15 +383,19 @@ bound_var_in_pattern_maybe(_Config) -> Errors = [], Warnings = [], Hints = [ - #{ - message => <<"Bound variable in pattern: X">>, - range => {{24, 9}, {24, 10}} - }, - #{ - message => <<"Bound variable in pattern: Y">>, - range => {{27, 9}, {27, 10}} - } - ], + #{ + message => <<"Bound variable in pattern: X">>, + range => {{26, 8}, {26, 9}} + }, + #{ + message => <<"Bound variable in pattern: Y">>, + range => {{28, 8}, {28, 9}} + }, + #{ + message => <<"Bound variable in pattern: Y">>, + range => {{34, 13}, {34, 14}} + } + ], els_test:run_diagnostics_test(Path, Source, Errors, Warnings, Hints). -spec bound_var_in_pattern_cannot_parse(config()) -> ok. diff --git a/rebar.config b/rebar.config index edfc81c1..e1bbffc3 100644 --- a/rebar.config +++ b/rebar.config @@ -2,8 +2,7 @@ debug_info, warnings_as_errors, warn_export_vars, - warn_unused_import, - warn_missing_spec_all + warn_unused_import ]}. {deps, [ @@ -15,7 +14,7 @@ {docsh, "0.7.2"}, {elvis_core, "~> 3.2.2"}, {rebar3_format, "0.8.2"}, - {erlfmt, "1.3.0"}, + {erlfmt, "1.5.0"}, {ephemeral, "2.0.4"}, {tdiff, "0.1.2"}, {uuid, "2.0.1", {pkg, uuid_erl}}, diff --git a/rebar.lock b/rebar.lock index 2a76758b..4f7b1faf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"docsh">>,{pkg,<<"docsh">>,<<"0.7.2">>},0}, {<<"elvis_core">>,{pkg,<<"elvis_core">>,<<"3.2.2">>},0}, {<<"ephemeral">>,{pkg,<<"ephemeral">>,<<"2.0.4">>},0}, - {<<"erlfmt">>,{pkg,<<"erlfmt">>,<<"1.3.0">>},0}, + {<<"erlfmt">>,{pkg,<<"erlfmt">>,<<"1.5.0">>},0}, {<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},2}, {<<"gradualizer">>, {git,"https://github.com/josefs/Gradualizer.git", @@ -28,7 +28,7 @@ {<<"docsh">>, <<"F893D5317A0E14269DD7FE79CF95FB6B9BA23513DA0480EC6E77C73221CAE4F2">>}, {<<"elvis_core">>, <<"D5AE5FB7ACDF9D23A2AA3F6E4610490A06F7E8FB33EE65E09C5EA3A0ECF64A73">>}, {<<"ephemeral">>, <<"B3E57886ADD5D90C82FE3880F5954978222A122CB8BAA123667401BBAAEC51D6">>}, - {<<"erlfmt">>, <<"672994B92B1A809C04C46F0B781B447BF9AB7A515F5856A96177BC1962F100A9">>}, + {<<"erlfmt">>, <<"5DDECA120A6E8E0A0FAB7D0BB9C2339D841B1C9E51DD135EE583256DEF20DE25">>}, {<<"getopt">>, <<"C73A9FA687B217F2FF79F68A3B637711BB1936E712B521D8CE466B29CBF7808A">>}, {<<"jsx">>, <<"20A170ABD4335FC6DB24D5FAD1E5D677C55DADF83D1B20A8A33B5FE159892A39">>}, {<<"katana_code">>, <<"0C42BDCD7E59995876AED9F678CF62E3D12EF42E0FBB2190556E64BFEBDD15C6">>}, @@ -44,7 +44,7 @@ {<<"docsh">>, <<"4E7DB461BB07540D2BC3D366B8513F0197712D0495BB85744F367D3815076134">>}, {<<"elvis_core">>, <<"3786F027751CC265E7389BF5AC1329DB547510D80F499B45EFE771BDAF889B36">>}, {<<"ephemeral">>, <<"4B293D80F75F9C4575FF4B9C8E889A56802F40B018BF57E74F19644EFEE6C850">>}, - {<<"erlfmt">>, <<"2A84AA1EBA2F4FCD7DD31D5C57E9DE2BC2705DDA18DA4553F27DF7114CFAA052">>}, + {<<"erlfmt">>, <<"3933A40CFBE790AD94E5B650B36881DE70456319263C1479B556E9AFDBD80C75">>}, {<<"getopt">>, <<"53E1AB83B9CEB65C9672D3E7A35B8092E9BDC9B3EE80721471A161C10C59959C">>}, {<<"jsx">>, <<"37BECA0435F5CA8A2F45F76A46211E76418FBEF80C36F0361C249FC75059DC6D">>}, {<<"katana_code">>, <<"AE3BBACA187511588F69695A9FF22251CB2CC672FDCCC180289779BDD25175EF">>},