implemented search for existing class completion comments

git-svn-id: trunk@7522 -
This commit is contained in:
mattias 2005-08-17 19:08:29 +00:00
parent cad5a68f98
commit 612ad985f5
3 changed files with 233 additions and 13 deletions

View File

@ -1707,28 +1707,34 @@ function TCodeCompletionCodeTool.InsertClassHeaderComment: boolean;
var
ClassNode: TCodeTreeNode;
ClassIdentifierNode: TCodeTreeNode;
NonSpacePos: LongInt;
Code: String;
InsertPos: LongInt;
Indent: LongInt;
StartPos, CommentStart, CommentEnd: TCodeXYPosition;
begin
Result:=true;
if not ASourceChangeCache.BeautifyCodeOptions.ClassHeaderComments then exit;
// check if there is already a comment in front of the class
// find the start of the class (the position in front of the class name)
ClassNode:=CodeCompleteClassNode;
if ClassNode=nil then exit;
ClassIdentifierNode:=ClassNode.Parent;
if ClassIdentifierNode=nil then exit;
NonSpacePos:=FindPrevNonSpace(Src,ClassIdentifierNode.StartPos-1);
if IsCommentEnd(Src,NonSpacePos) then begin
// there is already a comment in front
if not CleanPosToCaret(ClassIdentifierNode.StartPos,StartPos) then exit;
Code:=ExtractIdentifier(ClassIdentifierNode.StartPos);
// check if there is already a comment in front
if FindCommentInFront(StartPos,Code,false,true,false,false,true,
CommentStart,CommentEnd)
then
// comment already exists
exit;
end;
// insert comment in front
InsertPos:=ClassIdentifierNode.StartPos;
Indent:=GetLineIndent(Src,InsertPos);
Code:=GetIndentStr(Indent)
+'{ '+ExtractIdentifier(ClassIdentifierNode.StartPos)+' }';
Code:=GetIndentStr(Indent)+'{ '+Code+' }';
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,
InsertPos,InsertPos,Code);
end;
@ -1981,14 +1987,28 @@ var
end;
procedure InsertClassMethodsComment;
var
Code: String;
InsertXYPos, CommentStart, CommentEnd: TCodeXYPosition;
begin
// insert class comment
if ClassProcs.Count>0 then begin
ClassStartComment:=GetIndentStr(Indent)
+'{ '+ExtractClassName(FCodeCompleteClassNode,false)+' }';
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos,
ClassStartComment);
if ClassProcs.Count=0 then exit;
// find the start of the class (the position in front of the class name)
if not CleanPosToCaret(InsertPos,InsertXYPos) then exit;
Code:=ExtractClassName(CodeCompleteClassNode,false);
// check if there is already a comment in front
if FindCommentInFront(InsertXYPos,Code,false,true,false,false,true,
CommentStart,CommentEnd)
then begin
// comment already exists
exit;
end;
ClassStartComment:=GetIndentStr(Indent)
+'{ '+ExtractClassName(CodeCompleteClassNode,false)+' }';
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos,
ClassStartComment);
end;
begin

View File

@ -223,6 +223,7 @@ type
procedure MoveCursorToCleanPos(ACleanPos: PChar);
procedure MoveCursorToAtomPos(const AnAtomPos: TAtomPosition);
procedure MoveCursorToNearestAtom(ACleanPos: integer);
procedure MoveCursorToLastNodeAtom(ANode: TCodeTreeNode);
function IsPCharInSrc(ACleanPos: PChar): boolean;
procedure MoveHybridCursorToPos(DirtyPos: PChar);
function GetHybridCursorStart: integer;
@ -1776,6 +1777,19 @@ begin
MoveCursorToCleanPos(BestPos);
end;
procedure TCustomCodeTool.MoveCursorToLastNodeAtom(ANode: TCodeTreeNode);
var
BestPos: LongInt;
begin
MoveCursorToNodeStart(ANode);
BestPos:=CurPos.StartPos;
while (CurPos.EndPos<=ANode.EndPos) and (CurPos.StartPos<=SrcLen) do begin
BestPos:=CurPos.StartPos;
ReadNextAtom;
end;
MoveCursorToCleanPos(BestPos);
end;
function TCustomCodeTool.IsPCharInSrc(ACleanPos: PChar): boolean;
var NewPos: integer;
begin

View File

@ -170,7 +170,7 @@ type
function FindFormAncestor(const UpperClassName: string;
var AncestorClassName: string): boolean;
// form components
// published variables
function FindPublishedVariable(const UpperClassName, UpperVarName: string;
ExceptionOnClassNotFound: boolean): TCodeTreeNode;
function AddPublishedVariable(const UpperClassName,VarName, VarType: string;
@ -258,6 +258,12 @@ type
function GetIDEDirectives(DirectiveList: TStrings): boolean;
function SetIDEDirectives(DirectiveList: TStrings;
SourceChangeCache: TSourceChangeCache): boolean;
// comments
function FindCommentInFront(const StartPos: TCodeXYPosition;
const CommentText: string; InvokeBuildTree, SearchInParentNode,
WithCommentBounds, CaseSensitive, IgnoreSpaces: boolean;
out CommentStart, CommentEnd: TCodeXYPosition): boolean;
end;
@ -3163,6 +3169,186 @@ begin
Result:=true;
end;
function TStandardCodeTool.FindCommentInFront(const StartPos: TCodeXYPosition;
const CommentText: string;
InvokeBuildTree, SearchInParentNode, WithCommentBounds, CaseSensitive,
IgnoreSpaces: boolean;
out CommentStart, CommentEnd: TCodeXYPosition): boolean;
// searches a comment in front.
var
FoundStartPos: LongInt;
FoundEndPos: LongInt;
procedure CompareComment(StartPos, EndPos: integer);
var
Found: LongInt;
CompareStartPos: LongInt;
CompareEndPos: LongInt;
begin
//debugln('CompareComment "',copy(Src,StartPos,EndPos-StartPos),'"');
CompareStartPos:=StartPos;
CompareEndPos:=EndPos;
if not WithCommentBounds then begin
// chomp comment boundaries
case Src[CompareStartPos] of
'/','(': inc(CompareStartPos,2);
'{': inc(CompareStartPos,1);
end;
case Src[CompareEndPos-1] of
'}': dec(CompareEndPos);
')': dec(CompareEndPos,2);
#10,#13:
begin
dec(CompareEndPos);
if (Src[CompareEndPos-1] in [#10,#13])
and (Src[CompareEndPos-1]<>Src[CompareEndPos]) then
dec(CompareEndPos);
end;
end;
end;
if IgnoreSpaces then begin
//debugln('Compare: "',copy(Src,CompareStartPos,CompareEndPos-CompareStartPos),'"',
// ' "',CommentText,'"');
Found:=CompareTextIgnoringSpace(
@Src[CompareStartPos],CompareEndPos-CompareStartPos,
@CommentText[1],length(CommentText),
CaseSensitive);
end else begin
Found:=CompareText(@Src[CompareStartPos],CompareEndPos-CompareStartPos,
@CommentText[1],length(CommentText),
CaseSensitive);
end;
if Found=0 then begin
FoundStartPos:=StartPos;
FoundEndPos:=EndPos;
end;
end;
var
CleanCursorPos: integer;
ANode: TCodeTreeNode;
PrevNode: TCodeTreeNode;
p: LongInt;
CommentLvl: Integer;
CommentStartPos: LongInt;
begin
Result:=false;
if CommentText='' then exit;
{debugln('TStandardCodeTool.FindCommentInFront A CommentText="',CommentText,'" ',
' InvokeBuildTree='+dbgs(InvokeBuildTree),
' SearchInParentNode='+dbgs(SearchInParentNode),
' WithCommentBounds='+dbgs(WithCommentBounds),
' CaseSensitive='+dbgs(CaseSensitive),
' IgnoreSpaces='+dbgs(IgnoreSpaces));}
// parse source and find clean positions
if InvokeBuildTree then
BuildTreeAndGetCleanPos(trAll,StartPos,CleanCursorPos,[])
else
if CaretToCleanPos(StartPos,CleanCursorPos)<>0 then
exit;
// find node
ANode:=FindDeepestNodeAtPos(CleanCursorPos,true);
if (ANode=nil) then exit;
if SearchInParentNode and (ANode.Parent<>nil) then
ANode:=ANode.Parent;
{ find end of last atom in front of node
for example:
uses classes;
// Comment
type
If ANode is the 'type' block, the position after the semicolon is searched
}
PrevNode:=ANode.Prior;
if PrevNode<>nil then begin
MoveCursorToLastNodeAtom(PrevNode);
end else begin
MoveCursorToCleanPos(ANode.StartPos);
end;
//debugln('TStandardCodeTool.FindCommentInFront B Area="',copy(Src,CurPos.StartPos,CleanCursorPos-CurPos.StartPos),'"');
FoundStartPos:=-1;
repeat
p:=CurPos.EndPos;
//debugln('TStandardCodeTool.FindCommentInFront Atom=',GetAtom);
// read space and comment till next atom
CommentLvl:=0;
while true do begin
case Src[p] of
#0:
if p>SrcLen then
break
else
inc(p);
#1..#32:
inc(p);
'{': // pascal comment
begin
CommentLvl:=1;
CommentStartPos:=p;
inc(p);
while true do begin
case Src[p] of
#0: if p>SrcLen then break;
'{': if Scanner.NestedComments then inc(CommentLvl);
'}':
begin
dec(CommentLvl);
if CommentLvl=0 then break;
end;
end;
inc(p);
end;
inc(p);
CompareComment(CommentStartPos,p);
end;
'/': // Delphi comment
if (Src[p+1]<>'/') then begin
break;
end else begin
CommentStartPos:=p;
inc(p,2);
while (not (Src[p] in [#10,#13,#0])) do
inc(p);
inc(p);
if (p<=SrcLen) and (Src[p] in [#10,#13])
and (Src[p-1]<>Src[p]) then
inc(p);
CompareComment(CommentStartPos,p);
end;
'(': // old turbo pascal comment
if (Src[p+1]<>'*') then begin
break;
end else begin
CommentStartPos:=p;
inc(p,3);
while (p<=SrcLen)
and ((Src[p-1]<>'*') or (Src[p]<>')')) do
inc(p);
inc(p);
CompareComment(CommentStartPos,p);
end;
else
break;
end;
end;
ReadNextAtom;
until (CurPos.EndPos>=CleanCursorPos) or (CurPos.EndPos>=SrcLen);
Result:=(FoundStartPos>=1)
and CleanPosToCaret(FoundStartPos,CommentStart)
and CleanPosToCaret(FoundEndPos,CommentEnd);
end;
function TStandardCodeTool.GatherResourceStringsWithValue(
const CursorPos: TCodeXYPosition; const StringValue: string;
PositionList: TCodeXYPositions): boolean;