diff --git a/components/codetools/basiccodetools.pas b/components/codetools/basiccodetools.pas index dd728f2e74..7af92c36b0 100644 --- a/components/codetools/basiccodetools.pas +++ b/components/codetools/basiccodetools.pas @@ -174,6 +174,9 @@ function CompareAtom(p1, p2: PChar; NestedComments: boolean): integer; function CompareStringConstants(p1, p2: PChar): integer; // compare case sensitive function CompareComments(p1, p2: PChar; NestedComments: boolean): integer; // compare case insensitive +// dotted identifiers +function IsDottedIdentifier(const Identifier: string): boolean; + // space and special chars function TrimCodeSpace(const ACode: string): string; function CodeIsOnlySpace(const ACode: string; FromPos, ToPos: integer): boolean; @@ -4195,6 +4198,23 @@ begin if LengthOfLastLine=0 then ; end; +function IsDottedIdentifier(const Identifier: string): boolean; +var + p: PChar; +begin + Result:=false; + if Identifier='' then exit;; + p:=PChar(Identifier); + repeat + if not IsIdentStartChar[p^] then exit; + inc(p); + while IsIdentChar[p^] do inc(p); + if p^<>'.' then break; + inc(p); + until false; + Result:=(p-PChar(Identifier))=length(Identifier); +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/pascalreadertool.pas b/components/codetools/pascalreadertool.pas index 0391835088..15c81a44f3 100644 --- a/components/codetools/pascalreadertool.pas +++ b/components/codetools/pascalreadertool.pas @@ -210,6 +210,8 @@ type procedure MoveCursorToUsesEnd(UsesNode: TCodeTreeNode); procedure ReadNextUsedUnit(out UnitNameRange, InAtom: TAtomPosition); procedure ReadPriorUsedUnit(out UnitNameRange, InAtom: TAtomPosition); + function ExtractUsedUnitName(UseUnitNode: TCodeTreeNode; + InFilename: PAnsiString = nil): string; // comments function FindCommentInFront(const StartPos: TCodeXYPosition; @@ -2559,6 +2561,28 @@ begin until false; end; +function TPascalReaderTool.ExtractUsedUnitName(UseUnitNode: TCodeTreeNode; + InFilename: PAnsiString): string; +begin + Result:=''; + if InFilename<>nil then InFilename^:=''; + if (UseUnitNode=nil) or (UseUnitNode.Desc<>ctnUseUnit) then exit; + MoveCursorToCleanPos(UseUnitNode.StartPos); + ReadNextAtom; + while CurPos.Flag=cafWord do begin + if Result<>'' then Result:=Result+'.'; + Result:=Result+GetAtom; + ReadNextAtom; + if CurPos.Flag<>cafPoint then break; + ReadNextAtom; + end; + if (InFilename<>nil) and (UpAtomIs('IN')) then begin + ReadNextAtom; + if not AtomIsStringConstant then exit; + InFilename^:=copy(Src,CurPos.StartPos+1,CurPos.EndPos-CurPos.StartPos-2); + end; +end; + function TPascalReaderTool.FindCommentInFront(const StartPos: TCodeXYPosition; const CommentText: string; InvokeBuildTree, SearchInParentNode, WithCommentBounds, CaseSensitive, IgnoreSpaces, CompareOnlyStart: boolean; diff --git a/components/codetools/stdcodetools.pas b/components/codetools/stdcodetools.pas index cf1e14d4a4..8279e5ef3f 100644 --- a/components/codetools/stdcodetools.pas +++ b/components/codetools/stdcodetools.pas @@ -402,8 +402,9 @@ var UnitPos, InPos: TAtomPosition; NewUsesTerm: string; begin Result:=false; - if (OldUnitName='') or (length(OldUnitName)>255) or (NewUnitName='') - or (length(NewUnitName)>255) then exit; + if (not IsDottedIdentifier(OldUnitName)) + or (not IsDottedIdentifier(NewUnitName)) then + exit; if not FindUnitInAllUsesSections(OldUnitName,UnitPos,InPos) then begin //debugln('TStandardCodeTool.RenameUsedUnit not found: ',OldUnitName,' '); exit; @@ -663,7 +664,8 @@ var end; end; -var LineStart, LineEnd, Indent, InsertPos, InsertToPos, InsertLen: integer; +var + LineStart, LineEnd, Indent, InsertPos, InsertToPos, InsertLen: integer; NewUsesTerm: string; InsertBehind: Boolean; InsertNode: TCodeTreeNode; @@ -686,9 +688,10 @@ var LineStart, LineEnd, Indent, InsertPos, InsertToPos, InsertLen: integer; InsertPosFound: Boolean; begin Result:=false; - if (UsesNode=nil) or (UsesNode.Desc<>ctnUsesSection) or (NewUnitName='') - or (length(NewUnitName)>255) or (UsesNode.StartPos<1) - or (UsesNode.EndPos<1) then exit; + if (UsesNode=nil) or (UsesNode.Desc<>ctnUsesSection) + or (UsesNode.StartPos<1) or (UsesNode.EndPos<1) + or (not IsDottedIdentifier(NewUnitName)) + then exit; SourceChangeCache.MainScanner:=Scanner; Options:=SourceChangeCache.BeautifyCodeOptions; @@ -745,15 +748,7 @@ begin BestDiffCnt:=High(integer); Node:=FirstNormalUsesNode; while Node<>nil do begin - MoveCursorToCleanPos(Node.StartPos); - ReadNextAtom; - AnUnitName:=GetAtom; - ReadNextAtom; - if UpAtomIs('IN') then begin - ReadNextAtom; - AnUnitInFilename:=copy(Src,CurPos.StartPos+1,CurPos.EndPos-CurPos.StartPos-2); - end else - AnUnitInFilename:=''; + AnUnitName:=ExtractUsedUnitName(Node,@AnUnitInFilename); // search unit //DebugLn(['TStandardCodeTool.AddUnitToUsesSection Unit=',AnUnitName,' in "',AnUnitInFilename,'"']); NewCode:=FindUnitSource(AnUnitName,AnUnitInFilename,false); @@ -867,10 +862,7 @@ begin InsertToPos:=Node.EndPos; if (Node=InsertNode) and (not InsertBehind) then AddUseUnit(Lines,FirstIndent,Indent,NewUsesTerm); - MoveCursorToCleanPos(Node.StartPos); - ReadNextAtom; - InsertCode:=GetAtom; - ReadNextAtom; + InsertCode:=ExtractUsedUnitName(Node); if UpAtomIs('IN') then begin ReadNextAtom; InsertCode:=InsertCode+' '+Options.BeautifyKeyWord('in')+' '+GetAtom;