Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StrNode#single_quoted?, StrNode#double_quoted? and StrNode#percent_literal? to simplify checking for string delimiters #343

Merged
merged 1 commit into from
Dec 13, 2024

Conversation

dvandersluis
Copy link
Member

@dvandersluis dvandersluis commented Dec 12, 2024

This would allow rubocop code that checks for different string delimiter types to do so in a simpler way.

I took inspiration from ArrayNode#percent_literal? for the interface for StrNode#percent_literal?.

@dvandersluis dvandersluis marked this pull request as ready for review December 12, 2024 15:51
@dvandersluis dvandersluis changed the title Add StrNode#single_quoted?, StrNode#double_quoted? and StrNode#percent_literal?` to simplify checking for string delimiters Add StrNode#single_quoted?, StrNode#double_quoted? and StrNode#percent_literal? to simplify checking for string delimiters Dec 12, 2024
@dvandersluis dvandersluis force-pushed the str-node-percent-literal branch 2 times, most recently from 1db7de5 to c61b2e6 Compare December 12, 2024 15:53
Comment on lines 12 to 14
:% => /^%(?![qQ])/,
:q => /^%q/,
:Q => /^%Q/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that matching the beginning of lines in a multiline string is not expected.

Suggested change
:% => /^%(?![qQ])/,
:q => /^%q/,
:Q => /^%Q/
:% => /\A%(?![qQ])/,
:q => /\A%q/,
:Q => /\A%Q/

return false unless opening_delimiter

if type
opening_delimiter.source =~ PERCENT_LITERAL_TYPES[type]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the captured value is not used, match? seems to be the best choice.

Suggested change
opening_delimiter.source =~ PERCENT_LITERAL_TYPES[type]
opening_delimiter.source.match?(PERCENT_LITERAL_TYPES[type])

@@ -8,13 +8,56 @@ module AST
class StrNode < Node
include BasicLiteralNode

PERCENT_LITERAL_TYPES = {
:% => /^%(?![qQ])/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%%foo%, probably to the horror of some, is a valid string. I'm not sure if any cop currently cares, just wanted to point it out. I'm not 100% on what would be a valid delimiter for these, maybe [^a-zA-Z] would be good enough?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd still be a %(...) string though, wouldn't it? The extra %s replace brackets but the macro type is still a single %.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. It's in a similar vein as %w!a! being a valid array (hopefully no one actually writes such code).

@dvandersluis dvandersluis force-pushed the str-node-percent-literal branch from c61b2e6 to d015111 Compare December 12, 2024 17:46
@dvandersluis
Copy link
Member Author

Thanks @koic and @Earlopain, the requested changes have been made.

return false unless opening_delimiter

if type
opening_delimiter.source.match?(PERCENT_LITERAL_TYPES[type])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use fetch for a better error message in case type doesn't have an expected value

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

private

def opening_delimiter
return unless loc.respond_to?(:begin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that a str node's location does not respond to begin?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We could use loc_is? that I propose in #345)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that a str node's location does not respond to begin?

Yes, there are str nodes without delimiters inside other nodes (such as dstr or regexp, not an exhaustive list) that have no delimiters and thus no loc.begin. I added a test to cover this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We could use loc_is? that I propose in #345)

I like it!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use loc_is? now.

…ercent_literal?` to simplify checking for string delimiters
@dvandersluis dvandersluis force-pushed the str-node-percent-literal branch from d015111 to 1df9114 Compare December 13, 2024 01:59
@marcandre marcandre merged commit 2abbc5f into rubocop:master Dec 13, 2024
20 checks passed
@dvandersluis dvandersluis deleted the str-node-percent-literal branch December 13, 2024 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants