diff --git a/src/libponyc/pass/casemethod.c b/src/libponyc/pass/casemethod.c index 5d92a8f445..a01c445562 100644 --- a/src/libponyc/pass/casemethod.c +++ b/src/libponyc/pass/casemethod.c @@ -537,7 +537,9 @@ static ast_t* get_docstring(ast_t* body, ast_t* doc) if (body != NULL && ast_id(body) == TK_SEQ) { ast_t* first = ast_child(body); - if (first != NULL && ast_id(first) == TK_STRING) + if ((first != NULL) && + (ast_id(first) == TK_STRING) && + (ast_sibling(first) != NULL)) return first; } @@ -558,9 +560,23 @@ static void print_params(ast_t* params, printbuf_t* buf) AST_GET_CHILDREN(param, param_id, param_type); - printbuf(buf, ast_name(param_id)); - printbuf(buf, ": "); - printbuf(buf, ast_print_type(param_type)); + switch (ast_id(param_id)) + { + case TK_ID: + case TK_STRING: + printbuf(buf, ast_name(param_id)); + printbuf(buf, ": "); + printbuf(buf, ast_print_type(param_type)); + break; + + case TK_REFERENCE: + printbuf(buf, ast_name(ast_child(param_id))); + break; + + default: + printbuf(buf, ast_get_print(param_id)); + break; + } param = ast_sibling(param); } @@ -697,7 +713,7 @@ static ast_t* add_case_method(ast_t* match_method, ast_t* case_method, if (match_docstring != NULL && ast_id(match_docstring) == TK_STRING && case_docstring != NULL && ast_id(case_docstring) == TK_STRING) { - add_docstring(case_id, match_docstring, case_docstring, case_params, + add_docstring(case_id, match_docstring, case_docstring, case_params, case_ret_type); } diff --git a/test/libponyc/sugar.cc b/test/libponyc/sugar.cc index ab962c938c..e1fee9e7d7 100644 --- a/test/libponyc/sugar.cc +++ b/test/libponyc/sugar.cc @@ -2363,6 +2363,86 @@ TEST_F(SugarTest, CaseFunctionDefaultTypeParamClash) TEST_ERROR(short_form); } +TEST_F(SugarTest, CaseFunctionDocStringMergeSingleStringBody) +{ + const char* short_form = + "class Foo\n" + " var create: U32\n" + " fun name(a: U64): String => \"dunno\"\n" + " fun name(1): String => \"John Doe\"\n"; + const char* full_form = + "use \"builtin\"\n" + "class ref Foo\n" + " var create: U32\n" + " fun box name(a: U64): (None|String|String) =>\n" + " $1(consume a)\n" + " fun box $1($2: U64): (None|String|String) =>\n" + " match consume $2\n" + " | $let a: U64 => \"dunno\"\n" + " | 1 => \"John Doe\"\n" + " end"; + TEST_EQUIV(short_form, full_form); +} + + +TEST_F(SugarTest, CaseFunctionDocStringMerge) +{ + const char* short_form = + "class Foo\n" + " var create: U32\n" + " fun with_docstring(0): U64 =>\n" + " \"\"\"\n" + " exit case\n" + " \"\"\"\n" + " 0\n" + " fun with_docstring(a : U64): U64 if a > 1 =>\n" + " \"\"\"\n" + " bigger than one\n" + " \"\"\"\n" + " a-1\n" + " fun with_docstring(_): U64 =>\n" + " \"\"\"\n" + " dont care\n" + " \"\"\"\n" + " 1\n"; + TEST_COMPILE(short_form); + ast_t* m = module; + AST_GET_CHILDREN(m, use_decls, type_decls); + + ast_t* foo_ast = type_decls; + ASSERT_TRUE(foo_ast != NULL); + ASSERT_EQ(ast_id(foo_ast), TK_CLASS); + AST_GET_CHILDREN(foo_ast, id, type_params, cap, provides, members); + + ASSERT_TRUE(members != NULL); + + AST_GET_CHILDREN(members, fields, methods); + + ast_t* method = methods; + const char* method_name = "with_docstring"; + while (method != NULL) + { + ast_t* child = ast_childidx(method, 1); + + if (strncmp(ast_name(child), method_name, ast_name_len(child)) == 0) + break; + method = ast_sibling(method); + } + + ASSERT_TRUE(method != NULL); + AST_GET_CHILDREN(method, mcap, mid, mtype_params, mparams, mreturn_type, + merror, mbody, mdocstring); + ASSERT_STREQ( + ast_get_print(mdocstring), + "`with_docstring(0): U64`: exit case\n" + "\n" + "\n" + "`with_docstring(a: U64): U64`: bigger than one\n" + "\n" + "\n" + "`with_docstring(_): U64`: dont care\n"); +} + TEST_F(SugarTest, AsOperatorWithLambdaType) {