Bug 46699 - IBinding.isSynthetic() returns false for compiler-generated constructor
Summary: IBinding.isSynthetic() returns false for compiler-generated constructor
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.0 M6   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 46720
Blocks:
  Show dependency tree
 
Reported: 2003-11-14 15:11 EST by Robert M. Fuhrer CLA
Modified: 2003-12-17 07:10 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Robert M. Fuhrer CLA 2003-11-14 15:11:53 EST
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!
Comment 1 Olivier Thomann CLA 2003-11-14 15:34:23 EST
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?
Comment 2 Robert M. Fuhrer CLA 2003-11-14 16:26:24 EST
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?
Comment 3 Jim des Rivieres CLA 2003-11-14 17:24:40 EST
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.
Comment 4 Jim des Rivieres CLA 2003-11-14 22:42:34 EST
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.
Comment 5 Robert M. Fuhrer CLA 2003-11-18 09:25:54 EST
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?
Comment 6 Jim des Rivieres CLA 2003-11-18 10:06:49 EST
Leaving this bug open until the javadoc is updated.
Comment 7 Olivier Thomann CLA 2003-11-19 11:03:28 EST
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.
Comment 8 Olivier Thomann CLA 2003-11-19 11:39:35 EST
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.
Comment 9 Olivier Thomann CLA 2003-11-21 00:10:52 EST
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?
Comment 10 Olivier Thomann CLA 2003-11-24 10:10:32 EST
Could you please give some feedback on the proposal? Otherwise it will be closed
as WONTFIX.
Comment 11 Olivier Thomann CLA 2003-11-25 12:54:00 EST
Jim, once you update the javadoc of isSynthetic() and isDefaultConstructor(),
you can move it back and I will close it.
Comment 12 Jim des Rivieres CLA 2003-11-26 09:24:37 EST
Updated specs for IBinding.isSynthetic and IMethodBinding.isDefaultConstructor.
Comment 13 Olivier Thomann CLA 2003-11-26 09:58:00 EST
Thanks.
Fixed and released in HEAD.
Regression test added.
Comment 14 Robert M. Fuhrer CLA 2003-12-01 09:58:24 EST
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).
Comment 15 Olivier Thomann CLA 2003-12-01 10:11:27 EST
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.
Comment 16 Robert M. Fuhrer CLA 2003-12-01 16:45:48 EST
Oh, silly me; of course. So then your proposed solution would work great for me.
Comment 17 David Audel CLA 2003-12-17 07:10:14 EST
Verified for 3.0M6