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]: Javadoc not attached to class in some cases #6106

Open
Luro02 opened this issue Dec 17, 2024 · 1 comment
Open

[Bug]: Javadoc not attached to class in some cases #6106

Luro02 opened this issue Dec 17, 2024 · 1 comment
Labels

Comments

@Luro02
Copy link
Contributor

Luro02 commented Dec 17, 2024

Describe the bug

In some cases, the javadoc is not attached to the test class, like in the example source code (ctClass.getComments() would then be empty).

Note: if there is a package declaration or the javadoc is indented, it will attach the javadoc to the test class.

Source code you are trying to analyze/transform

/**
 *
 * @author uxxxx
 */
public class Test {}

Source code for your Spoon processing

import spoon.Launcher;
import spoon.compiler.Environment;
import spoon.processing.Processor;
import spoon.reflect.CtModel;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtType;
import spoon.reflect.visitor.DefaultImportComparator;
import spoon.reflect.visitor.DefaultJavaPrettyPrinter;
import spoon.reflect.visitor.ForceImportProcessor;
import spoon.reflect.visitor.ImportCleaner;
import spoon.reflect.visitor.ImportConflictDetector;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.compiler.VirtualFile;

import java.util.List;

public final class Main {
    private Main() {
    }

    private static CtModel buildModel() {
        Launcher launcher = new Launcher();

        Environment environment = launcher.getEnvironment();
        environment.setPrettyPrinterCreator(() -> new DefaultJavaPrettyPrinter(environment) {
            {
                // copy-pasted from StandardEnvironment#createPrettyPrinterAutoImport
                List<Processor<CtElement>> preprocessors = List.of(
                    // try to import as many types as possible
                    new ForceImportProcessor(),
                    // remove unused imports first. Do not add new imports at a time when conflicts are not resolved
                    new ImportCleaner().setCanAddImports(false),
                    // solve conflicts, the current imports are relevant too
                    new ImportConflictDetector(),
                    // compute final imports
                    new ImportCleaner().setImportComparator(new DefaultImportComparator())
                );
                this.setIgnoreImplicit(false);
                this.setPreprocessors(preprocessors);
                this.setMinimizeRoundBrackets(true);
            }
        });

        environment.setComplianceLevel(21);
        environment.setShouldCompile(true);

        launcher.addInputResource(new VirtualFile(
            """
            /**
             *
             * @author uxxxx
             */
            public class Test {}
            """,
            "Test"
        ));

        return launcher.buildModel();
    }


    public static void main(String[] args) {
        CtModel ctModel = buildModel();

        List<CtType<?>> types = ctModel.getElements(new TypeFilter<>(CtType.class));

        if (types.size() != 1) {
            throw new IllegalStateException("No types found");
        }

        CtType<?> ctType = types.get(0);
        if (ctType.getComments().isEmpty()) {
            throw new IllegalStateException("No javadoc found");
        }
    }
}

Actual output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.IllegalStateException: No javadoc found
	at org.example.Main.main(Main.java:75)

Process finished with exit code 1

Expected output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Process finished with exit code 0

Spoon Version

11.1.1-beta-18

JVM Version

openjdk version "21.0.2" 2024-01-16 LTS OpenJDK Runtime Environment Zulu21.32+17-CA (build 21.0.2+13-LTS) OpenJDK 64-Bit Server VM Zulu21.32+17-CA (build 21.0.2+13-LTS, mixed mode, sharing)

What operating system are you using?

Windows 11

@Luro02 Luro02 added the bug label Dec 17, 2024
@I-Al-Istannen
Copy link
Collaborator

This also works if you do not give the virtual file a name, as that triggers a special case in the JDTCommentBuilder:

The root cause seems to be that the class starts after the comment, if the comment is the first thing in the file. This causes the comment builder to use the compilation unit as the target, attaching the comment to it. If you provide e.g. a package, the class position is extended to encompass the comment (and not just the modifiers), avoiding this.

Spoon could rely on the .javadoc property to properly find the targeted element, at least in the case of javadoc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants