Skip to content

Commit 8318a11

Browse files
committed
Do not use 0 to indicate the latest ruby version to parse
This makes it hard to do version checks against this value. The current version checks work because there are so few possible values at the moment. As an example, PR 3337 introduces new syntax for ruby 3.5 and uses `PM_OPTIONS_VERSION_LATEST` as its version guard. Because what is considered the latest changes every year, it must later be changed to `parser->version == parser->version == PM_OPTIONS_VERSION_CRUBY_3_5 || parser->version == PM_OPTIONS_VERSION_LATEST`, with one extra version each year. With this change, the PR can instead write `parser->version >= PM_OPTIONS_VERSION_CRUBY_3_5` which is self-explanatory and works for future versions.
1 parent dee6c23 commit 8318a11

File tree

6 files changed

+36
-21
lines changed

6 files changed

+36
-21
lines changed

include/prism/options.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,20 @@ typedef void (*pm_options_shebang_callback_t)(struct pm_options *options, const
8282
* parse in the same way as a specific version of CRuby would have.
8383
*/
8484
typedef enum {
85-
/** The current version of prism. */
86-
PM_OPTIONS_VERSION_LATEST = 0,
85+
/** If an explicit version is not provided, the current version of prism will be used. */
86+
PM_OPTIONS_VERSION_UNSET = 0,
8787

8888
/** The vendored version of prism in CRuby 3.3.x. */
8989
PM_OPTIONS_VERSION_CRUBY_3_3 = 1,
9090

9191
/** The vendored version of prism in CRuby 3.4.x. */
92-
PM_OPTIONS_VERSION_CRUBY_3_4 = 2
92+
PM_OPTIONS_VERSION_CRUBY_3_4 = 2,
93+
94+
/** The vendored version of prism in CRuby 3.5.x. */
95+
PM_OPTIONS_VERSION_CRUBY_3_5 = 3,
96+
97+
/** The current version of prism. */
98+
PM_OPTIONS_VERSION_LATEST = PM_OPTIONS_VERSION_CRUBY_3_5
9399
} pm_options_version_t;
94100

95101
/**

java/org/prism/ParsingOptions.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ public abstract class ParsingOptions {
1212
* See pm_options_version_t in include/prism/options.h.
1313
*/
1414
public enum SyntaxVersion {
15-
LATEST(0),
15+
LATEST(0), // Handled in pm_parser_init
1616
V3_3(1),
17-
V3_4(2);
17+
V3_4(2),
18+
V3_5(3);
1819

1920
private final int value;
2021

javascript/src/parsePrism.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,14 @@ function dumpOptions(options) {
140140
values.push(dumpCommandLineOptions(options));
141141

142142
template.push("C");
143-
if (!options.version || options.version === "latest" || options.version.match(/^3\.5(\.\d+)?$/)) {
144-
values.push(0);
143+
if (!options.version || options.version === "latest") {
144+
values.push(0); // Handled in pm_parser_init
145145
} else if (options.version.match(/^3\.3(\.\d+)?$/)) {
146146
values.push(1);
147147
} else if (options.version.match(/^3\.4(\.\d+)?$/)) {
148148
values.push(2);
149+
} else if (options.version.match(/^3\.5(\.\d+)?$/)) {
150+
values.push(3);
149151
} else {
150152
throw new Error(`Unsupported version '${options.version}' in compiler options`);
151153
}

lib/prism/ffi.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ def dump_options_command_line(options)
422422
def dump_options_version(version)
423423
case version
424424
when nil, "latest"
425-
0
425+
0 # Handled in pm_parser_init
426426
when /\A3\.3(\.\d+)?\z/
427427
1
428428
when /\A3\.4(\.\d+)?\z/
429429
2
430430
when /\A3\.5(\.\d+)?\z/
431-
0
431+
3
432432
else
433433
raise ArgumentError, "invalid version: #{version}"
434434
end

src/options.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
8989
}
9090

9191
if (strncmp(version, "3.5", 3) == 0) {
92-
options->version = PM_OPTIONS_VERSION_LATEST;
92+
options->version = PM_OPTIONS_VERSION_CRUBY_3_5;
9393
return true;
9494
}
9595

@@ -108,7 +108,7 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
108108
}
109109

110110
if (strncmp(version, "3.5.", 4) == 0 && is_number(version + 4, length - 4)) {
111-
options->version = PM_OPTIONS_VERSION_LATEST;
111+
options->version = PM_OPTIONS_VERSION_CRUBY_3_5;
112112
return true;
113113
}
114114
}

src/prism.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ pm_conditional_predicate_warn_write_literal_p(const pm_node_t *node) {
14091409
static inline void
14101410
pm_conditional_predicate_warn_write_literal(pm_parser_t *parser, const pm_node_t *node) {
14111411
if (pm_conditional_predicate_warn_write_literal_p(node)) {
1412-
pm_parser_warn_node(parser, node, parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_WARN_EQUAL_IN_CONDITIONAL_3_3 : PM_WARN_EQUAL_IN_CONDITIONAL);
1412+
pm_parser_warn_node(parser, node, parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_WARN_EQUAL_IN_CONDITIONAL_3_3 : PM_WARN_EQUAL_IN_CONDITIONAL);
14131413
}
14141414
}
14151415

@@ -2976,7 +2976,7 @@ pm_call_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
29762976
*/
29772977
static void
29782978
pm_index_arguments_check(pm_parser_t *parser, const pm_arguments_node_t *arguments, const pm_node_t *block) {
2979-
if (parser->version != PM_OPTIONS_VERSION_CRUBY_3_3) {
2979+
if (parser->version >= PM_OPTIONS_VERSION_CRUBY_3_4) {
29802980
if (arguments != NULL && PM_NODE_FLAG_P(arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS)) {
29812981
pm_node_t *node;
29822982
PM_NODE_LIST_FOREACH(&arguments->arguments, index, node) {
@@ -9094,7 +9094,7 @@ lex_global_variable(pm_parser_t *parser) {
90949094
} while ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0);
90959095

90969096
// $0 isn't allowed to be followed by anything.
9097-
pm_diagnostic_id_t diag_id = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL;
9097+
pm_diagnostic_id_t diag_id = parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL;
90989098
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, parser->current, diag_id);
90999099
}
91009100

@@ -9131,7 +9131,7 @@ lex_global_variable(pm_parser_t *parser) {
91319131
} else {
91329132
// If we get here, then we have a $ followed by something that
91339133
// isn't recognized as a global variable.
9134-
pm_diagnostic_id_t diag_id = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL;
9134+
pm_diagnostic_id_t diag_id = parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL;
91359135
const uint8_t *end = parser->current.end + parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
91369136
PM_PARSER_ERR_FORMAT(parser, parser->current.start, end, diag_id, (int) (end - parser->current.start), (const char *) parser->current.start);
91379137
}
@@ -10158,7 +10158,7 @@ lex_at_variable(pm_parser_t *parser) {
1015810158
}
1015910159
} else if (parser->current.end < end && pm_char_is_decimal_digit(*parser->current.end)) {
1016010160
pm_diagnostic_id_t diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE;
10161-
if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3) {
10161+
if (parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3) {
1016210162
diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3 : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3;
1016310163
}
1016410164

@@ -14648,7 +14648,7 @@ parse_parameters(
1464814648
parser_lex(parser);
1464914649

1465014650
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &name);
14651-
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
14651+
uint32_t reads = parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
1465214652

1465314653
if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true);
1465414654
pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT, (uint16_t) (depth + 1));
@@ -14664,7 +14664,7 @@ parse_parameters(
1466414664
// If the value of the parameter increased the number of
1466514665
// reads of that parameter, then we need to warn that we
1466614666
// have a circular definition.
14667-
if ((parser->version == PM_OPTIONS_VERSION_CRUBY_3_3) && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
14667+
if ((parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3) && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
1466814668
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, name, PM_ERR_PARAMETER_CIRCULAR);
1466914669
}
1467014670

@@ -14749,13 +14749,13 @@ parse_parameters(
1474914749

1475014750
if (token_begins_expression_p(parser->current.type)) {
1475114751
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &local);
14752-
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
14752+
uint32_t reads = parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
1475314753

1475414754
if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true);
1475514755
pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT_KW, (uint16_t) (depth + 1));
1475614756
if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser);
1475714757

14758-
if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
14758+
if (parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
1475914759
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_PARAMETER_CIRCULAR);
1476014760
}
1476114761

