SynEdit: PascalHighlighter, fixes for proc modifiers in classes. (virtual, override, message, ...)

And treat "automated" like "public".
This commit is contained in:
Martin 2024-01-28 21:25:48 +01:00
parent 46f08c5eab
commit bf7bcceebf
2 changed files with 320 additions and 27 deletions

View File

@ -1578,11 +1578,13 @@ begin
end
else
if KeyComp('Final') and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(fRange * [rsAfterClassMembers, rsInProcHeader, rsProperty] = [rsAfterClassMembers]) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkKey
then begin
Result := tkModifier;
FRange := FRange + [rsInProcHeader];
end
else
Result := tkIdentifier;
end;
@ -1966,8 +1968,8 @@ begin
Result := tkIdentifier;
end else
if (PasCodeFoldRange.BracketNestLevel = 0) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader] = [rsWasInProcHeader]) and
(TopPascalCodeFoldBlockType in ProcModifierAllowed) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
KeyComp('Dynamic')
then begin
Result := tkModifier;
@ -1975,11 +1977,13 @@ begin
end
else
if KeyComp('Message') and
(fRange * [rsAfterClassMembers, rsInProcHeader, rsProperty] = [rsAfterClassMembers]) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkModifier
then begin
Result := tkModifier;
FRange := FRange + [rsInProcHeader];
end
else
Result := tkIdentifier;
end;
@ -2130,8 +2134,14 @@ begin
) and
( fRange *[rsAfterEqualOrColon, rsProperty] = [] ) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkModifier
then begin
Result := tkModifier;
if (fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(CompilerMode = pcmDelphi)
then
FRange := FRange + [rsInProcHeader]; // virtual reintroduce overload can be after virtual
end
else
Result := tkIdentifier;
end
@ -2141,13 +2151,19 @@ end;
function TSynPasSyn.Func84: TtkTokenKind;
begin
if KeyComp('Abstract') and (TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection])
if (PasCodeFoldRange.BracketNestLevel = 0) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
KeyComp('Abstract')
then begin
Result := tkModifier;
if (rsAfterClass in fRange) and (PasCodeFoldRange.BracketNestLevel = 0) then
// type foo = class abstract
if (rsAfterClass in fRange) and (TopPascalCodeFoldBlockType = cfbtClass) then
fRange := fRange + [rsAtClass] // forward, in case of further class modifiers end
else
if not (rsAfterClassMembers in fRange) then
// procedure foo; virtual; abstract;
if (fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) then
FRange := FRange + [rsInProcHeader]
else
Result := tkIdentifier;
end
else if ((CompilerMode = pcmMacPas) or not (rsCompilerModeSet in fRange)) and
@ -2365,9 +2381,9 @@ begin
StartPascalCodeFoldBlock(cfbtClassSection);
end
else
if (PasCodeFoldRange.BracketNestLevel = 0) and // TODO nested record
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader] = [rsWasInProcHeader]) and
(TopPascalCodeFoldBlockType in ProcModifierAllowed) and
if (PasCodeFoldRange.BracketNestLevel = 0) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
KeyComp('Override')
then begin
Result := tkModifier;
@ -2451,7 +2467,11 @@ end;
function TSynPasSyn.Func100: TtkTokenKind;
begin
if KeyComp('Automated') then
if KeyComp('Automated') and // in old times: class section
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection, cfbtRecord]) and
(fRange * [rsInProcHeader, rsAfterEqual, rsAfterEqualOrColon, rsVarTypeInSpecification] = []) and
(fRange * [rsAfterSemiColon, rsAfterClass] <> [])
then
Result := tkKey
else
if (rsInProcHeader in fRange) and KeyComp('constref') and
@ -2491,8 +2511,14 @@ begin
) and
( fRange *[rsAfterEqualOrColon, rsProperty] = [] ) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkModifier
then begin
Result := tkModifier;
if (fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(CompilerMode = pcmDelphi)
then
FRange := FRange + [rsInProcHeader]; // virtual reintroduce overload can be after virtual
end
else
Result := tkIdentifier;
end
@ -2546,8 +2572,8 @@ end;
function TSynPasSyn.Func103: TtkTokenKind;
begin
if (PasCodeFoldRange.BracketNestLevel = 0) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader] = [rsWasInProcHeader]) and
(TopPascalCodeFoldBlockType in ProcModifierAllowed) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
KeyComp('Virtual')
then begin
Result := tkModifier;
@ -2770,8 +2796,8 @@ function TSynPasSyn.Func132: TtkTokenKind;
begin
if D4syntax and
(PasCodeFoldRange.BracketNestLevel = 0) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader] = [rsWasInProcHeader]) and
(TopPascalCodeFoldBlockType in ProcModifierAllowed) and
(fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
KeyComp('Reintroduce')
then begin
Result := tkModifier;
@ -2851,8 +2877,14 @@ begin
) and
( fRange *[rsAfterEqualOrColon, rsProperty] = [] ) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkModifier
then begin
Result := tkModifier;
if (fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(CompilerMode = pcmDelphi)
then
FRange := FRange + [rsInProcHeader]; // virtual reintroduce overload can be after virtual
end
else
Result := tkIdentifier;
end
@ -2933,8 +2965,14 @@ begin
) and
( fRange *[rsAfterEqualOrColon, rsProperty] = [] ) and
(PasCodeFoldRange.BracketNestLevel = 0)
then
Result := tkModifier
then begin
Result := tkModifier;
if (fRange * [rsInProcHeader, rsProperty, rsAfterEqualOrColon, rsWasInProcHeader, rsAfterClassMembers] = [rsWasInProcHeader, rsAfterClassMembers]) and
(TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection]) and
(CompilerMode = pcmDelphi)
then
FRange := FRange + [rsInProcHeader]; // virtual reintroduce overload can be after virtual
end
else
Result := tkIdentifier;
end

