Bug 163443 - [clean up] private constructor with parameter flagged as unnecessary
Summary: [clean up] private constructor with parameter flagged as unnecessary
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: 3.3 M5   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-04 10:22 EST by Görge Albrecht CLA
Modified: 2007-02-11 16:24 EST (History)
4 users (show)

See Also:


Attachments
Proposed patch (7.22 KB, patch)
2007-01-09 09:41 EST, Philipe Mulet CLA
no flags Details | Diff
Better patch (7.10 KB, patch)
2007-01-10 12:19 EST, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Görge Albrecht CLA 2006-11-04 10:22:19 EST
When invoking clean up with "Remove unused private member - constructor" enabled on the example class from the clean up preference page, the constructor is not being removed.

class Example {
    private Example() {}
    public void bar() {
        int i= 10;
    }
}
Comment 1 Alex Blewitt CLA 2006-11-06 03:46:57 EST
That's not a bug. That's a feature. If you remove the private Example(), then you're implicitly creating a public constructor (public Example()) instead. So you've gone from a situation where no-one else can instantiate the class to a situation where everyone can create instances of that class. 

If this were 'fixed', you'd pretty much be guaranteed to break every Singleton class there is ...
Comment 2 Benno Baumgartner CLA 2006-11-06 05:10:09 EST
Thanks Alex, interesting... Here:
class E1 {
	private E1(int i) {}
}
class E2 {
	public E1 e= new E1();
}
The private constructor is flagged as never used locally (and therefore removed by clean up). Which is basically correct: It is never used locally. But why is then the constructor without a parameter not flagged? Moving to core for comments.

Fix on the clean up side is to change the example in the preview.
Comment 3 Görge Albrecht CLA 2006-11-09 03:38:46 EST
Re #1: Of course you're right, my example was too simple.

Considering the following code:

class Example {
  private Example() {
  }
  public Example(int i) {
  }
}

Clean Up should remove the private constructor, right?
Comment 4 Philipe Mulet CLA 2006-11-09 05:03:25 EST
I agree our behavior is suboptimal. We only tolerate a private constructor with no parameter, as known pattern to block instantiation.

In fact, it should tolerate private constructor (any params) if sole constructor.
Comment 5 Benno Baumgartner CLA 2006-11-09 10:17:55 EST
(In reply to comment #3)
> class Example {
>   private Example() {
>   }
>   public Example(int i) {
>   }
> }
> 
> Clean Up should remove the private constructor, right?
> 

Clean Up does remove all constructors which are marked as unused by the compiler. The above constructor is not marked, although it think it can be marked safely. I guess core does just never consider private unparameterized constructors.
Comment 6 Philipe Mulet CLA 2007-01-09 09:33:12 EST
re: comment 4
I think it should flag unused private constructors as soon as there are non-private constructors as well. Unsure about whether it needs to be the sole constructor.
i.e. should it complain for the following case ?

class E1 {
    private E1(int i) {}
    private E1(long l) {}
}

Comment 7 Philipe Mulet CLA 2007-01-09 09:41:51 EST
Created attachment 56627 [details]
Proposed patch

Patch for 3.3 stream, which only blame unused private constructors if non-private one(s) are also present. So it will not complain on last testcase above with 2 private constructors.
Comment 8 Benno Baumgartner CLA 2007-01-09 09:47:41 EST
(In reply to comment #6)
> I think it should flag unused private constructors as soon as there are
> non-private constructors as well. 

Agree. And not flag them if there are no non-private constructors.

> Unsure about whether it needs to be the sole
> constructor.
> i.e. should it complain for the following case ?
> 
> class E1 {
>     private E1(int i) {}
>     private E1(long l) {}
> }
> 

IMHO it should tolerate them and not complain. Removing (both) constructors would change the semantic, they are therefor not unnecessary. But of course it makes no sense to write unused constructors with parameters, but this would be another kind of warning, wouldn't it?
Comment 9 Philipe Mulet CLA 2007-01-09 10:03:13 EST
Likely yes, another warning (separate issue).

Need to tune quite a few existing test expectations then.
Eric - can you attach a patch with updated affected tests ?
Comment 10 Philipe Mulet CLA 2007-01-10 12:19:15 EST
Created attachment 56716 [details]
Better patch
Comment 11 Philipe Mulet CLA 2007-01-10 13:17:38 EST
Released for 3.3M5
Comment 12 David Audel CLA 2007-02-06 06:40:56 EST
Verified for 3.3 M5 using build I20070206-0010