@@ -16459,7 +16459,7 @@ parse_variable(pm_parser_t *parser) {
1645916459
pm_node_list_append(&current_scope->implicit_parameters, node);
1646016460

1646116461
return node;
16462-
} else if ((parser->version != PM_OPTIONS_VERSION_CRUBY_3_3) && pm_token_is_it(parser->previous.start, parser->previous.end)) {
16462+
} else if ((parser->version >= PM_OPTIONS_VERSION_CRUBY_3_4) && pm_token_is_it(parser->previous.start, parser->previous.end)) {
1646316463
pm_node_t *node = (pm_node_t *) pm_it_local_variable_read_node_create(parser, &parser->previous);
1646416464
pm_node_list_append(&current_scope->implicit_parameters, node);
1646516465

@@ -22628,6 +22628,12 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
2262822628
}
2262922629
}
2263022630

22631+
// Now that we have established the user-provided options, check if
22632+
// a version was given and parse as the latest version otherwise.
22633+
if (parser->version == PM_OPTIONS_VERSION_UNSET) {
22634+
parser->version = PM_OPTIONS_VERSION_LATEST;
22635+
}
22636+
2263122637
pm_accepts_block_stack_push(parser, true);
2263222638

2263322639
// Skip past the UTF-8 BOM if it exists.

0 commit comments

Comments
 (0)