From 0684e89b83b701f5da763ebfb786b4c56a66d376 Mon Sep 17 00:00:00 2001 From: mattias Date: Sat, 5 May 2007 16:28:59 +0000 Subject: [PATCH] codetools: added example how to insert a class behind a uses section git-svn-id: trunk@11085 - --- .gitattributes | 2 + components/codetools/examples/addclass.lpi | 66 ++++++++++++++++ components/codetools/examples/addclass.lpr | 89 ++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 components/codetools/examples/addclass.lpi create mode 100644 components/codetools/examples/addclass.lpr diff --git a/.gitattributes b/.gitattributes index f36f3c0244..7d195bf2de 100644 --- a/.gitattributes +++ b/.gitattributes @@ -72,6 +72,8 @@ components/codetools/customcodetool.pas svneol=native#text/pascal components/codetools/definetemplates.pas svneol=native#text/pascal components/codetools/directorycacher.pas svneol=native#text/plain components/codetools/eventcodetool.pas svneol=native#text/pascal +components/codetools/examples/addclass.lpi svneol=native#text/plain +components/codetools/examples/addclass.lpr svneol=native#text/plain components/codetools/examples/addeventmethod.lpi svneol=native#text/plain components/codetools/examples/addeventmethod.lpr svneol=native#text/plain components/codetools/examples/addmethod.lpi svneol=native#text/plain diff --git a/components/codetools/examples/addclass.lpi b/components/codetools/examples/addclass.lpi new file mode 100644 index 0000000000..1d8e6bb7a4 --- /dev/null +++ b/components/codetools/examples/addclass.lpi @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + </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="2"> + <Item1> + <PackageName Value="LCL"/> + </Item1> + <Item2> + <PackageName Value="CodeTools"/> + </Item2> + </RequiredPackages> + <Units Count="3"> + <Unit0> + <Filename Value="addclass.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="AddClass"/> + </Unit0> + <Unit1> + <Filename Value="scanexamples/simpleunit1.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="SimpleUnit1"/> + </Unit1> + <Unit2> + <Filename Value="scanexamples/addeventexample.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="AddEventExample"/> + </Unit2> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="5"/> + <SearchPaths> + <OtherUnitFiles Value="scanexamples/"/> + </SearchPaths> + <CodeGeneration> + <Generate Value="Faster"/> + </CodeGeneration> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/components/codetools/examples/addclass.lpr b/components/codetools/examples/addclass.lpr new file mode 100644 index 0000000000..a49b898306 --- /dev/null +++ b/components/codetools/examples/addclass.lpr @@ -0,0 +1,89 @@ +{ + *************************************************************************** + * * + * 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: + Demonstrating, how to add a method to a class and extending the uses section. +} +program AddClass; + +{$mode objfpc}{$H+} + +uses + Classes, SysUtils, CodeCache, CodeToolManager, SimpleUnit1, FileProcs, + BasicCodeTools, SourceChanger, CodeToolsConfig, CodeCompletionTool, CodeTree; + +var + Filename: string; + Code: TCodeBuffer; + Tool: TCodeTool; + UsesSection: TCodeTreeNode; + InsertPos: LongInt; + Indent: LongInt; + ClassSrc: String; + SourceChangeCache: TSourceChangeCache; + i: Integer; +begin + // load the file + Filename:=ExpandFileName(SetDirSeparators('scanexamples/simpleunit1.pas')); + Code:=CodeToolBoss.LoadFile(Filename,false,false); + if Code=nil then + raise Exception.Create('loading failed '+Filename); + + // Example: add a new class right after the uses section. + ClassSrc:='type'+LineEnding + +' TNewClass = class'+LineEnding + +' end;'; + // parse the unit + if not CodeToolBoss.Explore(Code,Tool,false,true) then begin + raise Exception.Create('parser error'); + end; + SourceChangeCache:=CodeToolBoss.SourceChangeCache; + // find a nice insert position (behind the uses section) + UsesSection:=Tool.FindMainUsesSection(false); + InsertPos:=UsesSection.EndPos; + // use the same indentation as the start of the uses section + Indent:=GetLineIndent(Tool.Src,UsesSection.StartPos); + ClassSrc:=SourceChangeCache.BeautifyCodeOptions.BeautifyStatement( + ClassSrc,Indent); + // init the SourceChangeCache + SourceChangeCache.MainScanner:=Tool.Scanner; + if not SourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos, + ClassSrc) + then + raise Exception.Create('unable to insert there (maybe the InsertPos does not exist?)'); + + // write the changed files + writeln('The following files will be modified:'); + for i:=0 to SourceChangeCache.BuffersToModifyCount-1 do + writeln(SourceChangeCache.BuffersToModify[i].Filename); + + // modify the files + if not SourceChangeCache.Apply then + raise Exception.Create('unable to apply changes (maybe a file is readonly?)'); + + // write the new source: + writeln('-----------------------------------'); + writeln('New source:'); + writeln(Code.Source); + writeln('-----------------------------------'); +end. +