spoon icon indicating copy to clipboard operation
spoon copied to clipboard

[Bug]: Orphan comment is not pretty printed by Spoon

Open jose opened this issue 3 years ago • 1 comments

Describe the bug

It seems that Spoon's pretty print feature is not able to handle orphan comments (e.g., comments at the very end of a method).

Source code you are trying to analyze/transform

// /tmp/demo-in/org/Foo.java

package org;

public class Foo {

    @Test
    public void should_match() throws Exception {
        class WithMockAndSpy {
            @Spy private InnerStrength strength;
            @Mock private List<String> list;

            abstract class InnerStrength {
                private final String name;

                InnerStrength() {
                    // Make sure that @Mock fields are always injected before @Spy fields.
                    assertNotNull(list);
                    // Make sure constructor is indeed called.
                    this.name = "inner";
                }

                abstract String strength();

                String fullStrength() {
                    return name + " " + strength();
                }
            }
        }

        WithMockAndSpy outer = new WithMockAndSpy();
        MockitoAnnotations.initMocks(outer);
        when(outer.strength.strength()).thenReturn("strength");
        // orphan comment
    }
}

Source code for your Spoon processing

final Launcher launcher = new Launcher();

launcher.addInputResource("/tmp/demo-in/org/Foo.java");
launcher.getEnvironment().setSourceOutputDirectory(new File("/tmp/demo-out"));
launcher.getEnvironment().setCommentEnabled(true);

launcher.run();

Actual output

package org;
public class Foo {
    @org.Test
    public void should_match() throws java.lang.Exception {
        class WithMockAndSpy {
            @org.Spy
            private WithMockAndSpy.InnerStrength strength;

            @org.Mock
            private org.List<java.lang.String> list;

            abstract class InnerStrength {
                private final java.lang.String name;

                InnerStrength() {
                    // Make sure that @Mock fields are always injected before @Spy fields.
                    assertNotNull(list);
                    // Make sure constructor is indeed called.
                    this.name = "inner";
                }

                abstract java.lang.String strength();

                java.lang.String fullStrength() {
                    return (name + " ") + strength();
                }
            }
        }
        WithMockAndSpy outer = new WithMockAndSpy();
        org.MockitoAnnotations.initMocks(outer);
        when(outer.strength.strength()).thenReturn("strength");
    }
}

Expected output

package org;
public class Foo {
    @org.Test
    public void should_match() throws java.lang.Exception {
        class WithMockAndSpy {
            @org.Spy
            private WithMockAndSpy.InnerStrength strength;

            @org.Mock
            private org.List<java.lang.String> list;

            abstract class InnerStrength {
                private final java.lang.String name;

                InnerStrength() {
                    // Make sure that @Mock fields are always injected before @Spy fields.
                    assertNotNull(list);
                    // Make sure constructor is indeed called.
                    this.name = "inner";
                }

                abstract java.lang.String strength();

                java.lang.String fullStrength() {
                    return (name + " ") + strength();
                }
            }
        }
        WithMockAndSpy outer = new WithMockAndSpy();
        org.MockitoAnnotations.initMocks(outer);
        when(outer.strength.strength()).thenReturn("strength");
        // orphan comment
    }
}

Spoon Version

10.2.0-beta-12

JVM Version

11

What operating system are you using?

Linux

jose avatar Aug 01 '22 12:08 jose

I took a quick look at this, and as it seems, it's not about comments at the end of the method but rather comments after the local class. As far as I was able to figure out, it seems like https://github.com/INRIA/spoon/blob/2fff4c50266f79bc06b961e3b01ca6c6e0fcc1ab/src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java#L153 picks the wrong element to attach the comment to.

SirYwell avatar Aug 05 '22 16:08 SirYwell