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: Use correct target for statically imported method calls #4991

Merged
merged 16 commits into from
Nov 24, 2022

Conversation

I-Al-Istannen
Copy link
Collaborator

@I-Al-Istannen I-Al-Istannen commented Oct 30, 2022

This PR tries to teach spoon that static imports aren't evil and java.lang imports can not be removed in these cases.

This required adjusting a few tests, as they expected spoon to fully-qualify static imports which it now no longer does.
EDIT: This is actually be an interesting question: Should the DJPP remove static imports and fully qualify them? This accidentally worked before for some cases but I now fixed the model representation and it no longer seems to be done by the DJPP.

One of the tests (testNoFQNWhenUsedInInnerClassAndShadowedByLocalVariable) seems to guard against:

Object spoon = null;
spoon.util.EmptyList list = null; // qualifying it here is wrong!

but I don't really see how it would test that as the call needs no qualification at all. I am not sure what exactly to do about that to be quite honest.

Closes #4981.

@I-Al-Istannen I-Al-Istannen changed the title wip: fix: Use correct target for statically imported method calls review: fix: Use correct target for statically imported method calls Oct 30, 2022
@MartinWitt
Copy link
Collaborator

Nice, going to have a look later.

@MartinWitt
Copy link
Collaborator

This is actually be an interesting question: Should the DJPP remove static imports and fully qualify them? This accidentally worked before for some cases but I now fixed the model representation and it no longer seems to be done by the DJPP.

Kind of interesting. As a user, if a call the DJPP with fully qualify, I wouldn't expect static imports or? So the DJPP should remove them and fully qualify them iff the user uses the fully qualify mode.
Otherwise LGTM.

I am not quite sure what I want here to be perfectly honest. You don't
need to import the methods so the trivial name suffices, but you might
still want to fully qualify them?
Previously it decided that a field was not imported even though a star
import covering it existed.
This ensures that no imports are added for qualified references.
@I-Al-Istannen
Copy link
Collaborator Author

Okay, there are a few new exiting things:

  1. The TargetedExpressionTest expected unqualified names for methods that can be used without being imported as they are declared in sibling classes. With this PR, it qualifies them. Is that desired?
  2. The ImportTest expected a statically imported constant to be qualified when printing with autoImports = true. This is now no longer the case with this PR.
  3. The current test failure is an element mismatch by the scanner as we now model targets of method calls correctly.

I would like some input on 1. and maybe 2. if possible.


The larger-scale changes in this PR are:

  1. The target of statically imported methods and fields is now set to their actual type instead of this. JDT models them as having a this reference as target, but that seems a bit nonsensical and breaks the printer.
  2. The type of the target of statically imported fields is now (heuristically) marked as implicit:
    import static foo.bar.Constants.CONSTANT;
    int i =                   CONSTANT.foo; // actual source code
    int i = foo.bar.Constants.CONSTANT.foo; // AST including implicit elements
                                       ^^^
                                       explicit field read
                              ^^^^^^^^^^^^
                              explicit field read
            ^^^^^^^^^^^^^^^^^^
            implicit type

Also CC @algomaster99 as you unconditionally added CtFieldRead imports in 4f44d9f and I am not sure I broke something there (See here for my changes). Judging by the issue trail you had a lot of fun you might not want to experience again :^) I don't want to offload the work for testing that on you, so a general pointer with if this breaks violently I will find out where you live would be fine.

