Skip to content

shortenFullyQualifiedTypes produces uncompilable code when the simple name collides with a type in the same compilation unit #3033

Description

@slachiewicz

Summary

shortenFullyQualifiedTypes shortens a fully-qualified reference into the simple name of a type declared in the same compilation unit. The result does not compile.

Reproducer

spotless-maven-plugin 3.10.0, with shortenFullyQualifiedTypes as the only configured step:

<configuration>
  <java>
    <shortenFullyQualifiedTypes />
  </java>
</configuration>

src/main/java/org/codehaus/plexus/archiver/jar/Manifest.java:

package org.codehaus.plexus.archiver.jar;

public class Manifest extends java.util.jar.Manifest {
    public static java.util.jar.Manifest empty() {
        return new java.util.jar.Manifest();
    }
}

After mvn spotless:apply:

package org.codehaus.plexus.archiver.jar;

import java.util.jar.Manifest;

public class Manifest extends Manifest {
    public static Manifest empty() {
        return new Manifest();
    }
}
$ javac src/main/java/org/codehaus/plexus/archiver/jar/Manifest.java
src/main/java/org/codehaus/plexus/archiver/jar/Manifest.java:3: error: Manifest is already defined in this compilation unit
import java.util.jar.Manifest;
^
1 error

Two separate problems in the output. The single-type-import collides with a top-level type declared in the same file, which JLS 7.5.1 makes a compile-time error on its own, and the class now extends itself.

Impact on a real project

Running the step over codehaus-plexus/plexus-archiver rewrote 12 files, after which mvn test-compile fails:

JarArchiver.java:[226,61] incompatible types:
  java.util.jar.Manifest cannot be converted to org.codehaus.plexus.archiver.jar.Manifest

The same run over plexus-utils and plexus-xml was correct and useful, so the trigger is narrow: a project that declares a type whose simple name matches a JDK type it also references by qualified name. That pattern is common in libraries that wrap or extend a JDK class, which is exactly where fully-qualified references tend to be written deliberately.

Suggested behavior

Leave a qualified reference alone when the simple name would resolve to a different type in scope, including a type declared in the same compilation unit. The qualification is carrying meaning in that case rather than being redundant.

Introduced by #2945, released in 3.10.0.

This issue was created with AI assistance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions