codetools: started parsing delphi 12 multiline string literals

This commit is contained in:
mattias 2023-11-09 16:29:06 +01:00
parent 591793ee8e
commit 3ff0868ca6
2 changed files with 64 additions and 9 deletions

View File

@ -640,6 +640,7 @@ type
FDirectiveCleanPos: integer; FDirectiveCleanPos: integer;
FDirectivesStored: boolean; FDirectivesStored: boolean;
FDirectoryCachePool: TCTDirectoryCachePool; FDirectoryCachePool: TCTDirectoryCachePool;
FIsDelphiMode: boolean;
FMacrosOn: boolean; FMacrosOn: boolean;
FMissingIncludeFiles: TMissingIncludeFiles; FMissingIncludeFiles: TMissingIncludeFiles;
FIncludeStack: TFPList; // list of TSourceLink FIncludeStack: TFPList; // list of TSourceLink
@ -853,6 +854,7 @@ type
property CompilerModeSwitches: TCompilerModeSwitches property CompilerModeSwitches: TCompilerModeSwitches
read FCompilerModeSwitches write FCompilerModeSwitches; read FCompilerModeSwitches write FCompilerModeSwitches;
property PascalCompiler: TPascalCompiler read FPascalCompiler write SetPascalCompiler; property PascalCompiler: TPascalCompiler read FPascalCompiler write SetPascalCompiler;
property IsDelphiMode: boolean read FIsDelphiMode;
property ScanTill: TLinkScannerRange read FScanTill write SetScanTill; property ScanTill: TLinkScannerRange read FScanTill write SetScanTill;
procedure Clear; procedure Clear;
@ -4582,6 +4584,33 @@ procedure TLinkScanner.SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
+' New='+dbgs(ord(SkippingUntil))); +' New='+dbgs(ord(SkippingUntil)));
end; end;
procedure SkipDelphiMultiLineLiteral(var p: PChar);
var
lvl, i: Integer;
begin
inc(p,2);
lvl:=3;
while (p^='''') do begin
inc(p);
inc(lvl);
end;
if lvl and 1=0 then
exit; // even amount are apostrophs in string literal, e.g. ''''
while p^<>#0 do begin
if (p^='''') and (p[1]='''') then begin
i:=2;
inc(p,2);
while p^='''' do begin
inc(i);
if i=lvl then
exit;
end;
end else
inc(p);
end;
end;
var var
p: PChar; p: PChar;
begin begin
@ -4632,15 +4661,19 @@ begin
inc(p); inc(p);
'''': '''':
begin begin
// skip string constant // skip string literal
inc(p); inc(p);
if IsDelphiMode and (p^='''') and (p[1]='''') then begin
SkipDelphiMultiLineLiteral(p);
end else begin
while not (p^ in ['''',#0,#10,#13]) do inc(p); while not (p^ in ['''',#0,#10,#13]) do inc(p);
if p^='''' then if p^='''' then
inc(p); inc(p);
end; end;
end;
'`': '`':
begin begin
// skip multiline string constant // skip multiline string literal
inc(p); inc(p);
while not (p^ in ['`',#0]) do inc(p); while not (p^ in ['`',#0]) do inc(p);
if p^='`' then if p^='`' then
@ -4685,10 +4718,12 @@ begin
FCompilerMode:=AValue; FCompilerMode:=AValue;
OldModeSwitches:=FCompilerModeSwitches; OldModeSwitches:=FCompilerModeSwitches;
FCompilerModeSwitches:=DefaultCompilerModeSwitches[CompilerMode]; FCompilerModeSwitches:=DefaultCompilerModeSwitches[CompilerMode];
if FPascalCompiler=pcPas2js then case FPascalCompiler of
FCompilerModeSwitches:=FCompilerModeSwitches+Pas2jsFixedModeswitches; pcPas2js: FCompilerModeSwitches:=FCompilerModeSwitches+Pas2jsFixedModeswitches;
end;
FNestedComments:=cmsNested_comment in CompilerModeSwitches; FNestedComments:=cmsNested_comment in CompilerModeSwitches;
Values.Variables[CompilerModeVars[FCompilerMode]]:='1'; Values.Variables[CompilerModeVars[FCompilerMode]]:='1';
FIsDelphiMode:=AValue in [cmDELPHI, cmDELPHIUNICODE];
EnabledModeSwitches:=FCompilerModeSwitches-OldModeSwitches; EnabledModeSwitches:=FCompilerModeSwitches-OldModeSwitches;
DisabledModeSwitches:=OldModeSwitches-FCompilerModeSwitches; DisabledModeSwitches:=OldModeSwitches-FCompilerModeSwitches;
@ -4706,6 +4741,7 @@ begin
if FPascalCompiler=AValue then Exit; if FPascalCompiler=AValue then Exit;
FPascalCompiler:=AValue; FPascalCompiler:=AValue;
case PascalCompiler of case PascalCompiler of
pcDelphi: FIsDelphiMode:=true;
pcPas2js: ; pcPas2js: ;
end; end;
end; end;

View File

@ -56,7 +56,8 @@ type
procedure TestParseProcAnoArg; procedure TestParseProcAnoArg;
procedure TestParseProcAnoArgSubFunc; procedure TestParseProcAnoArgSubFunc;
procedure TestParseThreadVar; procedure TestParseThreadVar;
procedure TestParseMultilineString; procedure TestParseMultilineStringFPC;
procedure TestParseMultilineStringDelphi;
procedure TestParseUnderscoreIsSeparator; procedure TestParseUnderscoreIsSeparator;
procedure TestParseDirective_IF_SizeOf_Char; procedure TestParseDirective_IF_SizeOf_Char;
end; end;
@ -617,7 +618,7 @@ begin
ParseModule; ParseModule;
end; end;
procedure TTestPascalParser.TestParseMultilineString; procedure TTestPascalParser.TestParseMultilineStringFPC;
begin begin
Add([ Add([
'program test1;', 'program test1;',
@ -636,6 +637,24 @@ begin
ParseModule; ParseModule;
end; end;
procedure TTestPascalParser.TestParseMultilineStringDelphi;
begin
Add([
'program test1;',
'{$TEXTBLOCK Native comment: could be native/cr/lf/crlf}',
'const',
' s = ''''''First',
' Second''Lit', // skip single apostroph
' Third''''Lit', // skip double apostroph
' '''''';', // last line defines ignored indentation. here: cut 4
' a = ''''''OneLine'''''';',
' b = ''''; // empty string literal',
' c = ''''''''; // string literal in string literal',
'begin',
'']);
ParseModule;
end;
procedure TTestPascalParser.TestParseUnderscoreIsSeparator; procedure TTestPascalParser.TestParseUnderscoreIsSeparator;
begin begin
Add([ Add([