-
-
Notifications
You must be signed in to change notification settings - Fork 352
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: ensure sniper pretty-printer prints modifiers and type separated by a space #4296
Conversation
For now, I have created a test case that will be sufficient to fix Sorald's issue. However, that is not the best way. There are still some type references whose source position is not set. For example, when we execute this test case, the model built misses out setting position of It is safe to say that this pull request will only fix Sorald's issue. For type references like above, a further inspection is needed. I can open a ticket for that and deal with that later. EDIT: #4297 |
@monperrus this is ready for review. I am also having some trouble naming the PR. The current title is the final goal but it's not related to Spoon. Another title I came up with was "fix: ensure pretty-printer prints modifiers and type separated by a space", but that's also related to Sorald. |
|
||
@Test | ||
public void test_sourcePositionOfNestedTypeInFieldExists() { | ||
final Launcher launcher = new Launcher(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you add a contract? thanks!
Overall LGTM, @slarse do you want to look at it and merge? |
…nto set-source-position
* @param receiverType Last type in the qualified name. | ||
* @param enclosingType Enclosing type of the type name. | ||
* @param listener Listener to know if we must build the type reference. | ||
* @return a type reference. | ||
*/ | ||
<T> CtTypeReference<T> getQualifiedTypeReference(char[][] tokens, TypeBinding receiverType, ReferenceBinding enclosingType, JDTTreeBuilder.OnAccessListener listener) { | ||
<T> CtTypeReference<T> getQualifiedTypeReference(char[][] tokens, ASTNode receiverNode, TypeBinding receiverType, ReferenceBinding enclosingType, JDTTreeBuilder.OnAccessListener listener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a new parameter here is fine from my side, because this isn't real public api. Any other opinions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed access to AST node to build the source position so for now, I just passed it as a parameter. I have opened an issue #4297 to find a more generic solution to this but that would require how CtTypeReference
are built and inserted into the model. This PR is kind of like a workaround but it fixes a very important issue in Sorald.
I will come back to #4297 once I am done dealing with some important issues in sorald.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's generally fine to add parameters to these internal methods (anything that isn't public, really), but here I think it's not the right solution. The added parameter is used in exactly the same way in two different places, which indicates to me that it should be used at the call site of the method rather than being passed in. So I think the code changes to this method should be reverted.
I think the place to solve this particular problem is in JDTTreeBuilder.visit(QualifiedTypeReference, BlockScope)
, and change the very end of the method like so:
- context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(qualifiedTypeReference, scope)), qualifiedTypeReference);
+ CtTypeReference<?> typeRef = references.buildTypeReference(qualifiedTypeReference, scope);
+ if (typeRef != null) {
+ typeRef.setPosition(position.buildPositionCtElement(typeRef, qualifiedTypeReference));
+ }
+ context.enter(factory.Code().createTypeAccessWithoutCloningReference(typeRef), qualifiedTypeReference);
It's there that we build a type reference for a type access, but never assign a source position to that type reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some small style comments otherwise looks fine for me. Adding a new parameter for a method is breaking behaviour, but the referencebuilder isn't part of the public api from my pov.
@MartinWitt incorporated your changes. |
Merging from my side is fine. Let's wait the 24 hours and merge with |
Having a peek. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a rather tricky one, took me a while to evaluate it.
I don't think this is the right solution. The ReferenceBuilder
isn't concerned with setting source positions, and for good reason: references are often implicit. For example, a variable read has a type, which is represented as a type reference, but the type is contained in the declaration of the variable, and not at the site of the variable read. For that reason, I think it's pretty important we deal with setting source positions further up the stack.
See comment on the source code.
* @param receiverType Last type in the qualified name. | ||
* @param enclosingType Enclosing type of the type name. | ||
* @param listener Listener to know if we must build the type reference. | ||
* @return a type reference. | ||
*/ | ||
<T> CtTypeReference<T> getQualifiedTypeReference(char[][] tokens, TypeBinding receiverType, ReferenceBinding enclosingType, JDTTreeBuilder.OnAccessListener listener) { | ||
<T> CtTypeReference<T> getQualifiedTypeReference(char[][] tokens, ASTNode receiverNode, TypeBinding receiverType, ReferenceBinding enclosingType, JDTTreeBuilder.OnAccessListener listener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's generally fine to add parameters to these internal methods (anything that isn't public, really), but here I think it's not the right solution. The added parameter is used in exactly the same way in two different places, which indicates to me that it should be used at the call site of the method rather than being passed in. So I think the code changes to this method should be reverted.
I think the place to solve this particular problem is in JDTTreeBuilder.visit(QualifiedTypeReference, BlockScope)
, and change the very end of the method like so:
- context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(qualifiedTypeReference, scope)), qualifiedTypeReference);
+ CtTypeReference<?> typeRef = references.buildTypeReference(qualifiedTypeReference, scope);
+ if (typeRef != null) {
+ typeRef.setPosition(position.buildPositionCtElement(typeRef, qualifiedTypeReference));
+ }
+ context.enter(factory.Code().createTypeAccessWithoutCloningReference(typeRef), qualifiedTypeReference);
It's there that we build a type reference for a type access, but never assign a source position to that type reference.
@slarse This is causing some problems. I inspected one of them. It turns out that the patch tries to build a source position of the element EDIT: So I found the problem with one of the test cases. It tries to look up previous annotations while building source position for type reference (spoon element) I am not sure how to go forward now. Maybe we can remove |
@nharrand need your opinions about disabling #3359 's fix because it is interfering with setting source position for
|
Works for me. Actions:
|
@monperrus I ignored the annotation position test for now. I will come back to it after we are done with sorald's paper submission. |
ack, thanks @algomaster99 |
@MartinWitt Something broke in the code quality test after this PR was merged. Can you take a look at it? |
Sure, taking a look, but at the first glance this looks like some maven-central related problem. |
@MartinWitt thanks! |
Reference: ASSERT-KTH/sorald#603
This patch is a consequence of what has been discussed here. The source position of a field's type was not being set correctly. I realised that the source position are stored in the AST nodes created by JDT compiler and the function in this patch did not have access to one. So, I have modified the function definition so I am able to build and set the position.
There are things left in this PR:
- [ ] Look for an alternative way because just by reading the code, my intuition is telling me thatReferenceBuilder
is a wrong place to set the position. It should probably be done somewhere in a related file.EDIT: The second task shall be handled in #4297.