Skip to content

Commit 9924f87

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 47143d1 commit 9924f87

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) {
@@ -9090,7 +9090,7 @@ lex_global_variable(pm_parser_t *parser) {
90909090
} while ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0);
90919091

90929092
// $0 isn't allowed to be followed by anything.
9093-
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;
9093+
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;
90949094
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, parser->current, diag_id);
90959095
}
90969096

@@ -9127,7 +9127,7 @@ lex_global_variable(pm_parser_t *parser) {
91279127
} else {
91289128
// If we get here, then we have a $ followed by something that
91299129
// isn't recognized as a global variable.
9130-
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;
9130+
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;
91319131
const uint8_t *end = parser->current.end + parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
91329132
PM_PARSER_ERR_FORMAT(parser, parser->current.start, end, diag_id, (int) (end - parser->current.start), (const char *) parser->current.start);
91339133
}
@@ -10154,7 +10154,7 @@ lex_at_variable(pm_parser_t *parser) {
1015410154
}
1015510155
} else if (parser->current.end < end && pm_char_is_decimal_digit(*parser->current.end)) {
1015610156
pm_diagnostic_id_t diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE;
10157-
if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3) {
10157+
if (parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3) {
1015810158
diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3 : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3;
1015910159
}
1016010160

@@ -14644,7 +14644,7 @@ parse_parameters(
1464414644
parser_lex(parser);
1464514645

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

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

@@ -14745,13 +14745,13 @@ parse_parameters(
1474514745

1474614746
if (token_begins_expression_p(parser->current.type)) {
1474714747
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &local);
14748-
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
14748+
uint32_t reads = parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
1474914749

1475014750
if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true);
1475114751
pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT_KW, (uint16_t) (depth + 1));
1475214752
if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser);
1475314753

14754-
if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
14754+
if (parser->version <= PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
1475514755
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_PARAMETER_CIRCULAR);
1475614756
}
1475714757

@@ -16455,7 +16455,7 @@ parse_variable(pm_parser_t *parser) {
1645516455
pm_node_list_append(&current_scope->implicit_parameters, node);
1645616456

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

@@ -22624,6 +22624,12 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
2262422624
}
2262522625
}
2262622626

22627+
// Now that we have established the user-provided options, check if
22628+
// a version was given and parse as the latest version otherwise.
22629+
if (parser->version == PM_OPTIONS_VERSION_UNSET) {
22630+
parser->version = PM_OPTIONS_VERSION_LATEST;
22631+
}
22632+
2262722633
pm_accepts_block_stack_push(parser, true);
2262822634

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

0 commit comments

Comments
 (0)