pastojs: adaptions for pas2js

git-svn-id: trunk@40064 -
This commit is contained in:
Mattias Gaertner 2018-10-28 14:34:08 +00:00
parent 4bf4ce5537
commit 01d1cde8a3
5 changed files with 114 additions and 64 deletions

View File

@ -886,7 +886,7 @@ Var
begin
if (U1<>0) then
begin
U:=UTF8Encode(WideChar(U1));
U:={$IFDEF FPC_HAS_CPSTRING}UTF8Encode(WideChar(U1)){$ELSE}widechar(U1){$ENDIF};
Result:=Result+U;
U1:=0;
end;
@ -921,7 +921,7 @@ begin
u2:=StrToInt('$'+W);
if (U1<>0) then
begin
App:=UTF8Encode(WideChar(U1)+WideChar(U2));
App:={$IFDEF FPC_HAS_CPSTRING}UTF8Encode({$ENDIF}WideChar(U1)+WideChar(U2){$IFDEF FPC_HAS_CPSTRING}){$ENDIF};
U2:=0;
end
else

View File

@ -20,6 +20,7 @@ interface
uses
{$IFDEF Pas2js}
NodeJSFS,
{$ENDIF}
Classes, SysUtils, RtlConsts, contnrs,
jstree, jswriter, JSSrcMap,
@ -318,16 +319,16 @@ type
function GetInitialBoolSwitches: TBoolSwitches;
function GetInitialConverterOptions: TPasToJsConverterOptions;
procedure CreateScannerAndParser(aFileResolver: TPas2jsFileResolver);
procedure CreatePCUReader;
procedure CreateConverter;
{$IFDEF HasPas2jsFiler}
procedure CreatePCUReader;
function FindPCU(const UseUnitName: string; out aFormat: TPas2JSPrecompileFormat): string;
{$ENDIF}
function OnResolverFindModule(const UseUnitName, InFilename: String; NameExpr,
InFileExpr: TPasExpr): TPasModule;
function LoadUsedUnit(const UseFilename, UseUnitname, InFilename: String;
NameExpr, InFileExpr: TPasExpr; UseIsForeign: boolean
{$IFDEF HasPas2jsFiler}; aFormat: TPas2JSPrecompileFormat{$ENDIF}): TPas2jsCompilerFile;
{$IFDEF HasPas2jsFiler}; aFormat: TPas2JSPrecompileFormat = nil{$ENDIF}): TPas2jsCompilerFile;
procedure OnResolverCheckSrcName(const Element: TPasElement);
procedure OpenFile(aFilename: string);// beware: this changes FileResolver.BaseDirectory
procedure ReadUnit;
@ -971,37 +972,6 @@ begin
end;
end;
procedure TPas2jsCompilerFile.CreatePCUReader;
var
aFile: TPas2jsCachedFile;
s: String;
begin
if PCUFilename='' then
RaiseInternalError(20180312144742,PCUFilename);
if PCUReader<>nil then
RaiseInternalError(20180312142938,GetObjName(PCUReader));
if PCUFormat=nil then
RaiseInternalError(20180312142954,'');
FPCUReader:=PCUFormat.ReaderClass.Create;
FPCUReader.SourceFilename:=ExtractFileName(PCUFilename);
if ShowDebug then
Log.LogMsg(nParsingFile,[QuoteStr(PCUFilename)]);
aFile:=Compiler.FileCache.LoadFile(PCUFilename,true);
if aFile=nil then
RaiseInternalError(20180312145941,PCUFilename);
FPCUReaderStream:=TMemoryStream.Create;
s:=aFile.Source;
//writeln('TPas2jsCompilerFile.CreatePCUReader ',PCUFilename,'-----START-----');
//writeln(s);
//writeln('TPas2jsCompilerFile.CreatePCUReader ',PCUFilename,'-----END-------');
if s<>'' then
begin
PCUReaderStream.Write(s[1],length(s));
PCUReaderStream.Position:=0;
end;
end;
procedure TPas2jsCompilerFile.CreateConverter;
begin
if FConverter<>nil then exit;
@ -1213,8 +1183,10 @@ end;
procedure TPas2jsCompilerFile.HandleException(E: Exception);
begin
{$IFDEF FPC}
if ShowDebug then
Log.LogExceptionBackTrace;
{$ENDIF}
if E is EScannerError then
begin
Log.Log(Scanner.LastMsgType,Scanner.LastMsg,Scanner.LastMsgNumber,
@ -1226,8 +1198,6 @@ begin
HandleEPasResolve(EPasResolve(E))
else if E is EPas2JS then
HandleEPas2JS(EPas2JS(E))
else if E is EPas2JsReadError then
HandleEPCUReader(EPas2JsReadError(E))
else if E is EFileNotFoundError then
begin
if (E.Message<>'') or (Log.LastMsgType<>mtFatal) then
@ -1239,11 +1209,15 @@ begin
Log.Log(mtFatal,E.Message);
Compiler.Terminate(ExitCodeFileNotFound);
end
else if (E is EPas2JsWriteError) or (E is EPas2JsReadError) then
{$IFDEF HasPas2jsFiler}
else if E is EPas2JsReadError then
HandleEPCUReader(EPas2JsReadError(E))
else if (E is EPas2JsWriteError) then
begin
Log.Log(mtFatal,E.ClassName+':'+E.Message);
Compiler.Terminate(ExitCodeErrorInternal);
end
{$ENDIF}
else
HandleUnknownException(E);
end;
@ -1444,12 +1418,15 @@ begin
Compiler.AddReadingModule(Self);
PascalResolver.InterfaceOnly:=IsForeign;
{$IFDEF HasPas2jsFiler}
if PCUReader<>nil then
begin
PCUReader.ReadPCU(PascalResolver,PCUReaderStream);
FPasModule:=PascalResolver.RootElement;
FReaderState:=prsCanContinue;
end else begin
end else
{$ENDIF}
begin
if IsMainFile then
Parser.ParseMain(FPasModule)
else
@ -1486,9 +1463,11 @@ begin
{$IFDEF VerboseUnitQueue}
writeln('TPas2jsCompilerFile.ReadContinue ',PasFilename);
{$ENDIF}
{$IFDEF HasPas2jsFiler}
if PCUReader<>nil then
Result:=PCUReader.ReadContinue
else
{$ENDIF}
begin
Parser.ParseContinue;
Result:=Parser.CurModule=nil;
@ -1516,21 +1495,26 @@ var
begin
Result:=FReaderState;
if Result=prsWaitingForUsedUnits then
begin
{$IFDEF HasPas2jsFiler}
if PCUReader<>nil then
begin
if PCUReader.ReadCanContinue then
Result:=prsCanContinue;
end else begin
end else
{$ENDIF}
begin
if Parser.CanParseContinue(Section) then
Result:=prsCanContinue;
end;
end;
end;
procedure TPas2jsCompilerFile.CreateJS;
begin
try
// show hints only for units that are actually converted
if PCUReader=nil then
if {$IFDEF HasPas2jsFiler}PCUReader=nil{$ELSE}true{$ENDIF} then
begin
//writeln('TPas2jsCompilerFile.CreateJS ',PasFilename);
UseAnalyzer.EmitModuleHints(PasModule);
@ -1656,6 +1640,37 @@ begin
end;
{$IFDEF HasPas2jsFiler}
procedure TPas2jsCompilerFile.CreatePCUReader;
var
aFile: TPas2jsCachedFile;
s: String;
begin
if PCUFilename='' then
RaiseInternalError(20180312144742,PCUFilename);
if PCUReader<>nil then
RaiseInternalError(20180312142938,GetObjName(PCUReader));
if PCUFormat=nil then
RaiseInternalError(20180312142954,'');
FPCUReader:=PCUFormat.ReaderClass.Create;
FPCUReader.SourceFilename:=ExtractFileName(PCUFilename);
if ShowDebug then
Log.LogMsg(nParsingFile,[QuoteStr(PCUFilename)]);
aFile:=Compiler.FileCache.LoadFile(PCUFilename,true);
if aFile=nil then
RaiseInternalError(20180312145941,PCUFilename);
FPCUReaderStream:=TMemoryStream.Create;
s:=aFile.Source;
//writeln('TPas2jsCompilerFile.CreatePCUReader ',PCUFilename,'-----START-----');
//writeln(s);
//writeln('TPas2jsCompilerFile.CreatePCUReader ',PCUFilename,'-----END-------');
if s<>'' then
begin
PCUReaderStream.Write(s[1],length(s));
PCUReaderStream.Position:=0;
end;
end;
function TPas2jsCompilerFile.FindPCU(const UseUnitName: string; out
aFormat: TPas2JSPrecompileFormat): string;
@ -1706,9 +1721,10 @@ end;
function TPas2jsCompilerFile.OnResolverFindModule(const UseUnitName,
InFilename: String; NameExpr, InFileExpr: TPasExpr): TPasModule;
var
FoundPasFilename, FoundPasUnitName, FoundPCUFilename, FoundPCUUnitName: string;
FoundPasFilename, FoundPasUnitName: string;
FoundPasIsForeign: Boolean;
{$IFDEF HasPas2jsFiler}
FoundPCUFilename, FoundPCUUnitName: string;
FoundPCUFormat: TPas2JSPrecompileFormat;
{$ENDIF}
@ -1731,12 +1747,14 @@ var
FoundPasUnitName:=TestUnitName;
end;
end;
{$IFDEF HasPas2jsFiler}
if FoundPCUFilename='' then
begin
FoundPCUFilename:=FindPCU(TestUnitName,FoundPCUFormat);
if FoundPCUFilename<>'' then
FoundPCUUnitName:=TestUnitName;
end;
{$ENDIF}
end;
var
@ -1754,9 +1772,11 @@ begin
FoundPasFilename:='';
FoundPasIsForeign:=false;
FoundPasUnitName:='';
{$IFDEF HasPas2jsFiler}
FoundPCUFilename:='';
FoundPCUFormat:=nil;
FoundPCUUnitName:='';
{$ENDIF}
if (InFilename='') and (Pos('.',UseUnitname)<1) then
begin
// generic unit -> search with namespaces
@ -1765,7 +1785,7 @@ begin
if DefNameSpace<>'' then
TryUnitName(DefNameSpace+'.'+UseUnitname);
if (FoundPasFilename='') or (FoundPCUFilename='') then
if (FoundPasFilename='') {$IFDEF HasPas2jsFiler}or (FoundPCUFilename=''){$ENDIF} then
begin
// then the cmdline namespaces
for i:=0 to Compiler.FileCache.Namespaces.Count-1 do begin
@ -1804,25 +1824,28 @@ begin
exit; // an in-filename unit source is missing -> stop
end;
end;
{$IFDEF HasPas2jsFiler}
if FoundPCUFilename='' then
begin
FoundPCUFilename:=FindPCU(UseUnitName,FoundPCUFormat);
FoundPCUUnitName:=UseUnitName;
end;
if (FoundPCUFilename<>'') and (FoundPasFilename='') then
if (FoundPasFilename='') and (FoundPCUFilename<>'') then
begin
aFile:=LoadUsedUnit(FoundPCUFilename,FoundPCUUnitName,'',NameExpr,nil,false,FoundPCUFormat);
if aFile<>nil then
Result:=aFile.PasModule;
exit;
end;
{$ENDIF}
if FoundPasFilename<>'' then
begin
// load unit
aFile:=LoadUsedUnit(FoundPasFilename,FoundPasUnitName,InFilename,
NameExpr,InFileExpr,FoundPasIsForeign,nil);
NameExpr,InFileExpr,FoundPasIsForeign);
if aFile<>nil then
Result:=aFile.PasModule;
end;
@ -1939,18 +1962,21 @@ begin
// ' IsForeign=',IsForeign,' JSFile="',FileResolver.Cache.FormatPath(useJSFilename),'"']);
// load Pascal or PCU file
Compiler.LoadPasFile(UseFilename,UseUnitname,aFile,aFormat);
Compiler.LoadPasFile(UseFilename,UseUnitname,aFile{$IFDEF HasPas2jsFiler},aFormat{$ENDIF});
// consistency checks
if aFile.PasUnitName<>UseUnitname then
RaiseInternalError(20170922143329,'aFile.PasUnitName='+aFile.PasUnitName+' UseUnitname='+UseUnitname);
if aFormat=nil then
{$IFDEF HasPas2jsFiler}
if aFormat<>nil then
begin
if CompareFilenames(aFile.PCUFilename,UseFilename)<>0 then
RaiseInternalError(20180312122331,'aFile.PCUFilename='+aFile.PCUFilename+' UseFilename='+UseFilename);
end else
{$ENDIF}
begin
if CompareFilenames(aFile.PasFilename,UseFilename)<>0 then
RaiseInternalError(20170922143330,'aFile.PasFilename='+aFile.PasFilename+' UseFilename='+UseFilename);
end else begin
if CompareFilenames(aFile.PCUFilename,UseFilename)<>0 then
RaiseInternalError(20180312122331,'aFile.PCUFilename='+aFile.PCUFilename+' UseFilename='+UseFilename);
end;
if aFile=Self then
@ -2146,7 +2172,7 @@ begin
{$IF defined(VerbosePasResolver) or defined(VerboseUnitQueue)}
writeln('TPas2jsCompiler.ProcessQueue aFile=',aFile.PasFilename,' NOT YET READY');
{$ENDIF}
if (aFile.PCUReader=nil) and (aFile.Parser.CurModule=nil) then
if {$IFDEF HasPas2jsFiler}(aFile.PCUReader=nil) and{$ENDIF} (aFile.Parser.CurModule=nil) then
RaiseInternalError(20180306111410,'File='+aFile.PasFilename+' Parser.CurModule=nil');
continue;
end;
@ -2175,7 +2201,7 @@ begin
aFile:=TPas2jsCompilerFile(FReadingModules[i]);
if aFile.PascalResolver=nil then
RaiseInternalError(20180313124125,aFile.PasFilename);
if (aFile.PCUReader=nil) and (aFile.Parser.CurModule<>nil) then
if {$IFDEF HasPas2jsFiler}(aFile.PCUReader=nil) and{$ENDIF} (aFile.Parser.CurModule<>nil) then
begin
{$IF defined(VerbosePasResolver) or defined(VerboseUnitQueue)}
writeln('TPas2jsCompiler.ProcessQueue aFile=',aFile.PasFilename,' was not finished');

