SynEdit: PasHighLighter, fix/improve "case" and "case-labels" in record. Issue #40586 and #40655

This commit is contained in:
Martin 2024-01-18 16:57:34 +01:00
parent 1d34cc6a2b
commit 2bda56bbb6
2 changed files with 185 additions and 53 deletions

View File

@ -144,6 +144,7 @@ type
cfbtWithDo,
cfbtIfElse,
cfbtRecordCase,
cfbtRecordCaseSection,
cfbtAnonymousProcedure,
// Internal type / not configurable
cfbtCaseElse, // "else" in case can have multiply statements
@ -166,7 +167,7 @@ const
PascalWordTripletRanges = TPascalCodeFoldBlockTypes(
[cfbtBeginEnd, cfbtTopBeginEnd, cfbtProcedure, cfbtAnonymousProcedure, cfbtClass, cfbtProgram,
cfbtRecord, cfbtRecordCase,
cfbtRecord, cfbtRecordCase, // TODO recordcase needs fmMarkup
cfbtTry, cfbtExcept, cfbtRepeat, cfbtAsm, cfbtCase, cfbtCaseElse,
cfbtIfDef, cfbtRegion,
cfbtIfThen, cfbtForDo,cfbtWhileDo,cfbtWithDo
@ -230,6 +231,7 @@ const
cfbtWithDo,
cfbtIfElse,
cfbtRecordCase,
cfbtRecordCaseSection,
cfbtProcedure,
// Internal type / not configurable
cfbtCaseElse,
@ -385,7 +387,6 @@ type
FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig;
function GetPasCodeFoldRange: TSynPasSynRange;
function IsNestedRecordFoldBlock(tfb: TPascalCodeFoldBlockType): boolean;
procedure PasDocAttrChanged(Sender: TObject);
procedure SetCompilerMode(const AValue: TPascalCompilerMode);
procedure SetExtendedKeywordsMode(const AValue: Boolean);
@ -1047,19 +1048,6 @@ begin
Result := TSynPasSynRange(CodeFoldRange);
end;
function TSynPasSyn.IsNestedRecordFoldBlock(tfb: TPascalCodeFoldBlockType
): boolean;
begin
case tfb of
cfbtRecord:
Result := TopPascalCodeFoldBlockType(1) in [cfbtRecord, cfbtRecordCase];
cfbtRecordCase:
Result := TopPascalCodeFoldBlockType(2) in [cfbtRecord, cfbtRecordCase];
else
Result := False;
end;
end;
procedure TSynPasSyn.PasDocAttrChanged(Sender: TObject);
begin
FUsePasDoc := fPasDocKeyWordAttri.IsEnabled or
@ -1144,25 +1132,32 @@ begin
then begin
Result := tkKey;
fRange := fRange - [rsAsm, rsAfterClassMembers];
tfb := TopPascalCodeFoldBlockType;
if not IsNestedRecordFoldBlock(tfb) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
sl := fStringLen;
// there may be more than on block ending here
tfb := TopPascalCodeFoldBlockType;
fStringLen:=0;
while (tfb in [cfbtIfThen,cfbtForDo,cfbtWhileDo,cfbtWithDo,cfbtIfElse]) do begin // no semicolon before end
EndPascalCodeFoldBlock(True);
tfb := TopPascalCodeFoldBlockType;
end;
fStringLen := sl;
if tfb = cfbtRecordCase then begin
while tfb = cfbtRecordCaseSection do begin // missing ")"?
EndPascalCodeFoldBlock;
tfb := TopPascalCodeFoldBlockType;
end;
fStringLen := sl;
if tfb = cfbtRecordCase then begin
repeat
EndPascalCodeFoldBlock;
tfb := TopPascalCodeFoldBlockType;
until not (tfb in [cfbtRecordCase, cfbtRecordCaseSection]);
fRange := fRange - [rsAtCaseLabel];
if TopPascalCodeFoldBlockType = cfbtRecord then
EndPascalCodeFoldBlock;
// After type declaration, allow "deprecated"?
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType,
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]
then
fRange := fRange + [rsVarTypeInSpecification];
end
@ -1171,7 +1166,7 @@ begin
EndPascalCodeFoldBlock;
// After type declaration, allow "deprecated"?
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType,
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]
then
fRange := fRange + [rsVarTypeInSpecification];
end else if tfb = cfbtUnit then begin
@ -1211,23 +1206,28 @@ begin
if TopPascalCodeFoldBlockType = cfbtUnit then // "Unit".."end."
EndPascalCodeFoldBlock;
end else begin
if tfb = cfbtClassSection then
if tfb = cfbtClassSection then begin
EndPascalCodeFoldBlockLastLine;
tfb := TopPascalCodeFoldBlockType;
end;
// after class-section either a class OR a record can close with the same "end"
if TopPascalCodeFoldBlockType = cfbtClass then begin
if tfb = cfbtClass then begin
EndPascalCodeFoldBlock;
fRange := fRange - [rsInObjcProtocol];
end
else
begin
if TopPascalCodeFoldBlockType = cfbtRecordCase then
EndPascalCodeFoldBlock;
if TopPascalCodeFoldBlockType = cfbtRecord then
if tfb = cfbtRecordCase then
repeat
EndPascalCodeFoldBlock;
tfb := TopPascalCodeFoldBlockType;
until not (tfb in [cfbtRecordCase, cfbtRecordCaseSection]);
if tfb = cfbtRecord then
EndPascalCodeFoldBlock;
end;
// After type declaration, allow "deprecated"?
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType,
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]
cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]
then
fRange := fRange + [rsVarTypeInSpecification];
end;
@ -1288,8 +1288,8 @@ begin
if TopPascalCodeFoldBlockType in PascalStatementBlocks + [cfbtUnitSection] then
StartPascalCodeFoldBlock(cfbtCase, True)
else
if TopPascalCodeFoldBlockType = cfbtRecord then
StartPascalCodeFoldBlock(cfbtRecordCase, True);
if TopPascalCodeFoldBlockType in [cfbtRecord, cfbtRecordCaseSection] then
StartPascalCodeFoldBlock(cfbtRecordCase, True); // TODO: only force, if there is case-label highlight // also word-triplet?
Result := tkKey;
end
else
@ -2024,7 +2024,7 @@ begin
tbf := TopPascalCodeFoldBlockType;
if ( ( (tbf in [cfbtVarType, cfbtLocalVarType]) and
(fRange * [rsVarTypeInSpecification, rsAfterEqualOrColon] = [rsVarTypeInSpecification]) ) or
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]) and
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]) and
( (fRange * [rsAfterClassMembers, rsInProcHeader] = [rsAfterClassMembers]) or
(fRange * [rsAfterClassMembers, rsAfterEqualOrColon, rsVarTypeInSpecification] = [rsVarTypeInSpecification])
) ) or
@ -2354,7 +2354,7 @@ begin
tbf := TopPascalCodeFoldBlockType;
if ( ( (tbf in [cfbtVarType, cfbtLocalVarType]) and
(fRange * [rsVarTypeInSpecification, rsAfterEqualOrColon] = [rsVarTypeInSpecification]) ) or
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]) and
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]) and
( (fRange * [rsAfterClassMembers, rsInProcHeader] = [rsAfterClassMembers]) or
(fRange * [rsAfterClassMembers, rsAfterEqualOrColon, rsVarTypeInSpecification] = [rsVarTypeInSpecification])
) ) or
@ -2386,8 +2386,7 @@ begin
end
else begin
if not(rsAfterEqualOrColon in fRange) then begin
if not IsNestedRecordFoldBlock(TopPascalCodeFoldBlockType()) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
CloseBeginEndBlocksBeforeProc;
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
@ -2441,8 +2440,7 @@ begin
end
else begin
if not(rsAfterEqualOrColon in fRange) then begin
if not IsNestedRecordFoldBlock(TopPascalCodeFoldBlockType()) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
CloseBeginEndBlocksBeforeProc;
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
@ -2496,8 +2494,7 @@ begin
begin
if not(rsAfterEqualOrColon in fRange) then
begin
if not IsNestedRecordFoldBlock(TopPascalCodeFoldBlockType()) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
CloseBeginEndBlocksBeforeProc;
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
EndPascalCodeFoldBlockLastLine;
@ -2713,7 +2710,7 @@ begin
tbf := TopPascalCodeFoldBlockType;
if ( ( (tbf in [cfbtVarType, cfbtLocalVarType]) and
(fRange * [rsVarTypeInSpecification, rsAfterEqualOrColon] = [rsVarTypeInSpecification]) ) or
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]) and
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]) and
( (fRange * [rsAfterClassMembers, rsInProcHeader] = [rsAfterClassMembers]) or
(fRange * [rsAfterClassMembers, rsAfterEqualOrColon, rsVarTypeInSpecification] = [rsVarTypeInSpecification])
) ) or
@ -2741,8 +2738,7 @@ begin
begin
if not(rsAfterEqualOrColon in fRange) then
begin
if not IsNestedRecordFoldBlock(TopPascalCodeFoldBlockType()) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
CloseBeginEndBlocksBeforeProc;
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
@ -2794,7 +2790,7 @@ begin
if KeyComp('Unimplemented') then begin
if ( ( (tbf in [cfbtVarType, cfbtLocalVarType]) and
(fRange * [rsVarTypeInSpecification, rsAfterEqualOrColon] = [rsVarTypeInSpecification]) ) or
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase]) and
( (tbf in [cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection]) and
( (fRange * [rsAfterClassMembers, rsInProcHeader] = [rsAfterClassMembers]) or
(fRange * [rsAfterClassMembers, rsAfterEqualOrColon, rsVarTypeInSpecification] = [rsVarTypeInSpecification])
) ) or
@ -2828,8 +2824,7 @@ var
begin
if KeyComp('Constructor') then begin
if not(rsAfterEqualOrColon in fRange) then begin
if not IsNestedRecordFoldBlock(TopPascalCodeFoldBlockType()) then
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
CloseBeginEndBlocksBeforeProc;
if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
@ -3505,7 +3500,7 @@ begin
inc(Run) // ":="
else begin
fRange := fRange + [rsAfterEqualOrColon] - [rsAtCaseLabel];
if (TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType, cfbtClass, cfbtClassSection, cfbtRecord]) and
if (TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType, cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCaseSection]) and
( (rsProperty in fRange) or not(rsAfterClassMembers in fRange) )
then
fRange := fRange + [rsVarTypeInSpecification];
@ -3727,9 +3722,15 @@ begin
Inc(Run);
if Run>=fLineLen then begin
fTokenID:=tkSymbol;
PasCodeFoldRange.IncBracketNestLevel;
if TopPascalCodeFoldBlockType = cfbtRecordCase then begin
StartPascalCodeFoldBlock(cfbtRecordCaseSection, True); // TODO: only if case-label attr is set
PasCodeFoldRange.BracketNestLevel := 0
end
else
PasCodeFoldRange.IncBracketNestLevel;
exit;
end;
case fLine[Run] of
'*':
begin
@ -3755,7 +3756,13 @@ begin
else
begin
fTokenID := tkSymbol;
PasCodeFoldRange.IncBracketNestLevel;
if TopPascalCodeFoldBlockType = cfbtRecordCase then begin
StartPascalCodeFoldBlock(cfbtRecordCaseSection, True); // TODO: only if case-label attr is set
PasCodeFoldRange.BracketNestLevel := 0;
fRange := fRange - [rsVarTypeInSpecification, rsAfterEqual, rsAfterEqualOrColon] + [rsAfterSemiColon];
end
else
PasCodeFoldRange.IncBracketNestLevel;
end;
end;
end;
@ -3765,7 +3772,17 @@ begin
inc(Run);
fTokenID := tkSymbol;
fRange := fRange + [rsAfterIdentifierOrValueAdd];
PasCodeFoldRange.DecBracketNestLevel;
if (PasCodeFoldRange.BracketNestLevel = 0) and
(TopPascalCodeFoldBlockType in [cfbtRecordCase, cfbtRecordCaseSection])
then begin
// End of case-section can close ONE embedded case
if TopPascalCodeFoldBlockType = cfbtRecordCase then
EndPascalCodeFoldBlock;
if TopPascalCodeFoldBlockType = cfbtRecordCaseSection then
EndPascalCodeFoldBlock;
end
else
PasCodeFoldRange.DecBracketNestLevel;
end;
procedure TSynPasSyn.SquareOpenProc;
@ -3798,7 +3815,7 @@ begin
inc(Run);
fTokenID := tkSymbol;
fRange := fRange + [rsAfterEqualOrColon, rsAfterEqual];
if (TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType, cfbtClass, cfbtClassSection, cfbtRecord]) and
if (TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType, cfbtClass, cfbtClassSection, cfbtRecord, cfbtRecordCaseSection]) and
not(rsAfterClassMembers in fRange)
then
fRange := fRange + [rsVarTypeInSpecification];
@ -3832,9 +3849,7 @@ begin
Inc(Run);
if (tfb = cfbtCase) then
fRange := fRange + [rsAtCaseLabel];
if (tfb = cfbtRecordCase) and (PasCodeFoldRange.BracketNestLevel = 0) then
if (tfb in [cfbtCase, cfbtRecordCase]) then
fRange := fRange + [rsAtCaseLabel];
if (tfb in [cfbtClass, cfbtClassSection]) and
@ -5261,7 +5276,7 @@ begin
m := m;
cfbtFirstPrivate..high(TPascalCodeFoldBlockType):
m := [];
cfbtRecordCase:
cfbtRecordCase, cfbtRecordCaseSection:
m := [fmFold]; // no markup
else
m := [fmFold] + m;

View File

@ -70,6 +70,7 @@ type
procedure TestContextForTypeHelper;
procedure TestContextForClassFunction; // in class,object,record
procedure TestContextForRecordHelper;
procedure TestContextForRecordCase;
procedure TestContextForStatic;
procedure TestCaretAsString;
procedure TestFoldNodeInfo;
@ -1521,6 +1522,10 @@ procedure TTestHighlighterPas.TestContextForDeprecated;
PopPushBaseName('record public');
SubTest2('record public');
PopPushBaseName('record case integer of 1:(');
SubTest2('record case integer of 1:(');
PopPushBaseName('record case integer of 1:( B:record case integer of 2:(');
SubTest2('record case integer of 1:( B:record case integer of 2:(');
PopPushBaseName('var/type');
SubTest2('byte;var');
PopBaseName;
@ -2228,6 +2233,118 @@ begin
end;
end;
procedure TTestHighlighterPas.TestContextForRecordCase;
var
AFolds: TPascalCodeFoldBlockTypes;
i: Integer;
begin
for i := 0 to $1F do begin
AFolds := [];
if (i and $10) = 0 then AFolds := [cfbtBeginEnd..cfbtNone] - [cfbtVarType, cfbtRecord, cfbtRecordCase, cfbtRecordCaseSection];
if (i and $01) = 0 then AFolds := AFolds + [cfbtVarType];
if (i and $02) = 0 then AFolds := AFolds + [cfbtRecord];
if (i and $04) = 0 then AFolds := AFolds + [cfbtRecordCase];
if (i and $08) = 0 then AFolds := AFolds + [cfbtRecordCaseSection];
ReCreateEdit;
SetLines
([ 'Unit A; interface',
'type',
' TFoo = record',
' A:byte;',
' case integer of',
' 1: (',
' B: record',
' case integer of',
' 3: (',
' );',
' 4: (',
' C: packed record',
' A:byte;',
' case integer of',
' 5: (',
' B: record end;',
' );',
' 6: (',
' X:byte;',
' case integer of',
' 8: (',
' );',
' 9: (',
' );',
' );',
' end;',
' );',
' end;',
' );',
' 2: (',
' );',
' end;',
'',
'var',
''
]);
EnableFolds(AFolds);
CheckTokensForLine(' TFoo = record', 2, [tkSpace, tkIdentifier, tkSpace, TK_Equal, tkSpace, tkKey]);
CheckTokensForLine(' A:byte;', 3, [tkSpace, tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine(' case integer of', 4, [tkSpace, tkKey, tkSpace, tkIdentifier, tkSpace, tkKey]);
CheckTokensForLine(' 1: (', 5, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' B: record', 6, [tkSpace, tkIdentifier, TK_Colon, tkSpace, tkKey]);
CheckTokensForLine(' case integer of', 7, [tkSpace, tkKey, tkSpace, tkIdentifier, tkSpace, tkKey]);
CheckTokensForLine(' 3: (', 8, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' );', 9, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' 4: (', 10, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' C: packed record', 11, [tkSpace, tkIdentifier, TK_Colon, tkSpace, tkKey, tkSpace, tkKey]);
CheckTokensForLine(' A:byte;', 12, [tkSpace, tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine(' case integer of', 13, [tkSpace, tkKey, tkSpace, tkIdentifier, tkSpace, tkKey]);
CheckTokensForLine(' 5: (', 14, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' B: record end;', 15, [tkSpace, tkIdentifier, TK_Colon, tkSpace, tkKey, tkSpace, tkKey, TK_Semi]);
CheckTokensForLine(' );', 16, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' 6: (', 17, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' X:byte;', 18, [tkSpace, tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine(' case integer of',19, [tkSpace, tkKey, tkSpace, tkIdentifier, tkSpace, tkKey]);
CheckTokensForLine(' 8: (', 20, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' );', 21, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' 9: (', 22, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' );', 23, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' );', 24, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' end;', 25, [tkSpace, tkKey, TK_Semi]);
CheckTokensForLine(' );', 26, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' end;', 27, [tkSpace, tkKey, TK_Semi]);
CheckTokensForLine(' );', 28, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' 2: (', 29, [tkSpace, tkNumber+FCaseLabelAttri, TK_Colon, tkSpace, TK_Bracket]);
CheckTokensForLine(' );', 30, [tkSpace, TK_Bracket, TK_Semi]);
CheckTokensForLine(' end;', 31, [tkSpace, tkKey, TK_Semi]);
if cfbtVarType in AFolds then
AssertEquals('Fold-Len type (1) ', 31, PasHighLighter.FoldLineLength(1, 0));
if cfbtRecord in AFolds then
AssertEquals('Fold-Len record (2) ', 29, PasHighLighter.FoldLineLength(2, 0));
if cfbtRecordCase in AFolds then begin
AssertEquals('Fold-Len case (4) ', 27, PasHighLighter.FoldLineLength( 4, 0));
AssertEquals('Fold-Len case (7) ', 20, PasHighLighter.FoldLineLength( 7, 0));
AssertEquals('Fold-Len case (13) ', 12, PasHighLighter.FoldLineLength(13, 0));
AssertEquals('Fold-Len case (19) ', 5, PasHighLighter.FoldLineLength(19, 0)); // closed by ")" of surrounding case-section
end;
if cfbtRecordCaseSection in AFolds then begin
AssertEquals('Fold-Len section (5) ', 23, PasHighLighter.FoldLineLength( 5, 0));
AssertEquals('Fold-Len section ( 8) ', 1, PasHighLighter.FoldLineLength( 8, 0));
AssertEquals('Fold-Len section (10) ', 16, PasHighLighter.FoldLineLength(10, 0));
AssertEquals('Fold-Len section (14) ', 2, PasHighLighter.FoldLineLength(14, 0));
AssertEquals('Fold-Len section (17) ', 7, PasHighLighter.FoldLineLength(17, 0));
AssertEquals('Fold-Len section (20) ', 1, PasHighLighter.FoldLineLength(20, 0));
AssertEquals('Fold-Len section (22) ', 1, PasHighLighter.FoldLineLength(22, 0));
AssertEquals('Fold-Len section (29) ', 1, PasHighLighter.FoldLineLength(29, 0));
end;
end;
end;
procedure TTestHighlighterPas.TestContextForStatic;
var
AFolds: TPascalCodeFoldBlockTypes;