IDE: code explorer: implemented wrong indentation

git-svn-id: trunk@19572 -
This commit is contained in:
mattias 2009-04-22 15:15:06 +00:00
parent 772489f2f8
commit 9074baf434
4 changed files with 157 additions and 12 deletions

View File

@ -73,6 +73,7 @@ type
cefcNestedProcs, // procs with a lot of nested sub procs cefcNestedProcs, // procs with a lot of nested sub procs
cefcUnnamedConsts, // numbers, strings in statements cefcUnnamedConsts, // numbers, strings in statements
cefcEmptyBlocks, // empty begin..end block (not even a comment) cefcEmptyBlocks, // empty begin..end block (not even a comment)
cefcWrongIndentation, // possible missing lines or begin blocks
cefcPublishedPropWithoutDefault, // published properties without default specifier cefcPublishedPropWithoutDefault, // published properties without default specifier
cefcUnsortedClassVisibility, // public,private,protected,published keywords are not sorted cefcUnsortedClassVisibility, // public,private,protected,published keywords are not sorted
cefcEmptyClassSections, // empty public,private,protected,published section cefcEmptyClassSections, // empty public,private,protected,published section
@ -93,6 +94,7 @@ const
cefcEmptyProcs, cefcEmptyProcs,
cefcUnnamedConsts, cefcUnnamedConsts,
cefcEmptyBlocks, cefcEmptyBlocks,
cefcWrongIndentation,
cefcPublishedPropWithoutDefault, cefcPublishedPropWithoutDefault,
cefcToDos cefcToDos
]; ];
@ -217,6 +219,7 @@ const
'NestedProcs', 'NestedProcs',
'UnnamedConsts', 'UnnamedConsts',
'EmptyBlocks', 'EmptyBlocks',
'WrongIndentation',
'PublishedPropWithoutDefault', 'PublishedPropWithoutDefault',
'UnsortedClassVisibility', 'UnsortedClassVisibility',
'EmptyClassSections', 'EmptyClassSections',
@ -289,6 +292,7 @@ begin
cefcNestedProcs: Result:=lisCEManyNestedProcedures; cefcNestedProcs: Result:=lisCEManyNestedProcedures;
cefcUnnamedConsts: Result:=lisCEUnnamedConstants; cefcUnnamedConsts: Result:=lisCEUnnamedConstants;
cefcEmptyBlocks: Result:=lisCEEmptyBlocks; cefcEmptyBlocks: Result:=lisCEEmptyBlocks;
cefcWrongIndentation: Result:=lisCEWrongIndentation;
cefcPublishedPropWithoutDefault: Result:=lisCEPublishedPropertyWithoutDefault; cefcPublishedPropWithoutDefault: Result:=lisCEPublishedPropertyWithoutDefault;
cefcUnsortedClassVisibility: Result:=lisCEUnsortedVisibility; cefcUnsortedClassVisibility: Result:=lisCEUnsortedVisibility;
cefcEmptyClassSections: Result:=lisCEEmptyClassSections; cefcEmptyClassSections: Result:=lisCEEmptyClassSections;

View File

@ -89,24 +89,30 @@ type
TCodeObsStackItem = record TCodeObsStackItem = record
StartPos: integer; StartPos: integer;
Typ: TCodeObsStackItemType; Typ: TCodeObsStackItemType;
StatementStartPos: integer;
end; end;
TCodeObsStack = ^TCodeObsStackItem; TCodeObsStack = ^TCodeObsStackItem;
{ TCodeObserverStatementState } { TCodeObserverStatementState }
TCodeObserverStatementState = class TCodeObserverStatementState = class
private
function GetStatementStartPos: integer;
procedure SetStatementStartPos(const AValue: integer);
public public
Stack: TCodeObsStack; Stack: TCodeObsStack;
StackPtr: integer; StackPtr: integer;
StackCapacity: integer; StackCapacity: integer;
IgnoreConstLevel: integer; IgnoreConstLevel: integer;
constructor Create; TopLvlStatementStartPos: integer;
destructor Destroy; override; destructor Destroy; override;
procedure Clear; procedure Clear;
procedure Reset;
procedure Push(Typ: TCodeObsStackItemType; StartPos: integer); procedure Push(Typ: TCodeObsStackItemType; StartPos: integer);
function Pop: TCodeObsStackItemType; function Pop: TCodeObsStackItemType;
procedure PopAll; procedure PopAll;
function TopType: TCodeObsStackItemType; function TopType: TCodeObsStackItemType;
property StatementStartPos: integer read GetStatementStartPos write SetStatementStartPos;
end; end;
{ TCodeExplorerView } { TCodeExplorerView }
@ -904,7 +910,12 @@ begin
ctnBeginBlock: ctnBeginBlock:
begin begin
if (CodeNode.SubDesc and ctnsNeedJITParsing)<>0 then if (CodeNode.SubDesc and ctnsNeedJITParsing)<>0 then
Tool.BuildSubTreeForBeginBlock(CodeNode); begin
try
Tool.BuildSubTreeForBeginBlock(CodeNode);
except
end;
end;
if (cefcLongProcs in ObserverCats) if (cefcLongProcs in ObserverCats)
and (CodeNode.Parent.Desc=ctnProcedure) then begin and (CodeNode.Parent.Desc=ctnProcedure) then begin
LineCnt:=LineEndCount(Tool.Src,CodeNode.StartPos,CodeNode.EndPos,i); LineCnt:=LineEndCount(Tool.Src,CodeNode.StartPos,CodeNode.EndPos,i);
@ -915,7 +926,8 @@ begin
end; end;
end; end;
if (cefcEmptyProcs in ObserverCats) if (cefcEmptyProcs in ObserverCats)
and (CodeNode.Parent.Desc=ctnProcedure) then begin and (CodeNode.Parent.Desc=ctnProcedure) then
begin
Tool.MoveCursorToCleanPos(CodeNode.StartPos); Tool.MoveCursorToCleanPos(CodeNode.StartPos);
Tool.ReadNextAtom;// read begin Tool.ReadNextAtom;// read begin
Tool.ReadNextAtom; Tool.ReadNextAtom;
@ -925,8 +937,8 @@ begin
AddCodeNode(cefcEmptyProcs,ProcNode); AddCodeNode(cefcEmptyProcs,ProcNode);
end; end;
end; end;
if (cefcUnnamedConsts in ObserverCats) if not CodeNode.HasParentOfType(ctnBeginBlock) then
and (not CodeNode.HasParentOfType(ctnBeginBlock)) then begin begin
CreateObserverNodesForStatement(Tool,CodeNode, CreateObserverNodesForStatement(Tool,CodeNode,
CodeNode.StartPos,CodeNode.EndPos,ObsState); CodeNode.StartPos,CodeNode.EndPos,ObsState);
end; end;
@ -1089,23 +1101,107 @@ var
Atom: TAtomPosition; Atom: TAtomPosition;
c1: Char; c1: Char;
Typ: TCodeObsStackItemType; Typ: TCodeObsStackItemType;
CheckWrongIndentation: boolean;
FindUnnamedConstants: boolean;
procedure CheckSubStatement(CanBeEqual: boolean);
var
StatementStartPos: Integer;
LastIndent: LongInt;
Indent: LongInt;
NeedUndo: Boolean;
LastPos: LongInt;
begin
//DebugLn(['CheckSubStatement START=',Tool.GetAtom,' ',CheckWrongIndentation,' ',ObserverState.StatementStartPos,' ',dbgstr(copy(Tool.Src,ObserverState.StatementStartPos,15))]);
if not CheckWrongIndentation then exit;
StatementStartPos:=ObserverState.StatementStartPos;
if StatementStartPos<1 then exit;
LastPos:=Tool.CurPos.StartPos;
Tool.ReadNextAtom;
if PositionsInSameLine(Tool.Src,LastPos,Tool.CurPos.StartPos) then exit;
NeedUndo:=true;
//DebugLn(['CheckSubStatement NEXT=',Tool.GetAtom,' NotSameLine=',not PositionsInSameLine(Tool.Src,StatementStartPos,Tool.CurPos.StartPos),' ',dbgstr(copy(Tool.Src,Tool.CurPos.StartPos,15))]);
if (Tool.CurPos.Flag<>cafNone)
and (not PositionsInSameLine(Tool.Src,StatementStartPos,Tool.CurPos.StartPos))
then begin
LastIndent:=GetLineIndent(Tool.Src,StatementStartPos);
Indent:=GetLineIndent(Tool.Src,Tool.CurPos.StartPos);
//DebugLn(['CheckSubStatement OTHER LINE ',Tool.GetAtom,' ',LastIndent,' ',Indent]);
if (Indent<LastIndent)
or ((Indent=LastIndent) and (not CanBeEqual) and (not Tool.UpAtomIs('BEGIN')))
then begin
//DebugLn(['CheckSubStatement START=',CheckWrongIndentation,' ',ObserverState.StatementStartPos,' ',dbgstr(copy(Tool.Src,ObserverState.StatementStartPos,15))]);
//DebugLn(['CheckSubStatement NEXT=',Tool.GetAtom,' NotSameLine=',not PositionsInSameLine(Tool.Src,StatementStartPos,Tool.CurPos.StartPos),' ',dbgstr(copy(Tool.Src,Tool.CurPos.StartPos,15))]);
//DebugLn(['CheckSubStatement OTHER LINE LastIndent=',LastIndent,' Indent=',Indent]);
// add wrong indentation
ObsTVNode:=CreateObserverNode(Tool,cefcWrongIndentation);
if ObsTVNode.Count>=CodeObserverMaxNodes then
begin
fObserverCatOverflow[cefcWrongIndentation]:=true;
end else begin
Data:=TViewNodeData.Create(CodeNode);
Data.Desc:=ctnConstant;
Data.SubDesc:=ctnsNone;
Data.StartPos:=Tool.CurPos.StartPos;
Data.EndPos:=Tool.CurPos.EndPos;
NodeText:=Tool.GetAtom;
// add some context information
Tool.UndoReadNextAtom;
NeedUndo:=false;
ProcNode:=CodeNode;
while (ProcNode<>nil) and (ProcNode.Desc<>ctnProcedure) do
ProcNode:=ProcNode.Parent;
if ProcNode<>nil then begin
OldPos:=Tool.CurPos.EndPos;
NodeText:=Format(lisCEIn, [NodeText, Tool.ExtractProcName(ProcNode, [
phpWithoutClassName])]);
Tool.MoveCursorToCleanPos(OldPos);
end;
NodeImageIndCex:=ImgIDConst;
TVNode:=CodeTreeview.Items.AddChild(ObsTVNode,NodeText);
TVNode.Data:=Data;
TVNode.Text:=NodeText;
TVNode.ImageIndex:=NodeImageIndCex;
TVNode.SelectedIndex:=NodeImageIndCex;
end;
end;
end;
if NeedUndo then
Tool.UndoReadNextAtom;
end;
begin begin
if (StartPos<1) or (StartPos>=EndPos) then exit; if (StartPos<1) or (StartPos>=EndPos) then exit;
CheckWrongIndentation:=cefcWrongIndentation in CodeExplorerOptions.ObserverCategories;
FindUnnamedConstants:=cefcUnnamedConsts in CodeExplorerOptions.ObserverCategories;
if (not FindUnnamedConstants) and (not CheckWrongIndentation) then exit;
Tool.MoveCursorToCleanPos(StartPos); Tool.MoveCursorToCleanPos(StartPos);
Last1Atom:=cafNone; Last1Atom:=cafNone;
Last2Atom:=cafNone; Last2Atom:=cafNone;
ObserverState.PopAll; ObserverState.Reset;
while Tool.CurPos.StartPos<EndPos do begin while Tool.CurPos.StartPos<EndPos do begin
CurAtom:=cafNone; CurAtom:=cafNone;
if ObserverState.StatementStartPos<1 then
begin
// start of statement
ObserverState.StatementStartPos:=Tool.CurPos.StartPos;
end;
c1:=Tool.Src[Tool.CurPos.StartPos]; c1:=Tool.Src[Tool.CurPos.StartPos];
case c1 of case c1 of
';':
begin
// end of statement
ObserverState.StatementStartPos:=0;
end;
'''','#','0'..'9','$','%': '''','#','0'..'9','$','%':
begin begin
// a constant // a constant
if (ObserverState.IgnoreConstLevel>=0) if (ObserverState.IgnoreConstLevel>=0)
and (ObserverState.IgnoreConstLevel>=ObserverState.StackPtr) and (ObserverState.IgnoreConstLevel>=ObserverState.StackPtr)
// ignore range
then begin then begin
// ignore range
end else if Tool.AtomIsEmptyStringConstant then begin end else if Tool.AtomIsEmptyStringConstant then begin
// ignore empty string constant '' // ignore empty string constant ''
end else if Tool.AtomIsCharConstant end else if Tool.AtomIsCharConstant
@ -1193,6 +1289,9 @@ begin
end; end;
end; end;
':':
ObserverState.StatementStartPos:=-1;
'_','a'..'z','A'..'Z': '_','a'..'z','A'..'Z':
begin begin
CurAtom:=cafWord; CurAtom:=cafWord;
@ -1205,6 +1304,7 @@ begin
then then
break; break;
end; end;
ObserverState.StatementStartPos:=-1;
end end
else if Tool.UpAtomIs('BEGIN') then else if Tool.UpAtomIs('BEGIN') then
ObserverState.Push(cositBegin,Tool.CurPos.StartPos) ObserverState.Push(cositBegin,Tool.CurPos.StartPos)
@ -1220,11 +1320,31 @@ begin
if Typ=cositTry then if Typ=cositTry then
break; break;
end; end;
ObserverState.StatementStartPos:=-1;
if Tool.UpAtomIs('FINALLY') then
ObserverState.Push(cositFinally,Tool.CurPos.StartPos)
else
ObserverState.Push(cositExcept,Tool.CurPos.StartPos);
end end
else if Tool.UpAtomIs('CASE') then else if Tool.UpAtomIs('CASE') then
ObserverState.Push(cositCase,Tool.CurPos.StartPos) begin
else if Tool.UpAtomIs('ELSE') and (ObserverState.TopType=cositCase) then ObserverState.Push(cositCase,Tool.CurPos.StartPos);
ObserverState.Pop; ObserverState.StatementStartPos:=Tool.CurPos.StartPos;
end
else if Tool.UpAtomIs('ELSE') then
begin
if ObserverState.TopType=cositCase then
begin
ObserverState.Pop;
ObserverState.Push(cositCaseElse,Tool.CurPos.StartPos);
end;
ObserverState.StatementStartPos:=-1;
CheckSubStatement(false);
end
else if Tool.UpAtomIs('DO') or Tool.UpAtomIs('THEN') then
CheckSubStatement(false)
else if Tool.UpAtomIs('OF') then
CheckSubStatement(true);
end; end;
end; end;
// read next atom // read next atom
@ -1893,9 +2013,21 @@ end;
{ TCodeObserverStatementState } { TCodeObserverStatementState }
constructor TCodeObserverStatementState.Create; function TCodeObserverStatementState.GetStatementStartPos: integer;
begin begin
if StackPtr=0 then
Result:=TopLvlStatementStartPos
else
Result:=Stack[StackPtr-1].StatementStartPos;
end;
procedure TCodeObserverStatementState.SetStatementStartPos(const AValue: integer
);
begin
if StackPtr=0 then
TopLvlStatementStartPos:=AValue
else
Stack[StackPtr-1].StatementStartPos:=AValue;
end; end;
destructor TCodeObserverStatementState.Destroy; destructor TCodeObserverStatementState.Destroy;
@ -1911,6 +2043,13 @@ begin
StackPtr:=0; StackPtr:=0;
end; end;
procedure TCodeObserverStatementState.Reset;
begin
PopAll;
TopLvlStatementStartPos:=0;
IgnoreConstLevel:=-1;
end;
procedure TCodeObserverStatementState.Push(Typ: TCodeObsStackItemType; procedure TCodeObserverStatementState.Push(Typ: TCodeObsStackItemType;
StartPos: integer); StartPos: integer);
begin begin
@ -1921,6 +2060,7 @@ begin
end; end;
Stack[StackPtr].Typ:=Typ; Stack[StackPtr].Typ:=Typ;
Stack[StackPtr].StartPos:=StartPos; Stack[StackPtr].StartPos:=StartPos;
Stack[StackPtr].StatementStartPos:=0;
inc(StackPtr); inc(StackPtr);
end; end;

View File

@ -67,7 +67,7 @@ const
[cefcLongProcs, cefcLongParamLists, cefcNestedProcs], [cefcLongProcs, cefcLongParamLists, cefcNestedProcs],
[cefcEmptyProcs, cefcEmptyBlocks, cefcEmptyClassSections], [cefcEmptyProcs, cefcEmptyBlocks, cefcEmptyClassSections],
[cefcUnnamedConsts, cefcUnsortedClassVisibility, cefcUnsortedClassMembers], [cefcUnnamedConsts, cefcUnsortedClassVisibility, cefcUnsortedClassMembers],
[cefcPublishedPropWithoutDefault, cefcToDos]); [cefcPublishedPropWithoutDefault, cefcWrongIndentation, cefcToDos]);
function GroupName(AGroup: TCEObserverCategoryGroup): String; function GroupName(AGroup: TCEObserverCategoryGroup): String;
begin begin

View File

@ -4170,6 +4170,7 @@ resourcestring
lisCEEmptyGroup = 'Empty constructs'; lisCEEmptyGroup = 'Empty constructs';
lisCEStyleGroup = 'Style'; lisCEStyleGroup = 'Style';
lisCEOtherGroup = 'Other'; lisCEOtherGroup = 'Other';
lisCEWrongIndentation = 'Wrong indentation';
implementation implementation