diff --git a/lib/from_erlang.ml b/lib/from_erlang.ml index 37485bb5..e8a87e5b 100644 --- a/lib/from_erlang.ml +++ b/lib/from_erlang.ml @@ -312,13 +312,7 @@ and expr_of_erlang_expr' = function raise Known_error.(FialyzerError (NotImplemented {issue_links=["https://github.com/dwango/fialyzer/issues/222"]; message="support block expr"})) | ExprCase {line; expr; clauses} -> - let cs = clauses |> List.map ~f:(function - | F.ClsCase {line; pattern; guard_sequence; body; _} -> - if Option.is_some guard_sequence then Log.debug [%here] "line:%d %s" line "Guard (when clauses) are not supported"; - ((pattern_of_erlang_pattern pattern, Constant (line, Atom "true")), expr_of_erlang_expr' body) - | F.ClsCatch _ | F.ClsFun _ | F.ClsIf _ -> - failwith "cannot reach here" - ) in + let cs = case_clauses_of_clauses clauses in Case (line, expr_of_erlang_expr' expr, cs) | ExprCatch {line; expr} -> let e = expr_of_erlang_expr' expr in @@ -380,9 +374,20 @@ and expr_of_erlang_expr' = function raise Known_error.(FialyzerError (NotImplemented {issue_links=["https://github.com/dwango/fialyzer/issues/227"]; message="support record expr"})) | ExprTuple {line; elements} -> Tuple (line, List.map ~f:expr_of_erlang_expr' elements) - | ExprTry _ -> - raise Known_error.(FialyzerError (NotImplemented {issue_links=["https://github.com/dwango/fialyzer/issues/223"]; - message="support try expr"})) + | ExprTry {line; exprs; case_clauses; catch_clauses; after} -> + (* TODO: ignore catch clauses, see the issue https://github.com/dwango/fialyzer/issues/252 *) + let e = + if List.is_empty case_clauses then + expr_of_erlang_exprs exprs + else + let cs = case_clauses_of_clauses case_clauses in + Case (line, expr_of_erlang_exprs exprs, cs) + in + if List.is_empty after then + e + else + let e_after = expr_of_erlang_exprs after in + Let (line, "_", e, e_after) | ExprVar {line; id} -> Ref (line, Var id) | ExprLit {lit} -> expr_of_literal lit | ExprCons {line; head; tail; _} -> ListCons (line, expr_of_erlang_expr' head, expr_of_erlang_expr' tail) @@ -461,6 +466,15 @@ and function_of_clauses clauses = let arity = List.nth_exn arities 0 in let fresh_variables = (make_fresh_variables arity) in {args=fresh_variables; body=make_case cs fresh_variables} +and case_clauses_of_clauses clauses = + let f = function + | F.ClsCase {line; pattern; guard_sequence; body; _} -> + if Option.is_some guard_sequence then Log.debug [%here] "line:%d %s" line "Guard (when clauses) are not supported"; + ((pattern_of_erlang_pattern pattern, Constant (line, Atom "true")), expr_of_erlang_expr' body) + | F.ClsCatch _ | F.ClsFun _ | F.ClsIf _ -> + failwith "cannot reach here" + in + List.map ~f clauses let expr_of_erlang_expr e = e |> extract_toplevel |> expr_of_erlang_expr' diff --git a/test/blackbox-test/test-cases/try_catch_expr.erl b/test/blackbox-test/test-cases/try_catch_expr.erl index 52ec6ca5..6f49914e 100644 --- a/test/blackbox-test/test-cases/try_catch_expr.erl +++ b/test/blackbox-test/test-cases/try_catch_expr.erl @@ -1,8 +1,34 @@ -module(try_catch_expr). --export([main/0]). +-export([catch_expr/0, expr_try1/0, expr_try2/0, expr_try3/0]). --spec main() -> any(). -main() -> +-spec catch_expr() -> any(). +catch_expr() -> catch 1 + 2. - + + +-spec expr_try1() -> number(). +expr_try1() -> + try + 1 + 2 + catch + Err:Stack -> {hoge, Err, Stack} + end. + +-spec expr_try2() -> number(). +expr_try2() -> + try 1 + 2 of + X -> 2 * X + catch + Err:Stack -> {hoge, Err, Stack} + end. + +-spec expr_try3() -> ok. +expr_try3() -> + try 1 + 2 of + X -> 2 * X + catch + Err:Stack -> {hoge, Err, Stack} + after + ok + end.