Skip to content

Commit e855bf4

Browse files
committed
Introduce YP_TOKEN_METHOD_NAME
1 parent 84d50f2 commit e855bf4

File tree

6 files changed

+39
-11
lines changed

6 files changed

+39
-11
lines changed

config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ tokens:
232232
comment: "<<"
233233
- name: LESS_LESS_EQUAL
234234
comment: "<<="
235+
- name: METHOD_NAME
236+
comment: "a method name"
235237
- name: MINUS
236238
comment: "-"
237239
- name: MINUS_EQUAL

include/yarp/diagnostic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ typedef enum {
160160
YP_ERR_OPERATOR_WRITE_BLOCK,
161161
YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
162162
YP_ERR_PARAMETER_BLOCK_MULTI,
163+
YP_ERR_PARAMETER_METHOD_NAME,
163164
YP_ERR_PARAMETER_NAME_REPEAT,
164165
YP_ERR_PARAMETER_NO_DEFAULT,
165166
YP_ERR_PARAMETER_NO_DEFAULT_KW,

lib/yarp/lex_compat.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class LexCompat
128128
LESS_EQUAL_GREATER: :on_op,
129129
LESS_LESS: :on_op,
130130
LESS_LESS_EQUAL: :on_op,
131+
METHOD_NAME: :on_ident,
131132
MINUS: :on_op,
132133
MINUS_EQUAL: :on_op,
133134
MINUS_GREATER: :on_tlambda,

src/diagnostic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = {
194194
[YP_ERR_OPERATOR_WRITE_BLOCK] = "Unexpected operator after a call with a block",
195195
[YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters",
196196
[YP_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed",
197+
[YP_ERR_PARAMETER_METHOD_NAME] = "Unexpected name for a parameter",
197198
[YP_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name",
198199
[YP_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter",
199200
[YP_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter",

src/yarp.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,8 +5707,10 @@ lex_identifier(yp_parser_t *parser, bool previous_command_start) {
57075707
}
57085708
}
57095709

5710-
return YP_TOKEN_IDENTIFIER;
5711-
} 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, '=')) {
5710+
return YP_TOKEN_METHOD_NAME;
5711+
}
5712+
5713+
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, '=')) {
57125714
// If we're in a position where we can accept a = at the end of an
57135715
// identifier, then we'll optionally accept it.
57145716
return YP_TOKEN_IDENTIFIER;
@@ -7301,7 +7303,7 @@ parser_lex(yp_parser_t *parser) {
73017303

73027304
yp_lex_state_t last_state = parser->lex_state;
73037305

7304-
if (type == YP_TOKEN_IDENTIFIER || type == YP_TOKEN_CONSTANT) {
7306+
if (type == YP_TOKEN_IDENTIFIER || type == YP_TOKEN_CONSTANT || type == YP_TOKEN_METHOD_NAME) {
73057307
if (lex_state_p(parser, YP_LEX_STATE_BEG_ANY | YP_LEX_STATE_ARG_ANY | YP_LEX_STATE_DOT)) {
73067308
if (previous_command_start) {
73077309
lex_state_set(parser, YP_LEX_STATE_CMDARG);
@@ -9289,7 +9291,8 @@ parse_parameters(
92899291
case YP_TOKEN_IDENTIFIER:
92909292
case YP_TOKEN_CONSTANT:
92919293
case YP_TOKEN_INSTANCE_VARIABLE:
9292-
case YP_TOKEN_GLOBAL_VARIABLE: {
9294+
case YP_TOKEN_GLOBAL_VARIABLE:
9295+
case YP_TOKEN_METHOD_NAME: {
92939296
parser_lex(parser);
92949297
switch (parser->previous.type) {
92959298
case YP_TOKEN_CONSTANT:
@@ -9304,6 +9307,9 @@ parse_parameters(
93049307
case YP_TOKEN_CLASS_VARIABLE:
93059308
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CLASS);
93069309
break;
9310+
case YP_TOKEN_METHOD_NAME:
9311+
yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PARAMETER_METHOD_NAME);
9312+
break;
93079313
default: break;
93089314
}
93099315

@@ -10133,6 +10139,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
1013310139
case YP_TOKEN_IDENTIFIER:
1013410140
case YP_TOKEN_CONSTANT:
1013510141
case YP_TOKEN_INSTANCE_VARIABLE:
10142+
case YP_TOKEN_METHOD_NAME:
1013610143
case YP_TOKEN_CLASS_VARIABLE:
1013710144
case YP_TOKEN_GLOBAL_VARIABLE:
1013810145
case YP_TOKEN_NUMBERED_REFERENCE:
@@ -10147,7 +10154,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s
1014710154
symbol = parser->previous;
1014810155
break;
1014910156
default:
10150-
expect1(parser, YP_TOKEN_IDENTIFIER, YP_ERR_SYMBOL_INVALID);
10157+
expect2(parser, YP_TOKEN_IDENTIFIER, YP_TOKEN_METHOD_NAME, YP_ERR_SYMBOL_INVALID);
1015110158
symbol = parser->previous;
1015210159
break;
1015310160
}
@@ -10219,7 +10226,8 @@ parse_undef_argument(yp_parser_t *parser) {
1021910226
case YP_CASE_KEYWORD:
1022010227
case YP_CASE_OPERATOR:
1022110228
case YP_TOKEN_CONSTANT:
10222-
case YP_TOKEN_IDENTIFIER: {
10229+
case YP_TOKEN_IDENTIFIER:
10230+
case YP_TOKEN_METHOD_NAME: {
1022310231
parser_lex(parser);
1022410232

1022510233
yp_token_t opening = not_provided(parser);
@@ -10249,7 +10257,8 @@ parse_alias_argument(yp_parser_t *parser, bool first) {
1024910257
case YP_CASE_OPERATOR:
1025010258
case YP_CASE_KEYWORD:
1025110259
case YP_TOKEN_CONSTANT:
10252-
case YP_TOKEN_IDENTIFIER: {
10260+
case YP_TOKEN_IDENTIFIER:
10261+
case YP_TOKEN_METHOD_NAME: {
1025310262
if (first) {
1025410263
lex_state_set(parser, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM);
1025510264
}
@@ -10356,6 +10365,7 @@ parse_method_definition_name(yp_parser_t *parser) {
1035610365
case YP_CASE_KEYWORD:
1035710366
case YP_TOKEN_CONSTANT:
1035810367
case YP_TOKEN_IDENTIFIER:
10368+
case YP_TOKEN_METHOD_NAME:
1035910369
parser_lex(parser);
1036010370
return parser->previous;
1036110371
case YP_CASE_OPERATOR:
@@ -10787,7 +10797,8 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) {
1078710797
static yp_node_t *
1078810798
parse_pattern_primitive(yp_parser_t *parser, yp_diagnostic_id_t diag_id) {
1078910799
switch (parser->current.type) {
10790-
case YP_TOKEN_IDENTIFIER: {
10800+
case YP_TOKEN_IDENTIFIER:
10801+
case YP_TOKEN_METHOD_NAME: {
1079110802
parser_lex(parser);
1079210803
yp_parser_local_add_token(parser, &parser->previous);
1079310804
return (yp_node_t *) yp_local_variable_target_node_create(parser, &parser->previous);
@@ -11722,7 +11733,8 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
1172211733

1172311734
return node;
1172411735
}
11725-
case YP_TOKEN_IDENTIFIER: {
11736+
case YP_TOKEN_IDENTIFIER:
11737+
case YP_TOKEN_METHOD_NAME: {
1172611738
parser_lex(parser);
1172711739
yp_token_t identifier = parser->previous;
1172811740
yp_node_t *node = parse_variable_call(parser);
@@ -13949,7 +13961,8 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
1394913961
case YP_CASE_OPERATOR:
1395013962
case YP_CASE_KEYWORD:
1395113963
case YP_TOKEN_CONSTANT:
13952-
case YP_TOKEN_IDENTIFIER: {
13964+
case YP_TOKEN_IDENTIFIER:
13965+
case YP_TOKEN_METHOD_NAME: {
1395313966
parser_lex(parser);
1395413967
message = parser->previous;
1395513968
break;
@@ -14079,7 +14092,8 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
1407914092
}
1408014093
case YP_CASE_OPERATOR:
1408114094
case YP_CASE_KEYWORD:
14082-
case YP_TOKEN_IDENTIFIER: {
14095+
case YP_TOKEN_IDENTIFIER:
14096+
case YP_TOKEN_METHOD_NAME: {
1408314097
parser_lex(parser);
1408414098
yp_token_t message = parser->previous;
1408514099

test/yarp/errors_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,15 @@ def test_conditional_predicate_closed
13241324
]
13251325
end
13261326

1327+
def test_parameter_name_ending_with_bang_or_question_mark
1328+
source = "def foo(x!,y?); end"
1329+
errors = [
1330+
["Unexpected name for a parameter", 8..10],
1331+
["Unexpected name for a parameter", 11..13]
1332+
]
1333+
assert_errors expression(source), source, errors, compare_ripper: false
1334+
end
1335+
13271336
private
13281337

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

0 commit comments

Comments
 (0)