Merged revision(s) 55339 #069ea79aae, 55376-55377 #698d8d24af-#698d8d24af from trunk:

SynEdit: Pas HL, handle generics foo<T: class> does not fold / patch by Pascal
........
SynEdit: Pas-HL, test for ^ in PMyByte = type ^Byte;
........
SynEdit: fix pas HL, class function. more tests / some tests by Pascal R
........

git-svn-id: branches/fixes_1_8@55402 -
This commit is contained in:
maxim 2017-06-26 23:07:32 +00:00
parent 84fcaeb829
commit cd6e93e397
2 changed files with 179 additions and 30 deletions

View File

@ -917,6 +917,7 @@ end;
function TSynPasSyn.Func15: TtkTokenKind;
begin
if KeyComp('If') then begin
//TODO: case a of 1: while x do if e then ...
StartPascalCodeFoldBlock(cfbtIfThen, TopPascalCodeFoldBlockType in [cfbtCase, cfbtIfThen]);
Result := tkKey
end
@ -1289,9 +1290,9 @@ function TSynPasSyn.Func54: TtkTokenKind;
begin
if KeyComp('Class') then begin
Result := tkKey;
if (rsAfterEqualOrColon in fRange) and (PasCodeFoldRange.BracketNestLevel = 0)
if (rsAfterEqual in fRange) and (PasCodeFoldRange.BracketNestLevel = 0)
then begin
fRange := fRange + [rsAtClass] - [rsVarTypeInSpecification];
fRange := fRange + [rsAtClass] - [rsVarTypeInSpecification, rsAfterEqual];
StartPascalCodeFoldBlock(cfbtClass);
end;
end
@ -1305,7 +1306,7 @@ begin
Result := tkKey;
if (rsAfterEqualOrColon in fRange) and (PasCodeFoldRange.BracketNestLevel = 0)
then begin
fRange := fRange + [rsAtClass] - [rsVarTypeInSpecification];
fRange := fRange + [rsAtClass] - [rsVarTypeInSpecification, rsAfterEqual];
StartPascalCodeFoldBlock(cfbtClass);
end;
end
@ -1384,7 +1385,7 @@ begin
StartPascalCodeFoldBlock(cfbtRecord);
fRange := fRange - [rsVarTypeInSpecification];
if CompilerMode = pcmDelphi then
fRange := fRange + [rsAtClass]; // highlight helper
fRange := fRange + [rsAtClass] - [rsAfterEqual]; // highlight helper
Result := tkKey;
end
else if KeyComp('Array') then Result := tkKey

View File

