spoon icon indicating copy to clipboard operation
spoon copied to clipboard

Sniper: Failure on comments inside enum values

Open plcarmel opened this issue 2 years ago • 7 comments

When there are comments inside enum values, Spoon fails to perform a transformation on the type.

package org.example;

enum Example {

    ENGLISH( /* boom */
            "Hello",
            "World"
    ),
    FRENCH(
            "Bonjour",
            "l'univers"
    );

    String hello;
    String world;

    public Example(
            String hello,
            String world
    ) {
        this.hello = hello;
        this.world = world;
    }
}
Exception in thread "main" spoon.SpoonException: Cannot compare this: [46, 115] with other: ["55", "185"]
        at spoon.support.sniper.internal.ElementSourceFragment.compare(ElementSourceFragment.java:371)
        at spoon.support.sniper.internal.ElementSourceFragment.add(ElementSourceFragment.java:285)
        at spoon.support.sniper.internal.ElementSourceFragment.addChild(ElementSourceFragment.java:317)
        at spoon.support.sniper.internal.ElementSourceFragment.addChild(ElementSourceFragment.java:243)
        at spoon.support.sniper.internal.ElementSourceFragment$1.enter(ElementSourceFragment.java:200)
        at spoon.reflect.visitor.CtScanner.visitCtEnumValue(CtScanner.java:442)
        at spoon.support.reflect.declaration.CtEnumValueImpl.accept(CtEnumValueImpl.java:18)
        at spoon.reflect.visitor.EarlyTerminatingScanner.doScan(EarlyTerminatingScanner.java:145)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:121)
        at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:184)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:106)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:83)
        at spoon.reflect.visitor.CtScanner.visitCtEnum(CtScanner.java:415)
        at spoon.support.reflect.declaration.CtEnumImpl.accept(CtEnumImpl.java:45)
        at spoon.reflect.visitor.EarlyTerminatingScanner.doScan(EarlyTerminatingScanner.java:145)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:121)
        at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:184)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:106)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:83)
        at spoon.reflect.visitor.EarlyTerminatingScanner.visitCtCompilationUnit(EarlyTerminatingScanner.java:160)
        at spoon.support.reflect.declaration.CtCompilationUnitImpl.accept(CtCompilationUnitImpl.java:407)
        at spoon.reflect.visitor.EarlyTerminatingScanner.doScan(EarlyTerminatingScanner.java:145)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:121)
        at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:184)
        at spoon.reflect.visitor.EarlyTerminatingScanner.scan(EarlyTerminatingScanner.java:106)
        at spoon.support.sniper.internal.ElementSourceFragment.createSourceFragmentsFrom(ElementSourceFragment.java:228)
        at spoon.support.reflect.declaration.CtCompilationUnitImpl.getOriginalSourceFragment(CtCompilationUnitImpl.java:359)
        at spoon.support.modelobs.SourceFragmentCreator.onChange(SourceFragmentCreator.java:32)
        at spoon.support.modelobs.ChangeCollector$ChangeListener.onObjectUpdate(ChangeCollector.java:175)
        at spoon.support.reflect.declaration.CtNamedElementImpl.setSimpleName(CtNamedElementImpl.java:45)
        at org.example.MainKt.main(Main.kt:15)
        at org.example.MainKt.main(Main.kt)

Code to reproduce the issue is available on GitHub: https://github.com/plcarmel/spoon-enum-bug

java -version
java version "11.0.13" 2021-10-19 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.13+10-LTS-370)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.13+10-LTS-370, mixed mode)

plcarmel avatar Dec 06 '21 14:12 plcarmel

Hi, thanks for the bug report.

The transformation itself isn't the problem here, the crash occurs in the sniper printer. I edited the title to make it more apparent.

slarse avatar Dec 06 '21 17:12 slarse

Are there any plans to fix this issue soon?

kl0u avatar Jan 31 '22 19:01 kl0u

@kl0u It seems like no one has taken it upon themselves to do this yet, so the sincere answer to your question would be no. If you would like to give it a shot, go ahead :)

slarse avatar Feb 02 '22 21:02 slarse

Thanks @slarse ! I cannot commit that I will work on that but if I have something I will create a PR.

kl0u avatar Feb 05 '22 18:02 kl0u

Hi, @kl0u did you find how to fix ? By the way I made some debugging and it's seems that when you add comment, the source code of CtFieldImpl object contains the comment as we can see here (and so change start and end values):

image

Without the comment, in yellow:

image

I am new in the project so I need some extra time to find a fix.

OlivierCavadenti avatar Mar 13 '22 09:03 OlivierCavadenti

@OlivierCavadenti I have not worked on it, so feel free to take over and I am also new to the project. The only thing I found some time ago was that it seems that in the ContextBuilder.enter(), the ASTNode seems to have correct sourceStart and sourceEnd but the modifiersSourceStart, declarationSourceStart and declarationSourceEnd are wrong when there is a comment. So it may be an eclipse issue. But I am not sure yet.

To reproduce it, you can run the example mentioned in the issue here and place a breakpoint in the enter() method and wait for the FRENCH element to come.

For a hacky way to see what I mean, this branch https://github.com/kl0u/spoon/tree/enum-fix fixes the problem for the test but breaks existing tests, so it is not a general fix.

kl0u avatar Mar 14 '22 21:03 kl0u

BTW for the above, I am wondering if the solution is simply one more if-clause that fixes the problem for this case by resetting the offsets, or there is a more principled solution. The problem with this if-clause solution is that it seems very targeted to this specific case. Any suggestions @slarse or anyone who knows the codebase better?

kl0u avatar Mar 20 '22 21:03 kl0u