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

relax parse error behavior #44

Merged
merged 8 commits into from Mar 18, 2022
Merged

Conversation

hendrikvanantwerpen
Copy link
Collaborator

@hendrikvanantwerpen hendrikvanantwerpen commented Feb 17, 2022

  • Improve display of parse errors
  • Move parse error check to CLI
  • Add flag to allow parse errors
  • Skip tree traversal unless there are errors

Example verbose error:

Unexpected syntax on line 3 column 17:

| type U = { X: { f number } };
                  ^

Example compact error:

Unexpected syntax on line 3 column 17: f

Can be reviewed commit-by-commit

tausbn
tausbn previously requested changes Feb 17, 2022
Copy link
Collaborator

@tausbn tausbn left a comment

Choose a reason for hiding this comment

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

I have a few comments and suggestions, but apart from that this looks really nice! I like the way you've moved the check for syntax errors into the main function. That'll make it a lot easier to set up custom handling of syntax errors for my purposes. 👍

src/execution.rs Outdated
}

impl ParseErrors {
pub(crate) fn add(&mut self, node: tree_sitter::Node, source: &str) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the intention behind passing in source for each node encountered that this makes it possible to store errors for multiple files in the same ParseErrors struct? In the current setup, source will be the same for all errors in a given file.

pub(crate) fn is_empty(&self) -> bool {
self.errors.is_empty()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be nice to have a way to access the errors, beyond just displaying them or checking that there are none.

The way I currently handle errors is to recognise them in a stanza, which is a bit awkward (since you can't actually query for ERROR nodes). However, it occurs to me that if I could access the list of errors, then I could just produce the relevant graph (consisting of a single "syntax error" node) directly, and do away with needlessly running the tree-sitter-graph machinery. (And in fact, I would be happy with just the first syntax error in the file.)

} else {
None
};
self.errors.push((start.row, start.column, node_source));
Copy link
Collaborator

Choose a reason for hiding this comment

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

For further handling, it would be nice to have also the end row/column available.
(For displaying the error, however, I don't think this is necessary.)

@@ -67,6 +76,17 @@ fn main() -> Result<()> {
let tree = parser
.parse(&source, None)
.ok_or_else(|| anyhow!("Could not parse {}", source_path.display()))?;
let allow_parse_errors = matches.is_present("allow-parse-errors");
if !allow_parse_errors {
let parse_errors = ParseErrors::from_tree(&tree, &source);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if it would be a bit more smooth to have from_tree return an Option<ParseError> (that could then be decomposed in an if let). That way, you wouldn't need is_empty at all.

Though of course then you have the awkwardness of Some(vec![]) being a potential value that should never appear.

Hm... Maybe it would suffice to just display the first syntax error in the file? (Which I believe will be the first error node encountered during the tree walk.) After all, after the first syntax error, the rest of the parse could be completely out of whack.

@hendrikvanantwerpen
Copy link
Collaborator Author

If I understand you correctly, you would also want to use this machinery yourself for finding/reporting errors.

This PR does not actually add the parse error logic to the API, it's only internal. I see that it could be useful for others as well, although that requires a bit more thought---along the lines of your comments. I think such logic should perhaps become part of the tree-sitter API, instead off this one.

On a practical note, I'm off for the next two weeks, so i won't be able to think about these things for a while. I think this PR is quite safe, since it does not change the API, so no external code that we may break later.

@robrix robrix requested a review from a team February 22, 2022 17:15
@hendrikvanantwerpen hendrikvanantwerpen force-pushed the relax-parse-error-behavior branch 2 times, most recently from fa8899a to 4b649f1 Compare March 17, 2022 19:06
@hendrikvanantwerpen hendrikvanantwerpen changed the base branch from main to shorthands March 17, 2022 19:08
@hendrikvanantwerpen
Copy link
Collaborator Author

@tausbn I have made some changes so that the error finding and display is now part of the lib instead of the bin, so it should be reusable. There are methods for finding all or just the first error, and error display has a flag that controls whether you get nice multi-line errors, or more compact single line errors.

Copy link
Contributor

@dcreager dcreager left a comment

Choose a reason for hiding this comment

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

Very nice. Not in scope for this PR, but I've seen recommendations for the miette if in the future we want to make the verbose error output more detailed and rustc-like.

src/util.rs Outdated
@@ -0,0 +1,140 @@
// -*- coding: utf-8 -*-
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest a different filename — util is very generic. Maybe parse_error.rs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is a good idea.

Base automatically changed from shorthands to main March 18, 2022 15:57
@hendrikvanantwerpen
Copy link
Collaborator Author

hendrikvanantwerpen commented Mar 18, 2022

Ooh, miette looks very fancy :) Definitely something to keep in mind if we touch this area again.

@hendrikvanantwerpen hendrikvanantwerpen dismissed tausbn’s stale review March 18, 2022 16:22

Comments addressed by providing a reusable module for parse errors

@hendrikvanantwerpen hendrikvanantwerpen merged commit 766fa6d into main Mar 18, 2022
@hendrikvanantwerpen hendrikvanantwerpen deleted the relax-parse-error-behavior branch March 18, 2022 16:23
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.

None yet

3 participants