Skip to content

Conversation

@thomasmarshall
Copy link
Contributor

This PR aims to address #3828 by validating expected node types and wrapping unexpected node types in an ErrorRecoveryNode. This should make it easier for consumer programs to handle invalid Ruby code. For example:

module def foo end

This is parsed as a ModuleNode where constant_path is a DefNode. After this change, constant_path will be an ErrorRecoveryNode with its child set to the DefNode. This way clients can just check PM_NODE_TYPE(PM_ERROR_RECOVERY_NODE) to understand if the expected node is either missing (formerly MissingNode, now ErrorRecoveryNode with empty child) or an unexpected node.

As per the suggestion from @kddnewton, I folded the missing nodes and unexpected nodes into a single ErrorRecoveryNode type. I also added tests for currently known error recovery scenarios and switched to validating expected node types at the callsites rather than in the constructors.

From an implementation perspective, I think it could be nicer to have comprehensive validations in the constructors because it doesn't require understanding any of the parsing logic (I think my changes are correct, but likely harder to review than validations in constructors). They could also potentially be codegen'd from config.yml somehow but I suppose we'd be doing unnecessary work in cases where unexpected nodes are not possible.

I split the changes into a series of small commits that should make it more straightforward to understand what is changing for each node type:

  • The first commit captures the existing error recovery scenarios in a Ruby test.
  • Then we rename MissingNode to ErrorRecoveryNode.
  • Then we setup the function validation macro.
  • Then there is a separate commit for each node type with an on error case in one of its fields in config.yml.
  • Finally, the last commit removes on error from config.yml as per this suggestion:

I would go ahead and get rid of the on error stuff in config.yml

However, I'm not 100% sure this is what was meant, I might have misunderstood.

This is a somewhat substantial change, so I understand if it's a little more difficult to review or feedback on. I'm very happy to make any changes to the approach and implementation, please just let me know!

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.

1 participant