From ee8215e2ed1990b30e3fcebb5f9c32c16d5b83e7 Mon Sep 17 00:00:00 2001 From: Mattias Gaertner Date: Sun, 28 Oct 2018 18:30:48 +0000 Subject: [PATCH] pastojs: adapted pas2jscompiler for pas2js git-svn-id: trunk@40072 - --- packages/fcl-js/src/jssrcmap.pas | 12 +- packages/fcl-js/src/jswriter.pp | 7 +- packages/fcl-json/src/fpjson.pp | 20 +- packages/pastojs/src/pas2jscompiler.pp | 382 ++++++++++++++---------- packages/pastojs/src/pas2jsfilecache.pp | 21 +- 5 files changed, 267 insertions(+), 175 deletions(-) diff --git a/packages/fcl-js/src/jssrcmap.pas b/packages/fcl-js/src/jssrcmap.pas index 91509fb4dd..b1e55264c3 100644 --- a/packages/fcl-js/src/jssrcmap.pas +++ b/packages/fcl-js/src/jssrcmap.pas @@ -140,8 +140,8 @@ type function ToJSON: TJSONObject; virtual; function ToString: string; override; procedure LoadFromJSON(Obj: TJSONObject); virtual; + procedure SaveToStream(aStream: TFPJSStream); virtual; {$ifdef HasStreams} - procedure SaveToStream(aStream: TStream); virtual; procedure LoadFromStream(aStream: TStream); virtual; procedure SaveToFile(Filename: string); virtual; procedure LoadFromFile(Filename: string); virtual; @@ -1079,21 +1079,27 @@ begin ParseMappings(aMappings); end; -{$ifdef HasStreams} -procedure TSourceMap.SaveToStream(aStream: TStream); +procedure TSourceMap.SaveToStream(aStream: TFPJSStream); var Obj: TJSONObject; begin Obj:=ToJSON; try if smoSafetyHeader in Options then + begin + {$ifdef pas2js} + aStream.push(DefaultSrcMapHeader); + {$else} aStream.Write(DefaultSrcMapHeader[1],length(DefaultSrcMapHeader)); + {$endif} + end; Obj.DumpJSON(aStream); finally Obj.Free; end; end; +{$ifdef HasStreams} procedure TSourceMap.LoadFromStream(aStream: TStream); var s: string; diff --git a/packages/fcl-js/src/jswriter.pp b/packages/fcl-js/src/jswriter.pp index 97e52bba92..bf23bfd0c4 100644 --- a/packages/fcl-js/src/jswriter.pp +++ b/packages/fcl-js/src/jswriter.pp @@ -99,11 +99,13 @@ Type end; {$endif} + TBufferWriter_Buffer = Array of {$ifdef fpc}byte{$else}string{$endif}; + { TBufferWriter } TBufferWriter = Class(TTextWriter) private type - TBuffer = Array of {$ifdef fpc}byte{$else}string{$endif}; + TBuffer = TBufferWriter_Buffer; private FBufPos, FCapacity: Cardinal; @@ -129,6 +131,9 @@ Type Procedure SaveToFile(Const AFileName : String); Property Buffer : Pointer Read GetBuffer; {$endif} + {$ifdef pas2js} + Property Buffer: TBufferWriter_Buffer read FBuffer; + {$endif} Property BufferLength : Integer Read GetBufferLength; Property Capacity : Cardinal Read GetCapacity Write SetCapacity; Property AsString : TJSWriterString Read GetAsString; diff --git a/packages/fcl-json/src/fpjson.pp b/packages/fcl-json/src/fpjson.pp index c7993b50f0..71e94abf76 100644 --- a/packages/fcl-json/src/fpjson.pp +++ b/packages/fcl-json/src/fpjson.pp @@ -30,7 +30,6 @@ uses contnrs; type - TJSONtype = (jtUnknown, jtNumber, jtString, jtBoolean, jtNull, jtArray, jtObject); TJSONInstanceType = ( jitUnknown, @@ -52,9 +51,11 @@ type TJSONCharType = AnsiChar; PJSONCharType = ^TJSONCharType; TJSONVariant = variant; + TFPJSStream = TStream; {$else} TJSONCharType = char; TJSONVariant = jsvalue; + TFPJSStream = TJSArray; {$endif} TFormatOption = (foSingleLineArray, // Array without CR/LF : all on one line foSingleLineObject, // Object without CR/LF : all on one line @@ -142,9 +143,7 @@ Type public Constructor Create; virtual; Procedure Clear; virtual; Abstract; - {$ifdef fpc} - Procedure DumpJSON(S : TStream); - {$endif} + Procedure DumpJSON(S : TFPJSStream); // Get enumerator function GetEnumerator: TBaseJSONEnumerator; virtual; Function FindPath(Const APath : TJSONStringType) : TJSONdata; @@ -1272,14 +1271,16 @@ begin Clear; end; -{$ifdef fpc} -procedure TJSONData.DumpJSON(S: TStream); +procedure TJSONData.DumpJSON(S: TFPJSStream); Procedure W(T : String); - begin - if (T<>'') then - S.WriteBuffer(T[1],Length(T)*SizeOf(Char)); + if T='' then exit; + {$ifdef pas2js} + S.push(T); + {$else} + S.WriteBuffer(T[1],Length(T)*SizeOf(Char)); + {$endif} end; Var @@ -1318,7 +1319,6 @@ begin W(AsJSON) end; end; -{$endif} class function TJSONData.GetCompressedJSON: Boolean; {$ifdef fpc}static;{$endif} begin diff --git a/packages/pastojs/src/pas2jscompiler.pp b/packages/pastojs/src/pas2jscompiler.pp index 31fb68b055..0275611e06 100644 --- a/packages/pastojs/src/pas2jscompiler.pp +++ b/packages/pastojs/src/pas2jscompiler.pp @@ -20,7 +20,7 @@ interface uses {$IFDEF Pas2js} - NodeJSFS, + JS, NodeJSFS, {$ENDIF} Classes, SysUtils, RtlConsts, contnrs, jstree, jswriter, JSSrcMap, @@ -2459,7 +2459,11 @@ var var DestFilename, DestDir, Src, MapFilename: String; aJSWriter: TJSWriter; - ms: TMemoryStream; + {$IFDEF Pas2js} + buf: TJSArray; + {$ELSE} + buf: TMemoryStream; + {$ENDIF} begin //writeln('TPas2jsCompiler.WriteJSFiles ',aFile.PasFilename,' Need=',aFile.NeedBuild,' Checked=',Checked.Find(aFile)<>nil); if (aFile.JSModule=nil) or (not aFile.NeedBuild) then exit; @@ -2502,8 +2506,10 @@ begin aJSWriter.WriteJS(aFile.JSModule); except on E: Exception do begin + {$IFDEF FPC} if ShowDebug then Log.LogExceptionBackTrace; + {$ENDIF} Log.LogPlain('[20180204193420] Error while creating JavaScript "'+FileCache.FormatPath(DestFilename)+'": '+E.Message); Terminate(ExitCodeErrorInternal); end; @@ -2521,11 +2527,15 @@ begin // write to stdout if FreeWriter then begin + {$IFDEF HasStdErr} Log.WriteMsgToStdErr:=false; + {$ENDIF} try Log.LogRaw(aFileWriter.AsString); finally + {$IFDEF HasStdErr} Log.WriteMsgToStdErr:=coWriteMsgToStdErr in Options; + {$ENDIF} end; end; end else if FreeWriter then @@ -2553,33 +2563,58 @@ begin // write js try - ms:=TMemoryStream.Create; + {$IFDEF Pas2js} + buf:=TJSArray.new; + {$ELSE} + buf:=TMemoryStream.Create; + {$ENDIF} try + {$IFDEF FPC_HAS_CPSTRING} // UTF8-BOM if (Log.Encoding='') or (Log.Encoding='utf8') then begin Src:=String(UTF8BOM); - ms.Write(Src[1],length(Src)); + buf.Write(Src[1],length(Src)); end; + {$ENDIF} // JS source - ms.Write(aFileWriter.Buffer^,aFileWriter.BufferLength); + {$IFDEF Pas2js} + buf:=TJSArray(aFileWriter.Buffer).slice(); + {$ELSE} + buf.Write(aFileWriter.Buffer^,aFileWriter.BufferLength); + {$ENDIF} // source map comment if aFileWriter.SrcMap<>nil then begin Src:='//# sourceMappingURL='+ExtractFilename(MapFilename)+LineEnding; - ms.Write(Src[1],length(Src)); + {$IFDEF Pas2js} + buf.push(Src); + {$ELSE} + buf.Write(Src[1],length(Src)); + {$ENDIF} end; - ms.Position:=0; - FileCache.SaveToFile(ms,DestFilename); + {$IFDEF Pas2js} + {$ELSE} + buf.Position:=0; + {$ENDIF} + FileCache.SaveToFile(buf,DestFilename); finally - ms.Free; + {$IFDEF Pas2js} + buf:=nil; + {$ELSE} + buf.Free; + {$ENDIF} end; except on E: Exception do begin + {$IFDEF FPC} if ShowDebug then Log.LogExceptionBackTrace; if E.Message<>SafeFormat(SFCreateError,[DestFileName]) then Log.LogPlain('Error: '+E.Message); + {$ELSE} + Log.LogPlain('Error: '+E.Message); + {$ENDIF} Log.LogMsg(nUnableToWriteFile,[QuoteStr(FileCache.FormatPath(DestFilename))]); Terminate(ExitCodeWriteError); end; @@ -2592,21 +2627,36 @@ begin not (coShowLineNumbers in Options)); FinishSrcMap(aFileWriter.SrcMap); try - ms:=TMemoryStream.Create; + {$IFDEF Pas2js} + buf:=TJSArray.new; + {$ELSE} + buf:=TMemoryStream.Create; + {$ENDIF} try // Note: No UTF-8 BOM in source map, Chrome 59 gives an error - aFileWriter.SrcMap.SaveToStream(ms); - ms.Position:=0; - FileCache.SaveToFile(ms,MapFilename); + aFileWriter.SrcMap.SaveToStream(buf); + {$IFDEF Pas2js} + {$ELSE} + buf.Position:=0; + {$ENDIF} + FileCache.SaveToFile(buf,MapFilename); finally - ms.Free; + {$IFDEF Pas2js} + buf:=nil; + {$ELSE} + buf.Free; + {$ENDIF} end; except on E: Exception do begin + {$IFDEF FPC} if ShowDebug then Log.LogExceptionBackTrace; if E.Message<>SafeFormat(SFCreateError,[DestFileName]) then Log.LogPlain('Error: '+E.Message); + {$ELSE} + Log.LogPlain('Error: '+E.Message); + {$ENDIF} Log.LogMsg(nUnableToWriteFile,[QuoteStr(FileCache.FormatPath(MapFilename))]); Terminate(ExitCodeWriteError); end; @@ -2853,7 +2903,9 @@ end; procedure TPas2jsCompiler.SetWriteMsgToStdErr(const AValue: boolean); begin SetOption(coWriteMsgToStdErr,AValue); + {$IFDEF HasStdErr} Log.WriteMsgToStdErr:=AValue; + {$ENDIF} end; procedure TPas2jsCompiler.AddDefinesForTargetPlatform; @@ -2911,14 +2963,14 @@ const IdentChars = ['a'..'z','A'..'Z','_','0'..'9']; var Line: String; - p, StartP: PChar; + l, p, StartP: integer; function GetWord: String; begin StartP:=p; - while (p^ in IdentChars) or (p^>#127) do inc(p); - Result:=copy(Line,StartP-PChar(Line)+1,p-StartP); - while p^ in [' ',#9] do inc(p); + while (p<=l) and ((Line[p] in IdentChars) or (Line[p]>#127)) do inc(p); + Result:=copy(Line,StartP,p-StartP); + while (p<=l) and (Line[p] in [' ',#9]) do inc(p); end; procedure DebugCfgDirective(const s: string); @@ -2951,15 +3003,16 @@ begin if ShowDebug then Log.LogMsgIgnoreFilter(nInterpretingFileOption,[QuoteStr(Line)]); if Line='' then continue; - p:=PChar(Line); - while (p^ in [' ',#9]) do inc(p); - if p^=#0 then continue; // empty line + l:=length(Line); + p:=1; + while (p<=l) and (Line[p] in [' ',#9]) do inc(p); + if l>p then continue; // empty line - if p^='#' then + if (p<=l) and (Line[p]='#') then begin // cfg directive inc(p); - if p^ in [#0,#9,' ','-'] then continue; // comment + if (p<=l) and (Line[p] in [#0,#9,' ','-']) then continue; // comment Directive:=lowercase(GetWord); case Directive of 'ifdef','ifndef': @@ -2987,7 +3040,7 @@ begin inc(IfLvl); if Skip=skipNone then begin - Expr:=copy(Line,p-PChar(Line)+1,length(Line)); + Expr:=copy(Line,p,length(Line)); if ConditionEvaluator.Eval(Expr) then begin // execute block @@ -3031,7 +3084,7 @@ begin if (Skip=skipIf) and (IfLvl=SkipLvl) then begin // if-block was skipped -> try this elseif - Expr:=copy(Line,p-PChar(Line)+1,length(Line)); + Expr:=copy(Line,p,length(Line)); if ConditionEvaluator.Eval(Expr) then begin // execute elseif block @@ -3067,7 +3120,7 @@ begin end; end; 'error': - ParamFatal('user defined: '+copy(Line,p-PChar(Line)+1,length(Line))) + ParamFatal('user defined: '+copy(Line,p,length(Line))) else if Skip=skipNone then CfgSyntaxError('unknown directive "#'+Directive+'"') @@ -3077,7 +3130,7 @@ begin end else if Skip=skipNone then begin // option line - Line:=String(p); + Line:=copy(Line,p,length(Line)); ReadParam(Line,false,false); end; end; @@ -3939,7 +3992,13 @@ begin FreeStuff; except on E: Exception do + begin + {$IFDEF Pas2js} + Log.LogRaw('TPas2jsCompiler.Destroy '+E.Message); + {$ELSE} Log.LogExceptionBackTrace; + {$ENDIF} + end; end else FreeStuff; @@ -4039,7 +4098,9 @@ begin ClearDefines; TStringList(FDefines).Sorted:=True; + {$IFDEF FPC} TStringList(FDefines).Duplicates:=dupError; + {$ENDIF} AddDefine('PAS2JS'); AddDefine('PAS2JS_FULLVERSION',IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease)); @@ -4126,8 +4187,10 @@ begin on E: ECompilerTerminate do begin end else begin + {$IFDEF FPC} if ShowDebug then Log.LogExceptionBackTrace; + {$ENDIF} raise; end; end; @@ -4138,17 +4201,18 @@ const MaxLineLen = 78; Indent = 12; - procedure l(s: string); + procedure w(s: string); var - p, LastCharStart, WordBreak: PChar; + l, p, LastCharStart, WordBreak: integer; Len: integer; CodePointCount: Integer; procedure InitLine; begin - p:=PChar(s); + l:=length(s); + p:=1; LastCharStart:=p; - WordBreak:=nil; + WordBreak:=0; CodePointCount:=0; end; @@ -4159,19 +4223,23 @@ const exit; end; InitLine; - repeat - case p^ of - #0: - if p-PChar(s)=length(s) then - break - else - inc(p); - 'a'..'z','A'..'Z','0'..'9','_','-','.',',','"','''','`',#128..#255: + while p<=l do + begin + case s[p] of + 'a'..'z','A'..'Z','0'..'9','_','-','.',',','"','''','`', + #128..high(char) : begin LastCharStart:=p; + {$IFDEF FPC_HAS_CPSTRING} Len:=UTF8CharacterStrictLength(p); if Len=0 then Len:=1; inc(p,Len); + {$ELSE} + if (p=MaxLineLen then begin - if (WordBreak=nil) or (WordBreak-PChar(s)'' then begin - l('Usage: '+CompilerExe+' '); + w('Usage: '+CompilerExe+' '); end else begin - l('Usage: pas2js '); + w('Usage: pas2js '); end; Log.LogLn; - l('Options:'); - l('Put + after a boolean switch option to enable it, - to disable it'); - l(' @ : Read compiler options from file in addition to the default '+DefaultConfigFile); - l(' -B : Rebuild all'); - l(' -d : Defines the symbol . Optional: -d:='); - l(' -i : Write information and halt. is a combination of the following:'); - l(' -iD : Write compiler date'); - l(' -iSO : Write compiler OS'); - l(' -iSP : Write compiler host processor'); - l(' -iTO : Write target platform'); - l(' -iTP : Write target processor'); - l(' -iV : Write short compiler version'); - l(' -iW : Write full compiler version'); - l(' -ic : Write list of supported JS processors usable by -P'); - l(' -io : Write list of supported optimizations usable by -Oo'); - l(' -it : Write list of supported targets usable by -T'); - l(' -C : Code generation options. is a combination of the following letters:'); + w('Options:'); + w('Put + after a boolean switch option to enable it, - to disable it'); + w(' @ : Read compiler options from file in addition to the default '+DefaultConfigFile); + w(' -B : Rebuild all'); + w(' -d : Defines the symbol . Optional: -d:='); + w(' -i : Write information and halt. is a combination of the following:'); + w(' -iD : Write compiler date'); + w(' -iSO : Write compiler OS'); + w(' -iSP : Write compiler host processor'); + w(' -iTO : Write target platform'); + w(' -iTP : Write target processor'); + w(' -iV : Write short compiler version'); + w(' -iW : Write full compiler version'); + w(' -ic : Write list of supported JS processors usable by -P'); + w(' -io : Write list of supported optimizations usable by -Oo'); + w(' -it : Write list of supported targets usable by -T'); + w(' -C : Code generation options. is a combination of the following letters:'); // -C3 Turn on ieee error checking for constants - l(' o : Overflow checking of integer operations'); + w(' o : Overflow checking of integer operations'); // -CO Check for possible overflow of integer operations - l(' r : Range checking'); - l(' R : Object checks. Verify method calls and object type casts.'); - l(' -F... Set file names and paths:'); - l(' -Fe : Redirect output to file . UTF-8 encoded.'); - l(' -FE : Set main output path to '); - l(' -Fi : Add to include paths'); - l(' -FN : add to namespaces. Namespaces with trailing - are removed.'); - l(' Delphi calls this flag "unit scope names".'); - //l(' -Fr : Load error message file '); - l(' -Fu : Add to unit paths'); - l(' -FU : Set unit output path to '); - l(' -I : Add to include paths, same as -Fi'); - l(' -J... Extra options of pas2js'); - l(' -Jc : Write all JavaScript concatenated into the output file'); - l(' -Je : Encode messages as .'); - l(' -Jeconsole : Console codepage. This is the default.'); - l(' -Jesystem : System codepage. On non Windows console and system are the same.'); - l(' -Jeutf-8 : Unicode UTF-8. Default when using -Fe.'); - l(' -JeJSON : Output compiler messages as JSON. Logo etc are outputted as-is.'); - l(' -Ji : Insert JS file into main JS file. E.g. -Jirtl.js. Can be given multiple times. To remove a file name append a minus, e.g. -Jirtl.js-.'); - l(' -Jl : lower case identifiers'); - l(' -Jm : generate source maps'); - l(' -Jmsourceroot= : use x as "sourceRoot", prefix URL for source file names.'); - l(' -Jmbasedir= : write source file names relative to directory x.'); - l(' -Jminclude : include Pascal sources in source map.'); - l(' -Jmxssiheader : start source map with XSSI protection )]}'', default.'); - l(' -Jm- : disable generating source maps'); - l(' -Jo : Enable or disable extra option. The x is case insensitive:'); - l(' -JoSearchLikeFPC : search source files like FPC, default: search case insensitive.'); - l(' -JoUseStrict : add "use strict" to modules, default.'); - l(' -JoCheckVersion- : do not add rtl version check, default.'); - l(' -JoCheckVersion=main : insert rtl version check into main.'); - l(' -JoCheckVersion=system : insert rtl version check into system unit init.'); - l(' -JoCheckVersion=unit : insert rtl version check into every unit init.'); - l(' -Ju : Add to foreign unit paths. Foreign units are not compiled.'); + w(' r : Range checking'); + w(' R : Object checks. Verify method calls and object type casts.'); + w(' -F... Set file names and paths:'); + w(' -Fe : Redirect output to file . UTF-8 encoded.'); + w(' -FE : Set main output path to '); + w(' -Fi : Add to include paths'); + w(' -FN : add to namespaces. Namespaces with trailing - are removed.'); + w(' Delphi calls this flag "unit scope names".'); + //w(' -Fr : Load error message file '); + w(' -Fu : Add to unit paths'); + w(' -FU : Set unit output path to '); + w(' -I : Add to include paths, same as -Fi'); + w(' -J... Extra options of pas2js'); + w(' -Jc : Write all JavaScript concatenated into the output file'); + w(' -Je : Encode messages as .'); + w(' -Jeconsole : Console codepage. This is the default.'); + w(' -Jesystem : System codepage. On non Windows console and system are the same.'); + w(' -Jeutf-8 : Unicode UTF-8. Default when using -Fe.'); + w(' -JeJSON : Output compiler messages as JSON. Logo etc are outputted as-is.'); + w(' -Ji : Insert JS file into main JS file. E.g. -Jirtl.js. Can be given multiple times. To remove a file name append a minus, e.g. -Jirtl.js-.'); + w(' -Jl : lower case identifiers'); + w(' -Jm : generate source maps'); + w(' -Jmsourceroot= : use x as "sourceRoot", prefix URL for source file names.'); + w(' -Jmbasedir= : write source file names relative to directory x.'); + w(' -Jminclude : include Pascal sources in source map.'); + w(' -Jmxssiheader : start source map with XSSI protection )]}'', default.'); + w(' -Jm- : disable generating source maps'); + w(' -Jo : Enable or disable extra option. The x is case insensitive:'); + w(' -JoSearchLikeFPC : search source files like FPC, default: search case insensitive.'); + w(' -JoUseStrict : add "use strict" to modules, default.'); + w(' -JoCheckVersion- : do not add rtl version check, default.'); + w(' -JoCheckVersion=main : insert rtl version check into main.'); + w(' -JoCheckVersion=system : insert rtl version check into system unit init.'); + w(' -JoCheckVersion=unit : insert rtl version check into every unit init.'); + w(' -Ju : Add to foreign unit paths. Foreign units are not compiled.'); {$IFDEF HasPas2jsFiler} if PrecompileFormats.Count>0 then begin @@ -4271,58 +4340,58 @@ begin l(' -JU- : Disable prior -JU option. Do not create precompiled units.'); end; {$ENDIF} - l(' -l : Write logo'); - l(' -MDelphi: Delphi 7 compatibility mode'); - l(' -MObjFPC: FPC''s Object Pascal compatibility mode (default)'); - l(' -NS : obsolete: add to namespaces. Same as -FN'); - l(' -n : Do not read the default config files'); - l(' -o : Change main JavaScript file to , "." means stdout'); - l(' -O : Optimizations:'); - l(' -O- : Disable optimizations'); - l(' -O1 : Level 1 optimizations (quick and debugger friendly)'); - //l(' -O2 : Level 2 optimizations (Level 1 + not debugger friendly)'); - l(' -Oo : Enable or disable optimization. The x is case insensitive:'); - l(' -OoEnumNumbers[-] : write enum value as number instead of name. Default in -O1.'); - l(' -OoRemoveNotUsedPrivates[-] : Default is enabled'); - l(' -OoRemoveNotUsedDeclarations[-] : Default enabled for programs with -Jc'); - l(' -P : Set target processor. Case insensitive:'); - l(' -Pecmascript5 : default'); - l(' -Pecmascript6'); - l(' -S : Syntax options. is a combination of the following letters:'); - l(' a : Turn on assertions'); - l(' c : Support operators like C (*=,+=,/= and -=)'); - l(' d : Same as -Mdelphi'); - l(' m : Enables macro replacements'); - l(' 2 : Same as -Mobjfpc (default)'); - l(' -SI : Set interface style to '); - l(' -SIcom : COM compatible interface (default)'); - l(' -SIcorba : CORBA compatible interface'); - l(' -T : Set target platform'); - l(' -Tbrowser : default'); - l(' -Tnodejs : add pas.run(), includes -Jc'); - l(' -u : Undefines the symbol '); - l(' -v : Be verbose. is a combination of the following letters:'); - l(' e : Show errors (default)'); - l(' w : Show warnings'); - l(' n : Show notes'); - l(' h : Show hints'); - l(' i : Show info'); - l(' l : Show line numbers, needs -vi'); - l(' a : Show everything'); - l(' 0 : Show nothing (except errors)'); - l(' b : Show file names with full path'); - l(' c : Show conditionals'); - l(' t : Show tried/used files'); - l(' d : Show debug notes and info, enables -vni'); - l(' q : Show message numbers'); - l(' x : Show used tools'); - l(' v : Write pas2jsdebug.log with lots of debugging info'); - l(' z : Write messages to stderr, -o. still uses stdout.'); - l(' -vm,: Do not show messages numbered and .'); - l(' -? : Show this help'); - l(' -h : Show this help'); + w(' -l : Write logo'); + w(' -MDelphi: Delphi 7 compatibility mode'); + w(' -MObjFPC: FPC''s Object Pascal compatibility mode (default)'); + w(' -NS : obsolete: add to namespaces. Same as -FN'); + w(' -n : Do not read the default config files'); + w(' -o : Change main JavaScript file to , "." means stdout'); + w(' -O : Optimizations:'); + w(' -O- : Disable optimizations'); + w(' -O1 : Level 1 optimizations (quick and debugger friendly)'); + //w(' -O2 : Level 2 optimizations (Level 1 + not debugger friendly)'); + w(' -Oo : Enable or disable optimization. The x is case insensitive:'); + w(' -OoEnumNumbers[-] : write enum value as number instead of name. Default in -O1.'); + w(' -OoRemoveNotUsedPrivates[-] : Default is enabled'); + w(' -OoRemoveNotUsedDeclarations[-] : Default enabled for programs with -Jc'); + w(' -P : Set target processor. Case insensitive:'); + w(' -Pecmascript5 : default'); + w(' -Pecmascript6'); + w(' -S : Syntax options. is a combination of the following letters:'); + w(' a : Turn on assertions'); + w(' c : Support operators like C (*=,+=,/= and -=)'); + w(' d : Same as -Mdelphi'); + w(' m : Enables macro replacements'); + w(' 2 : Same as -Mobjfpc (default)'); + w(' -SI : Set interface style to '); + w(' -SIcom : COM compatible interface (default)'); + w(' -SIcorba : CORBA compatible interface'); + w(' -T : Set target platform'); + w(' -Tbrowser : default'); + w(' -Tnodejs : add pas.run(), includes -Jc'); + w(' -u : Undefines the symbol '); + w(' -v : Be verbose. is a combination of the following letters:'); + w(' e : Show errors (default)'); + w(' w : Show warnings'); + w(' n : Show notes'); + w(' h : Show hints'); + w(' i : Show info'); + w(' l : Show line numbers, needs -vi'); + w(' a : Show everything'); + w(' 0 : Show nothing (except errors)'); + w(' b : Show file names with full path'); + w(' c : Show conditionals'); + w(' t : Show tried/used files'); + w(' d : Show debug notes and info, enables -vni'); + w(' q : Show message numbers'); + w(' x : Show used tools'); + w(' v : Write pas2jsdebug.log with lots of debugging info'); + w(' z : Write messages to stderr, -o. still uses stdout.'); + w(' -vm,: Do not show messages numbered and .'); + w(' -? : Show this help'); + w(' -h : Show this help'); Log.LogLn; - l('Macros: Format is $Name, $Name$ or $Name()'); + w('Macros: Format is $Name, $Name$ or $Name()'); for i:=0 to ParamMacros.Count-1 do begin ParamMacro:=ParamMacros[i]; Log.LogRaw([' $',ParamMacro.Name,BoolToStr(ParamMacro.CanHaveParams,'()',''),': ',ParamMacro.Description]); @@ -4505,9 +4574,11 @@ begin if (UnitFilename='') or not DirectoryCache.FileExists(UnitFilename) then begin + {$IFDEF HasPas2jsFiler} if aFormat=nil then Log.LogMsg(nSourceFileNotFound,[QuoteStr(UnitFilename)]) else + {$ENDIF} Log.LogMsg(nUnitFileNotFound,[QuoteStr(UnitFilename)]); Terminate(ExitCodeFileNotFound); end; @@ -4519,7 +4590,7 @@ begin Terminate(ExitCodeFileNotFound); end; - aFile:=TPas2jsCompilerFile.Create(Self,UnitFilename,aFormat); + aFile:=TPas2jsCompilerFile.Create(Self,UnitFilename{$IFDEF HasPas2jsFiler},aFormat{$ENDIF}); if UseUnitName<>'' then begin {$IFDEF VerboseSetPasUnitName} @@ -4549,13 +4620,16 @@ begin if ShowDebug then Log.LogPlain(['Debug: Opening file "',UnitFilename,'"...']); - if aFile.PCUFormat=nil then + {$IFDEF HasPas2jsFiler} + if aFile.PCUFormat<>nil then + begin + aFile.FileResolver.BaseDirectory:=ExtractFilePath(UnitFilename); + aFile.CreatePCUReader; + end else + {$ENDIF} begin // open file (beware: this changes FileResolver.BaseDirectory) aFile.OpenFile(UnitFilename); - end else begin - aFile.FileResolver.BaseDirectory:=ExtractFilePath(UnitFilename); - aFile.CreatePCUReader; end; end; diff --git a/packages/pastojs/src/pas2jsfilecache.pp b/packages/pastojs/src/pas2jsfilecache.pp index dd475a0251..8555e31fa1 100644 --- a/packages/pastojs/src/pas2jsfilecache.pp +++ b/packages/pastojs/src/pas2jsfilecache.pp @@ -31,6 +31,7 @@ uses {$ENDIF} {$ENDIF} Classes, SysUtils, + fpjson, PScanner, PasUseAnalyzer, PasResolver, FPPJsSrcMap, {$IFDEF HasPas2jsFiler} Pas2JsFiler, @@ -339,9 +340,7 @@ type procedure GetListing(const aDirectory: string; var Files: TStrings; FullPaths: boolean = true); procedure RaiseDuplicateFile(aFilename: string); - {$IFDEF HasStreams} - procedure SaveToFile(ms: TMemoryStream; Filename: string); - {$ENDIF} + procedure SaveToFile(ms: TFPJSStream; Filename: string); function ExpandDirectory(const Filename, BaseDir: string): string; public property AllJSIntoMainJS: Boolean read GetAllJSIntoMainJS write SetAllJSIntoMainJS; @@ -2166,15 +2165,19 @@ begin end; end; -{$IFDEF HasStreams} -procedure TPas2jsFilesCache.SaveToFile(ms: TMemoryStream; Filename: string); +procedure TPas2jsFilesCache.SaveToFile(ms: TFPJSStream; Filename: string); var s: string; - l: Int64; i: Integer; + {$IFDEF FPC} + l: TMaxPrecInt; + {$ENDIF} begin if Assigned(OnWriteFile) then begin + {$IFDEF Pas2js} + s:=ms.join(''); + {$ELSE} l:=ms.Size-ms.Position; if l>0 then begin @@ -2184,9 +2187,13 @@ begin end else s:=''; + {$ENDIF} OnWriteFile(Filename,s); end else begin + {$IFDEF Pas2js} + raise Exception.Create('TPas2jsFilesCache.SaveToFile TODO '+Filename); + {$ELSE} try ms.SaveToFile(Filename); except @@ -2201,9 +2208,9 @@ begin raise; end; end; + {$ENDIF} end; end; -{$ENDIF} function TPas2jsFilesCache.ExpandDirectory(const Filename, BaseDir: string ): string;