View File

@ -724,20 +724,25 @@ begin
exit;
end;
{$IFDEF Windows}
Result:=GetWindowsEncoding;
{$IFDEF Pas2js}
Result:=EncodingUTF8;
{$ELSE}
{$IFDEF Darwin}
Result:=EncodingUTF8;
{$IFDEF Windows}
Result:=GetWindowsEncoding;
{$ELSE}
Lang := GetEnvironmentVariable('LC_ALL');
if Lang='' then
begin
Lang := GetEnvironmentVariable('LC_MESSAGES');
{$IFDEF Darwin}
Result:=EncodingUTF8;
{$ELSE}
// unix
Lang := GetEnvironmentVariable('LC_ALL');
if Lang='' then
Lang := GetEnvironmentVariable('LANG');
end;
Result:=GetUnixEncoding;
begin
Lang := GetEnvironmentVariable('LC_MESSAGES');
if Lang='' then
Lang := GetEnvironmentVariable('LANG');
end;
Result:=GetUnixEncoding;
{$ENDIF}
{$ENDIF}
{$ENDIF}
Result:=NormalizeEncoding(Result);
@ -756,6 +761,15 @@ begin
end;
function IsASCII(const s: string): boolean; inline;
{$IFDEF Pas2js}
var
i: Integer;
begin
for i:=1 to length(s) do
if s[i]>#127 then exit(false);
Result:=true;
end;
{$ELSE}
var
p: PChar;
begin
@ -769,6 +783,7 @@ begin
inc(p);
until false;
end;
{$ENDIF}
{$IFDEF FPC_HAS_CPSTRING}
function UTF8CharacterStrictLength(P: PChar): integer;

