* Allow Delphi-style const [ref]

This commit is contained in:
Michaël Van Canneyt 2023-12-06 11:25:55 +01:00
parent a546d4e64d
commit be5e84715c
5 changed files with 119 additions and 8 deletions

View File

@ -5070,6 +5070,10 @@ end;
// Starts after the opening bracket token // Starts after the opening bracket token
procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken: TToken); procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken: TToken);
var
HasRef: Boolean;
Function GetParamName : string; Function GetParamName : string;
begin begin
@ -5084,6 +5088,41 @@ procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken:
ParseExcTokenError('identifier') ParseExcTokenError('identifier')
end; end;
end; end;
Procedure ParseAttr(Peek : Boolean);
begin
HasRef:=False;
NextToken;
While CurToken=tkIdentifier do
begin
HasRef:=HasRef or CurTokenIsIdentifier('ref');
NextToken;
// We ignore the attribute value for the moment.
if CurToken=tkComma then
NextToken;
end;
CheckToken(tkSquaredBraceClose);
if not Peek then
NextToken;
end;
Function CheckAttributes(peek: boolean) : Boolean;
begin
if Peek then
NextToken;
Result:=CurToken = tkSquaredBraceOpen;
if Result then
begin
if not (msPrefixedAttributes in CurrentModeswitches) then
ParseExc(nParserExpectedConstVarID,SParserExpectedConstVarID);
ParseAttr(Peek);
end
else if Peek then
UnGettoken;
end;
var var
OldForceCaret,IsUntyped, LastHadDefaultValue: Boolean; OldForceCaret,IsUntyped, LastHadDefaultValue: Boolean;
Name : String; Name : String;
@ -5092,6 +5131,8 @@ var
Arg: TPasArgument; Arg: TPasArgument;
Access: TArgumentAccess; Access: TArgumentAccess;
ArgType: TPasType; ArgType: TPasType;
HasAttr : Boolean;
begin begin
LastHadDefaultValue := false; LastHadDefaultValue := false;
while True do while True do
@ -5101,6 +5142,10 @@ begin
IsUntyped := False; IsUntyped := False;
ArgType := nil; ArgType := nil;
NextToken; NextToken;
// [ref] (const|var|) a : type;
HasRef:=False;
HasAttr:=CheckAttributes(False);
if CurToken = tkDotDotDot then if CurToken = tkDotDotDot then
begin begin
expectToken(endToken); expectToken(endToken);
@ -5108,14 +5153,21 @@ begin
end else if CurToken = tkConst then end else if CurToken = tkConst then
begin begin
Access := argConst; Access := argConst;
// (const|var|) [ref] a : type;
CheckAttributes(True);
if HasRef then
Access := argConstRef;
Name := GetParamName; Name := GetParamName;
end else if CurToken = tkConstRef then end else if CurToken = tkConstRef then
begin begin
Access := argConstref; Access := argConstref;
CheckAttributes(True);
Name := getParamName; Name := getParamName;
end else if CurToken = tkVar then end else if CurToken = tkVar then
begin begin
Access := ArgVar; Access := ArgVar;
// (const|var|) [ref] a : type;
CheckAttributes(True);
Name:=GetParamName; Name:=GetParamName;
end else if (CurToken = tkIdentifier) and (UpperCase(CurTokenString) = 'OUT') then end else if (CurToken = tkIdentifier) and (UpperCase(CurTokenString) = 'OUT') then
begin begin

View File

@ -82,6 +82,8 @@ type
procedure TestOneSpecializedClassInterface; procedure TestOneSpecializedClassInterface;
Procedure TestOneField; Procedure TestOneField;
Procedure TestOneFieldComment; Procedure TestOneFieldComment;
procedure TestOneFieldWithAttribute;
procedure TestOneFieldVarWithAttribute;
Procedure TestOneClassOfField; Procedure TestOneClassOfField;
procedure TestOneFieldStatic; procedure TestOneFieldStatic;
Procedure TestOneHelperField; Procedure TestOneHelperField;
@ -592,7 +594,7 @@ begin
ParseClass; ParseClass;
end; end;
Procedure TTestClassType.TestForwardExternalObjCClass; procedure TTestClassType.TestForwardExternalObjCClass;
begin begin
FStarted:=True; FStarted:=True;
FEnded:=True; FEnded:=True;
@ -715,6 +717,26 @@ begin
AssertVisibility; AssertVisibility;
end; end;
procedure TTestClassType.TestOneFieldWithAttribute;
begin
Parser.CurrentModeswitches:=Parser.CurrentModeswitches+[msPrefixedAttributes];
AddMember('[volatile] a : integer');
ParseClass;
AssertEquals('Have 2 members',2,TheClass.Members.Count);
AssertMemberName('a',Members[1]);
AssertVisibility;
end;
procedure TTestClassType.TestOneFieldVarWithAttribute;
begin
Parser.CurrentModeswitches:=Parser.CurrentModeswitches+[msPrefixedAttributes];
AddMember('var [volatile] a : integer');
ParseClass;
AssertEquals('Have 2 members',2,TheClass.Members.Count);
AssertMemberName('a',Members[1]);
end;
procedure TTestClassType.TestOneFieldStatic; procedure TTestClassType.TestOneFieldStatic;
begin begin
AddMember('a : integer; static'); AddMember('a : integer; static');
@ -2323,7 +2345,7 @@ begin
AssertVisibility; AssertVisibility;
end; end;
Procedure TTestClassType.TestExternalClassFunctionFinal; procedure TTestClassType.TestExternalClassFunctionFinal;
begin begin
Parser.CurrentModeswitches:=[msObjfpc,msexternalClass]; Parser.CurrentModeswitches:=[msObjfpc,msexternalClass];

