[Spoon-discuss] Enum bugs

Renaud Pawlak renaud.pawlak at gmail.com
Tue Jan 6 09:24:27 CET 2009


Hi Alex,

I am EXTREMELY confused about all you just said about enums because
one of the test we are running with Spoon is one the following
annotation (see the test package):

package spoon.test.enums;

import java.util.Stack;

public enum OpCode implements Performable {
    PUSH(1) {
        public void perform(Stack<Integer> s, int[] op) {
            s.push(op[0]); }},
    ADD(0) {
        public void perform(Stack<Integer> s, int[] op) {
            s.push( s.pop() + s.pop() ); }};
    OpCode(int numOp) { this.numOp = numOp; }
    private int numOp;
    private OpCode OP;
    public int dummy() {
    	return OP.numOp+numOp;
    }
}

It used to work fine at the time I wrote it and I believe that it is
complex enough to cover many cases.

Where did you get Spoon's source code and version are you sure that
you are doing the right analysis of the problem? Maybe there was a
regression at some point in Spoon?

For the constructor types, YES there are probably still some bugs with generics.

YES we tested spoon on big projects but at the time (like 2 years ago)
generics were maybe less widely used and we may not have covered
enough use cases. Plus, the type of tests we did were:

- generate source code with Spoon
- compile generated source code

In most cases, if there is a wrong change in the generated source
code, it will be detected by the compiler, but unfortunately not
always but that would be bad luck IMO. If the compiled projet has a
test suite, passing the test suite would be more efficient.

As for being ready for production, I believe that the main problem is
the lack of support! Small bugs will always have to be fixed because
Java is complex.

/Renaud



On Mon, Jan 5, 2009 at 11:47 PM, Alex Epshteyn
<alexander.epshteyn at gmail.com> wrote:
> I managed to finally get spoon to compile my project without crashing.
>  Renaud, could you code review he attached patches, please?  ( they're
> against the spoon-1.4 release sources)
>
> Now, although my project compiles without Spoon crashing, it seems
> like there is still a long way to go before the "spooned" code can be
> compiled.
>
> The next thing on my list is that DefaultJavaPrettyPrinter omits type
> args in constructors.  Example:
>
> Input:
>
> public <W extends Widget & SourcesClickEvents> PopupOpener(W openerWidget, ...)
>
> Output:
>
> public PopupOpener(W openerWidget, ....)
>
>
> This confirms my suspicion that DefaultJavaPrettyPrinter isn't ready
> for production use.  Is this something that could be worked around
> using the "code fragment API"?  I don't want to be stuck in an endless
> struggle of patching spoon just to preserve my original code, if I can
> avoid it.
>
> Thanks,
> Alex
>
>
>
> On Mon, Jan 5, 2009 at 3:37 PM, Alex Epshteyn
> <alexander.epshteyn at gmail.com> wrote:
>> I found several bugs with the way Spoon handles enums, both in
>> visiting and in code generation.  I realized that methods defined
>> inside enums in the input files are missing from the output files.
>> After some debugging, I've identified the following places in the code
>> that need some work:
>>
>> 1) CtScanner.java - visitCtEnum doesn't scan the methods of the enum:
>>
>>          public <T extends Enum<?>> void visitCtEnum(CtEnum<T> ctEnum) {
>>                enter(ctEnum);
>>                scan(ctEnum.getAnnotations());
>>                scan(ctEnum.getFields());
>>                scan(ctEnum.getNestedTypes());
>>                exit(ctEnum);
>>        }
>>
>>  My feeling is that it should be identical to visiting a class:
>>
>>          public <T> void visitCtClass(CtClass<T> ctClass) {
>>                enter(ctClass);
>>                scan(ctClass.getAnnotations());
>>                scan(ctClass.getSuperclass());
>>                scanReferences(ctClass.getSuperInterfaces());
>>                scanReferences(ctClass.getFormalTypeParameters());
>>                scan(ctClass.getAnonymousExecutables());
>>                scan(ctClass.getNestedTypes());
>>                scan(ctClass.getFields());
>>                scan(ctClass.getConstructors());
>>                scan(ctClass.getMethods());
>>                exit(ctClass);
>>        }
>>
>> 2) DefaultJavaPrettyPrinter.visitCtEnum - doesn't print the methods of
>> the enum.  Again, I think this method should be implemented more like
>> visitCtClass.
>>
>>
>> 3) I tried patching (1) and (2), but now my processor runs into the
>> following exception while attempting to insert code into enum methods:
>>
>> java.lang.NullPointerException
>>        at spoon.support.template.SubstitutionVisitor$InheritanceSustitutionScanner.visitCtTypeReference(SubstitutionVisitor.java:501)
>>        at spoon.support.reflect.reference.CtTypeReferenceImpl.accept(CtTypeReferenceImpl.java:62)
>>        at spoon.reflect.visitor.CtInheritanceScanner.scan(CtInheritanceScanner.java:139)
>>        at spoon.support.template.SubstitutionVisitor.scan(SubstitutionVisitor.java:661)
>>        at spoon.reflect.visitor.CtScanner.visitCtTypeReference(CtScanner.java:536)
>>        at spoon.support.reflect.reference.CtTypeReferenceImpl.accept(CtTypeReferenceImpl.java:62)
>>        at spoon.support.template.SubstitutionVisitor.<init>(SubstitutionVisitor.java:620)
>>        at spoon.template.Substitution.substitute(Substitution.java:433)
>>        at spoon.template.Substitution.substituteMethodBody(Substitution.java:388)
>>        at com.stackspooner.MethodProcessor.process(MethodProcessor.java:64)
>>
>> For some reason, the following template substitution code doesn't work
>> with enum methods:
>>
>>    mehtod.getBody().insertBefore(
>>        new TypeFilter<CtReturn>(CtReturn.class),
>>        Substitution.substituteMethodBody(
>>            (CtClass) method.getDeclaringType(),
>>            template, "endMethod"));
>>
>>
>> 4) I'm now concerned about the safety of using Spoon to instrument
>> production code, since I realized that DefaultJavaPrettyPrinter could
>> contain other bugs like this.  Have you guys tried running a test like
>> this on a nontrivial set of inputs:
>>
>> a) Parse the Java sources to produce AST_1
>> b) Output AST_1 using DefaultJavaPrettyPrinter
>> c) Reparse the output to produce AST_2
>> d) assert AST_1 == AST_2
>>
>> If this test passes on some sophisticated project, like Sun's JRE
>> source code, for instance, we could have a high degree of confidence
>> in DefaultJavaPrettyPrinter.
>>
>> I'm attaching the source code for an enum that demonstrates these bugs.
>>
>> Thanks,
>> Alex
>>
>
> _______________________________________________
> Spoon-discuss mailing list
> Spoon-discuss at lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/spoon-discuss
>



-- 
Renaud Pawlak, Professor
ISEP - 21 rue d'Assas 75006 Paris, France
Head of the Computer Engineering Department
Head of ISEP Research and Consulting for Computer Engineering
Phone: +33 149 54 52 78
Cell #1: +33 6 37 29 12 15
Cell #2: +33 6 36 47 06 01
Fax: +33 1 49 54 52 51
http://renaudpawlak.wikidot.com




More information about the Spoon-discuss mailing list