diff --git a/components/codetools/definetemplates.pas b/components/codetools/definetemplates.pas index b9e62f2415..53c5644a8c 100644 --- a/components/codetools/definetemplates.pas +++ b/components/codetools/definetemplates.pas @@ -5274,7 +5274,9 @@ function TDefineTree.GetDirDefinesForVirtualDirectory: TDirectoryDefines; begin DoPrepareTree; if FVirtualDirCache=nil then begin - //DebugLn('################ TDefineTree.GetDirDefinesForVirtualDirectory'); + {$IFDEF VerboseDefineCache} + DebugLn('################ TDefineTree.GetDirDefinesForVirtualDirectory'); + {$ENDIF} FVirtualDirCache:=TDirectoryDefines.Create; FVirtualDirCache.Path:=VirtualDirectory; if Calculate(FVirtualDirCache) then begin diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index 4031f17728..991f3af152 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -1502,6 +1502,11 @@ begin AddCompilerProcedure('Write','Args:Arguments'); AddCompilerProcedure('WriteLn','Args:Arguments'); AddCompilerProcedure('WriteStr','var S:String;Args:Arguments'); + if Scanner.PascalCompiler=pcPas2js then begin + AddCompilerFunction('Str','const X[:Width[:Decimals]]','string'); + AddCompilerFunction('AWait','const Expr: T','T'); + AddCompilerFunction('AWait','aType; p: TJSPromise','aType'); + end; end; if (ilcfStartOfOperand in CurrentIdentifierList.ContextFlags) and diff --git a/components/codetools/keywordfunclists.pas b/components/codetools/keywordfunclists.pas index 4c991220f1..8bd48d16c6 100644 --- a/components/codetools/keywordfunclists.pas +++ b/components/codetools/keywordfunclists.pas @@ -871,6 +871,7 @@ begin with IsKeyWordMethodSpecifier do begin Add('ABSTRACT' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('ASSEMBLER' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('ASYNC' ,{$ifdef FPC}@{$endif}AllwaysTrue); // pas2js Add('CDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('EXTDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); // often used for macros ADD('MWPASCAL' ,{$ifdef FPC}@{$endif}AllwaysTrue); @@ -907,6 +908,7 @@ begin with IsKeyWordProcedureSpecifier do begin Add('ALIAS' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('ASSEMBLER' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('ASYNC' ,{$ifdef FPC}@{$endif}AllwaysTrue); // pas2js Add('CDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('COMPILERPROC' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('DEPRECATED' ,{$ifdef FPC}@{$endif}AllwaysTrue); @@ -973,6 +975,7 @@ begin KeyWordLists.Add(IsKeyWordProcedureAnonymousSpecifier); with IsKeyWordProcedureAnonymousSpecifier do begin Add('ASSEMBLER' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('ASYNC' ,{$ifdef FPC}@{$endif}AllwaysTrue); // pas2js Add('CDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('EXTDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); // used often for macros Add('FAR' ,{$ifdef FPC}@{$endif}AllwaysTrue); @@ -997,6 +1000,7 @@ begin Add('EXTDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('MWPASCAL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('POPSTACK' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('SAFECALL' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('VECTORCALL' ,{$ifdef FPC}@{$endif}AllwaysTrue); // Note: 'inline' and 'is nested' are not a calling specifiers end; diff --git a/components/codetools/tests/testctpas2js.pas b/components/codetools/tests/testctpas2js.pas index 6ff4ea5a72..86f9cd0b8b 100644 --- a/components/codetools/tests/testctpas2js.pas +++ b/components/codetools/tests/testctpas2js.pas @@ -13,16 +13,17 @@ interface uses Classes, SysUtils, CodeToolManager, FileProcs, DefineTemplates, LinkScanner, - CodeCache, TestGlobals, LazLogger, LazFileUtils, LazUTF8, fpcunit, - testregistry; + CodeCache, ExprEval, TestGlobals, LazLogger, LazFileUtils, LazUTF8, fpcunit, + testregistry, TestFindDeclaration; type { TCustomTestPas2js } - TCustomTestPas2js = class(TTestCase) + TCustomTestPas2js = class(TCustomTestFindDeclaration) private FAutoSearchPas2js: boolean; + FBaseDir: string; FCode: TCodeBuffer; FPas2jsFilename: string; FUnitSetCache: TFPCUnitSetCache; @@ -36,15 +37,16 @@ type procedure Add(const s: string); procedure Add(Args: array of const); function FindPas2js: string; - function StartProgram: boolean; virtual; + function StartProgram: boolean; override; procedure ParseModule; virtual; procedure WriteSource(CleanPos: integer; Tool: TCodeTool); procedure WriteSource(const CursorPos: TCodeXYPosition); property AutoSearchPas2js: boolean read FAutoSearchPas2js write FAutoSearchPas2js; property Code: TCodeBuffer read FCode; - property Pas2jsFilename: string read FPas2jsFilename write FPas2jsFilename; + property Pas2jsFilename: string read FPas2jsFilename write FPas2jsFilename; // compiler filename property UnitSetCache: TFPCUnitSetCache read FUnitSetCache write FUnitSetCache; property VirtualDirDefines: TDefineTemplate read FVirtualDirDefines write FVirtualDirDefines; + property BaseDir: string read FBaseDir write FBaseDir; end; { TTestPas2js } @@ -53,6 +55,7 @@ type published procedure TestPas2js_ReadSettings; procedure TestPas2js_FindDeclaration; + procedure TestPas2js_FindDeclaration_AWait; end; implementation @@ -63,6 +66,7 @@ procedure TCustomTestPas2js.SetUp; var CurUnitSet: TFPCUnitSetCache; UnitSetID: String; + CompilerDefines: TDefineTemplate; begin inherited SetUp; if (Pas2jsFilename='') and AutoSearchPas2js then begin @@ -83,10 +87,12 @@ begin VirtualDirDefines:=TDefineTemplate.Create( 'VirtualDirPas2js', 'set pas2js as compiler for virtual directory', '',VirtualDirectory,da_Directory); - VirtualDirDefines.AddChild(TDefineTemplate.Create('UnitSet','UnitSet identifier', - UnitSetMacroName,UnitSetID,da_DefineRecurse)); - CodeToolBoss.DefineTree.Add(VirtualDirDefines); + VirtualDirDefines.AddChild(TDefineTemplate.Create('Reset','','','',da_UndefineAll)); + // create template for Pas2js settings + CompilerDefines:=CreateFPCTemplate(UnitSetCache,nil); + VirtualDirDefines.AddChild(CompilerDefines); end; + CodeToolBoss.DefineTree.Add(VirtualDirDefines); // check CurUnitSet:=CodeToolBoss.GetUnitSetForDirectory(''); @@ -94,6 +100,11 @@ begin Fail('CodeToolBoss.GetUnitSetForDirectory=nil'); if CurUnitSet<>UnitSetCache then AssertEquals('UnitSet VirtualDirectory should be pas2js',UnitSetID,CurUnitSet.GetUnitSetID); + + if CodeToolBoss.GetPascalCompilerForDirectory('')<>pcPas2js then + AssertEquals('VirtualDirectory compiler should be pas2js', + PascalCompilerNames[pcPas2js], + PascalCompilerNames[CodeToolBoss.GetPascalCompilerForDirectory('')]); end; FCode:=CodeToolBoss.CreateFile('test1.pas'); end; @@ -129,6 +140,7 @@ constructor TCustomTestPas2js.Create; begin inherited Create; FAutoSearchPas2js:=true; + FBaseDir:='pas2js'; end; procedure TCustomTestPas2js.Add(const s: string); @@ -241,6 +253,32 @@ begin //FindDeclarations(Code); end; +procedure TTestPas2js.TestPas2js_FindDeclaration_AWait; +begin + if not StartProgram then exit; + Add([ + '{$modeswitch externalclass}', + 'type', + ' TJSPromise = class external name ''Promise''', + ' end;', + 'function Crawl(d: double = 1.3): word; ', + 'begin', + 'end;', + 'function Run(d: double): word; async;', + 'var', + ' p: TJSPromise;', + 'begin', + ' Result:=await(word,p{declaration:Run.p});', + ' Result:=await(1);', + ' Result:=await(Crawl{declaration:Crawl});', + ' Result:=await(Crawl{declaration:Crawl}(4.5));', + 'end;', + 'begin', + ' Run{declaration:run}(3);', + 'end.']); + FindDeclarations(Code); +end; + initialization RegisterTest(TTestPas2js); end. diff --git a/components/codetools/tests/testpascalparser.pas b/components/codetools/tests/testpascalparser.pas index caeb7bebd4..7eef374199 100644 --- a/components/codetools/tests/testpascalparser.pas +++ b/components/codetools/tests/testpascalparser.pas @@ -30,7 +30,7 @@ type procedure Add(const s: string); procedure Add(Args: array of const); procedure StartUnit; - procedure StartProgram; + function StartProgram: boolean; virtual; procedure ParseModule; procedure CheckParseError(const CursorPos: TCodeXYPosition; Msg: string); procedure WriteSource(CleanPos: integer; Tool: TCodeTool); @@ -110,8 +110,9 @@ begin Add(''); end; -procedure TCustomTestPascalParser.StartProgram; +function TCustomTestPascalParser.StartProgram: boolean; begin + Result:=true; Add('program test1;'); Add(''); Add('{$mode objfpc}{$H+}');