View File

@ -68,6 +68,7 @@ type
procedure TestContextForClassObjRecHelp;
procedure TestContextForClassSection;
procedure TestContextForClassModifier; // Sealed abstract
procedure TestContextForClassProcModifier; // virtual override final reintroduce
procedure TestContextForClassHelper;
procedure TestContextForTypeHelper;
procedure TestContextForClassFunction; // in class,object,record
@ -1862,6 +1863,14 @@ procedure TTestHighlighterPas.TestContextForDeprecated;
'procedure '+s+'('+s+': '+s+'); '+s+';',
'var',
s+':procedure '+s+';',
'',
'type tfoo = class',
// 12
'procedure bar; message 1; '+s+';',
'procedure bar; message A; '+s+';',
'procedure bar; message ''x''; '+s+';',
'procedure bar; message #01; '+s+';',
'end;',
''
]);
CheckTokensForLine('var', 2,
@ -1880,6 +1889,19 @@ procedure TTestHighlighterPas.TestContextForDeprecated;
CheckTokensForLine('var a:procedure DEPRECATED;', 9,
[tkIdentifier, TK_Colon, tkKey, tkSpace, tkModifier {the one and only}, TK_Semi]);
CheckTokensForLine('procedure bar; message 1; DEPRECATED;', 12,
[tkKey, tkSpace, tkIdentifier+FAttrProcName, TK_Semi,
tkSpace, tkModifier, tkSpace, tkNumber, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure bar; message A; DEPRECATED;', 13,
[tkKey, tkSpace, tkIdentifier+FAttrProcName, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure bar; message ''X''; DEPRECATED;', 14,
[tkKey, tkSpace, tkIdentifier+FAttrProcName, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure bar; message ''X''; DEPRECATED;', 15,
[tkKey, tkSpace, tkIdentifier+FAttrProcName, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi, tkSpace, tkModifier, TK_Semi]);
PushBaseName('class');
SubTest2('class');
@ -2351,6 +2373,239 @@ begin
end;
end;
procedure TTestHighlighterPas.TestContextForClassProcModifier;
var
AFolds: TPascalCodeFoldBlockTypes;
i, j: Integer;
n: String;
h: TSynHighlighterAttributesModifier;
begin
ReCreateEdit;
h := FAttrProcName;
for i := 0 to 7 do begin
case i of
0: n := 'virtual';
1: n := 'dynamic';
2: n := 'override';
3: n := 'abstract';
4: n := 'final';
5: n := 'reintroduce';
6: n := 'message';
7: n := 'platform';
//8: n := 'overload'; // TODO
end;
SetLines
([ 'Unit A; interface {$mode delphi}',
'type',
'TFoo = class public',
// 3
n+':'+n+';'+n+':'+n+';', // 2 fields
'public',
// 5
n+':'+n+' deprecated;'+n+','+n+':'+n+';', // 3 fields
'public',
// 7
n+':procedure;'+n+':'+n+';', //
n+':procedure deprecated;'+n+':'+n+';', //
'',
'',
// 11
'procedure '+n+';'+n+';',
'procedure '+n+';deprecated; '+n+';', // deprecated before virtual: ONLY mode delphi
'procedure '+n+'; '+n+'; deprecated;',
'procedure '+n+';overload; '+n+';',
'procedure '+n+'; '+n+'; overload;',
'',
// 17
'procedure '+n+'; override; final;',
'procedure '+n+'; virtual; final;',
'procedure '+n+'; reintroduce; virtual;',
'procedure '+n+'; reintroduce; virtual; final;',
'procedure '+n+'; overload; reintroduce; virtual; final;',
'procedure '+n+'; reintroduce; virtual; final; overload;',
'procedure '+n+'; reintroduce; virtual; final; deprecated;',
'',
// 25
'procedure '+n+'; message A; '+n+';',
'procedure '+n+'; message 1; '+n+';',
'procedure '+n+'; message ''x''; '+n+';',
'procedure '+n+'; message #01; '+n+';',
'procedure '+n+'; message '+n+'; '+n+';',
// 30
'procedure '+n+'; '+n+'; message A;',
'procedure '+n+'; '+n+'; message 1;',
'procedure '+n+'; '+n+'; message ''x'';',
'procedure '+n+'; '+n+'; message '+n+';',
// 34
'procedure '+n+'; override; message A;final;',
'procedure '+n+'; override; message 1;final;',
'procedure '+n+'; override; message ''x'';final;',
'procedure '+n+'; override; message '+n+';final;',
// 38
'procedure '+n+'('+n+':'+n+');'+n+';',
'function '+n+':'+n+';'+n+';',
'function '+n+'('+n+':'+n+'):'+n+';'+n+';',
'end;',
''
]);
for j := 0 to $0F do begin
AFolds := [];
if (j and $08) = 0 then AFolds := [cfbtBeginEnd..cfbtNone] - [cfbtClass, cfbtClassSection, cfbtProcedure];
if (j and $01) = 0 then AFolds := AFolds + [cfbtClass];
if (j and $02) = 0 then AFolds := AFolds + [cfbtClassSection];
if (j and $04) = 0 then AFolds := AFolds + [cfbtProcedure];
EnableFolds(AFolds);
CheckTokensForLine(n+':'+n+';'+n+':'+n+';', 3,
[tkIdentifier, TK_Colon, tkIdentifier, TK_Semi,
tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine( 'public', 4, [tkKey]);
// 5
CheckTokensForLine( n+':'+n+' deprecated;'+n+','+n+':'+n+';', 5,
[tkIdentifier, TK_Colon, tkIdentifier, tkSpace, tkModifier, TK_Semi,
tkIdentifier, TK_Comma, tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine( 'public', 6, [tkKey]);
// 7
CheckTokensForLine( n+':procedure;'+n+':'+n+';', 7,
[tkIdentifier, TK_Colon, tkKey, TK_Semi,
tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
CheckTokensForLine( n+':procedure deprecated;'+n+':'+n+';', 8,
[tkIdentifier, TK_Colon, tkKey, tkSpace, tkModifier, TK_Semi,
tkIdentifier, TK_Colon, tkIdentifier, TK_Semi]);
// 11
CheckTokensForLine('procedure '+n+';'+n+';', 11,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkModifier, TK_Semi]);
// deprecated before virtual: ONLY mode delphi
CheckTokensForLine('procedure '+n+';deprecated; '+n+';', 12,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; '+n+'; deprecated;', 13,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+';overload; '+n+';', 14,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; '+n+'; overload;', 15,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
// 17
CheckTokensForLine('procedure '+n+'; override; final;', 17,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; virtual; final;', 18,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; reintroduce; virtual;', 19,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; reintroduce; virtual; final;', 20,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; overload; reintroduce; virtual; final;', 21,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; reintroduce; virtual; final; overload;', 22,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; reintroduce; virtual; final; deprecated;', 23,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, TK_Semi, tkSpace, tkModifier, TK_Semi]);
// 25
CheckTokensForLine('procedure '+n+'; message A; '+n+';',25,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi,
tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; message 1; '+n+';',26,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, tkSpace, tkNumber, TK_Semi,
tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; message ''x''; '+n+';',27,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi,
tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; message #01; '+n+';',28,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi,
tkSpace, tkModifier, TK_Semi]);
CheckTokensForLine('procedure '+n+'; message '+n+'; '+n+';',29,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi,
tkSpace, tkModifier, TK_Semi]);
// 30
CheckTokensForLine('procedure '+n+'; '+n+'; message A;',30,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; '+n+'; message 1;',31,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkNumber, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; '+n+'; message ''x'';',32,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; '+n+'; message '+n+';',33,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi
]);
// 34
CheckTokensForLine('procedure '+n+'; override; message A;final;',34,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi,
tkModifier, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; override; message 1;final;',35,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkNumber, TK_Semi,
tkModifier, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; override; message ''x'';final;',36,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkString, TK_Semi,
tkModifier, TK_Semi
]);
CheckTokensForLine('procedure '+n+'; override; message '+n+';final;',37,
[tkKey, tkSpace, tkIdentifier+h, TK_Semi,
tkSpace, tkModifier, TK_Semi,
tkSpace, tkModifier, tkSpace, tkIdentifier, TK_Semi,
tkModifier, TK_Semi
]);
// 38
CheckTokensForLine('procedure '+n+'('+n+':'+n+');'+n+';',38,
[tkKey, tkSpace, tkIdentifier+h,
TK_Bracket, tkIdentifier, TK_Comma, tkIdentifier, TK_Bracket, TK_Semi,
tkModifier, TK_Semi
]);
CheckTokensForLine('function '+n+':'+n+';'+n+';',39,
[tkKey, tkSpace, tkIdentifier+h, TK_Colon,
tkIdentifier, TK_Semi,
tkModifier, TK_Semi
]);
CheckTokensForLine('function '+n+'('+n+':'+n+'):'+n+';'+n+';',40,
[tkKey, tkSpace, tkIdentifier+h,
TK_Bracket, tkIdentifier, TK_Comma, tkIdentifier, TK_Bracket, TK_Colon,
tkIdentifier, TK_Semi,
tkModifier, TK_Semi
]);
end;
end;
end;
procedure TTestHighlighterPas.TestContextForClassHelper;
var
AFolds: TPascalCodeFoldBlockTypes;