[Lazarus] Bug in cody. Exploding a hanging with block.

ListMember listmember at letterboxes.org
Sun Jun 8 20:50:17 CEST 2014


I had some time to spare and I thought I might take a shot at, my long 
time desire of, getting rid of 'with's in VirtualTrees.pas

One thing I noticed is this: If the with block is more involved than a 
simple element, such as this:

       with Owner, FHeader, FFixedAreaConstraints, TreeView do begin

you have to start 'exploding' from the right-most element and work your 
way to the left-most one. Otherwise, the resulting code can become 
meaningless/uncompilable.

Since there's that workaround, I can live with that caveat.

But, I think the one below is a bug:

Here is the original code:

procedure TVirtualTreeColumns.UpdatePositions(Force: Boolean = False);
var
   I, RunningPos: Integer;
begin
   if not FNeedPositionsFix and (Force or (UpdateCount = 0)) then begin
     RunningPos := 0;
     for I := 0 to High(FPositionToIndex) do
*with Items[FPositionToIndex[I]] do **begin*
         FPosition := I;
         FLeft := RunningPos;
         if coVisible in FOptions then Inc(RunningPos, FWidth);
*end*;
   end;
end;

when I explode 'Items[FPositionToIndex[I]]' it becomes this:

procedure TVirtualTreeColumns.UpdatePositions(Force: Boolean = False);
var
   I, RunningPos: Integer;
begin
   if not FNeedPositionsFix and (Force or (UpdateCount = 0)) then begin
     RunningPos := 0;
*for I := 0 to High(FPositionToIndex) do**
**      Items[FPositionToIndex[I]].FPosition := I;*
       Items[FPositionToIndex[I]].FLeft := RunningPos;
       if coVisible in Items[FPositionToIndex[I]].FOptions then 
Inc(RunningPos, Items[FPositionToIndex[I]].FWidth);
   end;
end;

At first sight, it looks OK. It compiles.

But, it has, silently, intoduced a bug: It has removed the 'begin end' 
block that belonged to the 'with' and did not shift it back to the 'for' 
loop.

IOW, it should have been like this. Notice that 'begin' moved to back to 
the for-loop block.

procedure TVirtualTreeColumns.UpdatePositions(Force: Boolean = False);
var
   I, RunningPos: Integer;
begin
   if not FNeedPositionsFix and (Force or (UpdateCount = 0)) then begin
     RunningPos := 0;
*for I := 0 to High(FPositionToIndex) do begin*
       Items[FPositionToIndex[I]].FPosition := I;
       Items[FPositionToIndex[I]].FLeft := RunningPos;
       if coVisible in Items[FPositionToIndex[I]].FOptions then 
Inc(RunningPos, Items[FPositionToIndex[I]].FWidth);
*end*;
   end;
end;


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20140608/f7568514/attachment-0002.html>


More information about the Lazarus mailing list