Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change frozen_string_literal to be a tri-state #2577

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,9 @@ flags:
- name: FORCED_BINARY_ENCODING
comment: "internal bytes forced the encoding to binary"
- name: FROZEN
comment: "frozen by virtue of a `frozen_string_literal` comment"
comment: "frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`"
- name: MUTABLE
comment: "mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`"
comment: Flags for string nodes.
- name: SymbolFlags
values:
Expand Down
2 changes: 1 addition & 1 deletion ext/prism/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
} else if (key_id == rb_option_id_offset) {
if (!NIL_P(value)) pm_options_offset_set(options, NUM2UINT(value));
} else if (key_id == rb_option_id_frozen_string_literal) {
if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, value == Qtrue);
if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, RTEST(value));
} else if (key_id == rb_option_id_version) {
if (!NIL_P(value)) {
const char *version = check_string(value);
Expand Down
26 changes: 24 additions & 2 deletions include/prism/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@
#include <stddef.h>
#include <stdint.h>

/**
* String literals should be made frozen.
*/
#define PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED ((int8_t) -1)

/**
* String literals may be frozen or mutable depending on the implementation
* default.
*/
#define PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET ((int8_t) 0)

/**
* String literals should be made mutable.
*/
#define PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED ((int8_t) 1)

/**
* A scope of locals surrounding the code that is being parsed.
*/
Expand Down Expand Up @@ -85,8 +101,14 @@ typedef struct {
/** A bitset of the various options that were set on the command line. */
uint8_t command_line;

/** Whether or not the frozen string literal option has been set. */
bool frozen_string_literal;
/**
* Whether or not the frozen string literal option has been set.
* May be:
* - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
* - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
* - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
*/
int8_t frozen_string_literal;
casperisfine marked this conversation as resolved.
Show resolved Hide resolved
} pm_options_t;

/**
Expand Down
16 changes: 10 additions & 6 deletions include/prism/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,16 @@ struct pm_parser {
/** The command line flags given from the options. */
uint8_t command_line;

/**
* Whether or not we have found a frozen_string_literal magic comment with
* a true or false value.
* May be:
* - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
* - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
* - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
*/
int8_t frozen_string_literal;

/** Whether or not we're at the beginning of a command. */
bool command_start;

Expand Down Expand Up @@ -737,12 +747,6 @@ struct pm_parser {
*/
bool semantic_token_seen;

/**
* Whether or not we have found a frozen_string_literal magic comment with
* a true value.
*/
bool frozen_string_literal;

/**
* True if the current regular expression being lexed contains only ASCII
* characters.
Expand Down
2 changes: 1 addition & 1 deletion rust/ruby-prism/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl<'pr> ParseResult<'pr> {
/// Returns whether we found a `frozen_string_literal` magic comment with a true value.
#[must_use]
pub fn frozen_string_literals(&self) -> bool {
unsafe { (*self.parser.as_ptr()).frozen_string_literal }
unsafe { (*self.parser.as_ptr()).frozen_string_literal == 1 }
}

/// Returns a slice of the source string that was parsed using the given
Expand Down
4 changes: 2 additions & 2 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pm_options_offset_set(pm_options_t *options, uint32_t offset) {
*/
PRISM_EXPORTED_FUNCTION void
pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal) {
options->frozen_string_literal = frozen_string_literal;
options->frozen_string_literal = frozen_string_literal ? 1 : -1;
}

/**
Expand Down Expand Up @@ -212,7 +212,7 @@ pm_options_read(pm_options_t *options, const char *data) {
data += encoding_length;
}

options->frozen_string_literal = (*data++) ? true : false;
options->frozen_string_literal = (int8_t) *data++;
options->command_line = (uint8_t) *data++;
options->version = (pm_options_version_t) *data++;

Expand Down
28 changes: 18 additions & 10 deletions src/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -5836,8 +5836,13 @@ pm_string_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening,
pm_string_node_t *node = PM_ALLOC_NODE(parser, pm_string_node_t);
pm_node_flags_t flags = 0;

if (parser->frozen_string_literal) {
flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
switch (parser->frozen_string_literal) {
case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED:
flags = PM_STRING_FLAGS_MUTABLE;
break;
case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED:
flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
break;
}

*node = (pm_string_node_t) {
Expand Down Expand Up @@ -6236,8 +6241,13 @@ pm_symbol_node_to_string_node(pm_parser_t *parser, pm_symbol_node_t *node) {
pm_string_node_t *new_node = PM_ALLOC_NODE(parser, pm_string_node_t);
pm_node_flags_t flags = 0;

if (parser->frozen_string_literal) {
flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
switch (parser->frozen_string_literal) {
case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED:
flags = PM_STRING_FLAGS_MUTABLE;
break;
case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED:
flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN;
break;
}

*new_node = (pm_string_node_t) {
Expand Down Expand Up @@ -7113,9 +7123,9 @@ parser_lex_magic_comment_encoding(pm_parser_t *parser) {
static void
parser_lex_magic_comment_frozen_string_literal_value(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
if ((start + 4 <= end) && pm_strncasecmp(start, (const uint8_t *) "true", 4) == 0) {
parser->frozen_string_literal = true;
parser->frozen_string_literal = 1;
} else if ((start + 5 <= end) && pm_strncasecmp(start, (const uint8_t *) "false", 5) == 0) {
parser->frozen_string_literal = false;
parser->frozen_string_literal = -1;
}
}

Expand Down Expand Up @@ -18751,7 +18761,7 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
.in_keyword_arg = false,
.current_param_name = 0,
.semantic_token_seen = false,
.frozen_string_literal = false,
.frozen_string_literal = 0,
.current_regular_expression_ascii_only = false
};

Expand Down Expand Up @@ -18810,9 +18820,7 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
}

// frozen_string_literal option
if (options->frozen_string_literal) {
parser->frozen_string_literal = true;
}
parser->frozen_string_literal = options->frozen_string_literal;

// command_line option
parser->command_line = options->command_line;
Expand Down
Loading