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,
CodeToolsStrConsts, DirectoryCacher, CCodeParserTool, H2PasTool,
MultiKeyWordListTool, ResourceCodeTool, CodeToolsStructs, CacheCodeTools,
PPUParser, PPUGraph, CodeIndex, FindOverloads,
CodeBeautifier, PPUParser, PPUGraph, CodeIndex, FindOverloads,
// fast xml units, changes not merged in current fpc
Laz_DOM, Laz_XMLCfg, Laz_XMLRead, Laz_XMLWrite, Laz_XMLStreaming;

View File

@ -53,7 +53,7 @@ unit CodeBeautifier;
interface
uses
Classes, SysUtils;
Classes, SysUtils, CodeCache, BasicCodeTools;
type
TBeautifySplit =(
@ -75,8 +75,144 @@ type
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
{ 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.