Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/IDE/Refactoring/Push Members Down    [ Add a report in this area ]  
Report #:  26550   Status: Closed
Refactoring "Push members down" messes up uses clause
Project:  Delphi Build #:  10.0.2166.28377
Version:    10.0 Submitted By:   Kristofer Skaug
Report Type:  Basic functionality failure Date Reported:  3/26/2006 3:12:36 PM
Severity:    Commonly encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   239605
Resolution: Fixed (Resolution Comments) Resolved in Build: : 11.0.2587.4022
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description

When a method is refactored using "Push members down", the uses clause is messed up. This seems to happen when the code in the refactored method contains dependencies on identifiers declared in other units.
Specifically, in this case the units on which the refactored code depends, are re-inserted into the beginning of the uses clause, disregarding the fact that both units were already listed, so the unit no longer compiles.

See steps and attachment.
Steps to Reproduce:
1. Open the attached project.
2. Open Unit1.pas, verify it has the following form:

---------------------- < Unit1 > -----------------------------
unit Unit1;

interface

uses SysUtils,Windows,Unit2,Unit3;

type TParentClass = class
protected
  FParentValue: integer;
public
  procedure ParentMethod;
  procedure PushDownMethod;
end;

type TChildClass = class(TParentClass)
public
  procedure ChildMethod;
end;

implementation

{ TParentClass }

procedure TParentClass.ParentMethod;
begin
  FParentValue := 0;
end;

procedure TParentClass.PushDownMethod;
begin
  FParentValue := CONST_FROM_UNIT_2 + CONST_FROM_UNIT_3;
end;

{ TChildClass }

procedure TChildClass.ChildMethod;
begin
  FParentValue := 1;
end;

end.
---------------------< End Unit1> -------------------------

2. Go to TParentClass, procedure.PushDownMethod in the interface section
3. Select/highlight the "PushDownMethod" identifier
4. Invoke the "Push Members Down" refactoring,
    and confirm (Ctrl+R) the refactoring.
5. Verify that Unit1 is now modified as follows:

---------------------- < Unit1 > -----------------------------
unit Unit1;

interface

uses Unit3, Unit2, SysUtils,Windows,Unit2,Unit3;

type TParentClass = class
protected
  FParentValue: integer;
public
  procedure ParentMethod;
end;

type TChildClass = class(TParentClass)
public
  procedure ChildMethod;
  procedure PushDownMethod;
end;

implementation

{ TParentClass }

procedure TParentClass.ParentMethod;
begin
  FParentValue := 0;
end;

{ TChildClass }
procedure TChildClass.ChildMethod;
begin
  FParentValue := 1;
end;

procedure TChildClass.PushDownMethod;
begin
  FParentValue := CONST_FROM_UNIT_2 + CONST_FROM_UNIT_3;
end;

end.

---------------------< End Unit1> -------------------------

6. Try to compile (Ctrl+F9);
[Pascal Error] Unit1.pas(5): E2004 Identifier redeclared: 'Unit2'
Workarounds
None
Attachment
RefactorTest.zip
Comments

None

Server Response from: ETNACODE01