Skip to content

Commit

Permalink
Fix compiler crash on case methods with _ as a method parameter. (#…
Browse files Browse the repository at this point in the history
…2252)

Case method docstrings contain the signature and docstrings of each case method concatenated.
The method of printing the signature didn't work for _, the dont care symbol.
  • Loading branch information
mfelsche authored and jemc committed Sep 28, 2017
1 parent 5dbe4d8 commit 6628537
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 5 deletions.
26 changes: 21 additions & 5 deletions src/libponyc/pass/casemethod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}

Expand Down
80 changes: 80 additions & 0 deletions test/libponyc/sugar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit 6628537

Please sign in to comment.