@@ -10842,14 +10842,37 @@ parser_lex(pm_parser_t *parser) {
10842
10842
following = next_newline(following, parser->end - following);
10843
10843
}
10844
10844
10845
- // If the lex state was ignored, or we hit a '.' or a '&.',
10846
- // we will lex the ignored newline
10845
+ // If the lex state was ignored, we will lex the
10846
+ // ignored newline.
10847
+ if (lex_state_ignored_p(parser)) {
10848
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10849
+ lexed_comment = false;
10850
+ goto lex_next_token;
10851
+ }
10852
+
10853
+ // If we hit a '.' or a '&.' we will lex the ignored
10854
+ // newline.
10855
+ if (following && (
10856
+ (peek_at(parser, following) == '.') ||
10857
+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10858
+ )) {
10859
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10860
+ lexed_comment = false;
10861
+ goto lex_next_token;
10862
+ }
10863
+
10864
+
10865
+ // If we are parsing as CRuby 3.5 or later and we
10866
+ // hit a '&&' or a '||' then we will lex the ignored
10867
+ // newline.
10847
10868
if (
10848
- lex_state_ignored_p(parser) ||
10849
- (following && (
10850
- (peek_at(parser, following) == '.') ||
10851
- (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10852
- ))
10869
+ (parser->version == PM_OPTIONS_VERSION_LATEST) &&
10870
+ following && (
10871
+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '&') ||
10872
+ (peek_at(parser, following) == '|' && peek_at(parser, following + 1) == '|') ||
10873
+ (peek_at(parser, following) == 'a' && peek_at(parser, following + 1) == 'n' && peek_at(parser, following + 2) == 'd' && !char_is_identifier(parser, following + 3, parser->end - (following + 3))) ||
10874
+ (peek_at(parser, following) == 'o' && peek_at(parser, following + 1) == 'r' && !char_is_identifier(parser, following + 2, parser->end - (following + 2)))
10875
+ )
10853
10876
) {
10854
10877
if (!lexed_comment) parser_lex_ignored_newline(parser);
10855
10878
lexed_comment = false;
@@ -10889,6 +10912,63 @@ parser_lex(pm_parser_t *parser) {
10889
10912
parser->next_start = NULL;
10890
10913
LEX(PM_TOKEN_AMPERSAND_DOT);
10891
10914
}
10915
+
10916
+ if (parser->version == PM_OPTIONS_VERSION_LATEST) {
10917
+ // If we hit an && then we are in a logical chain
10918
+ // and we need to return the logical operator.
10919
+ if (peek_at(parser, next_content) == '&' && peek_at(parser, next_content + 1) == '&') {
10920
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10921
+ lex_state_set(parser, PM_LEX_STATE_BEG);
10922
+ parser->current.start = next_content;
10923
+ parser->current.end = next_content + 2;
10924
+ parser->next_start = NULL;
10925
+ LEX(PM_TOKEN_AMPERSAND_AMPERSAND);
10926
+ }
10927
+
10928
+ // If we hit a || then we are in a logical chain and
10929
+ // we need to return the logical operator.
10930
+ if (peek_at(parser, next_content) == '|' && peek_at(parser, next_content + 1) == '|') {
10931
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10932
+ lex_state_set(parser, PM_LEX_STATE_BEG);
10933
+ parser->current.start = next_content;
10934
+ parser->current.end = next_content + 2;
10935
+ parser->next_start = NULL;
10936
+ LEX(PM_TOKEN_PIPE_PIPE);
10937
+ }
10938
+
10939
+ // If we hit an 'and' then we are in a logical chain
10940
+ // and we need to return the logical operator.
10941
+ if (
10942
+ peek_at(parser, next_content) == 'a' &&
10943
+ peek_at(parser, next_content + 1) == 'n' &&
10944
+ peek_at(parser, next_content + 2) == 'd' &&
10945
+ !char_is_identifier(parser, next_content + 3, parser->end - (next_content + 3))
10946
+ ) {
10947
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10948
+ lex_state_set(parser, PM_LEX_STATE_BEG);
10949
+ parser->current.start = next_content;
10950
+ parser->current.end = next_content + 3;
10951
+ parser->next_start = NULL;
10952
+ parser->command_start = true;
10953
+ LEX(PM_TOKEN_KEYWORD_AND);
10954
+ }
10955
+
10956
+ // If we hit a 'or' then we are in a logical chain
10957
+ // and we need to return the logical operator.
10958
+ if (
10959
+ peek_at(parser, next_content) == 'o' &&
10960
+ peek_at(parser, next_content + 1) == 'r' &&
10961
+ !char_is_identifier(parser, next_content + 2, parser->end - (next_content + 2))
10962
+ ) {
10963
+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10964
+ lex_state_set(parser, PM_LEX_STATE_BEG);
10965
+ parser->current.start = next_content;
10966
+ parser->current.end = next_content + 2;
10967
+ parser->next_start = NULL;
10968
+ parser->command_start = true;
10969
+ LEX(PM_TOKEN_KEYWORD_OR);
10970
+ }
10971
+ }
10892
10972
}
10893
10973
10894
10974
// At this point we know this is a regular newline, and we can set the
0 commit comments