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

Feature request: Method to test for valid literal method name. #213

Closed
mbj opened this issue Nov 7, 2015 · 4 comments
Closed

Feature request: Method to test for valid literal method name. #213

mbj opened this issue Nov 7, 2015 · 4 comments
Labels

Comments

@mbj
Copy link
Collaborator

mbj commented Nov 7, 2015

For a feature in mutant I need to be able to determine if a given string is a valid literal method name.

While I could simply generate source and attempt to parse it, like:

Parser::CurrentRuby.parse("def #{candidate_method_name}; end")

It would be a horrible use of ad-hoc code generation + parsing:

Input candidate method names like: 'valid_method; end # invalid_crap' would easily bypass the check, as only the prefix of the candidate is checked for validity. Lots of other edge cases like this could be constructed. Its true the resulting AST could be checked for additional nodes, comments being parsed but still: Ugly.

I realize that this feature request could be out of scope of this project. The source of truth for "valid literal method names" is already present in the lexer + parser components, so it might be exposable for the general public, without huge complexity increase.

Or it might even be present in a semi-public API where I'd be happy to use it. Calling into the lexer with a pre set-up state?

@mbj mbj added the question label Nov 7, 2015
@whitequark
Copy link
Owner

Well, actually there is no simpler method to do it that I see. You have the lexer component and the parser component; the lexer has a good bunch of tokens it can emit from expr_fname, and not all of them are valid method names:
1435

whereas the parser has several dozen branches dedicated to making sense of that:
1434

Worse, they all change with Ruby versions.

So what I suggest is doing this, which is actually pretty concise and 100% reliable:

def check_name(name)
  buffer = Parser::Source::Buffer.new('<input>')
  buffer.source = "def #{name}; end"

  Parser::CurrentRuby.new.parse(buffer) == 
    Parser::AST::Node.new(:def, [name.to_sym, 
      Parser::AST::Node.new(:args), nil])
rescue Parser::SyntaxError
  false
end

@mbj
Copy link
Collaborator Author

mbj commented Nov 7, 2015

@whitequark Thx. Just to be sure we are on the same page: Will this account for the fact when part of the name to check is interpreted as a comment?

@whitequark
Copy link
Owner

Sure, it checks that the name that the parser returned is the same as the input.

@mbj
Copy link
Collaborator Author

mbj commented Nov 7, 2015

k, thx. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants