diff --git a/components/lazdebuggers/lazdebuggerfp/test/testbase.pas b/components/lazdebuggers/lazdebuggerfp/test/testbase.pas index 9f196abaa0..10103a6968 100644 --- a/components/lazdebuggers/lazdebuggerfp/test/testbase.pas +++ b/components/lazdebuggers/lazdebuggerfp/test/testbase.pas @@ -137,7 +137,7 @@ initialization end; end; ConfDir := AppDir; - AppDir := AppendPathDelim(AppDir + 'TestApps'); + AppDir := AppendPathDelim(AppDir + 'testapps'); if DirectoryExistsUTF8(ConfDir+'logs') then TestControlSetLogPath(ConfDir+'logs'+DirectorySeparator) diff --git a/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas b/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas index 0dbe38f154..f1570ff53a 100644 --- a/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas +++ b/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas @@ -126,6 +126,16 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'TObject(Self).Int_HideTest_Class' , 0, f)^.AddFlag([ehExpectNotFound]); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 3010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f); + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f); + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmCNT2'), f); + end; n := AName + ' (Stack: MethodMainChildNested)'; @@ -153,6 +163,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Class' , 3001, f); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 3010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f); + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f); + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmCN2'), f); end; n := AName + ' (Stack: MethodMainChild)'; @@ -180,6 +199,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Class' , 3001, f); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 3010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f); + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f); + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmC2'), f); end; n := AName + ' (Stack: MethodMain)'; @@ -206,6 +234,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n, 'Int_GlobalUnit2' , 202, f); t.Add(n + ', Hide, view glob Prg', 'Int_HideTest_Class' , 3000, f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f); + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f); + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmB2'), f)^.AddFlag(ehNotImplementedData); end; n := AName + ' (Stack: MethodMainBase)'; @@ -270,6 +307,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Class' , 1001, f); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 1010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // found in other unit + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f); + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmB2'), f); // found via unit / but otherwise ehNotImplemented; end; n := AName + ' (Stack: MethodMainBaseBase)'; @@ -297,6 +343,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Class' , 2001, f); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 2010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // found in other unit + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // found in other unit + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); + + t.Add(n, 'THideMainEnum(1)', weEnum('x'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // will find main unit end; n := AName + ' (Stack: main)'; @@ -324,6 +379,15 @@ procedure TTestWatches.TestWatchesScope; t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Class' , 3000, f); t.Add(n + '; Hide, view MainChild', 'Int_HideTest_Unit' , 3010, f); + + t.Add(n, 'TMethodMainChildNestedTwiceEnum(1)', weEnum('mmCNT2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildNestedEnum(1)', weEnum('mmCN2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMethodMainChildEnum(1)', weEnum('mmC2'), f)^.AddFlag(ehExpectNotFound); + t.Add(n, 'TMainEnum(1)', weEnum('mm2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // found in unit scope + t.Add(n, 'TMainBaseEnum(1)', weEnum('mmB2'), f)^.AddFlag([ehExpectNotFound, ehNotImplemented]); // found in unit scope + t.Add(n, 'TMainGlobEnum(1)', weEnum('mmG2'), f); + + t.Add(n, 'THideMainEnum(1)', weEnum('hmG2'), f)^.AddFlag([ehNotImplementedData]); // may find the class scope end; end; @@ -403,9 +467,12 @@ begin Debugger.SetBreakPoint(Src, 'MethodMain'); Debugger.SetBreakPoint(Src, 'WatchesScopeUnit1.pas', 'MethodMainBase'); Debugger.SetBreakPoint(Src, 'WatchesScopeUnit2.pas', 'MethodMainBaseBase'); + Debugger.SetBreakPoint(Src, 'Prg'); AssertDebuggerNotInErrorState; + (* ************ Nested Functions ************* *) + dbg.Run; Debugger.WaitForFinishRun(); AssertDebuggerState(dsPause); @@ -438,28 +505,7 @@ begin t.EvaluateWatches; t.CheckResults; -(* - - - t.Add('TestEnum', weEnum('te3', 'TTestEnum')); - t.Add('TTestEnum(x)', weEnum('te2', 'TTestEnum')); - t.Add('TTestEnum(y)', weEnum('te1', 'TTestEnum')); - t.Add('TTestEnum(1)', weEnum('te1', 'TTestEnum')); - - t.Add('Integer', weEnum('XX', '')); // TODO - t.Add('TTestEnum', weEnum('TTestEnum = (te1, te2, te3)', '')); // TODO - - - - t.Add('TestEnum', weEnum('te3', 'TTestEnum')); - t.Add('TTestEnum(x)', weEnum('te2', 'TTestEnum')); - t.Add('TTestEnum(y)', weEnum('te1', 'TTestEnum'))^.AddFlag(ehExpectNotFound); - t.Add('TTestEnum(1)', weEnum('te1', 'TTestEnum')); - - t.Add('Integer', weEnum('XX', '')); // TODO - t.Add('TTestEnum', weEnum('TTestEnum = (te1, te2, te3)', '')); // TODO - -*) + (* ************ Class ************* *) dbg.Run; Debugger.WaitForFinishRun(); // MethodMainChildNestedTwice @@ -509,8 +555,10 @@ begin t.EvaluateWatches; t.CheckResults; + (* ************ Program level ************* *) + dbg.Run; - Debugger.WaitForFinishRun(); // MethodMainBaseBase + Debugger.WaitForFinishRun(); AssertDebuggerState(dsPause); t.Clear; AddWatchesForClassMethods(t, 'Scope in Prg', 6); diff --git a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopePrg.pas b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopePrg.pas index e8b4d81868..3bc40ff811 100644 --- a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopePrg.pas +++ b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopePrg.pas @@ -1,4 +1,70 @@ // TEST_USES=WatchesScopeUnit1.pas,WatchesScopeUnit2.pas + +(* Test Purpose +- Access to variables/tyes in current and all outer scopes + (each scope has a variable with a different name) +- Choose variable of correct (most inner visible) scope + (all scopes have a variable of the same name) +- Global vars according to the unit of the current selected stackframe +- Missing: Global vars of other units, according to order in "uses" +*) + +(* Calling order / Do not change / Insertation allowed + +// Nested functions + +>> function FuncFoo: integer; + >> function FuncFooNested: AnsiString; + >> function FuncFooNestedTwice: AnsiString; + * TEST_BREAKPOINT//=FuncFooNestedTwice + << + + >> function FuncFooNestedTwice2(Int_Hide_Foo: Integer): AnsiString; + * TEST_BREAKPOINT//=FuncFooNestedTwice2 + << + + * TEST_BREAKPOINT//=FuncFooNested + << function FuncFooNested: AnsiString; + +* TEST_BREAKPOINT//=FuncFoo +<< function FuncFoo: integer; + +// Class vs Base Class + Nested Function in method (nested function access to self) + TClassMainBaseBase = class() // In Unit2 // private section should not be visible + TClassMainBase = class(TClassMainBaseBase) // In Unit1 // private section should not be visible + TClassMain = class(TClassMainBase) + TClassMainChild = class(TClassMain) + + +>> procedure TClassMainBaseBase.MethodMainBaseBase; + >> procedure TClassMainBase.MethodMainBase; + >> procedure TClassMain.MethodMain; + + >>>> class TClassMainChild + >> procedure TClassMainChild.MethodMainChild; + >> procedure MethodMainChildNested; + >> procedure MethodMainChildNestedTwice; + * TEST_BREAKPOINT//=MethodMainChildNestedTwice + << + + * TEST_BREAKPOINT//=MethodMainChildNested + << procedure MethodMainChildNested; + + * TEST_BREAKPOINT//=MethodMainChild + << procedure TClassMainChild.MethodMainChild; + <<<< class TClassMainChild + + * TEST_BREAKPOINT//=MethodMain + << procedure TClassMain.MethodMain; + + * TEST_BREAKPOINT//=MethodMainBase + << procedure TClassMainBase.MethodMainBase; + +* TEST_BREAKPOINT//=MethodMainBaseBase +<< procedure TClassMainBaseBase.MethodMainBaseBase; + +*) + program WatchesPrg; {$H-} @@ -17,6 +83,9 @@ type Int_TClassMain: Integer; procedure MethodMain; override; procedure MethodMainChild; virtual; + public + type + TMainEnum = (mm1, mm2); end; { TClassMainChild } @@ -34,6 +103,9 @@ type end; +type + TMainGlobEnum = (mmG1, mmG2); + THideMainEnum = (hmG1, hmG2); var BreakDummy: Integer; Int_GlobalPrg: Integer; @@ -43,24 +115,17 @@ var TestClassMainChild: TClassMainChild; Int_Hide_Foo: Integer; + e1: TMainGlobEnum; + e2: THideMainEnum; { TClassMain } procedure TClassMain.MethodMain; - - procedure MethodMainNested; - var - IntMain: Integer; - - procedure MethodMainNestedTwice; - var - IntMain: integer; - begin - end; - begin - end; - +var + e1: TMainEnum; begin + e1 := mm1; + MethodMainChild; // call inherited class BreakDummy := 1; // TEST_BREAKPOINT=MethodMain end; @@ -70,26 +135,42 @@ begin // end; - { TClassMainChild } procedure TClassMainChild.MethodMainChild; +type + TMethodMainChildEnum = (mmC1, mmC2); + THideMainEnum = (hmC1, hmC2); var Int_MethodMainChild: Integer; procedure MethodMainChildNested; + type + TMethodMainChildNestedEnum = (mmCN1, mmCN2); + THideMainEnum = (hmCN1, hmCN2); var Int_MethodMainChildNested: Integer; + e1: TMethodMainChildNestedEnum; + e2: THideMainEnum; procedure MethodMainChildNestedTwice; + type + TMethodMainChildNestedTwiceEnum = (mmCNT1, mmCNT2); + THideMainEnum = (hmCNT1, hmCNT2); var Int_MethodMainChildNestedTwice: integer; + e1: TMethodMainChildNestedTwiceEnum; + e2: THideMainEnum; begin + e1 := mmCNT1; + e2 := hmCNT1; Int_MethodMainChildNestedTwice := 30; BreakDummy := 1; // TEST_BREAKPOINT=MethodMainChildNestedTwice end; begin + e1 := mmCN1; + e2 := hmCN1; Int_MethodMainChildNested := 40; MethodMainChildNestedTwice; BreakDummy := 1; // TEST_BREAKPOINT=MethodMainChildNested @@ -97,7 +178,11 @@ var var Int_MethodMainChild_Late: integer; + e1: TMethodMainChildEnum; + e2: THideMainEnum; begin + e1 := mmC1; + e2 := hmC1; Int_MethodMainChild := 50; Int_MethodMainChild_Late := 52; Int_TClassMainChild := 70; @@ -159,9 +244,12 @@ begin end; + begin Unit1Init; Unit2Init; + e1 := mmG1; + e2 := hmG1; Int_GlobalUnit1 := 201; Int_GlobalUnit2 := 202; Int_GlobalPrg := 101; @@ -173,6 +261,7 @@ begin FuncFoo; TestClassMainChild := TClassMainChild.Create; + // Call the deepest class first, and make the way up to each inherited class TestClassMainChild.MethodMainBaseBase(); diff --git a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopeUnit1.pas b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopeUnit1.pas index c73b3b3e3a..91a4c93862 100644 --- a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopeUnit1.pas +++ b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesScopeUnit1.pas @@ -19,6 +19,10 @@ type Int_TClassMainBase: Integer; procedure MethodMainBase; override; procedure MethodMain; virtual; + private + type + TMainBaseEnum = (mmB1, mmB2); + THideMainEnum = (hmB1, hmB2); end; procedure Unit1Init; @@ -40,7 +44,13 @@ end; { TClassMainBase } procedure TClassMainBase.MethodMainBase; +var + e1: TMainBaseEnum; + e2: THideMainEnum; begin + e1 := mmB1; + e2 := hmB1; + Int_TClassMainBase := 170; Int_TClassMainBase_Prot := 171; Int_TClassMainBase_Priv := 172; diff --git a/components/lazdebuggers/lazdebugtestbase/testcommonsources.pas b/components/lazdebuggers/lazdebugtestbase/testcommonsources.pas index 1385966e8d..3ecf657444 100644 --- a/components/lazdebuggers/lazdebugtestbase/testcommonsources.pas +++ b/components/lazdebuggers/lazdebugtestbase/testcommonsources.pas @@ -78,7 +78,7 @@ var begin i := FBreakPoints.IndexOf(AName); if (i < 0) or (FBreakPoints.Objects[i] = nil) then - raise Exception.Create('Break unknown'); + raise Exception.Create('Break unknown '+AName); Result := Integer(PtrInt(FBreakPoints.Objects[i])); TestLogger.DebugLn(['Break: ',AName, ' ',Result]); end; @@ -172,7 +172,7 @@ begin if i > 0 then begin i := i + 16; if FBreakPoints.IndexOf(copy(FData[Line], i, MaxInt)) >= 0 then - raise Exception.Create('dup brkpoint name'); + raise Exception.Create('dup brkpoint name in: '+FFileName+' '+IntToStr(Line)); FBreakPoints.AddObject(copy(FData[Line], i, MaxInt), TObject(Line + 1)); end; end; diff --git a/components/lazdebuggers/lazdebugtestbase/ttestwatchutilities.pas b/components/lazdebuggers/lazdebugtestbase/ttestwatchutilities.pas index 1b78344ecf..a687d049fe 100644 --- a/components/lazdebuggers/lazdebugtestbase/ttestwatchutilities.pas +++ b/components/lazdebuggers/lazdebugtestbase/ttestwatchutilities.pas @@ -33,7 +33,10 @@ type ehExpectNotFound, ehExpectError, // watch is invalid (less specific, than not found / maybe invalid expression ?) - ehNotImplemented // The debugger is known to fail this test // same as ehIgnAll + ehNotImplemented, // The debugger is known to fail this test // same as ehIgnAll + ehNotImplementedKind, // skSimple... + ehNotImplementedType, // typename + ehNotImplementedData ); TWatchExpErrorHandlingFlags = set of TWatchExpErrorHandlingFlag; @@ -450,6 +453,8 @@ begin if ehIgnData in ehf then AnIgnoreRsn := AnIgnoreRsn + 'Test ignored (Data)'; + if ehNotImplementedData in ehf then + AnIgnoreRsn := AnIgnoreRsn + 'Not implemented (Data)'; case TstExpected.ExpResultKind of rkMatch: Result := CheckResultMatch(Context, AnIgnoreRsn); rkInteger: Result := CheckResultNum(Context, False, AnIgnoreRsn); @@ -502,6 +507,8 @@ begin else if (ehIgnKindPtr in ehf) and (t = skPointer) then AnIgnoreRsn := 'Ignored by flag (Kind may be Ptr)'; + if ehNotImplementedKind in ehf then + AnIgnoreRsn := AnIgnoreRsn + 'Not implemented (symkind)'; n := ''; if (t = skSimple) and (Expect.ExpSymKind in AcceptSkSimple) then begin @@ -533,6 +540,8 @@ begin ehf := Expect.ExpErrorHandlingFlags[Compiler.SymbolType]; if ehIgnTypeName in ehf then AnIgnoreRsn := AnIgnoreRsn + 'Test ignored'; + if ehNotImplementedType in ehf then + AnIgnoreRsn := AnIgnoreRsn + 'Not implemented (typename)'; WtchTpName := AContext.WatchVal.TypeInfo.TypeName;