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

Fix go comments bug #392

Merged
merged 9 commits into from
Mar 16, 2023
Merged

Fix go comments bug #392

merged 9 commits into from
Mar 16, 2023

Conversation

ketkarameya
Copy link
Collaborator

@ketkarameya ketkarameya commented Feb 23, 2023

Bug Diagnosis (#376): This problem is only inGo (because of its grammar, in my observation). The problem is caused when the comment is associated to the last statement of a method body in Go. Diagnosis:
Our comment fetching algorithm looks for comments on lines on the same line as deleted element and some lines above it (determined by the cleanup_comment_buffer flag). There is a caveat in this algorithm - (i) Get all the nodes that either start and end at [row] (ii) If all nodes are comments.
Now lets take the Go case where the comment is associated to the last statement of a method body in Go.
When we delete the last statement of the method body, now the last "statement" of the method body is a comment.
For some reason, tree sitter reports that this last row is where the comment and the block end. :|

Fix: Add a field ignore_node_for_comment property to PiranhaLanguage, now our algorithm will ignore the node kinds when reasoning about all nodes that start/end at last row.

Test Plan Added the test cases as reported in the issue. I added similar test cases for Java and Kotlin too, but I did not find this inconsistency for them (so did not have set the ignore_node_for_comment property for Java and Kotlin)

@ketkarameya ketkarameya added the bug Something isn't working label Feb 23, 2023
@ketkarameya ketkarameya linked an issue Feb 23, 2023 that may be closed by this pull request
@ketkarameya ketkarameya marked this pull request as ready for review February 23, 2023 23:10
Copy link
Collaborator Author

@ketkarameya ketkarameya left a comment

Choose a reason for hiding this comment

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

Self review and annotations

#[get = "pub"]
comment_nodes: Vec<String>,
/// The node kinds to be ignored when reasoning about comments
#[get = "pub"]
ignore_nodes_for_comments: Vec<String>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The property i mentioned in the PR description.

@@ -386,6 +386,13 @@ impl SourceCodeUnit {
.unwrap_or_else(|| self.root_node());

for node in traverse(node.walk(), Order::Post) {
if self
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The bug fix.

Copy link
Contributor

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

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

Change looks great (assuming I understood it correctly). Some minor requests regarding documentation and what seems to be a few stale comments 🙂

} else {
fmt.Println("remain")
}
// this comment doesnt get removed but it should
Copy link
Contributor

Choose a reason for hiding this comment

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

No longer true, no? Shouldn't the comment be updated to saying it will get removed (same with all the cases below)

#[get = "pub"]
comment_nodes: Vec<String>,
/// The node kinds to be ignored when reasoning about comments
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The node kinds to be ignored when reasoning about comments
/// The node kinds to be ignored when searching for comments

Just to be clear, the algorithm will find the nearest node to the deleted position that is not one of these. Then, if that node is a comment, it will delete it. Correct? Am I understanding the logic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. You have got it correct. I have made it more explicit now.

@@ -66,6 +76,13 @@ impl PiranhaLanguage {
self.comment_nodes().contains(&kind)
}

pub fn should_ignore_node_for_comment(&self, node: &Node) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation on this one, explaining what it does and how it's used.

Like, is the following correct?

[Piranha] will find the nearest node to the deleted position that is not one of these. Then, if that node is a comment, it will delete it.

(Even if so, please rewrite the doc comment a bit with some more info about how this function is used to implement the algorithm above)

Copy link
Collaborator Author

@ketkarameya ketkarameya left a comment

Choose a reason for hiding this comment

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

Addressed comments.
c1086c9 - Adds more comments, fixes comments, and slight cleanup

76bce7d - move _get_comment_at_line from piranha_argument to language

Copy link
Collaborator Author

@ketkarameya ketkarameya left a comment

Choose a reason for hiding this comment

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

Aaah! I missed a corner case in this bug fix. :|

@@ -72,7 +72,6 @@ func simplify_if_statement_false_comment_demo_single_comment() {

func simplify_if_statement_false_comment_demo_double_comment() {
fmt.Println("remain")
// this comment doesnt get removed
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The bug was not fully solved :| . Now its solved.

debug!("Deleting an associated comment");
*applied_edit = self._apply_edit(&Edit::delete_range(self.code(), comment_range), parser);
}
&mut self, edit: &Edit, parser: &mut tree_sitter::Parser,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

from apply_edit we call _delete_associated_comment and from _delete_associated_comment we recursively call apply_edit. This ensures that can delete a series of comments.

Let's say apply_edit deletes int foo in the below example.

// some 
// comment 
int foo;

becomes

// some 
// comment 

now _delete_associated_comment is triggered, and now we produce

// some 

Since _delete_associated_comment is effectively called recursively

<all comments are deleted>

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have this documented in a comment in the code in addition to in the PR review comments? Possibly in the documentation for this function.

@@ -313,13 +313,6 @@ impl SourceCodeUnit {
self.perform_delete_consecutive_new_lines();
}

pub(crate) fn apply_edit(&mut self, edit: &Edit, parser: &mut Parser) -> InputEdit {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

inlined apply_edit, this simplifies the code and also kinda solves this bug further.

Earlier we had a function called apply_edit which called _apply_edit and then called _delete_associated_comment . Now _delete_associated_comment called _apply_edit (not apply_edit ), therefore _delete_associated_comment was not getting invoked recursively, and therefore we were not deleting a series of comments.

I just inlined apply_edit into _apply_edit and renamed _apply_edit to apply_edit. Now when apply_edit is called from _delete_associated_comment, it ensures that _delete_associated_comment is called recursively. (I adjusted all the signatures and simplified the code)

Copy link
Contributor

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

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

LGTM. One small request documentation wise, though:

debug!("Deleting an associated comment");
*applied_edit = self._apply_edit(&Edit::delete_range(self.code(), comment_range), parser);
}
&mut self, edit: &Edit, parser: &mut tree_sitter::Parser,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have this documented in a comment in the code in addition to in the PR review comments? Possibly in the documentation for this function.

Copy link
Contributor

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

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

LGTM!

@ketkarameya ketkarameya merged commit ec82222 into master Mar 16, 2023
@ketkarameya ketkarameya deleted the go_comment_bug branch July 13, 2023 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Go comments not being cleaned up correctly
2 participants