Jedi Code Format: Support escaped identifiers (&identifier). Issue #38067, patch from Domingo Galmés.

git-svn-id: trunk@64131 -
This commit is contained in:
juha 2020-11-13 09:37:02 +00:00
parent e405b8c6ac
commit c319bc8947
2 changed files with 92 additions and 46 deletions

View File

@ -1218,41 +1218,50 @@ begin
Recognise(ttEquals);
//Recognise type helper (for fpc)
if (fcTokenList.FirstSolidTokenType in [ttType,ttRecord]) and
(fcTokenList.SolidToken(2).TokenType=ttHelper) then
begin
RecogniseTypeHelper;
end else
repeat
// type or restricted type
if (fcTokenList.FirstSolidTokenType in [ttObject, ttClass, ttInterface,
ttDispInterface]) then
RecogniseRestrictedType
else
RecogniseType;
//Recognise type helper (for fpc)
if (fcTokenList.FirstSolidTokenType in [ttType,ttRecord]) and
(fcTokenList.SolidToken(2).TokenType=ttHelper) then
begin
RecogniseTypeHelper;
end else
if fcTokenList.FirstSolidTokenType = ttLessThan then
begin
RecogniseGenericType;
end;
if fcTokenList.FirstSolidTokenType = ttIs then
begin
Recognise(ttIs);
Recognise(ttNested);
end;
// type or restricted type
if (fcTokenList.FirstSolidTokenType in [ttObject, ttClass, ttInterface,
ttDispInterface]) then
RecogniseRestrictedType
else
RecogniseType;
// the type can be deprecated
if fcTokenList.FirstSolidTokenType = ttDeprecated then
Recognise(ttDeprecated);
if fcTokenList.FirstSolidTokenType = ttLessThan then
begin
RecogniseGenericType;
end;
if fcTokenList.FirstSolidTokenType = ttIs then
begin
Recognise(ttIs);
Recognise(ttNested);
end;
// the type can be deprecated
if fcTokenList.FirstSolidTokenType = ttDeprecated then
Recognise(ttDeprecated);
if fcTokenList.FirstSolidTokenType <> ttDot then
break;
Recognise(ttDot);
until false;
Recognise(ttSemicolon);
PopNode;
end;
function TBuildParseTree.GenericAhead: boolean;
var
liTokenIndex: integer;
@ -5000,22 +5009,26 @@ begin
Recognise(IdentiferTokens);
{ tokens can be qualified by a unit name }
{ can be nested types }
if pbCanHaveUnitQualifier and (fcTokenList.FirstSolidTokenType = ttDot) then
begin
Recognise(ttDot);
while fcTokenList.FirstSolidTokenType = ttDot do
begin
Recognise(ttDot);
{ delphi.net can preface the identifier with an '&'
in order to do something obscure with it - make it a literal or something
{ delphi.net can preface the identifier with an '&'
in order to do something obscure with it - make it a literal or something
e.g. "WebRequest.&Create" is not a constructor,
but a C# method called "Create", which is not a reserved word in C#
}
e.g. "WebRequest.&Create" is not a constructor,
but a C# method called "Create", which is not a reserved word in C#
}
RecognisePossiblyAmpdIdentifier;
RecognisePossiblyAmpdIdentifier;
end;
end;
PopNode;
end;
end;
{ the name of a procedure/function/constructor can be
a plain name or classname.methodname
@ -5125,9 +5138,14 @@ begin
// a use not a decl
RecogniseGenericType;
end;
if fcTokenList.FirstSolidTokenType = ttDot then
begin
Recognise(ttDot);
RecogniseTypeId;
end;
end;
procedure TBuildParseTree.RecogniseAsmBlock;
begin
PushNode(nAsm);
@ -5432,7 +5450,7 @@ begin
begin
lcLastChar := lcNext.SourceCode[Length(lcNext.SourceCode)];
if (lcLastChar = 'h') then
if ((lcLastChar = 'h') or (lcLastChar = 'H')) then
begin
Recognise(ttIdentifier);
end;

View File

@ -124,6 +124,13 @@ begin
Result := IsMultiByte(pcChar);
end;
function CharIsOctDigit(const c: Char): Boolean;
const
OctDigits: set of Char = [ '0', '1', '2', '3', '4', '5', '6', '7'];
begin
Result := (c in OctDigits);
end;
{ TBuildTokenList }
constructor TBuildTokenList.Create;
@ -468,14 +475,32 @@ end;
function TBuildTokenList.TryWord(const pcToken: TSourceToken): boolean;
begin
Result := False;
if not CharIsWordChar(Current) then
exit;
pcToken.SourceCode := Current;
Consume;
// support reserved words as identifiers
// example.
// var &type:integer;
if Current='&' then
begin
if CharIsOctDigit(ForwardChar(1)) then
Exit;
pcToken.SourceCode := Current;
Consume;
if not CharIsWordChar(Current) then
begin
pcToken.TokenType := ttAmpersand;
exit;
end;
end
else
begin
if not CharIsWordChar(Current) then
exit;
pcToken.SourceCode := Current;
Consume;
end;
{ concat any subsequent word chars }
while CharIsWordChar(Current) or CharIsDigit(Current) do
@ -691,13 +716,6 @@ end;
{ ~pktb 2017.05.19 - Oct numbers are prefixed with & }
function TBuildTokenList.TryOctNumber(const pcToken: TSourceToken): boolean;
function CharIsOctDigit(const c: Char): Boolean;
const
OctDigits: set of AnsiChar = [
'0', '1', '2', '3', '4', '5', '6', '7'];
begin
Result := (c in OctDigits);
end;
begin
Result := False;
@ -705,6 +723,16 @@ begin
if Current <> '&' then
exit;
//ISN'T A Octal Number.
if not CharIsOctDigit(ForwardChar(1)) then
begin
pcToken.TokenType := ttAmpersand;
pcToken.SourceCode := Current;
Consume;
result:=true;
exit;
end;
pcToken.TokenType := ttNumber;
pcToken.SourceCode := Current;
Consume;