diff --git a/components/codetools/basiccodetools.pas b/components/codetools/basiccodetools.pas index 7af92c36b0..86864b1988 100644 --- a/components/codetools/basiccodetools.pas +++ b/components/codetools/basiccodetools.pas @@ -176,6 +176,7 @@ function CompareComments(p1, p2: PChar; NestedComments: boolean): integer; // co // dotted identifiers function IsDottedIdentifier(const Identifier: string): boolean; +function CompareDottedIdentifiers(Identifier1, Identifier2: PChar): integer; // space and special chars function TrimCodeSpace(const ACode: string): string; @@ -3525,7 +3526,7 @@ end; function CompareIdentifierPtrs(Identifier1, Identifier2: Pointer): integer; begin - Result := CompareIdentifiers(PChar(Identifier1), PChar(Identifier2)); + Result:=CompareIdentifiers(PChar(Identifier1), PChar(Identifier2)); end; function CompareIdentifiersCaseSensitive(Identifier1, Identifier2: PChar @@ -4215,6 +4216,46 @@ begin Result:=(p-PChar(Identifier))=length(Identifier); end; +function CompareDottedIdentifiers(Identifier1, Identifier2: PChar): integer; +begin + if (Identifier1<>nil) then begin + if (Identifier2<>nil) then begin + while (UpChars[Identifier1[0]]=UpChars[Identifier2[0]]) do begin + if (IsDottedIdentChar[Identifier1[0]]) then begin + inc(Identifier1); + inc(Identifier2); + end else begin + Result:=0; // for example 'aaA;' 'aAa;' + exit; + end; + end; + if (IsDottedIdentChar[Identifier1[0]]) then begin + if (IsDottedIdentChar[Identifier2[0]]) then begin + if UpChars[Identifier1[0]]>UpChars[Identifier2[0]] then + Result:=-1 // for example 'aab' 'aaa' + else + Result:=1; // for example 'aaa' 'aab' + end else begin + Result:=-1; // for example 'aaa' 'aa;' + end; + end else begin + if (IsDottedIdentChar[Identifier2[0]]) then + Result:=1 // for example 'aa;' 'aaa' + else + Result:=0; // for example 'aa;' 'aa,' + end; + end else begin + Result:=-1; // for example 'aaa' nil + end; + end else begin + if (Identifier2<>nil) then begin + Result:=1; // for example nil 'bbb' + end else begin + Result:=0; // for example nil nil + end; + end; +end; + function TrimCodeSpace(const ACode: string): string; // turn all lineends and special chars to space // space is combined to one char diff --git a/components/codetools/keywordfunclists.pas b/components/codetools/keywordfunclists.pas index fe8a87b58e..9d8904e77b 100644 --- a/components/codetools/keywordfunclists.pas +++ b/components/codetools/keywordfunclists.pas @@ -166,6 +166,7 @@ var IsNonWordChar, // [#0..#127]-IsIdentChar IsIdentStartChar, IsIdentChar, + IsDottedIdentChar, IsNumberChar, IsCommentStartChar, IsCommentEndChar, @@ -829,6 +830,7 @@ begin IsSpaceChar[c]:=c in [#0..#32]; IsIdentStartChar[c]:=c in ['a'..'z','A'..'Z','_']; IsIdentChar[c]:=c in ['a'..'z','A'..'Z','_','0'..'9']; + IsDottedIdentChar[c]:=c in ['.','a'..'z','A'..'Z','_','0'..'9']; IsNumberChar[c]:=c in ['0'..'9']; IsCommentStartChar[c]:=c in ['/','{','(']; IsCommentEndChar[c]:=c in ['}',')',#13,#10]; diff --git a/components/codetools/stdcodetools.pas b/components/codetools/stdcodetools.pas index a65fca183d..a0d397ee94 100644 --- a/components/codetools/stdcodetools.pas +++ b/components/codetools/stdcodetools.pas @@ -131,7 +131,7 @@ type SearchImplementation: boolean; SourceChangeCache: TSourceChangeCache): boolean; function CommentUnitsInUsesSections(MissingUnits: TStrings; - SourceChangeCache: TSourceChangeCache): boolean; // ToDo: dotted + SourceChangeCache: TSourceChangeCache): boolean; function FindUnusedUnits(Units: TStrings): boolean; // ToDo: dotted // lazarus resources @@ -1534,18 +1534,19 @@ function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings; LastCommaAfterCommentUnitsStart: Integer; LastNormalUnitEnd: Integer; LastCommentUnitEnd: Integer; + Node: TCodeTreeNode; begin Result:=true; if UsesNode=nil then exit; - MoveCursorToUsesStart(UsesNode); FirstCommentUnitStart:=-1; LastCommaAfterCommentUnitsStart:=-1; LastNormalUnitEnd:=-1; LastCommentUnitEnd:=-1; - repeat + Node:=UsesNode.FirstChild; + while Node<>nil do begin // check if unit should be commented - AtomIsIdentifier(true); - CurUnitName:=GetAtom; + CurUnitName:=ExtractUsedUnitName(Node); + // Note: CurPos is now on atom behind used unit, i.e. comma or semicolon i:=MissingUnits.Count-1; while (i>=0) and (CompareIdentifiers(PChar(Pointer(MissingUnits[i])), @@ -1556,11 +1557,11 @@ function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings; if CommentCurUnit then begin // unit should be commented - if FirstCommentUnitStart<1 then FirstCommentUnitStart:=CurPos.StartPos; - LastCommentUnitEnd:=CurPos.EndPos; + if FirstCommentUnitStart<1 then FirstCommentUnitStart:=Node.StartPos; + LastCommentUnitEnd:=Node.EndPos; end else begin // unit should be kept - LastNormalUnitEnd:=CurPos.EndPos; + LastNormalUnitEnd:=Node.EndPos; if FirstCommentUnitStart>=1 then begin // there are some units to be commented // See examples: 1., 2., 3. and 6. @@ -1571,18 +1572,6 @@ function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings; end; end; - ReadNextAtom; - if UpAtomIs('IN') then begin - ReadNextAtom; // read filename - if not AtomIsStringConstant then - RaiseExceptionFmt(ctsStrExpectedButAtomFound,[ctsStringConstant,GetAtom]); - if (not CommentCurUnit) then - LastNormalUnitEnd:=CurPos.EndPos; - if CommentCurUnit then - LastCommentUnitEnd:=CurPos.EndPos; - ReadNextAtom; // read comma or semicolon - end; - if CommentCurUnit then LastCommaAfterCommentUnitsStart:=CurPos.EndPos; @@ -1602,8 +1591,8 @@ function TStandardCodeTool.CommentUnitsInUsesSections(MissingUnits: TStrings; break; end; - ReadNextAtom; - until false; + Node:=Node.NextBrother; + end; end; begin