From 9a76510f832a2c2e70b8d30cf911c4fd659d0b2b Mon Sep 17 00:00:00 2001 From: mattias Date: Thu, 9 Apr 2009 12:57:21 +0000 Subject: [PATCH] codetools: added example for unused units git-svn-id: trunk@19286 - --- .gitattributes | 3 + .../codetools/examples/findunusedunits.lpi | 57 +++++++++++++++ .../codetools/examples/findunusedunits.lpr | 71 +++++++++++++++++++ .../examples/scanexamples/unusedunits1.pas | 34 +++++++++ components/codetools/stdcodetools.pas | 28 ++++++-- 5 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 components/codetools/examples/findunusedunits.lpi create mode 100644 components/codetools/examples/findunusedunits.lpr create mode 100644 components/codetools/examples/scanexamples/unusedunits1.pas diff --git a/.gitattributes b/.gitattributes index 18245124e2..a6f45e35ba 100644 --- a/.gitattributes +++ b/.gitattributes @@ -104,6 +104,8 @@ components/codetools/examples/completeabstractmethods.lpi svneol=native#text/pla components/codetools/examples/completeabstractmethods.lpr svneol=native#text/plain components/codetools/examples/finddeclaration.lpi svneol=native#text/plain components/codetools/examples/finddeclaration.lpr svneol=native#text/plain +components/codetools/examples/findunusedunits.lpi svneol=native#text/plain +components/codetools/examples/findunusedunits.lpr svneol=native#text/pascal components/codetools/examples/fixdefinitionorder.lpi svneol=native#text/plain components/codetools/examples/fixdefinitionorder.lpr svneol=native#text/plain components/codetools/examples/fixfilenames.lpi svneol=native#text/plain @@ -146,6 +148,7 @@ components/codetools/examples/scanexamples/simpleunit1.pas svneol=native#text/pl components/codetools/examples/scanexamples/test.h svneol=native#text/plain components/codetools/examples/scanexamples/tgeneric2.pas svneol=native#text/plain components/codetools/examples/scanexamples/uglyifdefs.pas svneol=native#text/plain +components/codetools/examples/scanexamples/unusedunits1.pas svneol=native#text/pascal components/codetools/examples/scanexamples/wrongforwarddefinitions.pas svneol=native#text/plain components/codetools/examples/setincludepath.lpi svneol=native#text/plain components/codetools/examples/setincludepath.pas svneol=native#text/plain diff --git a/components/codetools/examples/findunusedunits.lpi b/components/codetools/examples/findunusedunits.lpi new file mode 100644 index 0000000000..7e19a7d9cb --- /dev/null +++ b/components/codetools/examples/findunusedunits.lpi @@ -0,0 +1,57 @@ + + + + + + + + + + + + + </General> + <PublishOptions> + <Version Value="2"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="CodeTools"/> + </Item1> + </RequiredPackages> + <Units Count="3"> + <Unit0> + <Filename Value="findunusedunits.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="findunusedunits"/> + </Unit0> + <Unit1> + <Filename Value="scanexamples/simpleunit1.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="SimpleUnit1"/> + </Unit1> + <Unit2> + <Filename Value="scanexamples/unusedunits1.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="UnusedUnits1"/> + </Unit2> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> + <SearchPaths> + <OtherUnitFiles Value="scanexamples/"/> + </SearchPaths> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/components/codetools/examples/findunusedunits.lpr b/components/codetools/examples/findunusedunits.lpr new file mode 100644 index 0000000000..98bea0f08d --- /dev/null +++ b/components/codetools/examples/findunusedunits.lpr @@ -0,0 +1,71 @@ +{ + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************** + + Author: Mattias Gaertner + + Abstract: + Simple demonstrating, how to setup the codetools, FPC and Lazarus Source + directory to find a declaration. +} +program FindUnusedUnits; + +{$mode objfpc}{$H+} + +uses + Classes, SysUtils, CodeCache, CodeToolManager, DefineTemplates, + CodeToolsConfig, SimpleUnit1; + +const + ConfigFilename = 'codetools.config'; +var + Code: TCodeBuffer; + Filename: String; + Units: TStringList; +begin + if (ParamCount>=1) and (Paramcount<3) then begin + writeln('Usage:'); + writeln(' ',ParamStr(0)); + writeln(' ',ParamStr(0),' <filename>'); + end; + + CodeToolBoss.SimpleInit(ConfigFilename); + Filename:=ExpandFileName('scanexamples/unusedunits1.pas'); + + if (ParamCount>=1) then begin + Filename:=ExpandFileName(ParamStr(1)); + end; + + // Step 1: load the file + Code:=CodeToolBoss.LoadFile(Filename,false,false); + if Code=nil then + raise Exception.Create('loading failed '+Filename); + + // Step 2: find declaration + writeln('Filename: ',Code.Filename); + Units:=TStringList.Create; + if CodeToolBoss.FindUnusedUnits(Code,Units) then + begin + writeln(Units.Text); + end else begin + writeln('CodeToolBoss.FindUnusedUnits failed: ',CodeToolBoss.ErrorMessage); + end; + Units.Free; +end. + diff --git a/components/codetools/examples/scanexamples/unusedunits1.pas b/components/codetools/examples/scanexamples/unusedunits1.pas new file mode 100644 index 0000000000..024cc0fca7 --- /dev/null +++ b/components/codetools/examples/scanexamples/unusedunits1.pas @@ -0,0 +1,34 @@ +unit UnusedUnits1; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +type + + { TMyClass } + + TMyClass = class(TComponent) + public + constructor Create(AOwner: TComponent); override; + end; + +implementation + +{ TMyClass } + +constructor TMyClass.Create(AOwner: TComponent); +var + i: Integer; +begin + inherited Create(AOwner); + for i:=1 to 3 do begin + WriteLn('TMyClass.Create ',i); + end; +end; + +end. + diff --git a/components/codetools/stdcodetools.pas b/components/codetools/stdcodetools.pas index 31e1219131..3ac9a9018c 100644 --- a/components/codetools/stdcodetools.pas +++ b/components/codetools/stdcodetools.pas @@ -1369,7 +1369,7 @@ var if IsIdentStartChar[Src[CurPos.StartPos]] then begin Identifier:=@Src[CurPos.StartPos]; if Identifiers.Find(Identifier)=nil then begin - DebugLn(['GatherIdentifiers ',GetIdentifier(Identifier)]); + DebugLn(['Used Identifier=',GetIdentifier(Identifier)]); Identifiers.Add(Identifier); end; end; @@ -1381,10 +1381,10 @@ var var StartPos: Integer; - procedure Gather; + procedure Gather(EndPos: integer); begin if StartPos<1 then exit; - GatherIdentifiersInRange(StartPos,CurPos.StartPos); + GatherIdentifiersInRange(StartPos,EndPos); StartPos:=-1; end; @@ -1393,19 +1393,28 @@ var begin if Identifiers<>nil then exit; Identifiers:=TAVLTree.Create(@CompareIdentifierPtrs); + DebugLn(['GatherIdentifiers ']); StartPos:=-1; Node:=Tree.Root; while Node<>nil do begin case Node.Desc of - ctnEnumIdentifier: + ctnUseUnit,ctnUsesSection, + ctnProgram,ctnUnit,ctnPackage,ctnLibrary,ctnEndPoint: begin - Gather; + // skip node + Gather(Node.StartPos); + end; + ctnEnumIdentifier, + ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition: + begin + // start reading behind identifier + Gather(Node.StartPos); MoveCursorToCleanPos(Node.StartPos); ReadNextAtom; StartPos:=CurPos.EndPos; end; - ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition: - Gather; + else + StartPos:=Node.StartPos; end; Node:=Node.Next; end; @@ -1477,6 +1486,7 @@ var HasCode: boolean; UseInterface: boolean; Flags: String; + OldPos: LongInt; begin HasCode:=false; UseInterface:=false; @@ -1501,6 +1511,7 @@ var UnitName:=copy(Src,UnitNamePos.StartPos, UnitNamePos.EndPos-UnitNamePos.StartPos); if not IsUnitAlreadyChecked(UnitName) then begin + OldPos:=CurPos.StartPos; if UnitInFilePos.StartPos>=1 then begin UnitInFilename:=copy(Src,UnitInFilePos.StartPos+1, UnitInFilePos.EndPos-UnitInFilePos.StartPos-2); @@ -1520,6 +1531,9 @@ var Flags:=Flags+',used'; DebugLn(['CheckUsesSection ',UnitName,'=',Flags]); Units.Add(UnitName+'='+Flags); + // restore cursor + MoveCursorToCleanPos(OldPos); + ReadNextAtom; end; if AtomIsChar(';') then break; if not AtomIsChar(',') then