Skip to content

Commit

Permalink
Improve missing self error (#345)
Browse files Browse the repository at this point in the history
Co-authored-by: Akuli <[email protected]>
  • Loading branch information
littlewhitecloud and Akuli authored Mar 23, 2023
1 parent 9627cdc commit 6f1c37d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
7 changes: 7 additions & 0 deletions self_hosted/parser.jou
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def parse_name_type_value(tokens: Token**, expected_what_for_name: byte*) -> Ast

def parse_function_or_method_signature(tokens: Token**, is_method: bool) -> AstSignature:
# TODO: change error messages to say method, when it is a method (#243)
used_self: bool = False
if (*tokens)->kind != TokenKind::Name:
(*tokens)->fail_expected_got("a function name")

Expand Down Expand Up @@ -108,6 +109,7 @@ def parse_function_or_method_signature(tokens: Token**, is_method: bool) -> AstS
name_location = (*tokens)->location,
}
++*tokens
used_self = True

else:
arg = parse_name_type_value(tokens, "an argument name")
Expand Down Expand Up @@ -144,6 +146,11 @@ def parse_function_or_method_signature(tokens: Token**, is_method: bool) -> AstS
(*tokens)->fail_expected_got("a '->'")
++*tokens

if not used_self and is_method:
throwerror: byte[300]
snprintf(throwerror, sizeof throwerror, "missing self, should be 'def %s(self, ...)'", result.name)
fail((*tokens)->location, throwerror)

result.return_type = parse_type(tokens)
return result

Expand Down
14 changes: 11 additions & 3 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static AstNameTypeValue parse_name_type_value(const Token **tokens, const char *
static AstSignature parse_function_signature(const Token **tokens, bool accept_self)
{
AstSignature result = {0};

bool used_self = false;
if ((*tokens)->type != TOKEN_NAME)
fail_with_parse_error(*tokens, "a function name");
result.name_location = (*tokens)->location;
Expand All @@ -150,6 +150,7 @@ static AstSignature parse_function_signature(const Token **tokens, bool accept_s
fail_with_error((*tokens)->location, "'self' cannot be used here");
AstNameTypeValue self_arg = { .name="self", .name_location=(*tokens)++->location };
Append(&result.args, self_arg);
used_self = true;
} else {
AstNameTypeValue arg = parse_name_type_value(tokens, "an argument name");

Expand All @@ -167,7 +168,6 @@ static AstSignature parse_function_signature(const Token **tokens, bool accept_s
else
break;
}

if (!is_operator(*tokens, ")"))
fail_with_parse_error(*tokens, "a ')'");
++*tokens;
Expand All @@ -184,7 +184,15 @@ static AstSignature parse_function_signature(const Token **tokens, bool accept_s
fail_with_parse_error(*tokens, "a '->'");
}
++*tokens;


if (!used_self && accept_self) {
fail_with_error(
(*tokens)->location,
"missing self, should be 'def %s(self, ...)'",
result.name
);
}

result.returntype = parse_type(tokens);
return result;
}
Expand Down
8 changes: 8 additions & 0 deletions tests/syntax_error/missing_self.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Foo:
def bar() -> void: # Error: missing self, should be 'def bar(self, ...)'
return

def main() -> int:
f = Foo{}
f.bar()
return 0

0 comments on commit 6f1c37d

Please sign in to comment.