diff --git a/components/jcf2/Parse/BuildTokenList.pas b/components/jcf2/Parse/BuildTokenList.pas index dd33379eca..540ab5013d 100644 --- a/components/jcf2/Parse/BuildTokenList.pas +++ b/components/jcf2/Parse/BuildTokenList.pas @@ -79,6 +79,7 @@ type function TryWhiteSpace(const pcToken: TSourceToken): boolean; function TryLiteralString(const pcToken: TSourceToken; const pcDelimiter: Char): boolean; + function TryMultiLineLiteralString(const pcToken: TSourceToken): boolean; function TryNumber(const pcToken: TSourceToken): boolean; function TryHexNumber(const pcToken: TSourceToken): boolean; @@ -178,6 +179,8 @@ var { the rest } if TryWhiteSpace(lcNewToken) then exit; + if TryMultiLineLiteralString(lcNewToken) then + exit; if TryLiteralString(lcNewToken, NativeSingleQuote) then exit; if TryLiteralString(lcNewToken, NativeDoubleQuote) then @@ -488,6 +491,51 @@ begin end; end; +{ delphi 12 multiline string } +function TBuildTokenList.TryMultiLineLiteralString(const pcToken: TSourceToken): boolean; +var + liCount:integer; + liCountEnd:integer; +begin + Result := False; + liCount:=0; + while ForwardChar(liCount)=NativeSingleQuote do + Inc(liCount); + + if (liCount>=3) and ((liCount and 1)= 1) then + begin + Result := True; + { read the opening ''' odd number of single quotes } + pcToken.SourceCode := pcToken.SourceCode + CurrentChars(liCount); + Consume(liCount); + { read until the close ''' } + repeat + if Current = #0 then + Raise Exception.Create('Unterminated string: ' + pcToken.SourceCode); + + if (Current = NativeSingleQuote) then + begin + liCountEnd:=0; + while ForwardChar(liCountEnd)=NativeSingleQuote do + Inc(liCountEnd); + pcToken.SourceCode := pcToken.SourceCode + CurrentChars(liCountEnd); + Consume(liCountEnd); + if liCountEnd=liCount then + break; + end + else + begin + { normal char, read it } + pcToken.SourceCode := pcToken.SourceCode + Current; + Consume; + end; + + until False; + + pcToken.TokenType := ttQuotedLiteralString; + end; +end; + { complexities like 'Hello'#32'World' and #$12'Foo' are assemlbed in the parser } function TBuildTokenList.TryLiteralString(const pcToken: TSourceToken; const pcDelimiter: Char): boolean; diff --git a/components/jcf2/Parse/TokenUtils.pas b/components/jcf2/Parse/TokenUtils.pas index 6a2da047bd..a1b6deaf58 100644 --- a/components/jcf2/Parse/TokenUtils.pas +++ b/components/jcf2/Parse/TokenUtils.pas @@ -112,6 +112,7 @@ function IsFormalParamOpenBracket(const pt: TSourceToken): boolean; function IsMultiLineComment(const pcToken: TSourceToken): boolean; function IsSingleLineComment(const pcToken: TSourceToken): boolean; +function IsMultiLineQuotedString(const pcToken: TSourceToken): boolean; function IsBlankLineEnd(const pcToken: TSourceToken): boolean; @@ -576,6 +577,21 @@ begin Result := not IsMultiLineComment(pcToken); end; +function IsMultiLineQuotedString(const pcToken: TSourceToken): boolean; +var + liCount, liLen: integer; +begin + Result := False; + if (pcToken = nil) or (pcToken.TokenType <> ttQuotedLiteralString) then + exit; + // starts with odd number of single quotes >= 3 + liCount := 0; + liLen := Length(pcToken.SourceCode); + while (liCount < liLen) and (pcToken.SourceCode[liCount + 1] = NativeSingleQuote) do + Inc(liCount); + Result := (liCount >= 3) and ((liCount and 1) = 1); +end; + function IsBlankLineEnd(const pcToken: TSourceToken): boolean; var lcPrev: TSourceToken; diff --git a/components/jcf2/Process/Indent/Indenter.pas b/components/jcf2/Process/Indent/Indenter.pas index 8cd30a0108..b21c658fad 100644 --- a/components/jcf2/Process/Indent/Indenter.pas +++ b/components/jcf2/Process/Indent/Indenter.pas @@ -155,6 +155,8 @@ end; function IsIndented(const pt: TSourceToken): Boolean; begin + if IsMultiLineQuotedString(pt) then + exit(False); Result := IsFirstSolidTokenOnLine(pt); if Result then begin