mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
parent
d0b778cd19
commit
d282e76fb6
@ -7,17 +7,14 @@ if (method = Kernel.instance_method(:warn)).respond_to?(:parameters) ? method.pa
|
||||
Kernel.prepend(
|
||||
Module.new {
|
||||
def warn(*msgs, uplevel: nil, category: nil) # :nodoc:
|
||||
uplevel =
|
||||
case uplevel
|
||||
when nil
|
||||
1
|
||||
when Integer
|
||||
uplevel + 1
|
||||
else
|
||||
uplevel.to_int + 1
|
||||
end
|
||||
|
||||
super(*msgs, uplevel: uplevel)
|
||||
case uplevel
|
||||
when nil
|
||||
super(*msgs)
|
||||
when Integer
|
||||
super(*msgs, uplevel: uplevel + 1)
|
||||
else
|
||||
super(*msgs, uplevel: uplevel.to_int + 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
)
|
||||
@ -25,17 +22,14 @@ if (method = Kernel.instance_method(:warn)).respond_to?(:parameters) ? method.pa
|
||||
Object.prepend(
|
||||
Module.new {
|
||||
def warn(*msgs, uplevel: nil, category: nil) # :nodoc:
|
||||
uplevel =
|
||||
case uplevel
|
||||
when nil
|
||||
1
|
||||
when Integer
|
||||
uplevel + 1
|
||||
else
|
||||
uplevel.to_int + 1
|
||||
end
|
||||
|
||||
super(*msgs, uplevel: uplevel)
|
||||
case uplevel
|
||||
when nil
|
||||
super(*msgs)
|
||||
when Integer
|
||||
super(*msgs, uplevel: uplevel + 1)
|
||||
else
|
||||
super(*msgs, uplevel: uplevel.to_int + 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "prism"
|
||||
spec.version = "1.5.1"
|
||||
spec.version = "1.5.2"
|
||||
spec.authors = ["Shopify"]
|
||||
spec.email = ["ruby@shopify.com"]
|
||||
|
||||
|
||||
@ -19,6 +19,13 @@ module Prism
|
||||
# whitequark/parser gem's syntax tree. It inherits from the base parser for
|
||||
# the parser gem, and overrides the parse* methods to parse with prism and
|
||||
# then translate.
|
||||
#
|
||||
# Note that this version of the parser always parses using the latest
|
||||
# version of Ruby syntax supported by Prism. If you want specific version
|
||||
# support, use one of the version-specific subclasses, such as
|
||||
# `Prism::Translation::Parser34`. If you want to parse using the same
|
||||
# version of Ruby syntax as the currently running version of Ruby, use
|
||||
# `Prism::Translation::ParserCurrent`.
|
||||
class Parser < ::Parser::Base
|
||||
Diagnostic = ::Parser::Diagnostic # :nodoc:
|
||||
private_constant :Diagnostic
|
||||
@ -77,7 +84,7 @@ module Prism
|
||||
end
|
||||
|
||||
def version # :nodoc:
|
||||
34
|
||||
35
|
||||
end
|
||||
|
||||
# The default encoding for Ruby files is UTF-8.
|
||||
|
||||
@ -152,7 +152,7 @@ module Prism
|
||||
# ^^
|
||||
# ```
|
||||
def visit_back_reference_read_node(node)
|
||||
s(node, :back_ref, node.name.name.delete_prefix("$").to_sym)
|
||||
s(node, :back_ref, node.name.to_s.delete_prefix("$").to_sym)
|
||||
end
|
||||
|
||||
# ```
|
||||
|
||||
@ -60,6 +60,7 @@ errors:
|
||||
- CONDITIONAL_WHILE_PREDICATE
|
||||
- CONSTANT_PATH_COLON_COLON_CONSTANT
|
||||
- DEF_ENDLESS
|
||||
- DEF_ENDLESS_PARAMETERS
|
||||
- DEF_ENDLESS_SETTER
|
||||
- DEF_NAME
|
||||
- DEF_PARAMS_TERM
|
||||
@ -1800,7 +1801,7 @@ nodes:
|
||||
Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
|
||||
|
||||
case true; when false; end
|
||||
^^^^
|
||||
^^^^
|
||||
- name: conditions
|
||||
type: node[]
|
||||
kind: WhenNode
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef PRISM_EXT_NODE_H
|
||||
#define PRISM_EXT_NODE_H
|
||||
|
||||
#define EXPECTED_PRISM_VERSION "1.5.1"
|
||||
#define EXPECTED_PRISM_VERSION "1.5.2"
|
||||
|
||||
#include <ruby.h>
|
||||
#include <ruby/encoding.h>
|
||||
|
||||
@ -2622,10 +2622,11 @@ pm_break_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_argument
|
||||
// There are certain flags that we want to use internally but don't want to
|
||||
// expose because they are not relevant beyond parsing. Therefore we'll define
|
||||
// them here and not define them in config.yml/a header file.
|
||||
static const pm_node_flags_t PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY = 0x4;
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY = 0x40;
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_COMPARISON = 0x80;
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_INDEX = 0x100;
|
||||
static const pm_node_flags_t PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY = (1 << 2);
|
||||
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY = ((PM_CALL_NODE_FLAGS_LAST - 1) << 1);
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_COMPARISON = ((PM_CALL_NODE_FLAGS_LAST - 1) << 2);
|
||||
static const pm_node_flags_t PM_CALL_NODE_FLAGS_INDEX = ((PM_CALL_NODE_FLAGS_LAST - 1) << 3);
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new CallNode node. This sets everything to NULL or
|
||||
@ -5279,6 +5280,12 @@ pm_interpolated_string_node_append(pm_interpolated_string_node_t *node, pm_node_
|
||||
|
||||
switch (PM_NODE_TYPE(part)) {
|
||||
case PM_STRING_NODE:
|
||||
// If inner string is not frozen, it stops being a static literal. We should *not* clear other flags,
|
||||
// because concatenating two frozen strings (`'foo' 'bar'`) is still frozen. This holds true for
|
||||
// as long as this interpolation only consists of other string literals.
|
||||
if (!PM_NODE_FLAG_P(part, PM_STRING_FLAGS_FROZEN)) {
|
||||
pm_node_flag_unset((pm_node_t *) node, PM_NODE_FLAG_STATIC_LITERAL);
|
||||
}
|
||||
part->flags = (pm_node_flags_t) ((part->flags | PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN) & ~PM_STRING_FLAGS_MUTABLE);
|
||||
break;
|
||||
case PM_INTERPOLATED_STRING_NODE:
|
||||
@ -14443,6 +14450,17 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
||||
if (accepted_newline) {
|
||||
pm_parser_err_previous(parser, PM_ERR_INVALID_COMMA);
|
||||
}
|
||||
|
||||
// If this is a command call and an argument takes a block,
|
||||
// there can be no further arguments. For example,
|
||||
// `foo(bar 1 do end, 2)` should be rejected.
|
||||
if (PM_NODE_TYPE_P(argument, PM_CALL_NODE)) {
|
||||
pm_call_node_t *call = (pm_call_node_t *) argument;
|
||||
if (call->opening_loc.start == NULL && call->arguments != NULL && call->block != NULL) {
|
||||
pm_parser_err_previous(parser, PM_ERR_INVALID_COMMA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no comma at the end of the argument list then we're
|
||||
// done parsing arguments and can break out of this loop.
|
||||
@ -14594,6 +14612,18 @@ update_parameter_state(pm_parser_t *parser, pm_token_t *token, pm_parameters_ord
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that after parsing a parameter, the next token is not `=`.
|
||||
* Some parameters like `def(* = 1)` cannot become optional. When no parens
|
||||
* are present like in `def * = 1`, this creates ambiguity with endless method definitions.
|
||||
*/
|
||||
static inline void
|
||||
refute_optional_parameter(pm_parser_t *parser) {
|
||||
if (match1(parser, PM_TOKEN_EQUAL)) {
|
||||
pm_parser_err_previous(parser, PM_ERR_DEF_ENDLESS_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of parameters on a method definition.
|
||||
*/
|
||||
@ -14646,6 +14676,10 @@ parse_parameters(
|
||||
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_BLOCK;
|
||||
}
|
||||
|
||||
if (!uses_parentheses) {
|
||||
refute_optional_parameter(parser);
|
||||
}
|
||||
|
||||
pm_block_parameter_node_t *param = pm_block_parameter_node_create(parser, &name, &operator);
|
||||
if (repeated) {
|
||||
pm_node_flag_set_repeated_parameter((pm_node_t *)param);
|
||||
@ -14667,6 +14701,10 @@ parse_parameters(
|
||||
bool succeeded = update_parameter_state(parser, &parser->current, &order);
|
||||
parser_lex(parser);
|
||||
|
||||
if (!uses_parentheses) {
|
||||
refute_optional_parameter(parser);
|
||||
}
|
||||
|
||||
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_ALL;
|
||||
pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous);
|
||||
|
||||
@ -14848,6 +14886,10 @@ parse_parameters(
|
||||
context_pop(parser);
|
||||
pm_parameters_node_keywords_append(params, param);
|
||||
|
||||
if (!uses_parentheses) {
|
||||
refute_optional_parameter(parser);
|
||||
}
|
||||
|
||||
// If parsing the value of the parameter resulted in error recovery,
|
||||
// then we can put a missing node in its place and stop parsing the
|
||||
// parameters entirely now.
|
||||
@ -14879,6 +14921,10 @@ parse_parameters(
|
||||
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS;
|
||||
}
|
||||
|
||||
if (!uses_parentheses) {
|
||||
refute_optional_parameter(parser);
|
||||
}
|
||||
|
||||
pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name);
|
||||
if (repeated) {
|
||||
pm_node_flag_set_repeated_parameter(param);
|
||||
@ -14927,6 +14973,10 @@ parse_parameters(
|
||||
}
|
||||
}
|
||||
|
||||
if (!uses_parentheses) {
|
||||
refute_optional_parameter(parser);
|
||||
}
|
||||
|
||||
if (params->keyword_rest == NULL) {
|
||||
pm_parameters_node_keyword_rest_set(params, param);
|
||||
} else {
|
||||
@ -18491,20 +18541,28 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
||||
return (pm_node_t *) node;
|
||||
}
|
||||
case PM_TOKEN_CHARACTER_LITERAL: {
|
||||
parser_lex(parser);
|
||||
|
||||
pm_token_t opening = parser->previous;
|
||||
opening.type = PM_TOKEN_STRING_BEGIN;
|
||||
opening.end = opening.start + 1;
|
||||
|
||||
pm_token_t content = parser->previous;
|
||||
content.type = PM_TOKEN_STRING_CONTENT;
|
||||
content.start = content.start + 1;
|
||||
|
||||
pm_token_t closing = not_provided(parser);
|
||||
pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &content, &closing);
|
||||
pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(
|
||||
parser,
|
||||
&(pm_token_t) {
|
||||
.type = PM_TOKEN_STRING_BEGIN,
|
||||
.start = parser->current.start,
|
||||
.end = parser->current.start + 1
|
||||
},
|
||||
&(pm_token_t) {
|
||||
.type = PM_TOKEN_STRING_CONTENT,
|
||||
.start = parser->current.start + 1,
|
||||
.end = parser->current.end
|
||||
},
|
||||
&closing
|
||||
);
|
||||
|
||||
pm_node_flag_set(node, parse_unescaped_encoding(parser));
|
||||
|
||||
// Skip past the character literal here, since now we have handled
|
||||
// parser->explicit_encoding correctly.
|
||||
parser_lex(parser);
|
||||
|
||||
// Characters can be followed by strings in which case they are
|
||||
// automatically concatenated.
|
||||
if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
|
||||
@ -20901,7 +20959,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
|
||||
bool permitted = true;
|
||||
if (previous_binding_power != PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_USTAR)) permitted = false;
|
||||
|
||||
pm_node_t *value = parse_starred_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id, (uint16_t) (depth + 1));
|
||||
pm_node_t *value = parse_starred_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MODIFIER, diag_id, (uint16_t) (depth + 1));
|
||||
if (!permitted) pm_parser_err_node(parser, value, PM_ERR_UNEXPECTED_MULTI_WRITE);
|
||||
|
||||
parse_assignment_value_local(parser, value);
|
||||
@ -22498,9 +22556,10 @@ parse_program(pm_parser_t *parser) {
|
||||
statements = wrap_statements(parser, statements);
|
||||
} else {
|
||||
flush_block_exits(parser, previous_block_exits);
|
||||
pm_node_list_free(¤t_block_exits);
|
||||
}
|
||||
|
||||
pm_node_list_free(¤t_block_exits);
|
||||
|
||||
// If this is an empty file, then we're still going to parse all of the
|
||||
// statements in order to gather up all of the comments and such. Here we'll
|
||||
// correct the location information.
|
||||
|
||||
@ -212,6 +212,8 @@ typedef enum pm_<%= flag.human %> {
|
||||
/** <%= value.comment %> */
|
||||
PM_<%= flag.human.upcase %>_<%= value.name %> = <%= 1 << (index + Prism::Template::COMMON_FLAGS_COUNT) %>,
|
||||
<%- end -%>
|
||||
|
||||
PM_<%= flag.human.upcase %>_LAST,
|
||||
} pm_<%= flag.human %>_t;
|
||||
<%- end -%>
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ module Prism
|
||||
|
||||
# The patch version of prism that we are expecting to find in the serialized
|
||||
# strings.
|
||||
PATCH_VERSION = 1
|
||||
PATCH_VERSION = 2
|
||||
|
||||
# Deserialize the dumped output from a request to parse or parse_file.
|
||||
#
|
||||
|
||||
@ -144,6 +144,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
||||
[PM_ERR_CONDITIONAL_WHILE_PREDICATE] = { "expected a predicate expression for the `while` statement", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = { "expected a constant after the `::` operator", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_DEF_ENDLESS] = { "could not parse the endless method body", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_DEF_ENDLESS_PARAMETERS] = { "could not parse the endless method parameters", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_DEF_ENDLESS_SETTER] = { "invalid method name; a setter method cannot be defined in an endless method definition", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_DEF_NAME] = { "unexpected %s; expected a method name", PM_ERROR_LEVEL_SYNTAX },
|
||||
[PM_ERR_DEF_PARAMS_TERM] = { "expected a delimiter to close the parameters", PM_ERROR_LEVEL_SYNTAX },
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "prism/util/pm_string.h"
|
||||
|
||||
static const uint8_t empty_source[] = "";
|
||||
|
||||
/**
|
||||
* Returns the size of the pm_string_t struct. This is necessary to allocate the
|
||||
* correct amount of memory in the FFI backend.
|
||||
@ -133,8 +135,7 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
||||
// the source to a constant empty string and return.
|
||||
if (file_size == 0) {
|
||||
pm_string_file_handle_close(&handle);
|
||||
const uint8_t source[] = "";
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
|
||||
return PM_STRING_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -182,8 +183,7 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
||||
|
||||
if (size == 0) {
|
||||
close(fd);
|
||||
const uint8_t source[] = "";
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
|
||||
return PM_STRING_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -225,8 +225,7 @@ pm_string_file_init(pm_string_t *string, const char *filepath) {
|
||||
// the source to a constant empty string and return.
|
||||
if (file_size == 0) {
|
||||
pm_string_file_handle_close(&handle);
|
||||
const uint8_t source[] = "";
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
|
||||
return PM_STRING_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -278,8 +277,7 @@ pm_string_file_init(pm_string_t *string, const char *filepath) {
|
||||
size_t size = (size_t) sb.st_size;
|
||||
if (size == 0) {
|
||||
close(fd);
|
||||
const uint8_t source[] = "";
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
|
||||
return PM_STRING_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -19,11 +19,11 @@
|
||||
/**
|
||||
* The patch version of the Prism library as an int.
|
||||
*/
|
||||
#define PRISM_VERSION_PATCH 1
|
||||
#define PRISM_VERSION_PATCH 2
|
||||
|
||||
/**
|
||||
* The version of the Prism library as a constant string.
|
||||
*/
|
||||
#define PRISM_VERSION "1.5.1"
|
||||
#define PRISM_VERSION "1.5.2"
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
[a b]
|
||||
^ unexpected local variable or method; expected a `,` separator for the array elements
|
||||
|
||||
|
||||
[
|
||||
a b do
|
||||
^ unexpected local variable or method; expected a `,` separator for the array elements
|
||||
end,
|
||||
]
|
||||
|
||||
|
||||
6
test/prism/errors/command_calls_33.txt
Normal file
6
test/prism/errors/command_calls_33.txt
Normal file
@ -0,0 +1,6 @@
|
||||
1 if foo = bar baz
|
||||
^~~ unexpected local variable or method, expecting end-of-input
|
||||
|
||||
1 and foo = bar baz
|
||||
^~~ unexpected local variable or method, expecting end-of-input
|
||||
|
||||
24
test/prism/errors/command_calls_34.txt
Normal file
24
test/prism/errors/command_calls_34.txt
Normal file
@ -0,0 +1,24 @@
|
||||
foo(bar 1 do end, 2)
|
||||
^ invalid comma
|
||||
^ unexpected integer; expected a `)` to close the arguments
|
||||
^ unexpected integer, expecting end-of-input
|
||||
^ unexpected ')', expecting end-of-input
|
||||
^ unexpected ')', ignoring it
|
||||
|
||||
foo(bar 1 do end,)
|
||||
^ invalid comma
|
||||
|
||||
foo(1, bar 2 do end)
|
||||
^ unexpected integer; expected a `)` to close the arguments
|
||||
^ unexpected integer, expecting end-of-input
|
||||
^~ unexpected 'do', expecting end-of-input
|
||||
^~ unexpected 'do', ignoring it
|
||||
^~~ unexpected 'end', ignoring it
|
||||
^ unexpected ')', ignoring it
|
||||
|
||||
foo(1, bar 2)
|
||||
^ unexpected integer; expected a `)` to close the arguments
|
||||
^ unexpected integer, expecting end-of-input
|
||||
^ unexpected ')', expecting end-of-input
|
||||
^ unexpected ')', ignoring it
|
||||
|
||||
6
test/prism/errors/def_with_optional_splat.txt
Normal file
6
test/prism/errors/def_with_optional_splat.txt
Normal file
@ -0,0 +1,6 @@
|
||||
def foo(*bar = nil); end
|
||||
^ unexpected '='; expected a `)` to close the parameters
|
||||
^ unexpected ')', expecting end-of-input
|
||||
^ unexpected ')', ignoring it
|
||||
^~~ unexpected 'end', ignoring it
|
||||
|
||||
24
test/prism/errors/endless_method_command_call_parameters.txt
Normal file
24
test/prism/errors/endless_method_command_call_parameters.txt
Normal file
@ -0,0 +1,24 @@
|
||||
def f x: = 1
|
||||
^~ could not parse the endless method parameters
|
||||
|
||||
def f ... = 1
|
||||
^~~ could not parse the endless method parameters
|
||||
|
||||
def f * = 1
|
||||
^ could not parse the endless method parameters
|
||||
|
||||
def f ** = 1
|
||||
^~ could not parse the endless method parameters
|
||||
|
||||
def f & = 1
|
||||
^ could not parse the endless method parameters
|
||||
|
||||
def f *a = 1
|
||||
^ could not parse the endless method parameters
|
||||
|
||||
def f **a = 1
|
||||
^ could not parse the endless method parameters
|
||||
|
||||
def f &a = 1
|
||||
^ could not parse the endless method parameters
|
||||
|
||||
2
test/prism/fixtures/character_literal.txt
Normal file
2
test/prism/fixtures/character_literal.txt
Normal file
@ -0,0 +1,2 @@
|
||||
# encoding: Windows-31J
|
||||
p ?\u3042""
|
||||
3
test/prism/fixtures/command_method_call_2.txt
Normal file
3
test/prism/fixtures/command_method_call_2.txt
Normal file
@ -0,0 +1,3 @@
|
||||
foo(bar baz do end)
|
||||
|
||||
foo(bar baz, bat)
|
||||
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
'foo' 'bar'
|
||||
|
||||
'foo' 'bar' "baz#{bat}"
|
||||
5
test/prism/fixtures/string_concatination_frozen_true.txt
Normal file
5
test/prism/fixtures/string_concatination_frozen_true.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
'foo' 'bar'
|
||||
|
||||
'foo' 'bar' "baz#{bat}"
|
||||
@ -27,6 +27,8 @@ module Prism
|
||||
# Leaving these out until they are supported by parse.y.
|
||||
except << "leading_logical.txt"
|
||||
except << "endless_methods_command_call.txt"
|
||||
# https://bugs.ruby-lang.org/issues/21168#note-5
|
||||
except << "command_method_call_2.txt"
|
||||
|
||||
Fixture.each(except: except) do |fixture|
|
||||
define_method(fixture.test_name) { assert_valid_syntax(fixture.read) }
|
||||
|
||||
@ -48,6 +48,9 @@ module Prism
|
||||
# https://bugs.ruby-lang.org/issues/17398#note-12
|
||||
except << "endless_methods_command_call.txt"
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/21168#note-5
|
||||
except << "command_method_call_2.txt"
|
||||
|
||||
Fixture.each(except: except) do |fixture|
|
||||
define_method(fixture.test_name) { assert_lex(fixture) }
|
||||
end
|
||||
|
||||
@ -33,7 +33,8 @@ module Prism
|
||||
|
||||
# Leaving these out until they are supported by parse.y.
|
||||
"leading_logical.txt",
|
||||
"endless_methods_command_call.txt"
|
||||
"endless_methods_command_call.txt",
|
||||
"command_method_call_2.txt"
|
||||
]
|
||||
|
||||
Fixture.each(except: except) do |fixture|
|
||||
|
||||
@ -70,6 +70,9 @@ module Prism
|
||||
|
||||
# Ruby >= 3.5 specific syntax
|
||||
"endless_methods_command_call.txt",
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/21168#note-5
|
||||
"command_method_call_2.txt",
|
||||
]
|
||||
|
||||
# These files contain code that is being parsed incorrectly by the parser
|
||||
|
||||
@ -33,6 +33,9 @@ module Prism
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/17398#note-12
|
||||
"endless_methods_command_call.txt",
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/21168#note-5
|
||||
"command_method_call_2.txt",
|
||||
]
|
||||
|
||||
# Skip these tests that we haven't implemented yet.
|
||||
|
||||
@ -16,6 +16,7 @@ end
|
||||
module Prism
|
||||
class RubyParserTest < TestCase
|
||||
todos = [
|
||||
"character_literal.txt",
|
||||
"encoding_euc_jp.txt",
|
||||
"regex_char_width.txt",
|
||||
"seattlerb/masgn_colon3.txt",
|
||||
@ -78,6 +79,9 @@ module Prism
|
||||
|
||||
# Ruby >= 3.5 specific syntax
|
||||
"endless_methods_command_call.txt",
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/21168#note-5
|
||||
"command_method_call_2.txt",
|
||||
]
|
||||
|
||||
Fixture.each(except: failures) do |fixture|
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user