Community
Participate
Working Groups
JavaDoc for IBinding.isSynthetic() says: "Returns whether this binding is synthetic. A synthetic binding is one that was made up by the compiler, rather than something declared in the source code." It nevertheless returns false for a binding that refers to a compiler-generated constructor, as is the case for the call to "new Foo()" in the following code fragment: public class Foo { public void foo() { new Foo(); } } Given the ClassInstanceCreation corresponding to the constructor call, the IMethodBinding returned by ClassInstanceCreation.resolveConstructorBinding() clearly refers to a compiler-generated default constructor, but isSynthetic() on that method binding returns false. I.e. run the following on the above code fragment: ClassInstanceCreation ctorCall= /* ...get ctor call from somewhere... */; IMethodBinding binding= ctorCall.resolveConstructorBinding(); boolean isSynthetic= binding.isSynthetic(); // returns false!
Unfortunately the JVM specs don't say that the default constructor should be tagged as synthetic even if it is. We should update the javadoc to reflect this. Jim, any idea how to rephrase this?
I don't understand: why is the JVM spec relevant when the class in question is defined in source code and we're talking about data structures defined by the JDT?
The problem is that default constructors predates the notion of "synthetic" which was introduced with JDK 1.1. Java compilers have never marked default constructors as synthetic, even though they arguably should have.
After re-reading the JVM spec, I don't see why default constructors aren't marked as synthetic. Opening bug 46720 to investigate the compiler's behavior.
Having looked at bug 46720, I gather that IBinding.isSynthetic() is really just an alias for the JVM's definition of synthetic, so the JavaDoc's should say so clearly, and mention that default constructors "don't qualify". At the same time, clients need to be able to tell whether a given constructor is compiler-generated without needing to search the given class' AST for a MethodDeclaration with the right signature. I'm guessing that the IMethodBinding was created in a context in which this information was readily available. *Please* make the information available to clients of IMethodBinding! Do I need to submit a distinct bug report for this?
Leaving this bug open until the javadoc is updated.
In your specific case, you could use the findDeclaringNode method on the compilation unit. It answers null in your case. It won't work if you are not in the same compilation unit. I will investigate how to preserve this information in the method binding.
We could preserve and expose this information when it is from source. But if the binding is retrieved from a binary type, then it is impossible to know. There is no information that we could rely on to find out if this is the default constructor.
Would a isDefaultConstructor() method on IMethodBinding fix this problem even if it is not possible to get the information for a default constructor that is coming from a .class file?
Could you please give some feedback on the proposal? Otherwise it will be closed as WONTFIX.
Jim, once you update the javadoc of isSynthetic() and isDefaultConstructor(), you can move it back and I will close it.
Updated specs for IBinding.isSynthetic and IMethodBinding.isDefaultConstructor.
Thanks. Fixed and released in HEAD. Regression test added.
Just got back from vacation, so I just saw your request for feedback. Yes, a new method isDefaultConstructor() on IMethodBinding would solve my problem, assuming it worked for constructors that take arguments as well as no-arg constructors ("default" is somewhat overloaded in this context).
The default constructor is the constructor added by the compiler when no constructor are available for a class. So if you have an argument, it cannot be the default constructor. There is no other definition of default constructor.
Oh, silly me; of course. So then your proposed solution would work great for me.
Verified for 3.0M6