Skip to content
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
17 changes: 2 additions & 15 deletions lib/prism/parse_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,8 @@ def deep_freeze
# Binary search through the offsets to find the line number for the given
# byte offset.
def find_line(byte_offset)
left = 0
right = offsets.length - 1

while left <= right
mid = left + (right - left) / 2
return mid if (offset = offsets[mid]) == byte_offset

if offset < byte_offset
left = mid + 1
else
right = mid - 1
end
end

left - 1
index = offsets.bsearch_index { |offset| offset > byte_offset } || offsets.length
index - 1
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/tempfile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,8 @@ def open(*args, **kw)
#
# Implementation note:
#
# The keyword argument +anonymous=true+ is implemented using FILE_SHARE_DELETE on Windows.
# O_TMPFILE is used on Linux.
# The keyword argument <tt>anonymous=true</tt> is implemented using +FILE_SHARE_DELETE+ on Windows.
# +O_TMPFILE+ is used on Linux.
#
# Related: Tempfile.new.
#
Expand Down
15 changes: 9 additions & 6 deletions prism/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1860,7 +1860,7 @@ nodes:
comment: |
Represents the location of the `class` keyword.

class Foo; end
class Foo end
^^^^^
- name: constant_path
type: node
Expand Down Expand Up @@ -1899,19 +1899,19 @@ nodes:
comment: |
Represents the location of the `end` keyword.

class Foo; end
^^^
class Foo end
^^^
- name: name
type: constant
comment: |
The name of the class.

class Foo; end # name `:Foo`
class Foo end # name `:Foo`
comment: |
Represents a class declaration involving the `class` keyword.

class Foo; end
^^^^^^^^^^^^^^
class Foo end
^^^^^^^^^^^^^
- name: ClassVariableAndWriteNode
fields:
- name: name
Expand Down Expand Up @@ -3306,6 +3306,9 @@ nodes:
- EmbeddedVariableNode
- InterpolatedStringNode # `"a" "#{b}"`
- on error: XStringNode # `<<`FOO` "bar"
- on error: InterpolatedXStringNode
- on error: SymbolNode
- on error: InterpolatedSymbolNode
- name: closing_loc
type: location?
newline: parts
Expand Down
18 changes: 12 additions & 6 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -5344,8 +5344,10 @@ pm_interpolated_string_node_append(pm_interpolated_string_node_t *node, pm_node_
break;
case PM_X_STRING_NODE:
case PM_INTERPOLATED_X_STRING_NODE:
// If this is an x string, then this is a syntax error. But we want
// to handle it here so that we don't fail the assertion.
case PM_SYMBOL_NODE:
case PM_INTERPOLATED_SYMBOL_NODE:
// These will only happen in error cases. But we want to handle it
// here so that we don't fail the assertion.
CLEAR_FLAGS(node);
break;
default:
Expand Down Expand Up @@ -8443,7 +8445,7 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
if (*cursor == '\\' && (cursor + 1 < end)) cursor++;
}
value_end = cursor;
if (*cursor == '"') cursor++;
if (cursor < end && *cursor == '"') cursor++;
} else {
value_start = cursor;
while (cursor < end && *cursor != '"' && *cursor != ';' && !pm_char_is_whitespace(*cursor)) cursor++;
Expand Down Expand Up @@ -17336,7 +17338,11 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
pm_node_t *value = NULL;

if (match7(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
value = parse_pattern_hash_implicit_value(parser, captures, (pm_symbol_node_t *) key);
if (PM_NODE_TYPE_P(key, PM_SYMBOL_NODE)) {
value = parse_pattern_hash_implicit_value(parser, captures, (pm_symbol_node_t *) key);
} else {
value = (pm_node_t *) pm_missing_node_create(parser, key->location.end, key->location.end);
}
} else {
value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, (uint16_t) (depth + 1));
}
Expand Down Expand Up @@ -22861,8 +22867,8 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
// If the shebang does not include "ruby" and this is the main script being
// parsed, then we will start searching the file for a shebang that does
// contain "ruby" as if -x were passed on the command line.
const uint8_t *newline = next_newline(parser->start, parser->end - parser->start);
size_t length = (size_t) ((newline != NULL ? newline : parser->end) - parser->start);
const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end);
size_t length = (size_t) ((newline != NULL ? newline : parser->end) - parser->current.end);

if (length > 2 && parser->current.end[0] == '#' && parser->current.end[1] == '!') {
const char *engine;
Expand Down
14 changes: 14 additions & 0 deletions test/prism/errors/label_in_interpolated_string.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
case in el""Q
^~~~ expected a predicate for a case matching statement
^ expected a delimiter after the patterns of an `in` clause
^ unexpected constant, expecting end-of-input
!"""#{in el"":Q
^~ unexpected 'in', assuming it is closing the parent 'in' clause
^ expected a `}` to close the embedded expression
^~ cannot parse the string part
^~ cannot parse the string part
^ cannot parse the string part
^~~~~~~~~~~ unexpected label
^~~~~~~~~~~ expected a string for concatenation
^ expected an `end` to close the `case` statement

8 changes: 8 additions & 0 deletions test/prism/errors/pattern_string_key.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
case:a
in b:"","#{}"
^~~~~ expected a label after the `,` in the hash pattern
^ expected a pattern expression after the key
^ expected a delimiter after the patterns of an `in` clause
^ unexpected end-of-input, assuming it is closing the parent top level context
^ expected an `end` to close the `case` statement