Import handling in spoon contains horrors beyond my imagination and I am 100% sure I missed critical pieces buried along the way. I looked at the issue (#4981) and thought it would be easy — now I have dug a hole too deep to silently exit…

@algomaster99
Copy link
Contributor

The TargetedExpressionTest expected unqualified names for methods that can be used without being imported as they are declared in sibling classes. With this PR, it qualifies them. Is that desired?

The assertion is checked using toString method which calls the DJPP. If FULLY_QUALIFIED is not explicitly set, then I think we should just print the method name.

The ImportTest expected a statically imported constant to be qualified when printing with autoImports = true. This is now no longer the case with this PR.

This seems fine to me. autoImport=true refers to PRETTY_PRINTING_MODE being set to AUTOIMPORT, right?

so a general pointer with if this breaks violently I will find out where you live would be fine.

It is fine. We will see if it breaks something. Patching the pretty-printer is easy, but making sure that the patch is the best solution is a hard problem. And I live in Sweden, it won't be hard for you to find where I live xD

Import handling in spoon contains horrors beyond my imagination and I am 100% sure I missed critical pieces buried along the way. I looked at the issue (#4981) and thought it would be easy — now I have dug a hole too deep to silently exit…

I can understand. I feel that way about pretty printing in general. I used to open PRs about fixing issues, but then they just remain drafts for too long 😞

@I-Al-Istannen
Copy link
Collaborator Author

And I live in Sweden, it won't be hard for you to find where I live xD

That was meant the other way around :P

This seems fine to me. autoImport=true refers to PRETTY_PRINTING_MODE being set to AUTOIMPORT, right?

Yes, that's what I meant. Good :)

The assertion is checked using toString method which calls the DJPP. If FULLY_QUALIFIED is not explicitly set, then I think we should just print the method name.

The problem is that toString creates a pretty printer using the default factory (createPrettyPrinter) and that one defaults to FULLY_QUALIFIED. There doesn't seem to be anything used besides FULLY_QUALIFIED and AUTOIMPORT.

Patching the pretty-printer is easy, but making sure that the patch is the best solution is a hard problem.

Oh yea… Figuring out why things break, why the AST doesn't make any sense and why random checks in random places exist in their exact form — and once you've got that, good luck figuring out which to adjust :P I am fairly certain that fixing the AST and making the implicit type implicit is a good idea.

I can understand. I feel that way about pretty printing in general. I used to open PRs about fixing issues, but then they just remain drafts for too long 😞

🫂 Spoon has a few of such areas…

@algomaster99
Copy link
Contributor

that one defaults to FULLY_QUALIFIED

Oh, then I think it would be desired. It could be a breaking change though 😬

@I-Al-Istannen
Copy link
Collaborator Author

It could be a breaking change though

Oh god, it probably is. I wonder whether that is acceptable here as it arguably fixes an inconsistency. I will await judgment from the other maintainers

@I-Al-Istannen
Copy link
Collaborator Author

This currently produces incorrect code for references to non-static methods of the enclosing class. I have opened eclipse-jdt/eclipse.jdt.core#515 as I don't really see a nice way to correctly detect this in Spoon.

@I-Al-Istannen I-Al-Istannen changed the title review: fix: Use correct target for statically imported method calls wip: fix: Use correct target for statically imported method calls Nov 4, 2022
@I-Al-Istannen
Copy link
Collaborator Author

Okay, as JDT doesn't really want to touch this I now fix it in Spoon (I think). I believe it makes sense for us to silently invent new implicit elements to properly attribute the implicitly-qualified method calls.

I am not sure how nice reviewing this PR is in its current state. It changes quite a few things in a few places, but the import cleaner changes don't do much without the implicit this changes.

@I-Al-Istannen I-Al-Istannen changed the title wip: fix: Use correct target for statically imported method calls review: fix: Use correct target for statically imported method calls Nov 16, 2022
Comment on lines +274 to +276
assertEquals(3631, counter.nElement + countOfCommentsInCompilationUnits);
assertEquals(2423, counter.nEnter + countOfCommentsInCompilationUnits);
assertEquals(2423, counter.nExit + countOfCommentsInCompilationUnits);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just as a comment, I have no clue why we have a test case where we simply change numbers only for the CI :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, this one is a bit weird. Maybe a Map<Class<? extends CtElement> , int> would be better? Then you can see which part of the AST you changed and whether that was intentional?

MartinWitt
MartinWitt previously approved these changes Nov 20, 2022
@MartinWitt
Copy link
Collaborator

Just one comment missing other LGTM.

@MartinWitt MartinWitt changed the title review: fix: Use correct target for statically imported method calls fix: Use correct target for statically imported method calls Nov 24, 2022
@MartinWitt MartinWitt merged commit 8ba20e9 into INRIA:master Nov 24, 2022
@MartinWitt
Copy link
Collaborator

Thanks @I-Al-Istannen

@monperrus monperrus mentioned this pull request Mar 9, 2023
@I-Al-Istannen I-Al-Istannen deleted the fix/static-imports branch October 26, 2024 19:52
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.

[Bug]: SPOON does not generate static imports when prettyprinting in auto import mode
3 participants