View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0038067 | Lazarus | IDE | public | 2020-11-11 21:30 | 2020-11-13 23:06 |
Reporter | Yuri Serebrennikov | Assigned To | Juha Manninen | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 2.0.10 | ||||
Summary | 0038067: JCF does not support escaped identifiers (&identifier) | ||||
Description | For JSON deserialization I using symbol &. (https://freepascal.org/docs-html/current/ref/refse4.html) And the key combination Сtrl + D, stops working. | ||||
Steps To Reproduce | Create class TNameObject = class(TCollectionItem) private fType: string; published property &type: string read Ftype write Ftype; end; Press Ctrl+D. | ||||
Tags | No tags attached. | ||||
Fixed in Revision | r64131, r64134 | ||||
LazTarget | - | ||||
Widgetset | Win32/Win64 | ||||
Attached Files |
|
|
You mean the Jedi code formatting stops working? It can be added to the summary line. Key combination Сtrl + D can be assigned to any command although it is the code format by default. |
|
JCF doesn't support well identifiers names escaped with the ampersand char & so the &type causes the error. This patch solves the problem and offers better support for nested types. Now is posible format generics.collections.pas without errors. NestedTypesAndReservedWordIdentifiers.patch (6,268 bytes)
From 4b5976221fd0dd98b09a7c11d13b933cc62b0486 Mon Sep 17 00:00:00 2001 From: DomingoGP <dgalmesp@gmail.com> Date: Wed, 11 Nov 2020 22:23:22 +0100 Subject: [PATCH] Better support for nested types and reserved word variable names. --- components/jcf2/Parse/BuildParseTree.pas | 86 ++++++++++++++---------- components/jcf2/Parse/BuildTokenList.pas | 52 ++++++++++---- 2 files changed, 92 insertions(+), 46 deletions(-) diff --git a/components/jcf2/Parse/BuildParseTree.pas b/components/jcf2/Parse/BuildParseTree.pas index 51a5705faf..1a9f13f39b 100644 --- a/components/jcf2/Parse/BuildParseTree.pas +++ b/components/jcf2/Parse/BuildParseTree.pas @@ -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; + + if fcTokenList.FirstSolidTokenType = ttLessThan then + begin + RecogniseGenericType; + end; - // the type can be deprecated - if fcTokenList.FirstSolidTokenType = ttDeprecated then - Recognise(ttDeprecated); + 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; diff --git a/components/jcf2/Parse/BuildTokenList.pas b/components/jcf2/Parse/BuildTokenList.pas index 773c22430d..e2e0fbce9f 100644 --- a/components/jcf2/Parse/BuildTokenList.pas +++ b/components/jcf2/Parse/BuildTokenList.pas @@ -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; -- 2.29.1.windows.1 |
|
Yes. Jedi code formatting stops working. |
|
And if in code exist this construction, then Jedi formatting stop working too. for TCollectionItem(item) in ItemList do begin // do something..... end. |
|
I applied the patch for &ident in r64131. Thanks. The syntax "for TCollectionItem(item) in ItemList do" is unusual but it compiles. I keep this report open for a while in case somebody wants to fix it. Otherwise a new report can be opened for it. |
|
This patch solves the issue of casting in for .. in . Supports more than one cast. example. for MyCast2(TCollectionItem(item)) in itemList do begin // do something ... end; JCF_For_In_Typecasts.patch (1,321 bytes)
From 379448915f0a888897c4d105939016562b40a8ac Mon Sep 17 00:00:00 2001 From: DomingoGP <dgalmesp@gmail.com> Date: Fri, 13 Nov 2020 14:30:58 +0100 Subject: [PATCH] Typecasts in for Typecast1(item) in itemList do --- components/jcf2/Parse/BuildParseTree.pas | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/jcf2/Parse/BuildParseTree.pas b/components/jcf2/Parse/BuildParseTree.pas index 1a9f13f39b..1c248c839c 100644 --- a/components/jcf2/Parse/BuildParseTree.pas +++ b/components/jcf2/Parse/BuildParseTree.pas @@ -3473,6 +3473,7 @@ end; procedure TBuildParseTree.RecogniseForStmnt; var lc: TSourceToken; + lCountBrackets:integer; begin { ForStmt -> FOR QualId ':=' Expression (TO | DOWNTO) Expression DO Statement @@ -3485,6 +3486,22 @@ begin Recognise(ttFor); RecogniseQualId; + + //type cast for TCollectionItem(item) in ItemList do + // TypeCast1(TypeCast2(TypeCast3(item))) + lCountBrackets:=0; + while fcTokenList.FirstSolidTokenType=ttOpenBracket do + begin + Recognise(ttOpenBracket); + RecogniseQualId; + Inc(lCountBrackets); + end; + while lCountBrackets>0 do + begin + Recognise(ttCloseBracket); + Dec(lCountBrackets); + end; + lc := fcTokenList.FirstSolidToken; if lc.TokenType = ttIn then begin -- 2.29.1.windows.1 |
|
The typecast patch is now applied, too. Thanks. Resolving. |
Date Modified | Username | Field | Change |
---|---|---|---|
2020-11-11 21:30 | Yuri Serebrennikov | New Issue | |
2020-11-11 22:05 | Juha Manninen | Note Added: 0126840 | |
2020-11-11 22:06 | Juha Manninen | Note Edited: 0126840 | View Revisions |
2020-11-11 22:32 | Domingo Galmés | Note Added: 0126841 | |
2020-11-11 22:32 | Domingo Galmés | File Added: NestedTypesAndReservedWordIdentifiers.patch | |
2020-11-11 23:20 | Yuri Serebrennikov | Note Added: 0126843 | |
2020-11-11 23:24 | Yuri Serebrennikov | Note Added: 0126844 | |
2020-11-11 23:30 | Maxim Ganetsky | Summary | Key combination Сtrl + D, stops working. => JCF does not support escaped identifiers (&identifier) |
2020-11-11 23:30 | Maxim Ganetsky | LazTarget | => - |
2020-11-11 23:30 | Maxim Ganetsky | Widgetset | Win32/Win64 => Win32/Win64 |
2020-11-13 10:36 | Juha Manninen | Assigned To | => Juha Manninen |
2020-11-13 10:36 | Juha Manninen | Status | new => assigned |
2020-11-13 10:40 | Juha Manninen | Note Added: 0126872 | |
2020-11-13 14:40 | Domingo Galmés | Note Added: 0126877 | |
2020-11-13 14:40 | Domingo Galmés | File Added: JCF_For_In_Typecasts.patch | |
2020-11-13 23:06 | Juha Manninen | Status | assigned => resolved |
2020-11-13 23:06 | Juha Manninen | Resolution | open => fixed |
2020-11-13 23:06 | Juha Manninen | Fixed in Revision | => r64131, r64134 |
2020-11-13 23:06 | Juha Manninen | Widgetset | Win32/Win64 => Win32/Win64 |
2020-11-13 23:06 | Juha Manninen | Note Added: 0126902 |