Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 318936

Summary: [intertype] [refactoring] Pull out of constructors may change semantics of program
Product: [Tools] AJDT Reporter: Kris De Volder <kdevolder>
Component: UIAssignee: AJDT-inbox <AJDT-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: DEVELOPMENT   
Target Milestone: 2.1.0   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
AJDT_318936_CheckForThisCall.patch
andrew.eisenberg: iplog+
mylyn/context/zip none

Description Kris De Volder CLA 2010-07-05 14:47:32 EDT
When we pull out a constructor as an ITD, from a class that has initializers, the initializers will no longer be executed when that constructor is called. This is due to the way AspectJ works in this case.

e.g:

class Foo {
  int countDown = 100;
  public Foo() {
     System.out.println("countdown is starting: "+countDown);
  }
}

Before we pull out the constructor from this class, it will print countDown value as 100.

After we pull it out to an ITD we get 

aspect Aspect {
   public Foo.new() {
     System.out.println("countdown is starting: "+countDown);
   }
}

But due to the semantics of AspectJ constructor ITDs this no longer executes the initializer from the Foo class. (So countDown will now be printed as starting at 0).

(See http://www.eclipse.org/aspectj/doc/next/progguide/apcs02.html )

In some cases it may be possible to implement the refactoring to remedy this by inserting an explicit call to the class's this() constructor. But there are also cases where this seems impossible/hard (e.g. when the constructor already has an explicit call to a super constructor.

At first sight there would be three cases to consider:
  - original constructor has no explicit constructor calls
    => we can remedy this by inserting one.
  - original constructor has an explicit this constructor call
    => this case is ok
  - original constructor has an explicit call to super constructor
    => initializers will be lost, no easy remedy exists.

The current implementation of pull-out refactoring is unaware of any of these subtleties and just pulls out the constructor without warning or modification.
Comment 1 Kris De Volder CLA 2010-07-27 17:11:38 EDT
Created attachment 175357 [details]
AJDT_318936_CheckForThisCall.patch

Patch that adds warning messages when pulling out constructors that do not have a this() call.
Comment 2 Kris De Volder CLA 2010-07-27 17:11:41 EDT
Created attachment 175358 [details]
mylyn/context/zip
Comment 3 Andrew Eisenberg CLA 2010-07-27 17:47:10 EDT
Patch applied and committed.