@@ -10829,14 +10829,37 @@ parser_lex(pm_parser_t *parser) {
1082910829 following = next_newline(following, parser->end - following);
1083010830 }
1083110831
10832- // If the lex state was ignored, or we hit a '.' or a '&.',
10833- // we will lex the ignored newline
10832+ // If the lex state was ignored, we will lex the
10833+ // ignored newline.
10834+ if (lex_state_ignored_p(parser)) {
10835+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10836+ lexed_comment = false;
10837+ goto lex_next_token;
10838+ }
10839+
10840+ // If we hit a '.' or a '&.' we will lex the ignored
10841+ // newline.
10842+ if (following && (
10843+ (peek_at(parser, following) == '.') ||
10844+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10845+ )) {
10846+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10847+ lexed_comment = false;
10848+ goto lex_next_token;
10849+ }
10850+
10851+
10852+ // If we are parsing as CRuby 3.5 or later and we
10853+ // hit a '&&' or a '||' then we will lex the ignored
10854+ // newline.
1083410855 if (
10835- lex_state_ignored_p(parser) ||
10836- (following && (
10837- (peek_at(parser, following) == '.') ||
10838- (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10839- ))
10856+ (parser->version == PM_OPTIONS_VERSION_LATEST) &&
10857+ following && (
10858+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '&') ||
10859+ (peek_at(parser, following) == '|' && peek_at(parser, following + 1) == '|') ||
10860+ (peek_at(parser, following) == 'a' && peek_at(parser, following + 1) == 'n' && peek_at(parser, following + 2) == 'd' && !char_is_identifier(parser, following + 3)) ||
10861+ (peek_at(parser, following) == 'o' && peek_at(parser, following + 1) == 'r' && !char_is_identifier(parser, following + 2))
10862+ )
1084010863 ) {
1084110864 if (!lexed_comment) parser_lex_ignored_newline(parser);
1084210865 lexed_comment = false;
@@ -10876,6 +10899,61 @@ parser_lex(pm_parser_t *parser) {
1087610899 parser->next_start = NULL;
1087710900 LEX(PM_TOKEN_AMPERSAND_DOT);
1087810901 }
10902+
10903+ if (parser->version == PM_OPTIONS_VERSION_LATEST) {
10904+ // If we hit an && then we are in a logical chain
10905+ // and we need to return the logical operator.
10906+ if (peek_at(parser, next_content) == '&' && peek_at(parser, next_content + 1) == '&') {
10907+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10908+ lex_state_set(parser, PM_LEX_STATE_BEG);
10909+ parser->current.start = next_content;
10910+ parser->current.end = next_content + 2;
10911+ parser->next_start = NULL;
10912+ LEX(PM_TOKEN_AMPERSAND_AMPERSAND);
10913+ }
10914+
10915+ // If we hit a || then we are in a logical chain and
10916+ // we need to return the logical operator.
10917+ if (peek_at(parser, next_content) == '|' && peek_at(parser, next_content + 1) == '|') {
10918+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10919+ lex_state_set(parser, PM_LEX_STATE_BEG);
10920+ parser->current.start = next_content;
10921+ parser->current.end = next_content + 2;
10922+ parser->next_start = NULL;
10923+ LEX(PM_TOKEN_PIPE_PIPE);
10924+ }
10925+
10926+ // If we hit an 'and' then we are in a logical chain
10927+ // and we need to return the logical operator.
10928+ if (
10929+ peek_at(parser, next_content) == 'a' &&
10930+ peek_at(parser, next_content + 1) == 'n' &&
10931+ peek_at(parser, next_content + 2) == 'd' &&
10932+ !char_is_identifier(parser, next_content + 3)
10933+ ) {
10934+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10935+ lex_state_set(parser, PM_LEX_STATE_BEG);
10936+ parser->current.start = next_content;
10937+ parser->current.end = next_content + 3;
10938+ parser->next_start = NULL;
10939+ LEX(PM_TOKEN_KEYWORD_AND);
10940+ }
10941+
10942+ // If we hit a 'or' then we are in a logical chain
10943+ // and we need to return the logical operator.
10944+ if (
10945+ peek_at(parser, next_content) == 'o' &&
10946+ peek_at(parser, next_content + 1) == 'r' &&
10947+ !char_is_identifier(parser, next_content + 2)
10948+ ) {
10949+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10950+ lex_state_set(parser, PM_LEX_STATE_BEG);
10951+ parser->current.start = next_content;
10952+ parser->current.end = next_content + 2;
10953+ parser->next_start = NULL;
10954+ LEX(PM_TOKEN_KEYWORD_OR);
10955+ }
10956+ }
1087910957 }
1088010958
1088110959 // At this point we know this is a regular newline, and we can set the
0 commit comments