codetools: refactored

git-svn-id: trunk@29297 -
This commit is contained in:
mattias 2011-02-01 19:32:51 +00:00
parent a43e91a50a
commit d900d21d44
3 changed files with 129 additions and 90 deletions

View File

@ -2511,75 +2511,102 @@ function FindLineEndOrCodeInFrontOfPosition(const Source: string;
2: a:=1; 2: a:=1;
1: b:=1; | 1: b:=1; |
2: // comment 2: // comment for below
3: // comment 3: // comment for below
4: a:=1; 4: a:=1;
1: | 1: |
2: /* */ 2: (* comment belongs to the following line *)
3: a:=1; 3: a:=1;
1: end;| /* 1: end; (* comment belongs to the first line
2: */ a:=1; 2: *)| a:=1;
1: b:=1; // comment | 1: b:=1; // comment |
2: a:=1; 2: a:=1;
1: b:=1; /* 1: b:=1; (*
2: comment */ | 2: comment *) |
3: a:=1; 3: a:=1;
} }
var SrcStart: integer; var SrcStart: integer;
function ReadComment(var P: integer; SubComment: boolean): boolean; function IsSpace(c: char): boolean;
begin
if SkipSemicolonComma then
Result:=c in [' ',#9,';',',']
else
Result:=c in [' ',#9];
end;
function ReadComment(var p: integer; SubComment: boolean): boolean;
// true if comment was skipped // true if comment was skipped
// false if not skipped, because comment is compiler directive // false if not skipped, because comment is compiler directive or simple bracket
var OldP: integer; var OldP: integer;
IsDirective: Boolean; IsDirective: Boolean;
begin begin
//debugln(['ReadComment ',dbgstr(copy(Source,p-5,5))+'|'+Source[P]+dbgstr(copy(Source,p+1,5))]); //debugln(['ReadComment ',dbgstr(copy(Source,p-5,5))+'|'+Source[p]+dbgstr(copy(Source,p+1,5))]);
OldP:=P; OldP:=p+1;
IsDirective:=false; repeat
case Source[P] of IsDirective:=false;
'}': case Source[p] of
begin '}':
dec(P); begin
while (P>=SrcStart) and (Source[P]<>'{') do begin dec(p);
if NestedComments and (Source[P]='}') then while (p>SrcStart) and (Source[p]<>'{') do begin
ReadComment(P,true) if NestedComments and (Source[p]='}') then
else ReadComment(p,true)
dec(P);
end;
IsDirective:=(P>=SrcStart) and (Source[P+1]='$');
dec(P);
end;
')':
begin
dec(P);
if (P>=SrcStart) and (Source[P]='*') then begin
dec(P);
while (P>SrcStart)
and ((Source[P-1]<>'(') or (Source[P]<>'*')) do begin
if NestedComments and ((Source[P]=')') and (Source[P-1]='*')) then
ReadComment(P,true)
else else
dec(P); dec(p);
end; end;
IsDirective:=(P>=SrcStart) and (Source[P+1]='$'); IsDirective:=(p>=SrcStart) and (Source[p+1]='$');
dec(P,2); dec(p);
end else begin
// normal bracket
// => position behind code
inc(p);
Result:=false;
exit;
end; end;
end; ')':
else begin
exit(true); dec(p);
end; if (p>SrcStart) and (Source[p]='*') then begin
Result:=(not IsDirective) or (not StopAtDirectives) or SubComment; dec(p);
if not Result then P:=OldP+1; while (p>SrcStart)
and ((Source[p-1]<>'(') or (Source[p]<>'*')) do begin
if NestedComments and ((Source[p]=')') and (Source[p-1]='*')) then
ReadComment(p,true)
else
dec(p);
end;
IsDirective:=(p>=SrcStart) and (Source[p+1]='$');
dec(p,2);
end else begin
// normal bracket
// => position behind code
p:=OldP;
exit(false);
end;
end;
else
exit(true);
end;
if SubComment then exit(true); // always skip nested comments
if IsDirective and StopAtDirectives then begin
// directive can not be skipped
p:=OldP;
exit(false);
end;
// it is a normal comment
// check if it belongs to the code in front
while (p>=SrcStart) and IsSpace(Source[p]) do
dec(p);
if (p<SrcStart) or (Source[p] in [#10,#13]) then begin
// empty line in front of comment => comment can be skipped
exit(true);
end;
if not (Source[p] in [')','}']) then begin
// code => comment belongs to code in front
p:=OldP;
exit(false);
end;
// read next comment
until false;
end; end;
var var
@ -2587,46 +2614,47 @@ var
LineStartPos: LongInt; LineStartPos: LongInt;
IsEmpty: Boolean; IsEmpty: Boolean;
LineEndPos: Integer; LineEndPos: Integer;
p: LongInt;
begin begin
SrcStart:=MinPosition; SrcStart:=MinPosition;
if SrcStart<1 then SrcStart:=1; if SrcStart<1 then SrcStart:=1;
if Position<=SrcStart then begin if (Position<=SrcStart) then begin
Result:=SrcStart; Result:=SrcStart;
exit; exit;
end; end;
// simple heuristic // simple heuristic
// will fail on lines: // } // will fail on lines: // }
Result:=Position-1; Result:=-1;
if Result>length(Source) then Result:=length(Source); p:=Position-1;
while (Result>=SrcStart) do begin if p>length(Source) then p:=length(Source);
case Source[Result] of while (p>=SrcStart) do begin
'}',')': case Source[p] of
if not ReadComment(Result,false) then exit;
#10,#13: #10,#13:
begin begin
// line end in code found // line end found (outside comments)
if (Result>SrcStart) and (Source[Result-1] in [#10,#13]) if (p>SrcStart) and (Source[p-1] in [#10,#13])
and (Source[Result]<>Source[Result-1]) then and (Source[p]<>Source[p-1]) then
dec(Result); dec(p);
LineEndPos:=Result; // start of line end LineEndPos:=p; // start of line end
Result:=LineEndPos;
// test if in a // comment // test if in a // comment
LineStartPos:=Result; LineStartPos:=p;
IsEmpty:=true; IsEmpty:=true;
while (LineStartPos>SrcStart) do begin while (LineStartPos>SrcStart) do begin
case Source[LineStartPos-1] of case Source[LineStartPos-1] of
#10,#13: break; #10,#13: break;
' ',#9: ; ' ',#9: ;
';',',': if not SkipSemicolonComma then IsEmpty:=false;
else IsEmpty:=false; else IsEmpty:=false;
end; end;
dec(LineStartPos); dec(LineStartPos);
end; end;
if IsEmpty then begin if IsEmpty then begin
// the line is empty => return start of line end // the line is empty => return start of line end
Result:=LineEndPos; p:=LineEndPos;
if SkipEmptyLines then begin if SkipEmptyLines then begin
// skip all empty lines // skip all empty lines
LineStartPos:=Result; LineStartPos:=p;
while (LineStartPos>SrcStart) do begin while (LineStartPos>SrcStart) do begin
case Source[LineStartPos-1] of case Source[LineStartPos-1] of
#10,#13: #10,#13:
@ -2636,7 +2664,7 @@ begin
if (LineEndPos>SrcStart) and (Source[LineEndPos-1] in [#10,#13]) if (LineEndPos>SrcStart) and (Source[LineEndPos-1] in [#10,#13])
and (Source[LineEndPos]<>Source[LineEndPos-1]) then and (Source[LineEndPos]<>Source[LineEndPos-1]) then
dec(LineEndPos); dec(LineEndPos);
Result:=LineEndPos; p:=LineEndPos;
end; end;
' ',#9: ; ' ',#9: ;
else else
@ -2646,37 +2674,41 @@ begin
dec(LineStartPos); dec(LineStartPos);
end; end;
end; end;
exit; break;
end; end;
// line is not empty
TestPos:=LineStartPos; TestPos:=LineStartPos;
while (Source[TestPos] in [' ',#9]) do inc(TestPos); while (Source[TestPos] in [' ',#9]) do inc(TestPos);
if (Source[TestPos]='/') and (Source[TestPos+1]='/') then begin if (Source[TestPos]='/') and (Source[TestPos+1]='/') then begin
// the whole line is a // comment // the whole line is a // comment
// this comment belongs to the code // this comment belongs to the code behind
// => continue on next line // => continue on next line
Result:=LineStartPos-1; p:=LineStartPos-1;
continue; continue;
end; end;
dec(Result); dec(p);
end; end;
'}',')':
if not ReadComment(p,false) then break;
' ',#9: ' ',#9:
dec(Result); dec(p);
';',',': ';',',':
begin begin
if StopAtDirectives then begin if not SkipSemicolonComma then begin
// code found // code found
inc(Result); inc(p);
exit; break;
end; end;
dec(Result); dec(p);
end; end;
else else
// code found // code found
inc(Result); inc(p);
exit; break;
end; end;
end; end;
if Result<1 then Result:=p;
if Result<SrcStart then Result:=SrcStart; if Result<SrcStart then Result:=SrcStart;
end; end;

View File

@ -267,6 +267,7 @@ type
function FindFirstPosition: integer; function FindFirstPosition: integer;
function FindLastPosition: integer; function FindLastPosition: integer;
function ContainsNode(ANode: TCodeTreeNode): boolean; function ContainsNode(ANode: TCodeTreeNode): boolean;
function FindRootNode(Desc: TCodeTreeNodeDesc): TCodeTreeNode;
procedure Clear; procedure Clear;
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -923,6 +924,13 @@ begin
Result:=ANode=Root; Result:=ANode=Root;
end; end;
function TCodeTree.FindRootNode(Desc: TCodeTreeNodeDesc): TCodeTreeNode;
begin
Result:=Root;
while (Result<>nil) and (Result.Desc<>Desc) do
Result:=Result.NextBrother;
end;
procedure TCodeTree.ConsistencyCheck; procedure TCodeTree.ConsistencyCheck;
var RealNodeCount: integer; var RealNodeCount: integer;

View File

@ -246,6 +246,7 @@ type
function FindPrevNodeOnSameLvl(StartNode: TCodeTreeNode): TCodeTreeNode; function FindPrevNodeOnSameLvl(StartNode: TCodeTreeNode): TCodeTreeNode;
// sections // sections
function FindRootNode(Desc: TCodeTreeNodeDesc): TCodeTreeNode;
function FindInterfaceNode: TCodeTreeNode; function FindInterfaceNode: TCodeTreeNode;
function FindImplementationNode: TCodeTreeNode; function FindImplementationNode: TCodeTreeNode;
function FindInitializationNode: TCodeTreeNode; function FindInitializationNode: TCodeTreeNode;
@ -4665,6 +4666,12 @@ begin
end; end;
end; end;
function TPascalParserTool.FindRootNode(Desc: TCodeTreeNodeDesc
): TCodeTreeNode;
begin
Result:=Tree.FindRootNode(Desc);
end;
function TPascalParserTool.NodeHasParentOfType(ANode: TCodeTreeNode; function TPascalParserTool.NodeHasParentOfType(ANode: TCodeTreeNode;
NodeDesc: TCodeTreeNodeDesc): boolean; NodeDesc: TCodeTreeNodeDesc): boolean;
begin begin
@ -5119,30 +5126,22 @@ end;
function TPascalParserTool.FindInterfaceNode: TCodeTreeNode; function TPascalParserTool.FindInterfaceNode: TCodeTreeNode;
begin begin
Result:=Tree.Root; Result:=FindRootNode(ctnInterface);
while (Result<>nil) and (Result.Desc<>ctnInterface) do
Result:=Result.NextBrother;
end; end;
function TPascalParserTool.FindImplementationNode: TCodeTreeNode; function TPascalParserTool.FindImplementationNode: TCodeTreeNode;
begin begin
Result:=Tree.Root; Result:=FindRootNode(ctnImplementation);
while (Result<>nil) and (Result.Desc<>ctnImplementation) do
Result:=Result.NextBrother;
end; end;
function TPascalParserTool.FindInitializationNode: TCodeTreeNode; function TPascalParserTool.FindInitializationNode: TCodeTreeNode;
begin begin
Result:=Tree.Root; Result:=FindRootNode(ctnInitialization);
while (Result<>nil) and (Result.Desc<>ctnInitialization) do
Result:=Result.NextBrother;
end; end;
function TPascalParserTool.FindFinalizationNode: TCodeTreeNode; function TPascalParserTool.FindFinalizationNode: TCodeTreeNode;
begin begin
Result:=Tree.Root; Result:=FindRootNode(ctnFinalization);
while (Result<>nil) and (Result.Desc<>ctnFinalization) do
Result:=Result.NextBrother;
end; end;
function TPascalParserTool.FindMainBeginEndNode: TCodeTreeNode; function TPascalParserTool.FindMainBeginEndNode: TCodeTreeNode;