View File

@ -19,6 +19,7 @@ function FilenameIsAbsolute(const aFilename: string): boolean;
begin
writeln('FilenameIsAbsolute ToDo ',aFilename);
Result:=FilenameIsUnixAbsolute(aFilename);
raise Exception.Create('FilenameIsAbsolute ToDo');
end;
function ExpandFileNamePJ(const FileName: string; BaseDir: string): string;
@ -62,6 +63,7 @@ function GetCurrentDirPJ: String;
begin
writeln('GetCurrentDirPJ ToDo');
Result:='';
raise Exception.Create('GetCurrentDirPJ ToDo');
end;
function GetPhysicalFilename(const Filename: string; ExceptionOnError: boolean
@ -100,12 +102,14 @@ function ResolveSymLinks(const Filename: string; ExceptionOnError: boolean
begin
writeln('ResolveSymLinks ToDo ',Filename,' ',ExceptionOnError);
Result:=Filename;
raise Exception.Create('ResolveSymLinks ToDo');
end;
function FileIsWritable(const AFilename: string): boolean;
begin
writeln('FileIsWritable ToDo ',AFilename);
Result := false;
raise Exception.Create('FileIsWritable ToDo');
end;
function GetEnvironmentVariableCountPJ: Integer;
@ -123,6 +127,11 @@ begin
Result:=GetEnvironmentVariable(EnvVar);
end;
function GetConsoleTextEncoding: string;
begin
Result:=GetDefaultTextEncoding;
end;
procedure InitPlatform;
begin

View File

@ -2801,7 +2801,7 @@ End.
<li>%date%: current date as string literal, '[yyyy/mm/dd]'</li>
<li>%time%: current time as string literal, 'hh:mm:ss'</li>
<li>%line%: current source line number as string literal, e.g. '123'</li>
<li>%currentroutine%: short name of current routine as string literal</li>
<li>%currentroutine%: name of current routine as string literal</li>
<li>%pas2jstarget%, %pas2jstargetos%, %fpctarget%, %fpctargetos%: target os as string literal, e.g. 'Browser'</li>
<li>%pas2jstargetcpu%, %fpctargetcpu%: target cpu as string literal, e.g. 'ECMAScript5'</li>
<li>%pas2jsversion%, %fpcversion%: compiler version as strnig literal, e.g. '1.0.2'</li>