@ -45,6 +45,7 @@ type
function TestTextFoldInfo2: TStringArray;
function TestTextFoldInfo3: TStringArray;
function TestTextFoldInfo4(AIfCol: Integer): TStringArray;
function TestTextFoldInfo5: TStringArray;
procedure CheckTokensForLine(Name: String; LineIdx: Integer; ExpTokens: Array of TtkTokenKind);
published
@ -56,6 +57,7 @@ type
procedure TestContextForDeprecated;
procedure TestContextForClassModifier; // Sealed abstract
procedure TestContextForClassHelper;
procedure TestContextForClassFunction; // in class,object,record
procedure TestContextForRecordHelper;
procedure TestContextForStatic;
procedure TestCaretAsString;
@ -266,6 +268,24 @@ begin
end;
function TTestHighlighterPas.TestTextFoldInfo5: TStringArray;
begin
SetLength(Result, 13);
Result[0] := 'Unit Foo;';
Result[1] := 'Interface';
Result[2] := 'type';
Result[3] := 'TFoo<T: class> = class(TBar<T>)';
Result[4] := 'class procedure Proc;';
Result[5] := 'end;';
Result[6] := 'TFoo = record';
Result[7] := 'class procedure Proc;';
Result[8] := 'end;';
Result[9] := 'Implementation';
Result[10] := '//';
Result[11] := 'end.';
Result[12] := '';
end;
procedure TTestHighlighterPas.CheckTokensForLine(Name: String; LineIdx: Integer;
ExpTokens: array of TtkTokenKind);
var
@ -426,7 +446,28 @@ begin
[1, 1, 3, 0, 0, 0, 1]);
{%endregion}
{%region}
SetLines(TestTextFoldInfo5);
EnableFolds([cfbtBeginEnd..cfbtNone], [cfbtSlashComment]);
PushBaseName('Text 5 (class in generic type)');
AssertEquals('Len Unit', 11, PasHighLighter.FoldLineLength( 0,0));
AssertEquals('Len Intf', 7, PasHighLighter.FoldLineLength( 1,0));
AssertEquals('Len type', 6, PasHighLighter.FoldLineLength( 2,0));
AssertEquals('Len class', 2, PasHighLighter.FoldLineLength( 3,0));
AssertEquals('Len record', 2, PasHighLighter.FoldLineLength( 6,0));
AssertEquals('Len Impl', 1, PasHighLighter.FoldLineLength( 9,0));
AssertEquals('Len //', 0, PasHighLighter.FoldLineLength(10,0));
// un in ty cl pr en re pr en im // en
CheckFoldOpenCounts('', [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0]);
CheckFoldInfoCounts('', [sfaOpenFold, sfaFold],
[1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0]);
CheckFoldInfoCounts('', [sfaCloseFold, sfaFold, sfaLastLineClose],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
CheckFoldInfoCounts('', [sfaLastLineClose],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
{%endregion}
end;
procedure TTestHighlighterPas.TestExtendedKeywordsAndStrings;
@ -977,6 +1018,35 @@ begin
end;
procedure TTestHighlighterPas.TestContextForClassFunction;
var
i: Integer;
const
t: array[0..2] of string = ('class', 'object', 'record');
begin
for i:= 0 to 2 do begin
ReCreateEdit;
EnableFolds([cfbtBeginEnd..cfbtNone]);
SetLines
([ 'Unit A; interface',
'type',
'TFoo = '+t[i],
'class function f1: boolean;',
'class procedure p1(v: boolean);',
'end;',
''
]);
// unit/iface, type, record, -,-
CheckFoldOpenCounts('', [2, 1, 1, 0, 0]);
CheckTokensForLine('class function', 3,
[ tkKey, tkSpace, tkKey, tkSpace, tkIdentifier, tkSymbol, tkSpace, tkIdentifier, tkSymbol ]);
CheckTokensForLine('class procedure', 4,
[ tkKey, tkSpace, tkKey, tkSpace, tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkSpace, tkIdentifier, tkSymbol, tkSymbol ]);
end;
end;
procedure TTestHighlighterPas.TestContextForRecordHelper;
begin
ReCreateEdit;
@ -1087,24 +1157,26 @@ begin
([ 'Unit A; interface', // 0
'var',
'a:char=^o;',
'a:somestring=^o^c;',
'b:^char=nil;',
'type',
'c=^char;', // 5
'c=^char;', // 6
'c=type ^char;', // 6
'implementation',
'function x(f:^char=^k):^v;', // actually the compiler does not allow ^ as pointer for result
'function x(f:^char=^k^c):^v;', // actually the compiler does not allow ^ as pointer for result
'var',
'a:char=^o;',
'b:^char=nil;', // 10
'a:char=^o;', // 11
'b:^char=nil;', // 12
'type',
'c=^char;',
'begin',
'i:=^f;',
'x:=GetTypeData(PropInfo^.PropType{$IFNDEF FPC}^{$ENDIF});', // 15
'x:=GetTypeData(PropInfo^.PropType{$IFNDEF FPC}^{$ENDIF});', // 17
'c:=p^;',
'c:=p ^;',
'c:=p(**)^;',
'c:=p{} ^;',
'i:=f(1)^;', // 20
'c:=p{} ^;', // 21
'i:=f(1)^;', // 22
'i:=f[1]^;',
'i:=f^^;',
'c:=p^+^i''e''^a#13^x;',
@ -1115,50 +1187,54 @@ begin
CheckTokensForLine('a:char=^o;', 2,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkString, tkSymbol]);
CheckTokensForLine('b:^char=nil;', 3,
CheckTokensForLine('a:char=^o^c;', 3,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkString, tkString, tkSymbol]);
CheckTokensForLine('b:^char=nil;', 4,
[tkIdentifier, tkSymbol, tkSymbol, tkIdentifier, tkSymbol, tkKey, tkSymbol]);
CheckTokensForLine('c=^char;', 5,
CheckTokensForLine('c=^char;', 6,
[tkIdentifier, tkSymbol, tkSymbol, tkIdentifier, tkSymbol]);
CheckTokensForLine('c=type ^char;', 7,
[tkIdentifier, tkSymbol, tkKey, tkSpace, tkSymbol, tkIdentifier, tkSymbol]);
CheckTokensForLine('function x(f:^char=^k):^v;', 7,
CheckTokensForLine('function x(f:^char=^k):^v;', 9,
[tkKey, tkSpace, tkIdentifier, tkSymbol, tkIdentifier, // function x(f
tkSymbol, tkSymbol, tkIdentifier, tkSymbol, tkString, // :^char=^k
tkSymbol, tkSymbol, tkIdentifier, tkSymbol, tkString, tkString, // :^char=^k
tkSymbol, tkSymbol, tkSymbol, tkIdentifier, tkSymbol]); // ):^v;
CheckTokensForLine('LOCAL a:char=^o;', 9,
CheckTokensForLine('LOCAL a:char=^o;', 11,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkString, tkSymbol]);
CheckTokensForLine('LOCAL b:^char=nil;', 10,
CheckTokensForLine('LOCAL b:^char=nil;', 12,
[tkIdentifier, tkSymbol, tkSymbol, tkIdentifier, tkSymbol, tkKey, tkSymbol]);
CheckTokensForLine('LOCAL c=^char;', 12,
CheckTokensForLine('LOCAL c=^char;', 14,
[tkIdentifier, tkSymbol, tkSymbol, tkIdentifier, tkSymbol]);
CheckTokensForLine('i:=^f', 14,
CheckTokensForLine('i:=^f', 16,
[tkIdentifier, tkSymbol, tkString, tkSymbol]);
CheckTokensForLine('x:=GetTypeData(PropInfo^.PropType{$IFNDEF FPC}^{$ENDIF});', 15,
CheckTokensForLine('x:=GetTypeData(PropInfo^.PropType{$IFNDEF FPC}^{$ENDIF});', 17,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, // x:=GetTypeData(
tkIdentifier, tkSymbol, tkSymbol, tkIdentifier, // PropInfo^.PropType
tkDirective, tkSymbol, tkDirective, tkSymbol, tkSymbol]); // {$IFNDEF FPC}^{$ENDIF});
CheckTokensForLine('c:=p^;', 16,
CheckTokensForLine('c:=p^;', 18,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p ^;', 17,
CheckTokensForLine('c:=p ^;', 19,
[tkIdentifier, tkSymbol, tkIdentifier, tkSpace, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p(**)^;', 18,
CheckTokensForLine('c:=p(**)^;', 20,
[tkIdentifier, tkSymbol, tkIdentifier, tkComment, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p{} ^;', 19,
CheckTokensForLine('c:=p{} ^;', 21,
[tkIdentifier, tkSymbol, tkIdentifier, tkComment, tkSpace, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p(1)^;', 20,
CheckTokensForLine('c:=p(1)^;', 22,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkNumber, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p[1]^;', 21,
CheckTokensForLine('c:=p[1]^;', 23,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkNumber, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p^^;', 22,
CheckTokensForLine('c:=p^^;', 24,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkSymbol, tkSymbol]);
CheckTokensForLine('c:=p^+^i''e''^a#13^x;', 23,
CheckTokensForLine('c:=p^+^i''e''^a#13^x;', 25,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkSymbol, // c:=p^+
tkString, tkString, tkString, tkString, tkString, tkSymbol // ^i'e'^a#13^x;
]);
CheckTokensForLine('c:=x=^a and ^a=k and(^a^a=z);', 24,
CheckTokensForLine('c:=x=^a and ^a=k and(^a^a=z);', 26,
[tkIdentifier, tkSymbol, tkIdentifier, tkSymbol, tkString, tkSpace, // c:=x=^a
tkKey, tkSpace, tkString, tkSymbol, tkIdentifier, tkSpace, // and ^a=k
tkKey, tkSymbol, tkString, tkString, tkSymbol, tkIdentifier, // and(^a^a=z
@ -1288,7 +1364,7 @@ begin
PopPushBaseName('Text 1 -- [cfbtBeginEnd..cfbtNone], [], grp=1');
SetLines(TestTextFoldInfo1);
EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtForDo,cfbtWhileDo,cfbtWithDo], []);
DebugFoldInfo([],1);
//DebugFoldInfo([],1);
CheckFoldInfoCounts('', [], 1, [1, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 2]);
@ -1878,6 +1954,78 @@ begin
{%region TEXT 4}
{%region TEXT 5}
{%region TEXT 5 -- [cfbtBeginEnd..cfbtNone], []}
PopPushBaseName('Text 5 -- [cfbtBeginEnd..cfbtNone], [], 0');
SetLines(TestTextFoldInfo5);
EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtForDo,cfbtWhileDo,cfbtWithDo], []);
//DebugFoldInfo([]);
CheckFoldInfoCounts('', [], 0, [1, 1, 1, 1, 0, 1, 1, 0, 3, 1, 3, 1]);
// Line 0: unit foo;
CheckNode( 0, [], 0, 0, 0, 4, 0, 1, 0, 1,
cfbtUnit, cfbtUnit, FOLDGROUP_PASCAL,
[sfaOpen, sfaOpenFold, sfaFold, sfaFoldFold, sfaMultiLine]);
// Line 1: interface
CheckNode( 1, [], 0, 0, 0, 9, 1, 2, 1, 2,
cfbtUnitSection, cfbtUnitSection, FOLDGROUP_PASCAL,
[sfaOpen, sfaOpenFold, sfaFold, sfaFoldFold, sfaMultiLine]);
// Line 2: type
CheckNode( 2, [], 0, 0, 0, 4, 2, 3, 2, 3,
cfbtVarType, cfbtVarType, FOLDGROUP_PASCAL,
[sfaOpen, sfaFold, sfaFoldFold, sfaMultiLine, sfaOpenFold]);
// Line 3: TFoo<T: class> = class(TBar<T>)
CheckNode( 3, [], 0, 0, 17, 22, 3, 4, 3, 4,
cfbtClass, cfbtClass, FOLDGROUP_PASCAL,
[sfaOpen, sfaFold, sfaFoldFold, sfaMultiLine, sfaMarkup, sfaOpenFold]);
// Line 4: class procedure Proc;
CheckNode( 4, [], 0, -1, 0, 0, 4, 4, 4, 4,
cfbtNone, cfbtNone, FOLDGROUP_PASCAL,
[sfaInvalid]);
// Line 5: end.
CheckNode( 5, [], 0, 0, 0, 3, 4, 3, 4, 3,
cfbtClass, cfbtClass, FOLDGROUP_PASCAL,
[sfaClose, sfaFold, sfaMultiLine, sfaMarkup, sfaCloseFold]);
CheckNode( 6, [], 0, 0, 7, 13, 3, 4, 3, 4,
cfbtRecord, cfbtRecord, FOLDGROUP_PASCAL,
[sfaOpen, sfaFold, sfaFoldFold, sfaMultiLine, sfaMarkup, sfaOpenFold]);
// Line 7: class procedure Proc;
CheckNode( 7, [], 0, -1, 0, 0, 4, 4, 4, 4,
cfbtNone, cfbtNone, FOLDGROUP_PASCAL,
[sfaInvalid]);
// Line 8: end.
CheckNode( 8, [], 0, 0, 0, 3, 4, 3, 4, 3,
cfbtRecord, cfbtRecord, FOLDGROUP_PASCAL,
[sfaClose, sfaFold, sfaMultiLine, sfaMarkup, sfaCloseFold]);
CheckNode( 8, [], 0, 1, 4, 4, 3, 2, 3, 2,
cfbtVarType, cfbtVarType, FOLDGROUP_PASCAL,
[sfaClose, sfaFold, sfaMultiLine, sfaCloseForNextLine, sfaCloseFold]);
CheckNode( 8, [], 0, 2, 4, 4, 2, 1, 2, 1,
cfbtUnitSection, cfbtUnitSection, FOLDGROUP_PASCAL,
[sfaClose, sfaFold, sfaMultiLine, sfaCloseForNextLine, sfaCloseFold]);
// Line 9: implementation
CheckNode( 9, [], 0, 0, 0, 14, 1, 2, 1, 2,
cfbtUnitSection, cfbtUnitSection, FOLDGROUP_PASCAL,
[sfaOpen, sfaOpenFold,sfaFold, sfaFoldFold, sfaMultiLine]);
// Line 10: //, unit-section
CheckNode(10, [], 0, 0, 0, 2, 2, 3, 2, 3,
cfbtSlashComment, cfbtSlashComment, FOLDGROUP_PASCAL,
[sfaOpen, sfaOneLineOpen, sfaSingleLine]);
CheckNode(10, [], 0, 1, 2, 2, 3, 2, 3, 2,
cfbtSlashComment, cfbtSlashComment, FOLDGROUP_PASCAL,
[sfaClose, sfaOneLineClose, sfaCloseForNextLine, sfaSingleLine]);
CheckNode(10, [], 0, 2, 2, 2, 2, 1, 2, 1,
cfbtUnitSection, cfbtUnitSection, FOLDGROUP_PASCAL,
[sfaClose, sfaCloseFold,sfaFold, sfaCloseForNextLine, sfaMultiLine]);
// Line 11: end.
CheckNode(11, [], 0, 0, 0, 3, 1, 0, 1, 0,
cfbtUnit, cfbtUnit, FOLDGROUP_PASCAL,
[sfaClose, sfaCloseFold,sfaFold, sfaMultiLine]);
{%endregion TEXT 5 -- [cfbtBeginEnd..cfbtNone], []}
{%region TEXT 5}
end;
initialization