645
651
Line:=Lines[Lines.Count-1];
646
if (atIdentifier in Options.DoInsertSpaceAfter)
647
or (atComma in Options.DoInsertSpaceInFront) then
652
if (atIdentifier in Beauty.DoInsertSpaceAfter)
653
or (atComma in Beauty.DoInsertSpaceInFront) then
650
656
l:=length(Line)+length(NewUses)+1; // +1 for the following , or ;
651
if (atComma in Options.DoInsertSpaceAfter)
652
or (atIdentifier in Options.DoInsertSpaceInFront) then
657
if (atComma in Beauty.DoInsertSpaceAfter)
658
or (atIdentifier in Beauty.DoInsertSpaceInFront) then
654
660
if Lines.Count=1 then
655
661
inc(l,FirstIndent);
656
662
//DebugLn(['AddUseUnit Lines.Count=',Lines.Count,' l=',l,' Line="',Line,'" NewUses=',NewUses,' FirstIndent=',FirstIndent]);
657
if l<=Options.LineLength then begin
663
if l<=Beauty.LineLength then begin
658
664
// append to last line
659
if (atComma in Options.DoInsertSpaceAfter)
660
or (atIdentifier in Options.DoInsertSpaceInFront) then
665
if (atComma in Beauty.DoInsertSpaceAfter)
666
or (atIdentifier in Beauty.DoInsertSpaceInFront) then
662
668
Line:=Line+NewUses;
663
669
Lines[Lines.Count-1]:=Line;
666
672
Lines[Lines.Count-1]:=Line;
667
Line:=GetIndentStr(Indent)+NewUses;
673
Line:=Beauty.GetIndentStr(Indent)+NewUses;
844
850
// if not, rebuild the uses section
845
851
GetLineStartEndAtPosition(Src,InsertPos,LineStart,LineEnd);
846
852
InsertLen:=length(NewUsesTerm)+length(NewComma);
847
//DebugLn(['TStandardCodeTool.AddUnitToUsesSection Line=',copy(Src,LineStart,InsertPos-LineStart),'<InsertPos>',copy(Src,InsertPos,LineEnd-InsertPos),' NewLen=',LineEnd-LineStart+InsertLen,' Max=',Options.LineLength,' Addition=',NewUsesTerm]);
848
if (LineEnd-LineStart+InsertLen > Options.LineLength) then begin
853
//DebugLn(['TStandardCodeTool.AddUnitToUsesSection Line=',copy(Src,LineStart,InsertPos-LineStart),'<InsertPos>',copy(Src,InsertPos,LineEnd-InsertPos),' NewLen=',LineEnd-LineStart+InsertLen,' Max=',Beauty.LineLength,' Addition=',NewUsesTerm]);
854
if (LineEnd-LineStart+InsertLen > Beauty.LineLength) then begin
849
855
// line too long => reformat block of used units
850
856
// find start of block of used units
851
857
Node:=InsertNode;
1100
1106
if AtomIsChar(';') then begin
1101
1107
// last unit in uses section -> delete whole uses section
1102
1108
StartPos:=FindLineEndOrCodeInFrontOfPosition(UsesNode.StartPos,true,true);
1103
if not SourceChangeCache.Replace(gtNone,gtNone,
1104
StartPos,UsesNode.EndPos,'') then exit;
1109
EndPos:=UsesNode.EndPos;
1106
1111
// not last unit -> delete with comma behind
1107
1112
EndPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos);
1108
1113
if (EndPos>SrcLen) or (Src[EndPos] in [#10,#13]) then
1109
1114
StartPos:=FindLineEndOrCodeInFrontOfPosition(StartPos);// delete space in front or even the empty line
1110
if not SourceChangeCache.Replace(gtNone,gtNone,
1111
StartPos,EndPos,'') then exit;
1114
// not first unit in uses section -> delete with comma in front
1115
if not SourceChangeCache.Replace(gtNone,gtNone,
1116
EndPos,CurPos.StartPos,'') then exit;
1117
// not first unit in uses section
1118
if AtomIsChar(';') then begin
1119
// last unit -> delete with comma in front
1121
EndPos:=CurPos.StartPos;
1122
end else if PositionsInSameLine(Src,EndPos,StartPos) then begin
1123
// not first unit in line -> delete with comma in front
1125
EndPos:=CurPos.StartPos;
1127
// first unit in line -> delete with comma behind
1128
EndPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos);
1129
if (EndPos>SrcLen) or (Src[EndPos] in [#10,#13]) then
1130
StartPos:=FindLineEndOrCodeInFrontOfPosition(StartPos);// delete space in front or even the empty line
1133
if not SourceChangeCache.Replace(gtNone,gtNone,StartPos,EndPos,'') then
1118
1135
if not SourceChangeCache.Apply then exit;
1541
function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings;
1542
SourceChangeCache: TSourceChangeCache): boolean;
1558
function TStandardCodeTool.CommentUnitsInUsesSection(MissingUnits: TStrings;
1559
SourceChangeCache: TSourceChangeCache; UsesNode: TCodeTreeNode): boolean;
1561
// 1. uses {a,} b, c; commenting one unit not at end
1562
// 2. uses a, {b,} c; commenting one unit not at end
1563
// 3. uses {a, b,} c; commenting several units not at end
1564
// 4. uses a{, b, c} ; commenting units at end
1565
// 5. {uses a, b, c;} commenting all units
1566
// 6. uses {a,} b{, c}; commenting several units
1544
1568
procedure Comment(StartPos, EndPos: integer);
1546
1570
//debugln(['Comment ',dbgstr(copy(Src,StartPos,EndPos-StartPos))]);
1547
1571
CommentCode(StartPos,EndPos,SourceChangeCache,false);
1550
function CommentUnitsInUsesSection(UsesNode: TCodeTreeNode): boolean;
1552
// 1. uses {a,} b, c; commenting one unit not at end
1553
// 2. uses a, {b,} c; commenting one unit not at end
1554
// 3. uses {a, b,} c; commenting several units not at end
1555
// 4. uses a{, b, c} ; commenting units at end
1556
// 5. {uses a, b, c;} commenting all units
1557
// 6. uses {a,} b{, c}; commenting several units
1560
CurUnitName: String;
1561
CommentCurUnit: Boolean;
1562
FirstCommentUnitStart: Integer;
1563
LastCommaAfterCommentUnitsStart: Integer;
1564
LastNormalUnitEnd: Integer;
1565
LastCommentUnitEnd: Integer;
1566
Node: TCodeTreeNode;
1569
if UsesNode=nil then exit;
1570
FirstCommentUnitStart:=-1;
1571
LastCommaAfterCommentUnitsStart:=-1;
1572
LastNormalUnitEnd:=-1;
1573
LastCommentUnitEnd:=-1;
1574
Node:=UsesNode.FirstChild;
1575
while Node<>nil do begin
1576
// check if unit should be commented
1577
CurUnitName:=ExtractUsedUnitName(Node);
1578
// Note: CurPos is now on atom behind used unit, i.e. comma or semicolon
1579
i:=MissingUnits.Count-1;
1581
and (CompareIdentifiers(PChar(Pointer(MissingUnits[i])),
1582
PChar(Pointer(CurUnitName)))<>0) do
1584
CommentCurUnit:=i>=0;
1585
//debugln('CommentUnitsInUsesSection CurUnitName="',CurUnitName,'" CommentCurUnit=',dbgs(CommentCurUnit));
1576
CurUnitName: String;
1577
CommentCurUnit: Boolean;
1578
FirstCommentUnitStart: Integer;
1579
LastCommaAfterCommentUnitsStart: Integer;
1580
LastNormalUnitEnd: Integer;
1581
LastCommentUnitEnd: Integer;
1582
Node: TCodeTreeNode;
1585
if UsesNode=nil then exit;
1586
FirstCommentUnitStart:=-1;
1587
LastCommaAfterCommentUnitsStart:=-1;
1588
LastNormalUnitEnd:=-1;
1589
LastCommentUnitEnd:=-1;
1590
Node:=UsesNode.FirstChild;
1591
while Node<>nil do begin
1592
// check if unit should be commented
1593
CurUnitName:=ExtractUsedUnitName(Node);
1594
// Note: CurPos is now on atom behind used unit, i.e. comma or semicolon
1595
i:=MissingUnits.Count-1;
1597
and (CompareIdentifiers(PChar(Pointer(MissingUnits[i])),
1598
PChar(Pointer(CurUnitName)))<>0) do
1600
CommentCurUnit:=i>=0;
1601
//debugln('CommentUnitsInUsesSection CurUnitName="',CurUnitName,'" CommentCurUnit=',dbgs(CommentCurUnit));
1603
if CommentCurUnit then begin
1604
// unit should be commented
1605
if FirstCommentUnitStart<1 then FirstCommentUnitStart:=Node.StartPos;
1606
LastCommentUnitEnd:=Node.EndPos;
1608
// unit should be kept
1609
LastNormalUnitEnd:=Node.EndPos;
1610
if FirstCommentUnitStart>=1 then begin
1611
// there are some units to be commented
1612
// See examples: 1., 2., 3. and 6.
1613
Comment(FirstCommentUnitStart,LastCommaAfterCommentUnitsStart);
1614
FirstCommentUnitStart:=-1;
1615
LastCommentUnitEnd:=-1;
1616
LastCommaAfterCommentUnitsStart:=-1;
1620
if CommentCurUnit then
1621
LastCommaAfterCommentUnitsStart:=CurPos.EndPos;
1623
if CurPos.Flag<>cafComma then begin
1587
1624
if CommentCurUnit then begin
1588
// unit should be commented
1589
if FirstCommentUnitStart<1 then FirstCommentUnitStart:=Node.StartPos;
1590
LastCommentUnitEnd:=Node.EndPos;
1592
// unit should be kept
1593
LastNormalUnitEnd:=Node.EndPos;
1594
if FirstCommentUnitStart>=1 then begin
1595
// there are some units to be commented
1596
// See examples: 1., 2., 3. and 6.
1597
Comment(FirstCommentUnitStart,LastCommaAfterCommentUnitsStart);
1598
FirstCommentUnitStart:=-1;
1599
LastCommentUnitEnd:=-1;
1600
LastCommaAfterCommentUnitsStart:=-1;
1604
if CommentCurUnit then
1605
LastCommaAfterCommentUnitsStart:=CurPos.EndPos;
1607
if CurPos.Flag<>cafComma then begin
1608
if CommentCurUnit then begin
1609
// last unit must be commented
1610
if LastNormalUnitEnd>=1 then begin
1611
// comment last unit and keep some units in front
1613
Comment(LastNormalUnitEnd,LastCommentUnitEnd);
1615
// all units should be commented
1617
Comment(UsesNode.StartPos,CurPos.EndPos);
1623
Node:=Node.NextBrother;
1625
// last unit must be commented
1626
if LastNormalUnitEnd>=1 then begin
1627
// comment last unit and keep some units in front
1629
Comment(LastNormalUnitEnd,LastCommentUnitEnd);
1631
// all units should be commented
1633
Comment(UsesNode.StartPos,CurPos.EndPos);
1639
Node:=Node.NextBrother;
1643
function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings;
1644
SourceChangeCache: TSourceChangeCache): boolean;
1646
if (MissingUnits=nil) or (MissingUnits.Count=0) then
1629
if (MissingUnits=nil) or (MissingUnits.Count=0) then begin
1633
BuildTree(lsrImplementationUsesSectionEnd);
1649
BuildTree(lsrInitializationStart);
1634
1650
SourceChangeCache.MainScanner:=Scanner;
1635
if not CommentUnitsInUsesSection(FindMainUsesSection) then exit;
1636
if not CommentUnitsInUsesSection(FindImplementationUsesSection) then exit;
1651
if not CommentUnitsInUsesSection(MissingUnits, SourceChangeCache, FindMainUsesSection) then exit;
1652
if not CommentUnitsInUsesSection(MissingUnits, SourceChangeCache, FindImplementationUsesSection) then exit;
1637
1653
if not SourceChangeCache.Apply then exit;
3279
function TStandardCodeTool.CommentCode(const StartPos, EndPos: integer;
3280
SourceChangeCache: TSourceChangeCache; Apply: boolean): boolean;
3283
CurStartPos: LongInt;
3284
CommentNeeded: Boolean;
3287
if StartPos>=EndPos then
3288
RaiseException('TStandardCodeTool CommentCode');
3291
// comment with curly brackets {}
3294
CurEndPos:=CurStartPos;
3295
CommentNeeded:=false;
3297
//debugln(['TPascalReaderTool.CommentCode ',dbgstr(Src[i]),' Needed=',CommentNeeded,' ',dbgstr(copy(Src,CurStartPos,CurEndPos-CurStartPos))]);
3298
if (Src[i]='{') or (i>=EndPos) then begin
3299
// the area contains a comment -> comment in front
3300
if CommentNeeded then begin
3301
if not SourceChangeCache.Replace(gtNone,gtNone,
3302
CurStartPos,CurStartPos,'{') then exit;
3303
if not SourceChangeCache.Replace(gtNone,gtNone,
3304
CurEndPos,CurEndPos,'}') then exit;
3305
//DebugLn('Comment "',copy(Src,CurStartPos,i-CurStartPos),'"');
3306
CommentNeeded:=false;
3308
if i>=EndPos then break;
3310
i:=FindCommentEnd(Src,i,Scanner.NestedComments)-1;
3311
end else if not IsSpaceChar[Src[i]] then begin
3312
if not CommentNeeded then begin
3314
CommentNeeded:=true;
3321
Result:=SourceChangeCache.Apply
3261
3326
function TStandardCodeTool.GetStringConstBounds(
3262
3327
const CursorPos: TCodeXYPosition;
3263
3328
out StartPos, EndPos: TCodeXYPosition; ResolveComments: boolean): boolean;
6660
6735
// this function reads any bracket
6661
6736
// (the ReadTilBracketClose function reads only brackets in code, not comments)
6662
6737
var OpenBracket: char;
6663
CommentLvl: integer;
6666
6740
OpenBracket:=Src[CurPos.StartPos];
6667
6741
if OpenBracket='{' then begin
6668
6742
// read til end of comment
6670
inc(CurPos.StartPos);
6671
while (CurPos.StartPos<=SrcLen) and (CommentLvl>0) do begin
6672
case Src[CurPos.StartPos] of
6673
'{': if Scanner.NestedComments then inc(CommentLvl);
6675
if CommentLvl=1 then begin
6681
inc(CurPos.StartPos);
6743
CurPos.StartPos:=FindCommentEnd(Src,CurPos.StartPos,Scanner.NestedComments);
6744
Result:=CurPos.StartPos<=SrcLen;
6683
6745
end else if OpenBracket='(' then begin
6684
6746
if (CurPos.StartPos<SrcLen) and (Src[CurPos.StartPos+1]='*') then begin
6685
6747
// read til end of comment
6686
inc(CurPos.StartPos,3);
6688
if (CurPos.StartPos<=SrcLen)
6689
and ((Src[CurPos.StartPos-1]='*') and (Src[CurPos.StartPos]=')')) then
6694
inc(CurPos.StartPos);
6748
CurPos.StartPos:=FindCommentEnd(Src,CurPos.StartPos,Scanner.NestedComments);
6749
Result:=CurPos.StartPos<=SrcLen;
6751
// round bracket operator
6697
6752
Result:=ReadTilBracketClose(false);
6699
6754
end else if OpenBracket='[' then begin