mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 04:19:28 +02:00
* Parse async functions
This commit is contained in:
parent
d1bbc99e48
commit
a214682495
@ -24,8 +24,10 @@ uses
|
||||
|
||||
Const
|
||||
SEmptyLabel = '';
|
||||
MinAsyncVersion = ecma2021;
|
||||
|
||||
Type
|
||||
TECMAVersion = jsScanner.TECMAVersion;
|
||||
|
||||
{ TJSParser }
|
||||
|
||||
@ -51,6 +53,7 @@ Type
|
||||
procedure Expect(aToken: TJSToken);
|
||||
procedure Consume(aToken: TJSToken; AllowSemicolonInsert : Boolean = False);
|
||||
procedure FreeCurrentLabelSet;
|
||||
function GetVersion: TECMAVersion;
|
||||
procedure LeaveLabel;
|
||||
function LookupLabel(ALabelName: String; Kind: TJSToken): TJSLabel;
|
||||
function ParseAdditiveExpression: TJSElement;
|
||||
@ -117,7 +120,8 @@ Type
|
||||
Property NoIn : Boolean Read FNoIn Write FNoIn;
|
||||
Property IsLHS : Boolean Read FIsLHS Write FIsLHS;
|
||||
Public
|
||||
Constructor Create(AInput: TStream);
|
||||
Constructor Create(AInput: TStream; aVersion : TECMAVersion = ecma5);
|
||||
// Scanner has version
|
||||
Constructor Create(AScanner : TJSScanner);
|
||||
Destructor Destroy; override;
|
||||
Function Parse : TJSElement;
|
||||
@ -127,6 +131,7 @@ Type
|
||||
Function GetNextToken : TJSToken;
|
||||
Function PeekNextToken : TJSToken;
|
||||
Function IsEndOfLine : Boolean;
|
||||
Property ECMAVersion : TECMAVersion Read GetVersion;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -349,11 +354,11 @@ begin
|
||||
Error(Format(Fmt,Args));
|
||||
end;
|
||||
|
||||
Constructor TJSParser.Create(AInput: TStream);
|
||||
Constructor TJSParser.Create(AInput: TStream; aVersion : TECMAVersion = ecma5);
|
||||
begin
|
||||
FInput:=AInput;
|
||||
FCurrent:=TJSUnknown;
|
||||
FScanner:=TJSScanner.Create(FInput);
|
||||
FScanner:=TJSScanner.Create(FInput,aVersion);
|
||||
FFreeScanner:=True;
|
||||
end;
|
||||
|
||||
@ -1931,6 +1936,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TJSParser.GetVersion: TECMAVersion;
|
||||
begin
|
||||
Result:=FSCanner.ECMAVersion;
|
||||
end;
|
||||
|
||||
function TJSParser.ParseExpressionStatement : TJSElement;
|
||||
|
||||
Var
|
||||
@ -2034,21 +2044,27 @@ Var
|
||||
E : TJSElement;
|
||||
Done : Boolean;
|
||||
VS : TJSElementNodes;
|
||||
aSync : Boolean;
|
||||
begin
|
||||
{$ifdef debugparser} Writeln('>>> Entering source elements');{$endif}
|
||||
Result:=TJSSourceElements(CreateElement(TJSSourceElements));
|
||||
try
|
||||
Done:=False;
|
||||
aSync:=False;
|
||||
VS:=FCurrentVars;
|
||||
Try
|
||||
FCurrentVars:=Result.Vars;
|
||||
Repeat
|
||||
{$ifdef debugparser} Writeln('Sourceelements start:',GetEnumName(TypeInfo(TJSToken),Ord(CurrentToken)), ' As string: ',CurrentTokenString);{$endif debugparser}
|
||||
aSync:= (ECMAVersion>=MinAsyncVersion) and (CurrentToken=tjsIdentifier) and (CurrentTokenString='async');
|
||||
if aSync then
|
||||
GetNextToken;
|
||||
If (CurrentToken=jstoken.tjsFunction) then
|
||||
begin
|
||||
If (PeekNextToken<>tjsBraceOpen) then
|
||||
begin
|
||||
F:=Self.ParseFunctionDeclaration;
|
||||
F.AFunction.IsAsync:=aSync;
|
||||
Result.Functions.AddNode.Node:=F;
|
||||
end
|
||||
else
|
||||
|
@ -113,8 +113,8 @@ Type
|
||||
procedure Error(const Msg: string);overload;
|
||||
procedure Error(const Msg: string; Args: array of Const);overload;
|
||||
public
|
||||
constructor Create(ALineReader: TLineReader; ECMAVersion : TECMAVersion = ecma5);
|
||||
constructor Create(AStream : TStream; ECMAVersion : TECMAVersion = ecma5);
|
||||
constructor Create(ALineReader: TLineReader; aECMAVersion : TECMAVersion = ecma5);
|
||||
constructor Create(AStream : TStream; aECMAVersion : TECMAVersion = ecma5);
|
||||
destructor Destroy; override;
|
||||
procedure OpenFile(const AFilename: string);
|
||||
Function FetchRegexprToken: TJSToken;
|
||||
@ -162,18 +162,18 @@ begin
|
||||
ReadLn(FTextFile, Result);
|
||||
end;
|
||||
|
||||
constructor TJSScanner.Create(ALineReader: TLineReader; ECMAVersion: TECMAVersion);
|
||||
constructor TJSScanner.Create(ALineReader: TLineReader; aECMAVersion: TECMAVersion);
|
||||
begin
|
||||
inherited Create;
|
||||
FSourceFile := ALineReader;
|
||||
FNonKeyWords:=NonJSKeywords[ECMAVersion];
|
||||
ECMAVersion:=aECMAVersion;
|
||||
end;
|
||||
|
||||
constructor TJSScanner.Create(AStream: TStream; ECMAVersion: TECMAVersion);
|
||||
constructor TJSScanner.Create(AStream: TStream; aECMAVersion: TECMAVersion);
|
||||
begin
|
||||
FSourceStream:=ASTream;
|
||||
FOwnSourceFile:=True;
|
||||
Create(TStreamLineReader.Create(AStream));
|
||||
Create(TStreamLineReader.Create(AStream),aECMAVersion);
|
||||
end;
|
||||
|
||||
destructor TJSScanner.Destroy;
|
||||
|
@ -5,7 +5,7 @@ unit tcparser;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fpcunit, testregistry, jsParser, jstree, jsbase;
|
||||
Classes, SysUtils, fpcunit, testregistry, jsParser, jstree, jsbase;
|
||||
|
||||
type
|
||||
|
||||
@ -20,7 +20,7 @@ type
|
||||
protected
|
||||
procedure SetUp; override;
|
||||
procedure TearDown; override;
|
||||
Procedure CreateParser(Const ASource : string);
|
||||
Procedure CreateParser(Const ASource : string; aVersion : TECMAVersion = TECMAVersion.ecma5);
|
||||
Procedure CheckClass(E : TJSElement; C : TJSElementClass);
|
||||
Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSType); overload;
|
||||
Procedure AssertIdentifier(Msg : String; El : TJSElement; Const AName : TJSString);
|
||||
@ -106,6 +106,7 @@ type
|
||||
procedure TestBlockEmptyStatement;
|
||||
procedure TestBlockSimpleStatement;
|
||||
procedure TestFunctionDeclarationEmpty;
|
||||
procedure TestFunctionDeclarationAsync;
|
||||
procedure TestFunctionDeclarationWithArgs;
|
||||
procedure TestFunctionDeclarationWithBody;
|
||||
procedure TestIfSimple;
|
||||
@ -1691,6 +1692,7 @@ begin
|
||||
CheckClass(N,TJSFunctionDeclarationStatement);
|
||||
FD:=TJSFunctionDeclarationStatement(N);
|
||||
AssertNotNull('Function definition assigned',FD.AFunction);
|
||||
AssertFalse('Async function ',FD.AFunction.IsAsync);
|
||||
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
||||
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
||||
AssertEquals('No parameters',0,FD.AFunction.Params.Count);
|
||||
@ -1703,6 +1705,33 @@ begin
|
||||
// TJSEmptyBlockStatement
|
||||
end;
|
||||
|
||||
procedure TTestJSParser.TestFunctionDeclarationAsync;
|
||||
Var
|
||||
E : TJSSourceElements;
|
||||
N : TJSElement;
|
||||
FD : TJSFunctionDeclarationStatement;
|
||||
|
||||
begin
|
||||
CreateParser('async function a () {}',MinAsyncVersion);
|
||||
E:=GetSourceElements;
|
||||
AssertEquals('1 function defined',1,E.functions.Count);
|
||||
N:=E.Functions.Nodes[0].Node;
|
||||
AssertNotNull('Function element defined ',N);
|
||||
CheckClass(N,TJSFunctionDeclarationStatement);
|
||||
FD:=TJSFunctionDeclarationStatement(N);
|
||||
AssertNotNull('Function definition assigned',FD.AFunction);
|
||||
AssertTrue('Async function ',FD.AFunction.IsAsync);
|
||||
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
||||
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
||||
AssertEquals('No parameters',0,FD.AFunction.Params.Count);
|
||||
N:=FD.AFunction.Body;
|
||||
CheckClass(N,TJSFunctionBody);
|
||||
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
||||
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
||||
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
||||
AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
|
||||
end;
|
||||
|
||||
procedure TTestJSParser.TestFunctionDeclarationWithArgs;
|
||||
|
||||
Var
|
||||
@ -2521,10 +2550,10 @@ begin
|
||||
FReeAndNil(FSource);
|
||||
end;
|
||||
|
||||
Procedure TTestJSParser.CreateParser(Const ASource: string);
|
||||
Procedure TTestJSParser.CreateParser(Const ASource: string; aVersion : TECMAVersion = TECMAVersion.ecma5);
|
||||
begin
|
||||
FSource:=TStringStream.Create(ASource);
|
||||
FParser:=TJSParser.Create(FSource);
|
||||
FParser:=TJSParser.Create(FSource,aVersion);
|
||||
end;
|
||||
|
||||
Procedure TTestJSParser.CheckClass(E: TJSElement; C: TJSElementClass);
|
||||
|
Loading…
Reference in New Issue
Block a user