Skip to content

Commit

Permalink
Merge pull request #1588 from haldun/haldun/add-method-name
Browse files Browse the repository at this point in the history
Introduce YP_TOKEN_METHOD_NAME
  • Loading branch information
kddnewton authored Sep 22, 2023
2 parents 84d50f2 + e855bf4 commit 89b59b0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 11 deletions.
2 changes: 2 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ tokens:
comment: "<<"
- name: LESS_LESS_EQUAL
comment: "<<="
- name: METHOD_NAME
comment: "a method name"
- name: MINUS
comment: "-"
- name: MINUS_EQUAL
Expand Down
1 change: 1 addition & 0 deletions include/yarp/diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ typedef enum {
YP_ERR_OPERATOR_WRITE_BLOCK,
YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
YP_ERR_PARAMETER_BLOCK_MULTI,
YP_ERR_PARAMETER_METHOD_NAME,
YP_ERR_PARAMETER_NAME_REPEAT,
YP_ERR_PARAMETER_NO_DEFAULT,
YP_ERR_PARAMETER_NO_DEFAULT_KW,
Expand Down
1 change: 1 addition & 0 deletions lib/yarp/lex_compat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class LexCompat
LESS_EQUAL_GREATER: :on_op,
LESS_LESS: :on_op,
LESS_LESS_EQUAL: :on_op,
METHOD_NAME: :on_ident,
MINUS: :on_op,
MINUS_EQUAL: :on_op,
MINUS_GREATER: :on_tlambda,
Expand Down
1 change: 1 addition & 0 deletions src/diagnostic.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = {
[YP_ERR_OPERATOR_WRITE_BLOCK] = "Unexpected operator after a call with a block",
[YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters",
[YP_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed",
[YP_ERR_PARAMETER_METHOD_NAME] = "Unexpected name for a parameter",
[YP_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name",
[YP_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter",
[YP_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter",
Expand Down
36 changes: 25 additions & 11 deletions src/yarp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5707,8 +5707,10 @@ lex_identifier(yp_parser_t *parser, bool previous_command_start) {
}
}

return YP_TOKEN_IDENTIFIER;
} else if (lex_state_p(parser, YP_LEX_STATE_FNAME) && peek_offset(parser, 1) != '~' && peek_offset(parser, 1) != '>' && (peek_offset(parser, 1) != '=' || peek_offset(parser, 2) == '>') && match(parser, '=')) {
return YP_TOKEN_METHOD_NAME;
}

if (lex_state_p(parser, YP_LEX_STATE_FNAME) && peek_offset(parser, 1) != '~' && peek_offset(parser, 1) != '>' && (peek_offset(parser, 1) != '=' || peek_offset(parser, 2) == '>') && match(parser, '=')) {
// If we're in a position where we can accept a = at the end of an
// identifier, then we'll optionally accept it.
return YP_TOKEN_IDENTIFIER;
Expand Down Expand Up @@ -7301,7 +7303,7 @@ parser_lex(yp_parser_t *parser) {

yp_lex_state_t last_state = parser->lex_state;

if (type == YP_TOKEN_IDENTIFIER || type == YP_TOKEN_CONSTANT) {
if (type == YP_TOKEN_IDENTIFIER || type == YP_TOKEN_CONSTANT || type == YP_TOKEN_METHOD_NAME) {
if (lex_state_p(parser, YP_LEX_STATE_BEG_ANY | YP_LEX_STATE_ARG_ANY | YP_LEX_STATE_DOT)) {
if (previous_command_start) {
lex_state_set(parser, YP_LEX_STATE_CMDARG);
Expand Down Expand Up @@ -9289,7 +9291,8 @@ parse_parameters(
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_INSTANCE_VARIABLE:
case YP_TOKEN_GLOBAL_VARIABLE: {
case YP_TOKEN_GLOBAL_VARIABLE:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);
switch (parser->previous.type) {
case YP_TOKEN_CONSTANT:
Expand All @@ -9304,6 +9307,9 @@ parse_parameters(
case YP_TOKEN_CLASS_VARIABLE:
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CLASS);
break;
case YP_TOKEN_METHOD_NAME:
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PARAMETER_METHOD_NAME);
break;
default: break;
}

Expand Down Expand Up @@ -10133,6 +10139,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_INSTANCE_VARIABLE:
case YP_TOKEN_METHOD_NAME:
case YP_TOKEN_CLASS_VARIABLE:
case YP_TOKEN_GLOBAL_VARIABLE:
case YP_TOKEN_NUMBERED_REFERENCE:
Expand All @@ -10147,7 +10154,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
symbol = parser->previous;
break;
default:
expect1(parser, YP_TOKEN_IDENTIFIER, YP_ERR_SYMBOL_INVALID);
expect2(parser, YP_TOKEN_IDENTIFIER, YP_TOKEN_METHOD_NAME, YP_ERR_SYMBOL_INVALID);
symbol = parser->previous;
break;
}
Expand Down Expand Up @@ -10219,7 +10226,8 @@ parse_undef_argument(yp_parser_t *parser) {
case YP_CASE_KEYWORD:
case YP_CASE_OPERATOR:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);

yp_token_t opening = not_provided(parser);
Expand Down Expand Up @@ -10249,7 +10257,8 @@ parse_alias_argument(yp_parser_t *parser, bool first) {
case YP_CASE_OPERATOR:
case YP_CASE_KEYWORD:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
if (first) {
lex_state_set(parser, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM);
}
Expand Down Expand Up @@ -10356,6 +10365,7 @@ parse_method_definition_name(yp_parser_t *parser) {
case YP_CASE_KEYWORD:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME:
parser_lex(parser);
return parser->previous;
case YP_CASE_OPERATOR:
Expand Down Expand Up @@ -10787,7 +10797,8 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) {
static yp_node_t *
parse_pattern_primitive(yp_parser_t *parser, yp_diagnostic_id_t diag_id) {
switch (parser->current.type) {
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);
yp_parser_local_add_token(parser, &parser->previous);
return (yp_node_t *) yp_local_variable_target_node_create(parser, &parser->previous);
Expand Down Expand Up @@ -11722,7 +11733,8 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {

return node;
}
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);
yp_token_t identifier = parser->previous;
yp_node_t *node = parse_variable_call(parser);
Expand Down Expand Up @@ -13949,7 +13961,8 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
case YP_CASE_OPERATOR:
case YP_CASE_KEYWORD:
case YP_TOKEN_CONSTANT:
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);
message = parser->previous;
break;
Expand Down Expand Up @@ -14079,7 +14092,8 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
}
case YP_CASE_OPERATOR:
case YP_CASE_KEYWORD:
case YP_TOKEN_IDENTIFIER: {
case YP_TOKEN_IDENTIFIER:
case YP_TOKEN_METHOD_NAME: {
parser_lex(parser);
yp_token_t message = parser->previous;

Expand Down
9 changes: 9 additions & 0 deletions test/yarp/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,15 @@ def test_conditional_predicate_closed
]
end

def test_parameter_name_ending_with_bang_or_question_mark
source = "def foo(x!,y?); end"
errors = [
["Unexpected name for a parameter", 8..10],
["Unexpected name for a parameter", 11..13]
]
assert_errors expression(source), source, errors, compare_ripper: false
end

private

def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")
Expand Down

0 comments on commit 89b59b0

Please sign in to comment.