-
-
Notifications
You must be signed in to change notification settings - Fork 353
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
Spoon representation does not model the implicit String and int parameters to enum constructors #4758
Comments
It's a bit more complicated: The two parameters inserted by javac are synthetic, not implicit. They are not required to exist and other compilers can choose to do something else. The JLS § 8.9.2 mentions:
So, as synthetic constructs are compiler-dependend, it's basically impossible for spoon to model them correctly. However, I just saw that the implicit methods |
I see, that does make it more complicated. But the semantics of the enum, in regard to the String names and int ordinals, is uniquely defined, even if the implementation is not uniquely defined. Am I right about this? I believe the compiler does not have the freedom to choose arbitrary names or ordinals for the enum values. They are well-defined and uniquely defined. Isn't it then a correct modeling of the program semantics for spoon to, as a compiler, choose any legal implementation with which to produce the required (and explicit) arguments to the |
Hey, my main question is: What problem are you trying to solve that you currently can not due to this?
I am not sure I agree, as your source code clearly shows exactly this to be correct! |
The item that is incorrect is one very specific thing: In the constructor of an enum, spoon generates a call to The source code examples I gave earlier are not a contradiction here, since the source program does not explicitly invoke the super constructor. Indeed, it is forbidden for the source program to have a super constructor call in the constructor of an enum, (JLS 8.9.2), presumably exactly for the reason that it is the compiler, not the user, who must supply the arguments to the super constructor.
The upshot is that spoon generates a representation that fails to type-check, which is problematic for my use case. I can certainly come up with a workaround that rewrites the representation into something that type-checks, but I still felt it appropriate to file a bug report since the tool currently emits an invalid function call. Perhaps it is best not to emit the call at all, in the spirit of not modelling things that are implementation details? |
That sounds like the best solution to me, though it is a bit weird. Less so than the alternatives though IHMO.
Is this actually observable (e.g. printed) or does your type-checker consider the implicit (hopefully marked as such) super invocation and fails while doing so? |
I have had a look at the issue and the source for the call is JDT itself. It seems like we build the AST before JDT has lowered the constructor far enough to add the String and int parameters to it. I've linked a PR that just removes the super call in such a case. Not ideal, but I do agree that the current version is unacceptable and this sounded better than manually adding compiler internals back into the model. |
The constructor for
java.lang.Enum
takes two arguments, String and int. Accordingly, the default constructor for any enum type, unlike for ordinary classes, implicitly accepts these two arguments and forwards them to the super constructor. User-defined enum constructors can have additional explicit arguments; the signature of a user-defined enum constructor has the implicit String and int parameters prepended to it.So, for example, the source code
is converted by
javac
to something that essentially looks likeAlso, the source code
is converted by
javac
to something that essentially looks likeOne can view the disassembly with
javap -c -p -s
to see this.The Spoon representation currently does not model the implicit String and int parameters, omitting them from an enum's constructor parameters and from the call to the super constructor. This is incorrect, because
java.lang.Enum
does not have a zero-argument constructor.The text was updated successfully, but these errors were encountered: