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

bug: Implicit type access/package reference made explicit (noclasspath) #3363

Closed
slarse opened this issue May 11, 2020 · 0 comments · Fixed by #3364
Closed

bug: Implicit type access/package reference made explicit (noclasspath) #3363

slarse opened this issue May 11, 2020 · 0 comments · Fixed by #3364

Comments

@slarse
Copy link
Collaborator

slarse commented May 11, 2020

Hello!

Another day, another noclasspath bug :). For once, this bug is pretty simple. Sometimes when an unqualified type access is in the code to a type that is not on the classpath, Spoon will make the type/package explicit. The case where this messed things up for me was with static imports.

package pkg;

import static pkg.constants.Constants.SOMETHING;

public class Main {
    public static void main(String[] args) {
        System.out.println(SOMETHING);
    }
}

Here, SOMETHING is clearly entirely unqualified, yet it will get parsed into Constants.SOMETHING, where Constants will be explicit. This causes compile errors for me as the class Constants is not itself imported.

Remove that static import, and it instead becomes a qualified pkg.SOMETHING, which is arguably incorrect as it doesn't really make sense for accessing a constant, but if SOMETHING was a type or something like that instead then it would be correct. Perhaps we want to fix that, too, but now I'm mainly out to fix the implicitness.

The problem lies here:

<T> CtTypeAccess<T> createTypeAccessNoClasspath(SingleNameReference singleNameReference) {
final CtTypeReference<T> typeReference = jdtTreeBuilder.getFactory().Core().createTypeReference();
if (singleNameReference.binding == null) {
typeReference.setSimpleName(CharOperation.charToString(singleNameReference.token));
} else {
typeReference.setSimpleName(CharOperation.charToString(singleNameReference.binding.readableName()));
}
jdtTreeBuilder.getReferencesBuilder().setPackageOrDeclaringType(typeReference, jdtTreeBuilder.getReferencesBuilder().getDeclaringReferenceFromImports(singleNameReference.token));
return jdtTreeBuilder.getFactory().Code().createTypeAccess(typeReference);
}

As this is a SingleNameReference, any qualification attached to it should be made implicit as far as I can gather. Yet, anything that can be scrounged up from the imports is attached without abandon:

jdtTreeBuilder.getReferencesBuilder().setPackageOrDeclaringType(typeReference, jdtTreeBuilder.getReferencesBuilder().getDeclaringReferenceFromImports(singleNameReference.token));

I have a PR in the works, the fix seems to be as straightforward as simply making any reference found from the imports implicit.

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 a pull request may close this issue.

1 participant