-
Notifications
You must be signed in to change notification settings - Fork 27
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
BestFitScanner doesn't handle joint declarations well (affects DeadStoreProcessor (rule 1854)) #522
Comments
There are two problems here: There's a missing newline after the opening curly brace. I thought I fixed that in INRIA/spoon#3856, but apparently I didn't, at least not for statement lists. The joint declaration is strangely modeled in Spoon. It's modeled as two separate |
The joint declaration is strangely modeled in Spoon. It's modeled as two separate CtVariable, but with the exact same source position. As we match Sonar rule violations to Spoon elements by best positional match, and these will always tie, it will simply pick the first one. So we need to expand the matching rules in order to accommodate for joint declarations. Would it be impossible to change this in Spoon? Also, how is the source position represented by Spoon? Is it by line/column number, token index or file offset? Where can I find the code that handles the matching of Sonar rule violations to Spoon elements? |
Change: probably not. That would be backwards incompatible, and Spoon is very much built around being backwards compatible. Personally, I think it should be modeled with a separate element in the metamodel (say, @monperrus do you have any immediate thoughts on the modelling of joint declarations in Spoon?
Line, column and character index. See SourcePosition.
It's in |
Given a declaration like this where both variables are unused, Sonar seems to report the following columns for 1854: String x = "hello", y = "world";
^^^^^^^^^ ^^^^^^^^^ Is Otherwise, maybe String x = "hello", y = "world";
^^^^^^^^^ ^^^^^^^^^ Sonar
^^^^^^^^^^^^^^^^^^^^^^^^^ CtVariable x
^^^^^^^^^^^^ CtVariable y This is assuming that |
Another heuristic that might work is to not use the intersection algorithm for Candidates: {x, y}
String x = "hello", y = "world";
^^^^^^^^^ Sonar
String x = "hello", y = "world";
^^^^^^^^^^^ Search
Result: {x} There's probably a plethora of corner cases though and I don't know if it would be possible to differentiate between this case (finding nodes in variable declarations) and the case where the violation is a normal assignment. |
I'd say no, I've used it for years.
I think special treatment for |
Yeah, I think the Hamming distance would work, however, I think the Sonar fragment does not actually include the name, so the fragment would need to be expanded first, in which case some kind of string search would be needed anyway:
Also, I think the detection algorithm would need some careful planning
There's probably a lot of annoying and weird code in the wild that could be troublesome. // (pathological) declaration and assignment on the same line
String x = 1, y = 2; z = 20;
// for loop with multiple declarations
for (int x = 0, y = 10; x < 10; y = y + 1)
// declaration split over multiple lines
String CONSTANT_A = "constant a",
CONSTANT_B = "constant b",
CONSTANT_C = "constant c"; |
Right, that's a good point. The way you suggest to extract the names should work fine. We can use
We can just run the intersection algorithm first to find matching candidates whose source positions overlap with the rule violation (recall that each variable in a joint declaration gets the source position of the entire declaration in Spoon), and then further filter those with the hamming distance approach. That should work in theory, I think, and then we'll just work out the practical problems by adding more and more annoying test cases. |
Yeah, the string search should work I think, searching backwards from the fragment one would need to make sure to read until the whitespace is hit to disambiguate between two identifiers where one is the suffix of the other, say
Yeah, this sounds like it should work. |
Great, so we have a plan! Want me to go ahead and draft an implementation of this? Or do you want to give it a go? |
Feel free to go ahead, I'll try to follow the progress. |
Okay, I'll likely get started tomorrow morning. I'll ping you in the PR once I've got a bare-minimum draft ready. |
I realized that there's one very annoying corner case where a variable isn't initialized. Something like this: int x = 2, y, z = 3; While the |
Dead stores aren't detected in loop headers, but unused local variables are (rule S1481). We'd need to add a processor for that rule to verify that the approach works for variables in loop headers. |
Does this refer to the detection conducted by Sonar?
Yeah, I guess a processor for rule public class Unused {
public void unused() {
String x;
/* ... code that does not use x */
}
} does only trigger |
Yes.
Yup, and it's also a trivial processor to implement. Excluding boilerplate, it should just be this: protected void repairInternal(CtLocalVariable<?> localVar) {
localVar.delete();
} |
Maybe you already have small reproducible examples and I am not sure if this is even related but running
java -jar sorald-0.2.0-jar-with-dependencies.jar repair --source=Test.java --rule-key=1854
(Unused assignments should be removed) onyields:
Originally posted by @lyxell in #337 (comment)
The text was updated successfully, but these errors were encountered: