{ *************************************************************************** * * * 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 . 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 Assign to a class. } program AddMethodAssign; {$mode objfpc}{$H+} uses Classes, SysUtils, CodeCache, CodeToolManager, FileProcs, AVL_Tree, BasicCodeTools, SourceChanger, CodeTree, AssignExample1; var Filename: string; Code: TCodeBuffer; Tool: TCodeTool; AssignDeclNode: TCodeTreeNode; MemberNodeExts: TAVLTree; AssignBodyNode: TCodeTreeNode; AVLNode: TAVLTreeNode; NodeExt: TCodeTreeNodeExtension; NextAVLNode: TAVLTreeNode; ClassNode: TCodeTreeNode; AncestorClassNode: TCodeTreeNode; begin // load the file Filename:=ExpandFileName(SetDirSeparators('scanexamples/assignexample1.pas')); Code:=CodeToolBoss.LoadFile(Filename,false,false); if Code=nil then raise Exception.Create('loading failed '+Filename); // parse the unit, check if in a class with an Assign method try MemberNodeExts:=nil; if not CodeToolBoss.FindAssignMethod(Code,3,18,Tool, ClassNode,AncestorClassNode, AssignDeclNode,MemberNodeExts,AssignBodyNode) then raise Exception.Create('parser error'); debugln(['Assign declaration found: ',AssignDeclNode<>nil]); debugln(['Assign body found: ',AssignBodyNode<>nil]); // remove nodes which are written by a property if MemberNodeExts<>nil then begin AVLNode:=MemberNodeExts.FindLowest; while AVLNode<>nil do begin NextAVLNode:=MemberNodeExts.FindSuccessor(AVLNode); NodeExt:=TCodeTreeNodeExtension(AVLNode.Data); if NodeExt.Data<>nil then begin debugln(['skipping identifier ',NodeExt.Txt,' because it is written by a property']); MemberNodeExts.FreeAndDelete(AVLNode); end else begin debugln('assigning identifier ',NodeExt.Txt,' ...'); end; AVLNode:=NextAVLNode; end; end; if (MemberNodeExts=nil) or (MemberNodeExts.Count=0) then begin debugln('no assignable members found'); exit; end; // if AssignDeclNode=nil then begin if not Tool.AddAssignMethod(MemberNodeExts,'Assign','Source','TObject', true,false, CodeToolBoss.SourceChangeCache) then raise Exception.Create('AddAssignMethod failed'); end else begin debugln(['there is already an Assign method']); end; finally DisposeAVLTree(MemberNodeExts); end; // write the new source: writeln('-----------------------------------'); writeln('New source:'); writeln(Code.Source); writeln('-----------------------------------'); end.