[ruby/prism] Shareable constant nodes
https://github.com/ruby/prism/commit/473cfed6d0
This commit is contained in:
parent
59785680dd
commit
c45ad17fa1
@ -1423,6 +1423,11 @@ module Prism
|
|||||||
builder.self(token(node.location))
|
builder.self(token(node.location))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A shareable constant.
|
||||||
|
def visit_shareable_constant_node(node)
|
||||||
|
visit(node.write)
|
||||||
|
end
|
||||||
|
|
||||||
# class << self; end
|
# class << self; end
|
||||||
# ^^^^^^^^^^^^^^^^^^
|
# ^^^^^^^^^^^^^^^^^^
|
||||||
def visit_singleton_class_node(node)
|
def visit_singleton_class_node(node)
|
||||||
|
@ -2858,6 +2858,11 @@ module Prism
|
|||||||
on_var_ref(on_kw("self"))
|
on_var_ref(on_kw("self"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A shareable constant.
|
||||||
|
def visit_shareable_constant_node(node)
|
||||||
|
visit(node.write)
|
||||||
|
end
|
||||||
|
|
||||||
# class << self; end
|
# class << self; end
|
||||||
# ^^^^^^^^^^^^^^^^^^
|
# ^^^^^^^^^^^^^^^^^^
|
||||||
def visit_singleton_class_node(node)
|
def visit_singleton_class_node(node)
|
||||||
|
@ -1274,6 +1274,11 @@ module Prism
|
|||||||
s(node, :self)
|
s(node, :self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A shareable constant.
|
||||||
|
def visit_shareable_constant_node(node)
|
||||||
|
visit(node.write)
|
||||||
|
end
|
||||||
|
|
||||||
# class << self; end
|
# class << self; end
|
||||||
# ^^^^^^^^^^^^^^^^^^
|
# ^^^^^^^^^^^^^^^^^^
|
||||||
def visit_singleton_class_node(node)
|
def visit_singleton_class_node(node)
|
||||||
|
@ -248,6 +248,7 @@ warnings:
|
|||||||
- INTEGER_IN_FLIP_FLOP
|
- INTEGER_IN_FLIP_FLOP
|
||||||
- INVALID_CHARACTER
|
- INVALID_CHARACTER
|
||||||
- INVALID_NUMBERED_REFERENCE
|
- INVALID_NUMBERED_REFERENCE
|
||||||
|
- INVALID_SHAREABLE_CONSTANT_VALUE
|
||||||
- KEYWORD_EOL
|
- KEYWORD_EOL
|
||||||
- LITERAL_IN_CONDITION_DEFAULT
|
- LITERAL_IN_CONDITION_DEFAULT
|
||||||
- LITERAL_IN_CONDITION_VERBOSE
|
- LITERAL_IN_CONDITION_VERBOSE
|
||||||
@ -667,6 +668,15 @@ flags:
|
|||||||
- name: FORCED_US_ASCII_ENCODING
|
- name: FORCED_US_ASCII_ENCODING
|
||||||
comment: "internal bytes forced the encoding to US-ASCII"
|
comment: "internal bytes forced the encoding to US-ASCII"
|
||||||
comment: Flags for regular expression and match last line nodes.
|
comment: Flags for regular expression and match last line nodes.
|
||||||
|
- name: ShareableConstantNodeFlags
|
||||||
|
values:
|
||||||
|
- name: LITERAL
|
||||||
|
comment: "constant writes that should be modified with shareable constant value literal"
|
||||||
|
- name: EXPERIMENTAL_EVERYTHING
|
||||||
|
comment: "constant writes that should be modified with shareable constant value experimental everything"
|
||||||
|
- name: EXPERIMENTAL_COPY
|
||||||
|
comment: "constant writes that should be modified with shareable constant value experimental copy"
|
||||||
|
comment: Flags for shareable constant nodes.
|
||||||
- name: StringFlags
|
- name: StringFlags
|
||||||
values:
|
values:
|
||||||
- name: FORCED_UTF8_ENCODING
|
- name: FORCED_UTF8_ENCODING
|
||||||
@ -3063,6 +3073,29 @@ nodes:
|
|||||||
|
|
||||||
self
|
self
|
||||||
^^^^
|
^^^^
|
||||||
|
- name: ShareableConstantNode
|
||||||
|
fields:
|
||||||
|
- name: flags
|
||||||
|
type: flags
|
||||||
|
kind: ShareableConstantNodeFlags
|
||||||
|
- name: write
|
||||||
|
type: node
|
||||||
|
kind:
|
||||||
|
- ConstantWriteNode
|
||||||
|
- ConstantAndWriteNode
|
||||||
|
- ConstantOrWriteNode
|
||||||
|
- ConstantOperatorWriteNode
|
||||||
|
- ConstantPathWriteNode
|
||||||
|
- ConstantPathAndWriteNode
|
||||||
|
- ConstantPathOrWriteNode
|
||||||
|
- ConstantPathOperatorWriteNode
|
||||||
|
comment: The constant write that should be modified with the shareability state.
|
||||||
|
comment: |
|
||||||
|
This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified.
|
||||||
|
|
||||||
|
# shareable_constant_value: literal
|
||||||
|
C = { a: 1 }
|
||||||
|
^^^^^^^^^^^^
|
||||||
- name: SingletonClassNode
|
- name: SingletonClassNode
|
||||||
fields:
|
fields:
|
||||||
- name: locals
|
- name: locals
|
||||||
|
@ -448,6 +448,13 @@ typedef struct {
|
|||||||
void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token);
|
void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token);
|
||||||
} pm_lex_callback_t;
|
} pm_lex_callback_t;
|
||||||
|
|
||||||
|
/** The type of shareable constant value that can be set. */
|
||||||
|
typedef uint8_t pm_shareable_constant_value_t;
|
||||||
|
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_NONE = 0x0;
|
||||||
|
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_LITERAL = 0x1;
|
||||||
|
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING = 0x2;
|
||||||
|
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY = 0x4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct represents a node in a linked list of scopes. Some scopes can see
|
* This struct represents a node in a linked list of scopes. Some scopes can see
|
||||||
* into their parent scopes, while others cannot.
|
* into their parent scopes, while others cannot.
|
||||||
@ -487,6 +494,12 @@ typedef struct pm_scope {
|
|||||||
*/
|
*/
|
||||||
int8_t numbered_parameters;
|
int8_t numbered_parameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current state of constant shareability for this scope. This is
|
||||||
|
* changed by magic shareable_constant_value comments.
|
||||||
|
*/
|
||||||
|
pm_shareable_constant_value_t shareable_constant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean indicating whether or not this scope can see into its parent.
|
* A boolean indicating whether or not this scope can see into its parent.
|
||||||
* If closed is true, then the scope cannot see into its parent.
|
* If closed is true, then the scope cannot see into its parent.
|
||||||
|
114
prism/prism.c
114
prism/prism.c
@ -5731,6 +5731,25 @@ pm_self_node_create(pm_parser_t *parser, const pm_token_t *token) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate and initialize a new ShareableConstantNode node.
|
||||||
|
*/
|
||||||
|
static pm_shareable_constant_node_t *
|
||||||
|
pm_shareable_constant_node_create(pm_parser_t *parser, pm_node_t *write, pm_shareable_constant_value_t value) {
|
||||||
|
pm_shareable_constant_node_t *node = PM_ALLOC_NODE(parser, pm_shareable_constant_node_t);
|
||||||
|
|
||||||
|
*node = (pm_shareable_constant_node_t) {
|
||||||
|
{
|
||||||
|
.type = PM_SHAREABLE_CONSTANT_NODE,
|
||||||
|
.flags = (pm_node_flags_t) value,
|
||||||
|
.location = PM_LOCATION_NODE_VALUE(write)
|
||||||
|
},
|
||||||
|
.write = write
|
||||||
|
};
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a new SingletonClassNode node.
|
* Allocate a new SingletonClassNode node.
|
||||||
*/
|
*/
|
||||||
@ -6745,6 +6764,7 @@ pm_parser_scope_push(pm_parser_t *parser, bool closed) {
|
|||||||
.locals = { 0 },
|
.locals = { 0 },
|
||||||
.parameters = PM_SCOPE_PARAMETERS_NONE,
|
.parameters = PM_SCOPE_PARAMETERS_NONE,
|
||||||
.numbered_parameters = PM_SCOPE_NUMBERED_PARAMETERS_NONE,
|
.numbered_parameters = PM_SCOPE_NUMBERED_PARAMETERS_NONE,
|
||||||
|
.shareable_constant = (closed || parser->current_scope == NULL) ? PM_SCOPE_SHAREABLE_CONSTANT_NONE : parser->current_scope->shareable_constant,
|
||||||
.closed = closed
|
.closed = closed
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6790,6 +6810,27 @@ pm_parser_scope_forwarding_keywords_check(pm_parser_t *parser, const pm_token_t
|
|||||||
pm_parser_scope_forwarding_param_check(parser, token, PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
|
pm_parser_scope_forwarding_param_check(parser, token, PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current state of constant shareability.
|
||||||
|
*/
|
||||||
|
static inline pm_shareable_constant_value_t
|
||||||
|
pm_parser_scope_shareable_constant_get(pm_parser_t *parser) {
|
||||||
|
return parser->current_scope->shareable_constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current state of constant shareability. We'll set it on all of the
|
||||||
|
* open scopes so that reads are quick.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pm_parser_scope_shareable_constant_set(pm_parser_t *parser, pm_shareable_constant_value_t shareable_constant) {
|
||||||
|
pm_scope_t *scope = parser->current_scope;
|
||||||
|
|
||||||
|
do {
|
||||||
|
scope->shareable_constant = shareable_constant;
|
||||||
|
} while (!scope->closed && (scope = scope->previous) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current param name as the return value and set it to the given
|
* Save the current param name as the return value and set it to the given
|
||||||
* constant id.
|
* constant id.
|
||||||
@ -7345,6 +7386,28 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have hit a ractor pragma, attempt to lex that.
|
||||||
|
uint32_t value_length = (uint32_t) (value_end - value_start);
|
||||||
|
if (key_length == 24 && pm_strncasecmp(key_source, (const uint8_t *) "shareable_constant_value", 24) == 0) {
|
||||||
|
if (value_length == 4 && pm_strncasecmp(value_start, (const uint8_t *) "none", 4) == 0) {
|
||||||
|
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_NONE);
|
||||||
|
} else if (value_length == 7 && pm_strncasecmp(value_start, (const uint8_t *) "literal", 7) == 0) {
|
||||||
|
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_LITERAL);
|
||||||
|
} else if (value_length == 23 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_everything", 23) == 0) {
|
||||||
|
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING);
|
||||||
|
} else if (value_length == 17 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_copy", 17) == 0) {
|
||||||
|
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY);
|
||||||
|
} else {
|
||||||
|
PM_PARSER_WARN_TOKEN_FORMAT(
|
||||||
|
parser,
|
||||||
|
parser->current,
|
||||||
|
PM_WARN_INVALID_SHAREABLE_CONSTANT_VALUE,
|
||||||
|
(int) value_length,
|
||||||
|
(const char *) value_start
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When we're done, we want to free the string in case we had to
|
// When we're done, we want to free the string in case we had to
|
||||||
// allocate memory for it.
|
// allocate memory for it.
|
||||||
pm_string_free(&key);
|
pm_string_free(&key);
|
||||||
@ -11991,6 +12054,21 @@ parse_target_validate(pm_parser_t *parser, pm_node_t *target) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Potentially wrap a constant write node in a shareable constant node depending
|
||||||
|
* on the current state.
|
||||||
|
*/
|
||||||
|
static pm_node_t *
|
||||||
|
parse_shareable_constant_write(pm_parser_t *parser, pm_node_t *write) {
|
||||||
|
pm_shareable_constant_value_t shareable_constant = pm_parser_scope_shareable_constant_get(parser);
|
||||||
|
|
||||||
|
if (shareable_constant != PM_SCOPE_SHAREABLE_CONSTANT_NONE) {
|
||||||
|
return (pm_node_t *) pm_shareable_constant_node_create(parser, write, shareable_constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
return write;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the given node into a valid write node.
|
* Convert the given node into a valid write node.
|
||||||
*/
|
*/
|
||||||
@ -12005,15 +12083,17 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
|
|||||||
pm_node_destroy(parser, target);
|
pm_node_destroy(parser, target);
|
||||||
return (pm_node_t *) node;
|
return (pm_node_t *) node;
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_PATH_NODE:
|
case PM_CONSTANT_PATH_NODE: {
|
||||||
return (pm_node_t *) pm_constant_path_write_node_create(parser, (pm_constant_path_node_t *) target, operator, value);
|
pm_node_t *node = (pm_node_t *) pm_constant_path_write_node_create(parser, (pm_constant_path_node_t *) target, operator, value);
|
||||||
|
return parse_shareable_constant_write(parser, node);
|
||||||
|
}
|
||||||
case PM_CONSTANT_READ_NODE: {
|
case PM_CONSTANT_READ_NODE: {
|
||||||
pm_constant_write_node_t *node = pm_constant_write_node_create(parser, (pm_constant_read_node_t *) target, operator, value);
|
pm_node_t *node = (pm_node_t *) pm_constant_write_node_create(parser, (pm_constant_read_node_t *) target, operator, value);
|
||||||
if (context_def_p(parser)) {
|
if (context_def_p(parser)) {
|
||||||
pm_parser_err_node(parser, (pm_node_t *) node, PM_ERR_WRITE_TARGET_IN_METHOD);
|
pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_IN_METHOD);
|
||||||
}
|
}
|
||||||
pm_node_destroy(parser, target);
|
pm_node_destroy(parser, target);
|
||||||
return (pm_node_t *) node;
|
return parse_shareable_constant_write(parser, node);
|
||||||
}
|
}
|
||||||
case PM_BACK_REFERENCE_READ_NODE:
|
case PM_BACK_REFERENCE_READ_NODE:
|
||||||
case PM_NUMBERED_REFERENCE_READ_NODE:
|
case PM_NUMBERED_REFERENCE_READ_NODE:
|
||||||
@ -17954,16 +18034,18 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
||||||
return (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
||||||
|
|
||||||
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_READ_NODE: {
|
case PM_CONSTANT_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
||||||
pm_node_t *result = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
||||||
|
|
||||||
pm_node_destroy(parser, node);
|
pm_node_destroy(parser, node);
|
||||||
return result;
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
@ -18065,16 +18147,18 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
||||||
return (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
||||||
|
|
||||||
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_READ_NODE: {
|
case PM_CONSTANT_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
||||||
pm_node_t *result = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
||||||
|
|
||||||
pm_node_destroy(parser, node);
|
pm_node_destroy(parser, node);
|
||||||
return result;
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
@ -18186,16 +18270,18 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
||||||
return (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
||||||
|
|
||||||
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_READ_NODE: {
|
case PM_CONSTANT_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
|
||||||
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
||||||
pm_node_t *result = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
pm_node_t *write = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
||||||
|
|
||||||
pm_node_destroy(parser, node);
|
pm_node_destroy(parser, node);
|
||||||
return result;
|
return parse_shareable_constant_write(parser, write);
|
||||||
}
|
}
|
||||||
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
||||||
parser_lex(parser);
|
parser_lex(parser);
|
||||||
|
@ -327,6 +327,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|||||||
[PM_WARN_FLOAT_OUT_OF_RANGE] = { "Float %.*s%s out of range", PM_WARNING_LEVEL_VERBOSE },
|
[PM_WARN_FLOAT_OUT_OF_RANGE] = { "Float %.*s%s out of range", PM_WARNING_LEVEL_VERBOSE },
|
||||||
[PM_WARN_INTEGER_IN_FLIP_FLOP] = { "integer literal in flip-flop", PM_WARNING_LEVEL_DEFAULT },
|
[PM_WARN_INTEGER_IN_FLIP_FLOP] = { "integer literal in flip-flop", PM_WARNING_LEVEL_DEFAULT },
|
||||||
[PM_WARN_INVALID_CHARACTER] = { "invalid character syntax; use %s%s%s", PM_WARNING_LEVEL_DEFAULT },
|
[PM_WARN_INVALID_CHARACTER] = { "invalid character syntax; use %s%s%s", PM_WARNING_LEVEL_DEFAULT },
|
||||||
|
[PM_WARN_INVALID_SHAREABLE_CONSTANT_VALUE] = { "invalid value for shareable_constant_value: %.*s", PM_WARNING_LEVEL_VERBOSE },
|
||||||
[PM_WARN_INVALID_NUMBERED_REFERENCE] = { "'%.*s' is too big for a number variable, always nil", PM_WARNING_LEVEL_DEFAULT },
|
[PM_WARN_INVALID_NUMBERED_REFERENCE] = { "'%.*s' is too big for a number variable, always nil", PM_WARNING_LEVEL_DEFAULT },
|
||||||
[PM_WARN_KEYWORD_EOL] = { "`%.*s` at the end of line without an expression", PM_WARNING_LEVEL_VERBOSE },
|
[PM_WARN_KEYWORD_EOL] = { "`%.*s` at the end of line without an expression", PM_WARNING_LEVEL_VERBOSE },
|
||||||
[PM_WARN_LITERAL_IN_CONDITION_DEFAULT] = { "%sliteral in %s", PM_WARNING_LEVEL_DEFAULT },
|
[PM_WARN_LITERAL_IN_CONDITION_DEFAULT] = { "%sliteral in %s", PM_WARNING_LEVEL_DEFAULT },
|
||||||
|
@ -781,6 +781,15 @@ module Prism
|
|||||||
assert_location(SelfNode, "self")
|
assert_location(SelfNode, "self")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_ShareableConstantNode
|
||||||
|
source = <<~RUBY
|
||||||
|
# shareable_constant_value: literal
|
||||||
|
C = { foo: 1 }
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
assert_location(ShareableConstantNode, source, 36...50)
|
||||||
|
end
|
||||||
|
|
||||||
def test_SingletonClassNode
|
def test_SingletonClassNode
|
||||||
assert_location(SingletonClassNode, "class << self; end")
|
assert_location(SingletonClassNode, "class << self; end")
|
||||||
end
|
end
|
||||||
@ -915,8 +924,7 @@ module Prism
|
|||||||
|
|
||||||
def assert_location(kind, source, expected = 0...source.length, **options)
|
def assert_location(kind, source, expected = 0...source.length, **options)
|
||||||
result = Prism.parse(source, **options)
|
result = Prism.parse(source, **options)
|
||||||
assert_equal [], result.comments
|
assert result.success?
|
||||||
assert_equal [], result.errors
|
|
||||||
|
|
||||||
node = result.value.statements.body.last
|
node = result.value.statements.body.last
|
||||||
node = yield node if block_given?
|
node = yield node if block_given?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user