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: correct package assumption when there is a star import #3338

Merged

Conversation

slarse
Copy link
Collaborator

@slarse slarse commented Apr 19, 2020

Fix #3337

Hello!

This is an attempt to fix Spoon incorrectly guessing the package of a type in noclasspath mode. See #3337 for details.

I need some help with this PR, see the comments.

This is too restrictive, and counts e.g. java.util.* as an offending import, even though it's fine
ref.setPackage(jdtTreeBuilder.getContextBuilder().compilationUnitSpoon.getDeclaredPackage().getReference());
ContextBuilder ctx = jdtTreeBuilder.getContextBuilder();
boolean isNoClasspath = jdtTreeBuilder.getFactory().getEnvironment().getNoClasspath();
if (isNoClasspath && containsStarImport(ctx.compilationunitdeclaration.imports)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure we need to check if it's noclasspath mode, we shouldn't get here in classpath mode? Perhaps assert isNoClasspath instead?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps assert isNoClasspath instead?

good idea.

}
} else {
throw new AssertionError("unexpected declaring type: " + declaring.getClass() + " of " + declaring);
}
}

private static boolean containsStarImport(ImportReference[] imports) {
return imports != null && Arrays.stream(imports).anyMatch(imp -> imp.toString().endsWith("*"));
Copy link
Collaborator Author

@slarse slarse Apr 19, 2020

Choose a reason for hiding this comment

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

This will return true if there's any star import, which is too restrictive. For example, if there's an import java.util.*, then this will return true and we won't assign the CU's package to the type. But if the star import is actually available, which should be the case for stdlib packages, depending on JDK version, then it should be fine to guess assign the CU's package to the type.

Is there any way to check which imported packages are actually available at this stage?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any way to check which imported packages are actually available at this stage?

Do you mean which subpackages under .**are available in the classpath?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, I was rather thinking of just checking if the containing package is available. For example, if any type from java.util is available on the classpath, then we conclude that all types from java.util.* are available on the classpath. If that is the case, we assume that had SomeClass actually belonged to java.util, it would too have been on the classpath too, and since it is not we assign it to the compilation unit's package.

But as I typed the above paragraph I realized a few things. First, third party packages are often split across projects leading to packages possibly being partially available, so the assumption "all types from the x.y.* import are available if any type from package x.y is available" is not necessarily true (think e.g. org.apache). Second, differing versions of the standard library may cause issues. Third, accounting for what I just pointed out makes this incredibly complex.

I think the simple and probably sufficient solution is to simply not guess the package if the type is not on the classpath, and there is any * import.

@slarse
Copy link
Collaborator Author

slarse commented May 4, 2020

@monperrus I'm not sure what the cleanest way to resolve this is. The current state of the PR is to just create a new, empty package reference whenever there is a star import. But that coincides with how unnamed packages are implemented, which is not what this is. it's rather an unknown package.

While it works to have unknown packages simply be an unnamed package, it seems like there should be a distinction between an unnamed package and an unknown package, but I'm not sure of the best way to do that.

Then again, as this is an isolated problem in noclasspath mode when there also happens to exist star imports in the file, simply having the unknown package default to an unnamed package is acceptable if it's properly documented.

@monperrus
Copy link
Collaborator

To me, it's acceptable this way. I generally prefer not to over-engineer for corner-cases.

If you unWIP, and nobody is against it, I'll merge.

@slarse slarse changed the title WIP: fix: Fix incorrect package assumption when there is a star import (need help) review: fix: Fix incorrect package assumption when there is a star import (need help) May 5, 2020
@slarse slarse changed the title review: fix: Fix incorrect package assumption when there is a star import (need help) review: fix: Fix incorrect package assumption when there is a star import May 5, 2020
@slarse
Copy link
Collaborator Author

slarse commented May 5, 2020

Done.

@slarse
Copy link
Collaborator Author

slarse commented May 5, 2020

Not sure why the build failed, should I try to merge master into this branch?

https://travis-ci.org/github/INRIA/spoon/jobs/683288854

@monperrus monperrus changed the title review: fix: Fix incorrect package assumption when there is a star import fix: correct package assumption when there is a star import May 5, 2020
@monperrus monperrus merged commit 6dd8258 into INRIA:master May 5, 2020
@monperrus
Copy link
Collaborator

The CI error is not related.

So we merge, thanks a lot for your contribution.

@monperrus
Copy link
Collaborator

FYI, CI fix at #3356

@slarse slarse deleted the issue/3337-fix-incorrect-package-assumption branch May 28, 2021 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants