From 0d87d46948a0e2cbd959216fbe25cdade4b9ffbf Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 27 Nov 2017 13:50:11 +0000 Subject: [PATCH] codetools: added test for FindCodeContext procs git-svn-id: trunk@56505 - --- .../codetools/tests/testfinddeclaration.pas | 51 ++++++++++++++- .../codetools/tests/testidentcompletion.pas | 64 +++++++++++++++++-- 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/components/codetools/tests/testfinddeclaration.pas b/components/codetools/tests/testfinddeclaration.pas index 496a338b73..a8a5cb6198 100644 --- a/components/codetools/tests/testfinddeclaration.pas +++ b/components/codetools/tests/testfinddeclaration.pas @@ -46,8 +46,8 @@ type public Name: string; Kind: char; - CleanPos: integer; - NameStartPos, NameEndPos: integer; + NameStartPos, NameEndPos: integer; // identifier in front of comment + CleanPos: integer; // comment end end; { TCustomTestFindDeclaration } @@ -66,6 +66,7 @@ type function AddMarker(const aName: string; Kind: char; CleanPos: integer; NameStartPos, NameEndPos: integer): TFDMarker; function IndexOfMarker(const aName: string; Kind: char): integer; + procedure ParseSimpleMarkers(aCode: TCodeBuffer); function FindMarker(const aName: string; Kind: char): TFDMarker; procedure CheckReferenceMarkers; procedure FindDeclarations(Filename: string; ExpandFile: boolean = true); @@ -253,6 +254,7 @@ begin inc(p); NameStartPos:=p; if Src[p] in ['#','@'] then begin + {#name} {@name} inc(p); if not IsIdentStartChar[Src[p]] then begin WriteSource(p); @@ -265,6 +267,9 @@ begin continue; end; + // check for specials: + {declaration:path} + {guesstype:type} if not IsIdentStartChar[Src[p]] then continue; while (p<=length(Src)) and (IsIdentChar[Src[p]]) do inc(p); Marker:=copy(Src,NameStartPos,p-NameStartPos); @@ -504,6 +509,48 @@ begin Result:=-1; end; +procedure TCustomTestFindDeclaration.ParseSimpleMarkers(aCode: TCodeBuffer); +var + CommentP, p, IdentifierStartPos, IdentifierEndPos, NameStartPos: Integer; + Src, Marker: String; +begin + FMainCode:=aCode; + DoParseModule(MainCode,FMainTool); + CommentP:=1; + Src:=MainTool.Src; + while CommentPlength(Src) then break; + p:=CommentP; + CommentP:=FindCommentEnd(Src,CommentP,MainTool.Scanner.NestedComments); + if Src[p]<>'{' then continue; + if Src[p+1] in ['$','%',' ',#0..#31] then continue; + + IdentifierStartPos:=p; + IdentifierEndPos:=p; + while (IdentifierStartPos>1) and (IsIdentChar[Src[IdentifierStartPos-1]]) do + dec(IdentifierStartPos); + + inc(p); + NameStartPos:=p; + if Src[p] in ['#','@'] then begin + {#name} {@name} + inc(p); + if not IsIdentStartChar[Src[p]] then begin + WriteSource(p); + Fail('Expected identifier at '+MainTool.CleanPosToStr(p,true)); + end; + NameStartPos:=p; + while IsIdentChar[Src[p]] do inc(p); + Marker:=copy(Src,NameStartPos,p-NameStartPos); + AddMarker(Marker,Src[NameStartPos-1],CommentP,IdentifierStartPos,IdentifierEndPos); + end else begin + WriteSource(p); + Fail('invalid marker at '+MainTool.CleanPosToStr(p)); + end; + end; +end; + function TCustomTestFindDeclaration.FindMarker(const aName: string; Kind: char ): TFDMarker; var diff --git a/components/codetools/tests/testidentcompletion.pas b/components/codetools/tests/testidentcompletion.pas index 75226bb523..2ab6257dce 100644 --- a/components/codetools/tests/testidentcompletion.pas +++ b/components/codetools/tests/testidentcompletion.pas @@ -28,11 +28,9 @@ unit TestIdentCompletion; interface uses - Classes, SysUtils, - fpcunit, testregistry, - FileProcs, LazFileUtils, LazLogger, - CodeToolManager, ExprEval, - CustomCodeTool, FindDeclarationTool, KeywordFuncLists, + Classes, SysUtils, fpcunit, testregistry, FileProcs, LazFileUtils, LazLogger, + CodeToolManager, ExprEval, CustomCodeTool, FindDeclarationTool, + KeywordFuncLists, CodeCache, IdentCompletionTool, CodeTree, TestFindDeclaration; type @@ -42,6 +40,7 @@ type TTestIdentCompletion = class(TCustomTestFindDeclaration) published procedure Test_GetValuesOfCaseVariable_Enum; + procedure Test_FindCodeContext_ProcParams; end; implementation @@ -73,6 +72,61 @@ begin end; end; +procedure TTestIdentCompletion.Test_FindCodeContext_ProcParams; + + procedure CheckCodeContext(Context: TCodeContextInfoItem; MarkerName: string); + var + Marker: TFDMarker; + begin + AssertNotNull('CheckCodeContext: missing context for #'+MarkerName,Context); + AssertEquals('CheckCodeContext: Context.Expr.Desc for #'+MarkerName, + ExpressionTypeDescNames[xtContext],ExpressionTypeDescNames[Context.Expr.Desc]); + if MainTool<>Context.Expr.Context.Tool then + Fail('CheckCodeContext: Context.Expr.Context.Tool for #'+MarkerName+' expected "'+MainTool.MainFilename+'", but found "'+Context.Expr.Context.Tool.MainFilename+'"'); + Marker:=FindMarker(MarkerName,'#'); + AssertNotNull('CheckCodeContext: missing marker #'+MarkerName,Marker); + AssertEquals('CheckCodeContext: Context.Expr.Context.Node.StartPos for #'+MarkerName, + Marker.CleanPos,Context.Expr.Context.Node.StartPos); + end; + +var + SrcMark: TFDMarker; + CursorPos: TCodeXYPosition; + CodeContexts: TCodeContextInfo; + i: Integer; +begin + StartProgram; + Add([ + '{#a}procedure DoIt(i, j: longint);', + 'begin', + 'end;', + '{#b}procedure DoIt(s, h: string);', + 'begin', + 'end;', + 'begin', + ' DoIt(3,{#c}4);', + 'end.']); + ParseSimpleMarkers(Code); + SrcMark:=FindMarker('c','#'); + AssertNotNull('missing src marker #c',SrcMark); + MainTool.CleanPosToCaret(SrcMark.CleanPos,CursorPos); + CodeContexts:=nil; + try + if not CodeToolBoss.FindCodeContext(Code,CursorPos.X,CursorPos.Y,CodeContexts) + then begin + WriteSource(CursorPos); + Fail('CodeToolBoss.FindCodeContext'); + end; + AssertEquals('CodeContexts.Count',2,CodeContexts.Count); + //for i:=0 to CodeContexts.Count-1 do + // debugln(['TTestIdentCompletion.Test_FindCodeContext_ProcParams ',i,' ',CodeContexts[i].AsDebugString(true)]); + CheckCodeContext(CodeContexts[0],'b'); + CheckCodeContext(CodeContexts[1],'a'); + finally + CodeContexts.Free; + end; +end; + initialization RegisterTests([TTestIdentCompletion]); end.