From 612b486281cb5f2e21dd2d28def5d44bd872a90c Mon Sep 17 00:00:00 2001 From: mattias Date: Sun, 8 Sep 2013 22:47:26 +0000 Subject: [PATCH] IDE: implement find references of used unit git-svn-id: trunk@42686 - --- components/codetools/codetoolmanager.pas | 9 ++- .../examples/findusedunitreferences.lpr | 6 +- components/codetools/finddeclarationtool.pas | 10 ++- components/ideintf/idecommands.pas | 4 +- ide/keymapping.pp | 5 ++ ide/lazarusidestrconsts.pas | 1 + ide/main.pp | 75 +++++++++++++++++++ ide/sourceeditor.pp | 17 +++-- 8 files changed, 109 insertions(+), 18 deletions(-) diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index f8b82108d7..346087b55f 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -483,7 +483,8 @@ type function FindUnitReferences(UnitCode, TargetCode: TCodeBuffer; SkipComments: boolean; var ListOfPCodeXYPosition: TFPList): boolean; function FindUsedUnitReferences(Code: TCodeBuffer; X, Y: integer; - SkipComments: boolean; var ListOfPCodeXYPosition: TFPList): boolean; + SkipComments: boolean; out UsedUnitFilename: string; + var ListOfPCodeXYPosition: TFPList): boolean; function RenameIdentifier(TreeOfPCodeXYPosition: TAVLTree; const OldIdentifier, NewIdentifier: string; DeclarationCode: TCodeBuffer = nil; DeclarationCaretXY: PPoint = nil): boolean; @@ -2552,8 +2553,8 @@ begin end; function TCodeToolManager.FindUsedUnitReferences(Code: TCodeBuffer; X, - Y: integer; SkipComments: boolean; var ListOfPCodeXYPosition: TFPList - ): boolean; + Y: integer; SkipComments: boolean; out UsedUnitFilename: string; + var ListOfPCodeXYPosition: TFPList): boolean; // finds in unit of Code all references of the unit at the uses clause at X,Y var CursorPos: TCodeXYPosition; @@ -2568,7 +2569,7 @@ begin CursorPos.Y:=Y; CursorPos.Code:=Code; try - FCurCodeTool.FindUsedUnitReferences(CursorPos,SkipComments, + FCurCodeTool.FindUsedUnitReferences(CursorPos,SkipComments,UsedUnitFilename, ListOfPCodeXYPosition); Result:=true; except diff --git a/components/codetools/examples/findusedunitreferences.lpr b/components/codetools/examples/findusedunitreferences.lpr index 2bdff8ea6c..1ec5275565 100644 --- a/components/codetools/examples/findusedunitreferences.lpr +++ b/components/codetools/examples/findusedunitreferences.lpr @@ -46,6 +46,7 @@ var ListOfPCodeXYPosition: TFPList; X: Integer; Y: Integer; + UsedUnitFilename: string; begin if (ParamCount>=1) and (Paramcount<3) then begin writeln('Usage:'); @@ -77,9 +78,10 @@ begin writeln('Filename: ',Code.Filename); ListOfPCodeXYPosition:=nil; try - if CodeToolBoss.FindUsedUnitReferences(Code,X,Y,false,ListOfPCodeXYPosition) then + if CodeToolBoss.FindUsedUnitReferences(Code,X,Y,false,UsedUnitFilename, + ListOfPCodeXYPosition) then begin - writeln('List:'); + writeln('List of ',UsedUnitFilename,':'); writeln(ListOfPCodeXYPositionToStr(ListOfPCodeXYPosition)); end else begin writeln('CodeToolBoss.FindUsedUnitReferences failed: ',CodeToolBoss.ErrorMessage); diff --git a/components/codetools/finddeclarationtool.pas b/components/codetools/finddeclarationtool.pas index fa70e83b1b..98dbc31a78 100644 --- a/components/codetools/finddeclarationtool.pas +++ b/components/codetools/finddeclarationtool.pas @@ -828,9 +828,11 @@ type function FindUnitReferences(UnitCode: TCodeBuffer; SkipComments: boolean; out ListOfPCodeXYPosition: TFPList): boolean; // searches unitname of UnitCode procedure FindUsedUnitReferences(const CursorPos: TCodeXYPosition; - SkipComments: boolean; out ListOfPCodeXYPosition: TFPList); // searches all references of unit in uses clause + SkipComments: boolean; out UsedUnitFilename: string; + out ListOfPCodeXYPosition: TFPList); // searches all references of unit in uses clause procedure FindUsedUnitReferences(TargetTool: TFindDeclarationTool; - SkipComments: boolean; out ListOfPCodeXYPosition: TFPList); // searches all references of TargetTool + SkipComments: boolean; + out ListOfPCodeXYPosition: TFPList); // searches all references of TargetTool function CleanPosIsDeclarationIdentifier(CleanPos: integer; Node: TCodeTreeNode): boolean; @@ -5124,7 +5126,7 @@ end; procedure TFindDeclarationTool.FindUsedUnitReferences( const CursorPos: TCodeXYPosition; SkipComments: boolean; out - ListOfPCodeXYPosition: TFPList); + UsedUnitFilename: string; out ListOfPCodeXYPosition: TFPList); var CleanPos: integer; Node: TCodeTreeNode; @@ -5134,6 +5136,7 @@ var TargetTool: TFindDeclarationTool; begin //debugln(['TFindDeclarationTool.FindUsedUnitReferences ',dbgs(CursorPos)]); + UsedUnitFilename:=''; ListOfPCodeXYPosition:=nil; BuildTreeAndGetCleanPos(CursorPos,CleanPos); Node:=FindDeepestNodeAtPos(CleanPos,true); @@ -5145,6 +5148,7 @@ begin AnUnitName:=ExtractUsedUnitNameAtCursor(@UnitInFilename); //debugln(['TFindDeclarationTool.FindUsedUnitReferences Used Unit=',AnUnitName,' in "',UnitInFilename,'"']); TargetCode:=FindUnitSource(AnUnitName,UnitInFilename,true,Node.StartPos); + UsedUnitFilename:=TargetCode.Filename; //debugln(['TFindDeclarationTool.FindUsedUnitReferences TargetCode=',TargetCode.Filename]); TargetTool:=FOnGetCodeToolForBuffer(Self,TargetCode,false); FindUsedUnitReferences(TargetTool,SkipComments,ListOfPCodeXYPosition); diff --git a/components/ideintf/idecommands.pas b/components/ideintf/idecommands.pas index e1c9376587..18df6d726b 100644 --- a/components/ideintf/idecommands.pas +++ b/components/ideintf/idecommands.pas @@ -139,6 +139,7 @@ const ecRemoveUnusedUnits = ecFirstLazarus + 121; ecUseUnit = ecFirstLazarus + 122; ecFindOverloads = ecFirstLazarus + 123; + ecFindUsedUnitRefs = ecFirstLazarus + 124; // file menu ecNew = ecFirstLazarus + 201; @@ -1214,7 +1215,7 @@ begin end; const - IDEEditorCommandStrs: array[0..297] of TIdentMapEntry = ( + IDEEditorCommandStrs: array[0..298] of TIdentMapEntry = ( // search (Value: ecFind; Name: 'ecFind'), (Value: ecFindAgain; Name: 'ecFindAgain'), @@ -1306,6 +1307,7 @@ const (Value: ecRemoveUnusedUnits; Name: 'ecRemoveUnusedUnits'), (Value: ecUseUnit; Name: 'ecUseUnit'), (Value: ecFindOverloads; Name: 'ecFindOverloads'), + (Value: ecFindUsedUnitRefs; Name: 'ecFindUsedUnitRefs'), // file menu (Value: ecNew; Name: 'ecNew'), diff --git a/ide/keymapping.pp b/ide/keymapping.pp index f9ac778a35..0887e14774 100644 --- a/ide/keymapping.pp +++ b/ide/keymapping.pp @@ -557,6 +557,7 @@ begin ecShowCodeContext : Result:= srkmecShowCodeContext; ecExtractProc : Result:= srkmecExtractProc; ecFindIdentifierRefs : Result:= srkmecFindIdentifierRefs; + ecFindUsedUnitRefs : Result:= lisMenuFindReferencesOfUsedUnit; ecRenameIdentifier : Result:= srkmecRenameIdentifier; ecInvertAssignment : Result:= srkmecInvertAssignment; ecSyntaxCheck : Result:= srkmecSyntaxCheck; @@ -1046,6 +1047,7 @@ begin ecShowCodeContext: SetSingle(VK_SPACE,[ssCtrl,ssShift]); ecExtractProc: SetSingle(VK_UNKNOWN,[]); ecFindIdentifierRefs: SetSingle(VK_I,[ssCtrl,ssShift]); + ecFindUsedUnitRefs: SetSingle(VK_UNKNOWN,[]); ecRenameIdentifier: SetSingle(VK_F2,[], VK_E,[ssShift,ssCtrl]); ecInvertAssignment: SetSingle(VK_UNKNOWN,[]); ecSyntaxCheck: SetSingle(VK_UNKNOWN,[]); @@ -1486,6 +1488,7 @@ begin ecShowCodeContext: SetSingle(VK_SPACE,[ssShift,ssCtrl]); ecExtractProc: SetSingle(VK_UNKNOWN,[]); ecFindIdentifierRefs: SetSingle(VK_UNKNOWN,[]); + ecFindUsedUnitRefs: SetSingle(VK_UNKNOWN,[]); ecRenameIdentifier: SetSingle(VK_E,[ssShift,ssCtrl]); ecInvertAssignment: SetSingle(VK_UNKNOWN,[]); ecSyntaxCheck: SetSingle(VK_UNKNOWN,[]); @@ -2106,6 +2109,7 @@ begin ecShowCodeContext: SetSingle(VK_SPACE,[ssCtrl,ssShift]); ecExtractProc: SetSingle(VK_UNKNOWN,[]); ecFindIdentifierRefs: SetSingle(VK_UNKNOWN,[]); + ecFindUsedUnitRefs: SetSingle(VK_UNKNOWN,[]); ecRenameIdentifier: SetSingle(VK_E,[ssMeta,ssShift]); ecInvertAssignment: SetSingle(VK_UNKNOWN,[]); ecSyntaxCheck: SetSingle(VK_UNKNOWN,[]); @@ -2689,6 +2693,7 @@ begin AddDefault(C, 'Identifier completion', dlgEdIdComlet, ecIdentCompletion); AddDefault(C, 'Rename identifier', srkmecRenameIdentifier, ecRenameIdentifier); AddDefault(C, 'Find identifier references', srkmecFindIdentifierRefs, ecFindIdentifierRefs); + AddDefault(C, 'Find references of used unit', lisMenuFindReferencesOfUsedUnit, ecFindUsedUnitRefs); AddDefault(C, 'Show code context', srkmecShowCodeContext, ecShowCodeContext); AddDefault(C, 'Extract proc', srkmecExtractProc, ecExtractProc); AddDefault(C, 'Invert assignment', srkmecInvertAssignment, ecInvertAssignment); diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index d41bf28d64..9557a804fe 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -2887,6 +2887,7 @@ resourcestring lisMenuExtractProc = 'Extract Procedure ...'; srkmecFindIdentifierRefs = 'Find Identifier References'; lisMenuFindIdentifierRefs = 'Find Identifier References ...'; + lisMenuFindReferencesOfUsedUnit = 'Find References Of Used Unit'; srkmecRenameIdentifier = 'Rename Identifier'; lisMenuRenameIdentifier = 'Rename Identifier ...'; srkmecInvertAssignment = 'Invert Assignment'; diff --git a/ide/main.pp b/ide/main.pp index 59689821e1..20fb9fd6bd 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -932,6 +932,7 @@ type procedure DoFindDeclarationAtCursor; procedure DoFindDeclarationAtCaret(const LogCaretXY: TPoint); function DoFindRenameIdentifier(Rename: boolean): TModalResult; + function DoFindUsedUnitReferences: boolean; function DoReplaceUnitUse(OldFilename, OldUnitName, NewFilename, NewUnitName: string; IgnoreErrors, Quiet, Confirm: boolean): TModalResult; @@ -3344,6 +3345,9 @@ begin ecFindIdentifierRefs: DoFindRenameIdentifier(false); + ecFindUsedUnitRefs: + DoFindUsedUnitReferences; + ecRenameIdentifier: DoFindRenameIdentifier(true); @@ -10968,6 +10972,77 @@ begin end; end; +function TMainIDE.DoFindUsedUnitReferences: boolean; +var + SrcEdit: TSourceEditor; + AnUnitInfo: TUnitInfo; + LogCaretXY: Classes.TPoint; + ListOfPCodeXYPosition: TFPList; + UsedUnitFilename: string; + SearchPageIndex: TTabSheet; + OldSearchPageIndex: TTabSheet; + i: Integer; + CodePos: PCodeXYPosition; + CurLine: String; + TrimmedLine: String; + TrimCnt: Integer; + Identifier: String; +begin + Result:=false; + if not BeginCodeTool(SrcEdit,AnUnitInfo,[]) then exit; + + ListOfPCodeXYPosition:=nil; + try + LogCaretXY:=SrcEdit.EditorComponent.LogicalCaretXY; + if not CodeToolBoss.FindUsedUnitReferences(AnUnitInfo.Source, + LogCaretXY.X,LogCaretXY.Y,true,UsedUnitFilename,ListOfPCodeXYPosition) then + begin + DoJumpToCodeToolBossError; + exit; + end; + + LazarusIDE.DoShowSearchResultsView(false); + // create a search result page + //debugln(['ShowIdentifierReferences ',DbgSName(SearchResultsView)]); + SearchPageIndex:=SearchResultsView.AddSearch( + 'Ref: '+ExtractFileName(UsedUnitFilename), + UsedUnitFilename, + '', + ExtractFilePath(UsedUnitFilename), + '*.pas;*.pp;*.p', + [fifWholeWord,fifSearchDirectories]); + if SearchPageIndex = nil then exit; + + // list results + SearchResultsView.BeginUpdate(SearchPageIndex.PageIndex); + for i:=0 to ListOfPCodeXYPosition.Count-1 do begin + CodePos:=PCodeXYPosition(ListOfPCodeXYPosition[i]); + CurLine:=TrimRight(CodePos^.Code.GetLine(CodePos^.Y-1)); + if CodePos^.X<=length(CurLine) then + Identifier:=GetIdentifier(@CurLine[CodePos^.X]) + else + Identifier:=''; + TrimmedLine:=Trim(CurLine); + TrimCnt:=length(CurLine)-length(TrimmedLine); + //debugln('DoFindUsedUnitReferences x=',dbgs(CodePos^.x),' y=',dbgs(CodePos^.y),' ',CurLine); + SearchResultsView.AddMatch(SearchPageIndex.PageIndex, + CodePos^.Code.Filename, + Point(CodePos^.X,CodePos^.Y), + Point(CodePos^.X+length(Identifier),CodePos^.Y), + TrimmedLine, + CodePos^.X-TrimCnt, length(Identifier)); + end; + + OldSearchPageIndex:=SearchPageIndex; + SearchPageIndex:=nil; + SearchResultsView.EndUpdate(OldSearchPageIndex.PageIndex); + IDEWindowCreators.ShowForm(SearchResultsView,true); + + finally + FreeListOfPCodeXYPosition(ListOfPCodeXYPosition); + end; +end; + function TMainIDE.DoShowAbstractMethods: TModalResult; begin Result:=ShowAbstractMethodsDialog; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 72cc6093a4..a9add30c3e 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -621,7 +621,6 @@ type procedure CompleteCodeMenuItemClick(Sender: TObject); procedure ExtractProcMenuItemClick(Sender: TObject); procedure InvertAssignmentMenuItemClick(Sender: TObject); - procedure FindIdentifierReferencesMenuItemClick(Sender: TObject); procedure RenameIdentifierMenuItemClick(Sender: TObject); procedure ShowAbstractMethodsMenuItemClick(Sender: TObject); procedure ShowEmptyMethodsMenuItemClick(Sender: TObject); @@ -1257,6 +1256,7 @@ var SrcEditMenuFindPrevWordOccurrence: TIDEMenuCommand; SrcEditMenuFindinFiles: TIDEMenuCommand; SrcEditMenuFindIdentifierReferences: TIDEMenuCommand; + SrcEditMenuFindUsedUnitReferences: TIDEMenuCommand; // open file SrcEditMenuOpenFileAtCursor: TIDEMenuCommand; SrcEditMenuClosePage: TIDEMenuCommand; @@ -1504,7 +1504,11 @@ begin (AParent, 'Find in files', srkmecFindInFiles, nil, @ExecuteIdeMenuClick, nil, 'menu_search_files'); SrcEditMenuFindIdentifierReferences := RegisterIDEMenuCommand - (AParent, 'FindIdentifierReferences',lisMenuFindIdentifierRefs, nil, @ExecuteIdeMenuClick); + (AParent, 'FindIdentifierReferences',lisMenuFindIdentifierRefs, nil, + @ExecuteIdeMenuClick); + SrcEditMenuFindUsedUnitReferences := RegisterIDEMenuCommand + (AParent, 'FindUsedUnitReferences', lisMenuFindReferencesOfUsedUnit, + nil, @ExecuteIdeMenuClick); {%endregion} {%endregion} @@ -6278,6 +6282,7 @@ begin CurWordAtCursor:=ASrcEdit.GetWordAtCurrentCaret; AtIdentifier:=IsValidIdent(CurWordAtCursor); SrcEditMenuFindIdentifierReferences.Enabled:=AtIdentifier; + SrcEditMenuFindUsedUnitReferences.Enabled:=AtIdentifier; SrcEditMenuRenameIdentifier.Enabled:=AtIdentifier and (not ASrcEdit.ReadOnly); SrcEditMenuShowAbstractMethods.Enabled:=not ASrcEdit.ReadOnly; SrcEditMenuShowEmptyMethods.Enabled:=not ASrcEdit.ReadOnly; @@ -7501,11 +7506,6 @@ begin ASrcEdit.InvertAssignment; end; -procedure TSourceNotebook.FindIdentifierReferencesMenuItemClick(Sender: TObject); -begin - MainIDEInterface.DoCommand(ecFindIdentifierRefs); -end; - procedure TSourceNotebook.RenameIdentifierMenuItemClick(Sender: TObject); begin MainIDEInterface.DoCommand(ecRenameIdentifier); @@ -9817,6 +9817,8 @@ begin SrcEditMenuFindNextWordOccurrence.Command := GetCommand(ecFindNextWordOccurrence); SrcEditMenuFindPrevWordOccurrence.Command := GetCommand(ecFindPrevWordOccurrence); SrcEditMenuFindInFiles.Command := GetCommand(ecFindInFiles); + SrcEditMenuFindIdentifierReferences.Command:=GetCommand(ecFindIdentifierRefs); + SrcEditMenuFindUsedUnitReferences.Command:=GetCommand(ecFindUsedUnitRefs); {%endregion} {%endregion} @@ -9879,7 +9881,6 @@ begin {%region *** Refactoring Section ***} SrcEditMenuRenameIdentifier.Command:=GetCommand(ecRenameIdentifier); - SrcEditMenuFindIdentifierReferences.Command:=GetCommand(ecFindIdentifierRefs); SrcEditMenuExtractProc.Command:=GetCommand(ecExtractProc); SrcEditMenuInvertAssignment.Command:=GetCommand(ecInvertAssignment); SrcEditMenuShowAbstractMethods.Command:=GetCommand(ecShowAbstractMethods);