codetools: started fully automatic indentation

git-svn-id: trunk@20124 -
This commit is contained in:
mattias 2009-05-22 14:19:54 +00:00
parent 12525ac2ec
commit b2377c0c8b
2 changed files with 138 additions and 2 deletions

View File

@ -24,7 +24,7 @@ uses
CodeCache, KeywordFuncLists, SourceLog, ExprEval, DefineTemplates, FileProcs, CodeCache, KeywordFuncLists, SourceLog, ExprEval, DefineTemplates, FileProcs,
CodeToolsStrConsts, DirectoryCacher, CCodeParserTool, H2PasTool, CodeToolsStrConsts, DirectoryCacher, CCodeParserTool, H2PasTool,
MultiKeyWordListTool, ResourceCodeTool, CodeToolsStructs, CacheCodeTools, MultiKeyWordListTool, ResourceCodeTool, CodeToolsStructs, CacheCodeTools,
PPUParser, PPUGraph, CodeIndex, FindOverloads, CodeBeautifier, PPUParser, PPUGraph, CodeIndex, FindOverloads,
// fast xml units, changes not merged in current fpc // fast xml units, changes not merged in current fpc
Laz_DOM, Laz_XMLCfg, Laz_XMLRead, Laz_XMLWrite, Laz_XMLStreaming; Laz_DOM, Laz_XMLCfg, Laz_XMLRead, Laz_XMLWrite, Laz_XMLStreaming;

View File

@ -53,7 +53,7 @@ unit CodeBeautifier;
interface interface
uses uses
Classes, SysUtils; Classes, SysUtils, CodeCache, BasicCodeTools;
type type
TBeautifySplit =( TBeautifySplit =(
@ -75,8 +75,144 @@ type
wpLowerCaseFirstLetterUp wpLowerCaseFirstLetterUp
); );
TFABContext = (
cbcNone,
cbcRepeat,
cbcUntil
);
TOnGetFABExamples = procedure(Sender: TObject; Code: TCodeBuffer;
out CodeBuffers: TFPList) of object;
TFABIndentation = record
Indent: integer;
UseTabs: boolean;
InsertEmptyLines: integer;
end;
{ TFullyAutomaticBeautifier }
TFullyAutomaticBeautifier = class
private
FOnGetExamples: TOnGetFABExamples;
FAtomStarts: PInteger;
FAtomCapacity: integer;
FAtomCount: integer;
procedure ParseSource(const Source: string; NewNestedComments: boolean);
function IndexOfAtomInFront(CleanPos: integer): integer;
public
Src: string;
SrcLen: integer;
NestedComments: boolean;
constructor Create;
destructor Destroy; override;
procedure Clear;
function GetIndent(const Source: string; CleanPos: integer;
NewNestedComments: boolean;
out Indent: TFABIndentation): boolean;
property OnGetExamples: TOnGetFABExamples read FOnGetExamples write FOnGetExamples;
end;
implementation implementation
{ TFullyAutomaticBeautifier }
procedure TFullyAutomaticBeautifier.ParseSource(const Source: string;
NewNestedComments: boolean);
var
AtomStart: integer;
MinAtomCapacity: Integer;
p: Integer;
begin
Src:=Source;
SrcLen:=length(Src);
NestedComments:=NewNestedComments;
FAtomCount:=0;
MinAtomCapacity:=SrcLen div 4;
if MinAtomCapacity<1024 then
MinAtomCapacity:=1024;
if FAtomCapacity<MinAtomCapacity then begin
FAtomCapacity:=MinAtomCapacity;
ReAllocMem(FAtomStarts,FAtomCapacity*SizeOf(integer));
end;
p:=1;
repeat
ReadRawNextPascalAtom(Src,p,AtomStart,NestedComments);
if p>SrcLen then break;
FAtomStarts[FAtomCount]:=AtomStart;
inc(FAtomCount);
if FAtomCount>FAtomCapacity then begin
FAtomCapacity:=FAtomCapacity*2;
ReAllocMem(FAtomStarts,FAtomCapacity*SizeOf(integer));
end;
until false;
end;
function TFullyAutomaticBeautifier.IndexOfAtomInFront(CleanPos: integer
): integer;
// returns index in FAtomStarts of atom in front
// if CleanPos is start of an atom the atom in front is returned
// default: -1
var
l: Integer;
r: LongInt;
m: Integer;
p: LongInt;
begin
l:=0;
r:=FAtomCount-1;
while l<=r do begin
m:=(l+r) shr 1;
p:=FAtomStarts[m];
if p>CleanPos then
r:=m-1
else if p<CleanPos then begin
if l=r then exit(m);
l:=m+1;
end else
exit(m-1);
end;
Result:=-1;
end;
constructor TFullyAutomaticBeautifier.Create;
begin
end;
destructor TFullyAutomaticBeautifier.Destroy;
begin
Clear;
ReAllocMem(FAtomStarts,0);
FAtomCapacity:=0;
inherited Destroy;
end;
procedure TFullyAutomaticBeautifier.Clear;
begin
FAtomCount:=0;
end;
function TFullyAutomaticBeautifier.GetIndent(const Source: string;
CleanPos: integer; NewNestedComments: boolean;
out Indent: TFABIndentation): boolean;
var
AtomIndex: LongInt;
begin
FillByte(Indent,SizeOf(Indent),0);
// parse source
ParseSource(Source,NewNestedComments);
// find context
AtomIndex:=IndexOfAtomInFront(CleanPos);
if AtomIndex<0 then begin
// in comments/space in front of any code
exit(false);
end;
end;
end. end.