From 29dc7d7e6778deca5a6442686c8165bd6fca415f Mon Sep 17 00:00:00 2001 From: mattias Date: Sun, 25 Oct 2009 20:10:39 +0000 Subject: [PATCH] codetools: auto indent: using last indent git-svn-id: trunk@22281 - --- components/codetools/codebeautifier.pas | 152 +++++++++++++++++------- 1 file changed, 112 insertions(+), 40 deletions(-) diff --git a/components/codetools/codebeautifier.pas b/components/codetools/codebeautifier.pas index 1b6b74837f..85a0a0df0d 100644 --- a/components/codetools/codebeautifier.pas +++ b/components/codetools/codebeautifier.pas @@ -45,6 +45,11 @@ interface { $DEFINE ShowCodeBeautifier} { $DEFINE ShowCodeBeautifierParser} +{ $DEFINE ShowCodeBeautifierLearn} + +{$IFDEF ShowCodeBeautifierParser} +{$DEFINE ShowCodeBeautifierLearn} +{$ENDIF} uses Classes, SysUtils, AVL_Tree, FileProcs, KeywordFuncLists, CodeCache, @@ -133,24 +138,29 @@ type IndentValid: boolean; end; - TFABFoundIndentationPolicy = record + TFABFoundIndentationPolicy = packed record + Typ, SubTyp: TFABBlockType; Indent: integer; - Types: array[TFABBlockType] of TFABBlockTypes; - AllTypes: TFABBlockTypes; end; + PFABFoundIndentationPolicy = ^TFABFoundIndentationPolicy; { TFABPolicies } TFABPolicies = class + private + function FindIndentation(Typ, SubType: TFABBlockType; + out InsertPos: integer): boolean; public - Indentations: array of TFABFoundIndentationPolicy; + IndentationCount, IndentationCapacity: integer; + Indentations: PFABFoundIndentationPolicy; Code: TCodeBuffer; CodeChangeStep: integer; constructor Create; destructor Destroy; override; procedure Clear; - procedure AddIndent(Typ, SubType: TFABBlockType; Indent: integer); + procedure AddIndent(Typ, SubType: TFABBlockType; SrcPos, Indent: integer); function GetSmallestIndent(Typ: TFABBlockType): integer;// -1 if none found + function CodePosToStr(p: integer): string; end; type @@ -384,7 +394,7 @@ var AtomStart: integer; FirstAtomOnNewLine: Boolean; - {$IFDEF ShowCodeBeautifierParser} + {$IFDEF ShowCodeBeautifierLearn} function PosToStr(p: integer): string; var X: integer; @@ -424,9 +434,9 @@ var and (Policies<>nil) then begin if Block^.InnerIdent<0 then UpdateBlockInnerIndent; if Block^.InnerIdent>=0 then begin - Policies.AddIndent(Block^.Typ,Typ,Block^.InnerIdent); - {$IFDEF ShowCodeBeautifierParser} - DebugLn([GetIndentStr(Stack.Top*2),'nested indentation learned ',FABBlockTypeNames[Block^.Typ],' to ',FABBlockTypeNames[Typ],': ',GetAtomString(@Src[AtomStart],NestedComments),' at ',PosToStr(p),' Indent=',Block^.InnerIdent]); + Policies.AddIndent(Block^.Typ,Typ,p,Block^.InnerIdent); + {$IFDEF ShowCodeBeautifierLearn} + DebugLn([GetIndentStr(Stack.Top*2),'nested indentation learned ',FABBlockTypeNames[Block^.Typ],'/',FABBlockTypeNames[Typ],': ',GetAtomString(@Src[AtomStart],NestedComments),' at ',PosToStr(p),' Indent=',Block^.InnerIdent]); {$ENDIF} end; end; @@ -812,9 +822,9 @@ begin if FirstAtomOnNewLine then begin UpdateBlockInnerIndent; if Block^.InnerIdent>=0 then begin - Policies.AddIndent(Block^.Typ,bbtNone,Block^.InnerIdent); - {$IFDEF ShowCodeBeautifierParser} - DebugLn([GetIndentStr(Stack.Top*2),'Indentation learned for statements: ',FABBlockTypeNames[Block^.Typ],' Indent=',Block^.InnerIdent]); + Policies.AddIndent(Block^.Typ,bbtNone,p,Block^.InnerIdent); + {$IFDEF ShowCodeBeautifierLearn} + DebugLn([GetIndentStr(Stack.Top*2),'Indentation learned for statements: ',FABBlockTypeNames[Block^.Typ],' Indent=',Block^.InnerIdent,' at ',PosToStr(p)]); {$ENDIF} end; end; @@ -973,6 +983,10 @@ begin Policies:=TFABPolicies.Create; Stack:=TFABBlockStack.Create; try + {$IFDEF ShowCodeBeautifierLearn} + Policies.Code:=TCodeBuffer.Create; + Policies.Code.Source:=Source; + {$ENDIF} // parse source in front //DebugLn(['TFullyAutomaticBeautifier.GetIndent "',copy(Source,1,CleanPos-1),'"']); ParseSource(Source,1,CleanPos,NewNestedComments,Stack,Policies, @@ -995,7 +1009,7 @@ begin if Stack.Top>0 then ParentBlock:=Stack.Stack[Stack.Top-1]; - DebugLn(['TFullyAutomaticBeautifier.GetIndent parsed code in front: context=',FABBlockTypeNames[ParentBlock.Typ],'/',FABBlockTypeNames[Block.Typ],' blockindent=',GetLineIndentWithTabs(Source,Block.StartPos,DefaultTabWidth)]); + DebugLn(['TFullyAutomaticBeautifier.GetIndent parsed code in front: context=',FABBlockTypeNames[ParentBlock.Typ],'/',FABBlockTypeNames[Block.Typ],' indent=',GetLineIndentWithTabs(Source,Block.StartPos,DefaultTabWidth)]); if CheckPolicies(Policies,Result) then exit; // parse source behind @@ -1005,6 +1019,7 @@ begin finally Stack.Free; + FreeAndNil(Policies.Code); Policies.Free; end; @@ -1110,6 +1125,42 @@ end; { TFABPolicies } +function TFABPolicies.FindIndentation(Typ, SubType: TFABBlockType; + out InsertPos: integer): boolean; +// binary search +var + l: Integer; + r: Integer; + m: Integer; + Ind: PFABFoundIndentationPolicy; +begin + l:=0; + r:=IndentationCount-1; + while l<=r do begin + m:=(l+r) div 2; + Ind:=@Indentations[m]; + if (Typ>Ind^.Typ) then + r:=m-1 + else if (TypInd^.SubTyp then + r:=m-1 + else if SubTypeIndent then begin + Ind^.Indent:=Indent; + {$IFDEF ShowCodeBeautifierLearn} + DebugLn(['TFABPolicies.AddIndent Changed SubTyp ',FABBlockTypeNames[Typ],'-',FABBlockTypeNames[SubType],': indent=',Indent,' ',CodePosToStr(SrcPos)]); + {$ENDIF} end; - FillByte(Indentations[i],SizeOf(TFABFoundIndentationPolicy),0); - Indentations[i].Indent:=Indent; end; - Include(Indentations[i].Types[Typ],SubType); - Include(Indentations[i].AllTypes,Typ); - //for i:=0 to length(Indentations)-1 do DebugLn(['TFABPolicies.AddIndent i=',i,' indent=',Indentations[i].Indent]); end; function TFABPolicies.GetSmallestIndent(Typ: TFABBlockType): integer; var - l: Integer; i: Integer; begin - l:=length(Indentations); - i:=0; - while (inil then begin + Code.AbsoluteToLineCol(p,Line,Col); + Result:='('+IntToStr(Line)+','+IntToStr(Col)+')'; + end else begin + Result:='(p='+IntToStr(p)+')'; end; - Result:=-1; end; end.