Making package statements effectively optional

Hi,

how would I go about making package statements effectively optional?

My first idea was to inject synthetic package statements into PsiClasses.

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 PsiClasses 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

I’ve done worse. Humor me. :relieved_face: :folded_hands:

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);
        }
    }