Blaz_Kosi
(b.kosi)
August 18, 2025, 11:01am
1
Hi,
how would I go about making package statements effectively optional?
My first idea was to inject synthetic package statements into PsiClass
es.
However, this does not seem like it will pan out, because even though it seems it’s possible to get the package name from a PsiFile
(as seen in the WrongPackageStatementInspection
class):
PsiDirectory directory = javaFile.getOriginalFile().getContainingDirectory();
if (directory == null) return null;
PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
if (dirPackage == null) return null;
String packageName = dirPackage.getQualifiedName();
this doesn’t appear to always work, because files and stubs early on in their lifetimes don’t know about their directories:
file.getContainingDirectory() == null
should I get the directory from the original file in those cases?
((LightVirtualFile)file.getViewProvider().getVirtualFile()).getOriginalFile().getParent()
or is there a better way?
Should I instead provide a new implementation of PsiShortNamesCache
? This still doesn’t seem like the complete solution, because while a PsiClass
would be able to resolve other PsiClass
es that lack package statements, it still wouldn’t know its own package, right?
Kind Regards
I feel it requires an extreme engineering effort and I personally would never try to do that as Java support itself is not ready for that
Blaz_Kosi
(b.kosi)
August 18, 2025, 12:56pm
3
I’ve done worse. Humor me.
I’ll rephrase my question, what’s the most reliable way to get a PsiDirectory
parent from:
a PsiFile
, in the case when the naïve approach: psiFile.getOriginalFile().getContainingDirectory()
returns null
.
a PsiFileStub
a PsiClass
a PsiClassStub
I assume the latter two will have the same answer: “get it from their PsiFileStub
”, but I wanted to include them just for completeness sake.
Currently, this is what I have:
public static @NotNull String getPackageName(final PsiFile psiFile) {
final PsiDirectory directory = getDirectory(psiFile);
if (directory == null) {
return "";
}
final PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
if (dirPackage == null) {
return "";
}
return dirPackage.getQualifiedName();
}
private static @Nullable PsiDirectory getDirectory(@NotNull final PsiFile psiFile) {
final PsiFile originalFile = psiFile.getOriginalFile();
final PsiDirectory directory = originalFile.getContainingDirectory();
if (directory != null) {
return directory;
}
final VirtualFile virtualFile = originalFile.getViewProvider().getVirtualFile();
final VirtualFile originalVirtualFile;
if (virtualFile instanceof LightVirtualFile) {
originalVirtualFile = ((LightVirtualFile) virtualFile).getOriginalFile();
} else {
originalVirtualFile = virtualFile;
}
final VirtualFile parentFile = originalVirtualFile.getParent();
if (parentFile == null) {
return null;
} else if (!parentFile.isValid()) {
return null;
} else {
return originalFile.getManager().findDirectory(parentFile);
}
}