View File

@ -69,6 +69,8 @@ type
Procedure TestFunctionOneOutArg; Procedure TestFunctionOneOutArg;
procedure TestProcedureOneConstRefArg; procedure TestProcedureOneConstRefArg;
Procedure TestFunctionOneConstRefArg; Procedure TestFunctionOneConstRefArg;
procedure TestFunctionOneConstRefAttributeArg;
procedure TestFunctionOneConstRefAttributeArgReversed;
procedure TestProcedureTwoArgs; procedure TestProcedureTwoArgs;
Procedure TestFunctionTwoArgs; Procedure TestFunctionTwoArgs;
procedure TestProcedureTwoArgsSeparate; procedure TestProcedureTwoArgsSeparate;
@ -515,7 +517,7 @@ begin
AssertArg(ProcType,0,'B',argDefault,'^Integer',''); AssertArg(ProcType,0,'B',argDefault,'^Integer','');
end; end;
procedure TTestProcedureFunction.TestFunctionPointerResult; procedure TTestProcedureFunction.TestFUnctionPointerResult;
begin begin
ParseFunction('()','^LongInt'); ParseFunction('()','^LongInt');
AssertFunc([],[],ccDefault,0); AssertFunc([],[],ccDefault,0);
@ -556,6 +558,24 @@ begin
AssertArg(FuncType,0,'B',argConst,'Integer',''); AssertArg(FuncType,0,'B',argConst,'Integer','');
end; end;
procedure TTestProcedureFunction.TestFunctionOneConstRefAttributeArg;
begin
Parser.CurrentModeswitches:=Parser.CurrentModeswitches+[msPrefixedAttributes];
ParseFunction('([ref] Const B : Integer)');
AssertFunc([],[],ccDefault,1);
AssertArg(FuncType,0,'B',argConstRef,'Integer','');
end;
procedure TTestProcedureFunction.TestFunctionOneConstRefAttributeArgReversed;
begin
Parser.CurrentModeswitches:=Parser.CurrentModeswitches+[msPrefixedAttributes];
ParseFunction('(Const [ref] B : Integer)');
AssertFunc([],[],ccDefault,1);
AssertArg(FuncType,0,'B',argConstRef,'Integer','');
end;
procedure TTestProcedureFunction.TestProcedureOneOutArg; procedure TTestProcedureFunction.TestProcedureOneOutArg;
begin begin
Parser.CurrentModeswitches:=[msObjfpc]; Parser.CurrentModeswitches:=[msObjfpc];
@ -1491,7 +1511,7 @@ end;
Procedure TTestProcedureFunction.TestFunctionSyscallSingleNumber; procedure TTestProcedureFunction.TestFunctionSyscallSingleNumber;
begin begin
// function Something : Someresult; syscall 12 // function Something : Someresult; syscall 12
AddDeclaration('function A : Integer; syscall 12'); AddDeclaration('function A : Integer; syscall 12');
@ -1500,7 +1520,7 @@ begin
end; end;
Procedure TTestProcedureFunction.TestFunctionSyscallDoubleNumber; procedure TTestProcedureFunction.TestFunctionSyscallDoubleNumber;
begin begin
// function Something : Someresult; syscall 12 13 // function Something : Someresult; syscall 12 13
@ -1510,7 +1530,7 @@ begin
end; end;
Procedure TTestProcedureFunction.TestFunctionSysCallSysTrapIdentifier; procedure TTestProcedureFunction.TestFunctionSysCallSysTrapIdentifier;
begin begin
// function Something : Someresult; syscall systrapNNN // function Something : Someresult; syscall systrapNNN

View File

@ -64,6 +64,7 @@ Type
Procedure TestVarPublicName; Procedure TestVarPublicName;
Procedure TestVarDeprecatedExternalName; Procedure TestVarDeprecatedExternalName;
Procedure TestVarHintPriorToInit; Procedure TestVarHintPriorToInit;
Procedure TestVarAttribute;
Procedure TestErrorRecovery; Procedure TestErrorRecovery;
end; end;
@ -452,6 +453,22 @@ begin
AssertEquals('Correct initialization value',False, E.Value); AssertEquals('Correct initialization value',False, E.Value);
end; end;
procedure TTestVarParser.TestVarAttribute;
var
V : TPasVariable;
begin
add('{$mode delphi}');
Add('Var');
Add(' [xyz] A : integer;');
ParseDeclarations;
AssertEquals('One variable definition',1,Declarations.Variables.Count);
AssertEquals('First declaration is type definition.',TPasVariable,TObject(Declarations.Variables[0]).ClassType);
V:=TPasVariable(Declarations.Variables[0]);
AssertEquals('First declaration has correct name.','A',V.Name);
end;
procedure TTestVarParser.TestErrorRecovery; procedure TTestVarParser.TestErrorRecovery;
begin begin

View File

@ -27,13 +27,13 @@
</PublishOptions> </PublishOptions>
<RunParams> <RunParams>
<local> <local>
<CommandLineParams Value="--suite=TTestScanner.TestDelphiMultiLineTrailingGarbage2"/> <CommandLineParams Value="--suite=TTestProcedureFunction.TestFunctionOneConstRefAttributeArg"/>
</local> </local>
<FormatVersion Value="2"/> <FormatVersion Value="2"/>
<Modes Count="1"> <Modes Count="1">
<Mode0 Name="default"> <Mode0 Name="default">
<local> <local>
<CommandLineParams Value="--suite=TTestScanner.TestDelphiMultiLineTrailingGarbage2"/> <CommandLineParams Value="--suite=TTestProcedureFunction.TestFunctionOneConstRefAttributeArg"/>
</local> </local>
</Mode0> </Mode0>
</Modes> </Modes>