pastojs: formatting

git-svn-id: trunk@37983 -
This commit is contained in:
Mattias Gaertner 2018-01-17 10:57:49 +00:00
parent 3e82c18a82
commit a2164135f1
7 changed files with 378 additions and 190 deletions

View File

@ -592,7 +592,8 @@ begin
raise EPas2jsMacro.Create('macro cycle detected: "'+s+'"');
p:=1;
while p<length(s) do begin
if (s[p]='$') and (s[p+1] in ['_','a'..'z','A'..'Z']) then begin
if (s[p]='$') and (s[p+1] in ['_','a'..'z','A'..'Z']) then
begin
StartP:=p;
inc(p,2);
while (p<=length(s)) and (s[p] in ['_','a'..'z','A'..'Z','0'..'9']) do
@ -602,7 +603,8 @@ begin
if Macro=nil then
raise EPas2jsMacro.Create('macro not found "'+MacroName+'" in "'+s+'"');
NewValue:='';
if Macro.CanHaveParams and (p<=length(s)) and (s[p]='(') then begin
if Macro.CanHaveParams and (p<=length(s)) and (s[p]='(') then
begin
// read NewValue
inc(p);
ParamStartP:=p;
@ -613,7 +615,8 @@ begin
case s[p] of
'(': inc(BracketLvl);
')':
if BracketLvl=1 then begin
if BracketLvl=1 then
begin
NewValue:=copy(s,ParamStartP,p-ParamStartP);
break;
end else begin
@ -623,7 +626,8 @@ begin
until false;
end else if (p<=length(s)) and (s[p]='$') then
inc(p);
if Assigned(Macro.OnSubstitute) then begin
if Assigned(Macro.OnSubstitute) then
begin
if not Macro.OnSubstitute(Sender,NewValue,Lvl+1) then
raise EPas2jsMacro.Create('macro "'+MacroName+'" failed in "'+s+'"');
end else
@ -670,7 +674,8 @@ begin
FreeAndNil(FUsedBy[ub]);
FreeAndNil(FJSModule);
FreeAndNil(FConverter);
if FPasModule<>nil then begin
if FPasModule<>nil then
begin
FPasModule.Release;
FPasModule:=nil;
end;
@ -731,7 +736,8 @@ begin
Parser.Log:=Log;
PascalResolver.P2JParser:=Parser;
if not IsMainFile then begin
if not IsMainFile then
begin
aUnitName:=ExtractFilenameOnly(PasFilename);
if CompareText(aUnitName,'system')=0 then
Parser.ImplicitUses.Clear;
@ -746,9 +752,11 @@ begin
if (Element.ClassType=TPasUnitModule) or (Element.ClassType=TPasModule) then
begin
SrcName:=Element.Name;
if IsMainFile then begin
if IsMainFile then
begin
// main source is an unit
if PasUnitName='' then begin
if PasUnitName='' then
begin
{$IFDEF VerboseSetPasUnitName}
writeln('TPas2jsCompilerFile.OnPasTreeCheckSrcName ',PasFilename,' Name=',Element.Name,' IsMainFile=',IsMainFile);
{$ENDIF}
@ -867,7 +875,8 @@ var
aFilename: String;
aRow, aColumn: integer;
begin
if E.PasElement<>nil then begin
if E.PasElement<>nil then
begin
aFilename:=E.PasElement.SourceFilename;
PascalResolver.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,aRow,aColumn);
end else begin
@ -884,7 +893,8 @@ var
aFilename: String;
aRow, aColumn: integer;
begin
if E.PasElement<>nil then begin
if E.PasElement<>nil then
begin
aFilename:=E.PasElement.SourceFilename;
PascalResolver.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,aRow,aColumn);
Log.Log(E.MsgType,E.Message,E.MsgNumber,aFilename,aRow,aColumn);
@ -903,7 +913,8 @@ end;
procedure TPas2jsCompilerFile.HandleException(E: Exception);
begin
if E is EScannerError then begin
if E is EScannerError then
begin
Log.Log(Scanner.LastMsgType,Scanner.LastMsg,Scanner.LastMsgNumber,
Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
Compiler.Terminate(ExitCodeSyntaxError);
@ -923,7 +934,8 @@ var
Line, Col: integer;
Filename: String;
begin
if (El<>nil) then begin
if (El<>nil) then
begin
Filename:=El.SourceFilename;
TPasResolver.UnmangleSourceLineNumber(El.SourceLinenumber,Line,Col);
end else begin
@ -942,7 +954,8 @@ end;
procedure TPas2jsCompilerFile.ParserFinished;
begin
try
if ShowDebug then begin
if ShowDebug then
begin
Log.LogRaw('Pas-Module:');
Log.LogRaw(PasModule.GetDeclaration(true));
end;
@ -1053,15 +1066,18 @@ begin
Result:=nil;
aModule:=GetCurPasModule;
if aModule=nil then exit;
if aModule.ClassType=TPasModule then begin
if aModule.ClassType=TPasModule then
begin
IntfSection:=TPasModule(aModule).InterfaceSection;
if IntfSection<>nil then
Result:=IntfSection.UsesClause;
end else if aModule.ClassType=TPasProgram then begin
end else if aModule.ClassType=TPasProgram then
begin
PrgSection:=TPasProgram(aModule).ProgramSection;
if PrgSection<>nil then
Result:=PrgSection.UsesClause;
end else if aModule.ClassType=TPasLibrary then begin
end else if aModule.ClassType=TPasLibrary then
begin
LibSection:=TPasLibrary(aModule).LibrarySection;
if LibSection<>nil then
Result:=LibSection.UsesClause;
@ -1112,7 +1128,8 @@ begin
if (aModule=nil) or (aModule.CustomData=nil) then exit;
if aModule.CustomData is TPas2jsCompilerFile then
Result:=TPas2jsCompilerFile(aModule.CustomData)
else if aModule.CustomData is TPasModuleScope then begin
else if aModule.CustomData is TPasModuleScope then
begin
Scope:=TPasModuleScope(aModule.CustomData);
Resolver:=NoNil(Scope.Owner) as TPas2jsCompilerResolver;
Result:=Resolver.Owner as TPas2jsCompilerFile;
@ -1126,7 +1143,8 @@ var
i: Integer;
begin
Result:=nil;
if CompareText(ExtractFilenameOnly(PasFilename),UseUnitname)=0 then begin
if CompareText(ExtractFilenameOnly(PasFilename),UseUnitname)=0 then
begin
// duplicate identifier or unit cycle
Parser.RaiseParserError(nUnitCycle,[UseUnitname]);
end;
@ -1139,11 +1157,13 @@ begin
else
RaiseInternalError(20170504161408,'internal error TPas2jsCompilerFile.FindModule PasTree.LastElement='+GetObjName(LastEl)+' '+GetObjName(LastEl.Parent));
if (Pos('.',UseUnitname)<1) then begin
if (Pos('.',UseUnitname)<1) then
begin
// generic unit -> search with namespaces
// first the default program namespace
aNameSpace:=Compiler.GetDefaultNamespace;
if aNameSpace<>'' then begin
if aNameSpace<>'' then
begin
Result:=FindUnit(aNameSpace+'.'+UseUnitname);
if Result<>nil then exit;
end;
@ -1172,14 +1192,16 @@ function TPas2jsCompilerFile.FindUnit(const UseUnitname: String): TPasModule;
begin
for i:=0 to aFile.UsedByCount[ubMainSection]-1 do begin
aParent:=aFile.UsedBy[ubMainSection,i];
if aParent=SearchFor then begin
if aParent=SearchFor then
begin
// unit cycle found
Cycle:=TFPList.Create;
Cycle.Add(aParent);
Cycle.Add(aFile);
exit(true);
end;
if FindCycle(aParent,SearchFor,Cycle) then begin
if FindCycle(aParent,SearchFor,Cycle) then
begin
Cycle.Add(aFile);
exit(true);
end;
@ -1196,7 +1218,8 @@ var
Cycle: TFPList;
CyclePath: String;
begin
if Parser.CurModule.ImplementationSection=nil then begin
if Parser.CurModule.ImplementationSection=nil then
begin
// main uses section (e.g. interface or program, not implementation)
// -> check for cycles
@ -1204,7 +1227,8 @@ var
Cycle:=nil;
try
if FindCycle(aFile,aFile,Cycle) then begin
if FindCycle(aFile,aFile,Cycle) then
begin
CyclePath:='';
for i:=0 to Cycle.Count-1 do begin
if i>0 then CyclePath+=',';
@ -1230,7 +1254,8 @@ begin
// first try registered units
aFile:=Compiler.FindUsedUnit(UseUnitname);
if aFile<>nil then begin
if aFile<>nil then
begin
// known unit
if (aFile.PasUnitName<>'') and (CompareText(aFile.PasUnitName,UseUnitname)<>0) then
begin
@ -1246,7 +1271,8 @@ begin
// search Pascal file
UsePasFilename:=FileResolver.FindUnitFileName(UseUnitname,InFilename,UseIsForeign);
if UsePasFilename='' then begin
if UsePasFilename='' then
begin
// can't find unit
exit;
end;
@ -1260,7 +1286,8 @@ begin
// load Pascal file
Compiler.LoadPasFile(UsePasFilename,UseUnitname,aFile);
if aFile=Self then begin
if aFile=Self then
begin
// unit uses itself -> cycle
Parser.RaiseParserError(nUnitCycle,[UseUnitname]);
end;
@ -1344,7 +1371,8 @@ var
begin
// check defines
i:=FDefines.IndexOf(aName);
if i>=0 then begin
if i>=0 then
begin
M:=TMacroDef(FDefines.Objects[i]);
if M=nil then
Value:=CondDirectiveBool[true]
@ -1355,7 +1383,8 @@ begin
// check modeswitches
ms:=StrToModeSwitch(aName);
if (ms<>msNone) and (ms in p2jsMode_SwitchSets[Mode]) then begin
if (ms<>msNone) and (ms in p2jsMode_SwitchSets[Mode]) then
begin
Value:=CondDirectiveBool[true];
exit(true);
end;
@ -1405,7 +1434,8 @@ begin
FreeAndNil(Checked);
// write success message
if ExitCode=0 then begin
if ExitCode=0 then
begin
Seconds:=(Now-StartTime)*86400;
Log.LogMsgIgnoreFilter(nLinesInFilesCompiled,
[IntToStr(FileCache.ReadLineCounter),IntToStr(SrcFileCount),
@ -1443,7 +1473,8 @@ function TPas2jsCompiler.MarkNeedBuilding(aFile: TPas2jsCompilerFile;
UsedFile:=TPas2jsCompilerFile.GetFile(aModule);
if UsedFile=nil then
RaiseInternalError(20171214121631,aModule.Name);
if MarkNeedBuilding(UsedFile,Checked,SrcFileCount) then begin
if MarkNeedBuilding(UsedFile,Checked,SrcFileCount) then
begin
if not aFile.NeedBuild then
Mark(nUnitNeedsCompileDueToUsedUnit,
[aFile.GetModuleName,UsedFile.GetModuleName]);
@ -1466,7 +1497,8 @@ begin
CheckUsesClause(aFile.GetPasMainUsesClause);
CheckUsesClause(aFile.GetPasImplUsesClause);
if (not aFile.NeedBuild) and (not aFile.IsForeign) then begin
if (not aFile.NeedBuild) and (not aFile.IsForeign) then
begin
// this unit can be compiled
if aFile.IsMainFile then
Mark(nUnitNeedsCompileDueToOption,[aFile.GetModuleName,'<main source file>'])
@ -1484,9 +1516,11 @@ begin
end;
end;
if aFile.NeedBuild then begin
if aFile.NeedBuild then
begin
// unit needs compile
if aFile.IsForeign then begin
if aFile.IsForeign then
begin
// ... but is forbidden to compile
Log.LogMsg(nOptionForbidsCompile,[aFile.GetModuleName]);
Terminate(ExitCodeWriteError);
@ -1555,17 +1589,20 @@ begin
for i:=0 to SrcMap.SourceCount-1 do begin
LocalFilename:=SrcMap.SourceFiles[i];
if LocalFilename='' then continue;
if SrcMapInclude then begin
if SrcMapInclude then
begin
// include source in SrcMap
aFile:=FileCache.LoadTextFile(LocalFilename);
SrcMap.SourceContents[i]:=aFile.Source;
end;
// translate local file name
if BaseDir<>'' then begin
if not TryCreateRelativePath(LocalFilename,BaseDir,true,MapFilename)
then begin
if BaseDir<>'' then
begin
if not TryCreateRelativePath(LocalFilename,BaseDir,true,MapFilename) then
begin
// e.g. file is on another partition
if not SrcMapInclude then begin
if not SrcMapInclude then
begin
Log.Log(mtError,
SafeFormat(sUnableToTranslatePathToDir,[LocalFilename,BaseDir]),
nUnableToTranslatePathToDir);
@ -1620,7 +1657,8 @@ var
begin
aFileWriter:=TPas2JSMapper.Create(4096);
FreeWriter:=true;
if SrcMapEnable then begin
if SrcMapEnable then
begin
SrcMap:=TPas2JSSrcMap.Create(ExtractFilename(aFilename));
aFileWriter.SrcMap:=SrcMap;
SrcMap.Release;// release the refcount from the Create
@ -1642,7 +1680,8 @@ begin
Checked.Add(aFile);
FreeWriter:=false;
if FileCache.AllJSIntoMainJS and (CombinedFileWriter=nil) then begin
if FileCache.AllJSIntoMainJS and (CombinedFileWriter=nil) then
begin
// create CombinedFileWriter
DestFilename:=FileCache.GetResolvedMainJSFile;
CreateFileWriter(DestFilename);
@ -1659,7 +1698,8 @@ begin
aJSWriter:=nil;
aFileWriter:=CombinedFileWriter;
try
if aFileWriter=nil then begin
if aFileWriter=nil then
begin
// create writer for this file
CreateFileWriter(DestFilename);
if aFile.IsMainFile and not FileCache.AllJSIntoMainJS then
@ -1679,10 +1719,12 @@ begin
if DoWriteJSFile(aFile.JSFilename,aFileWriter) then
exit;// descendant has written -> finished
if (aFile.JSFilename='') and (FileCache.MainJSFile='.') then begin
if (aFile.JSFilename='') and (FileCache.MainJSFile='.') then
begin
// write to stdout
Log.LogRaw(aFileWriter.AsAnsistring);
end else if FreeWriter then begin
end else if FreeWriter then
begin
// write to file
//writeln('TPas2jsCompiler.WriteJSFiles ',aFile.PasFilename,' ',aFile.JSFilename);
@ -1691,11 +1733,13 @@ begin
// check output directory
DestDir:=ChompPathDelim(ExtractFilePath(DestFilename));
if (DestDir<>'') and not DirectoryExists(DestDir) then begin
if (DestDir<>'') and not DirectoryExists(DestDir) then
begin
Log.LogMsg(nOutputDirectoryNotFound,[FileCache.FormatPath(DestDir)]);
Terminate(ExitCodeFileNotFound);
end;
if DirectoryExists(DestFilename) then begin
if DirectoryExists(DestFilename) then
begin
Log.LogMsg(nFileIsFolder,[FileCache.FormatPath(DestFilename)]);
Terminate(ExitCodeWriteError);
end;
@ -1707,14 +1751,16 @@ begin
fs:=TFileStream.Create(DestFilename,fmCreate);
try
// UTF8-BOM
if (Log.Encoding='') or (Log.Encoding='utf8') then begin
if (Log.Encoding='') or (Log.Encoding='utf8') then
begin
Src:=String(UTF8BOM);
fs.Write(Src[1],length(Src));
end;
// JS source
fs.Write(aFileWriter.Buffer^,aFileWriter.BufferLength);
// source map comment
if aFileWriter.SrcMap<>nil then begin
if aFileWriter.SrcMap<>nil then
begin
Src:='//# sourceMappingURL='+ExtractFilename(MapFilename)+LineEnding;
fs.Write(Src[1],length(Src));
end;
@ -1730,7 +1776,8 @@ begin
end;
// write source map
if aFileWriter.SrcMap<>nil then begin
if aFileWriter.SrcMap<>nil then
begin
Log.LogMsg(nWritingFile,[FileCache.FormatPath(MapFilename)],'',0,0,
not (coShowLineNumbers in Options));
FinishSrcMap(aFileWriter.SrcMap);
@ -1755,7 +1802,8 @@ begin
end;
finally
if FreeWriter then begin
if FreeWriter then
begin
if CombinedFileWriter=aFileWriter then
CombinedFileWriter:=nil;
aFileWriter.Free
@ -1915,7 +1963,8 @@ begin
while (p^ in [' ',#9]) do inc(p);
if p^=#0 then continue; // empty line
if p^='#' then begin
if p^='#' then
begin
// cfg directive
inc(p);
if p^ in [#0,#9,' ','-'] then continue; // comment
@ -1924,9 +1973,11 @@ begin
'ifdef','ifndef':
begin
inc(IfLvl);
if Skip=skipNone then begin
if Skip=skipNone then
begin
aName:=GetWord;
if IsDefined(aName)=(Directive='ifdef') then begin
if IsDefined(aName)=(Directive='ifdef') then
begin
// execute block
if ShowDebug then
DebugCfgDirective('true -> execute');
@ -1942,9 +1993,11 @@ begin
'if':
begin
inc(IfLvl);
if Skip=skipNone then begin
if Skip=skipNone then
begin
Expr:=copy(Line,p-PChar(Line)+1,length(Line));
if ConditionEvaluator.Eval(Expr) then begin
if ConditionEvaluator.Eval(Expr) then
begin
// execute block
if ShowDebug then
DebugCfgDirective('true -> execute');
@ -1963,13 +2016,15 @@ begin
CfgSyntaxError('"'+Directive+'" without ifdef');
if (Skip=skipElse) and (IfLvl=SkipLvl) then
CfgSyntaxError('"there was already an $else');;
if (Skip=skipIf) and (IfLvl=SkipLvl) then begin
if (Skip=skipIf) and (IfLvl=SkipLvl) then
begin
// if-block was skipped -> execute else block
if ShowDebug then
DebugCfgDirective('execute');
SkipLvl:=0;
Skip:=skipNone;
end else if Skip=skipNone then begin
end else if Skip=skipNone then
begin
// if-block was executed -> skip else block
if ShowDebug then
DebugCfgDirective('skip');
@ -1980,10 +2035,12 @@ begin
begin
if IfLvl=0 then
CfgSyntaxError('"'+Directive+'" without ifdef');
if (Skip=skipIf) and (IfLvl=SkipLvl) then 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));
if ConditionEvaluator.Eval(Expr) then begin
if ConditionEvaluator.Eval(Expr) then
begin
// execute elseif block
if ShowDebug then
DebugCfgDirective('true -> execute');
@ -1994,7 +2051,8 @@ begin
if ShowDebug then
DebugCfgDirective('false -> skip');
end;
end else if Skip=skipNone then begin
end else if Skip=skipNone then
begin
// if-block was executed -> skip without test
if ShowDebug then
DebugCfgDirective('no test -> skip');
@ -2006,7 +2064,8 @@ begin
if IfLvl=0 then
CfgSyntaxError('"'+Directive+'" without ifdef');
dec(IfLvl);
if IfLvl<SkipLvl then begin
if IfLvl<SkipLvl then
begin
// end block
if ShowDebug then
DebugCfgDirective('end block');
@ -2022,7 +2081,8 @@ begin
else
DebugCfgDirective('skipping unknown directive');
end;
end else if Skip=skipNone then begin
end else if Skip=skipNone then
begin
// option line
Line:=String(p);
ReadParam(Line,false,false);
@ -2063,9 +2123,11 @@ begin
end;
// then try compiler directory
if (CompilerExe<>'') then begin
if (CompilerExe<>'') then
begin
aFilename:=ExtractFilePath(CompilerExe);
if aFilename<>'' then begin
if aFilename<>'' then
begin
aFilename:=IncludeTrailingPathDelimiter(aFilename)+DefaultConfigFile;
if TryConfig(aFilename) then exit;
end;
@ -2115,7 +2177,8 @@ begin
ParamMacros.Substitute(Param,Self);
if Param='' then exit;
if Quick and ((Param='-h') or (Param='-?') or (Param='--help')) then begin
if Quick and ((Param='-h') or (Param='-?') or (Param='--help')) then
begin
WriteHelp;
Terminate(0);
end;
@ -2201,10 +2264,12 @@ begin
end;
end;
'd': // define
if not Quick then begin
if not Quick then
begin
Identifier:=copy(Param,3,length(Param));
i:=Pos(':=',Identifier);
if i>0 then begin
if i>0 then
begin
Value:=copy(Identifier,i+2,length(Identifier));
Identifier:=LeftStr(Identifier,i-1);
if not IsValidIdent(Identifier) then
@ -2232,7 +2297,8 @@ begin
end;
end;
'I': // include path, same as -Fi
if not Quick then begin
if not Quick then
begin
inc(p);
if not FileCache.AddIncludePaths(String(p),FromCmdLine,ErrorMsg) then
ParamFatal('invalid include path "'+ErrorMsg+'"');
@ -2247,11 +2313,13 @@ begin
'i':
if p^=#0 then
ParamFatal('missing insertion file: '+Param)
else if not Quick then begin
else if not Quick then
begin
aFilename:=String(p);
if aFilename='' then
UnknownParam;
if aFilename[length(aFilename)]='-' then begin
if aFilename[length(aFilename)]='-' then
begin
Delete(aFilename,length(aFilename),1);
if aFilename='' then
UnknownParam;
@ -2353,7 +2421,8 @@ begin
inc(p,length(Identifier));
Enable:=true;
c:=Identifier[length(Identifier)];
if c in ['+','-'] then begin
if c in ['+','-'] then
begin
Enable:=c='+';
Delete(Identifier,length(Identifier),1);
end;
@ -2406,7 +2475,8 @@ begin
ParamFatal('invalid target platform "'+Identifier+'"');
end;
'u': // undefine
if not Quick then begin
if not Quick then
begin
Identifier:=copy(Param,3,length(Param));
if not IsValidIdent(Identifier) then
ParamFatal('-u: invalid undefine: "'+Param+'"');
@ -2422,7 +2492,8 @@ begin
end;
end;
'@':
if not Quick then begin
if not Quick then
begin
// load extra config file
aFilename:=copy(Param,2,length(Param));
if aFilename='' then
@ -2434,7 +2505,8 @@ begin
end;
else
// filename
if (not Quick) then begin
if (not Quick) then
begin
if not FromCmdLine then
CfgSyntaxError('invalid parameter');
if FileCache.MainSrcFile<>'' then
@ -2452,7 +2524,8 @@ var
Enabled, Disabled: string;
i: Integer;
begin
if p^='m' then begin
if p^='m' then
begin
// read m-flags
repeat
inc(p);
@ -2554,7 +2627,8 @@ begin
if Pos(Letter,Allowed)<1 then
ParamFatal('unknown option "'+Param+'". Use -h for help.');
inc(p);
if p^='-' then begin
if p^='-' then
begin
// disable
if Pos(Letter,Disabled)<1 then Disabled+=Letter;
i:=Pos(Letter,Enabled);
@ -2820,7 +2894,8 @@ var
M: TMacroDef;
begin
i:=FDefines.IndexOf(aName);
if (i<>-1) then begin
if (i<>-1) then
begin
M:=TMacroDef(FDefines.Objects[i]);
M.Free;
FDefines.Delete(i);
@ -2919,7 +2994,8 @@ begin
WriteLogo;
// show debug info
if ShowDebug then begin
if ShowDebug then
begin
WriteOptions;
WriteDefines;
end;
@ -2957,7 +3033,8 @@ const
end;
begin
if length(s)<=MaxLineLen then begin
if length(s)<=MaxLineLen then
begin
Log.LogRaw(s);
exit;
end;
@ -2982,7 +3059,8 @@ const
inc(p);
end;
inc(CodePointCount);
if CodePointCount>=MaxLineLen then begin
if CodePointCount>=MaxLineLen then
begin
if (WordBreak=nil) or (WordBreak-PChar(s)<MaxLineLen div 3) then
WordBreak:=LastCharStart;
Len:=WordBreak-PChar(s);
@ -3001,7 +3079,8 @@ var
begin
WriteLogo;
Log.LogLn;
if CompilerExe<>'' then begin
if CompilerExe<>'' then
begin
l('Usage: '+CompilerExe+' <your.pas>');
end else begin
l('Usage: pas2js <your.pas>');
@ -3128,7 +3207,8 @@ begin
// message encoding
Log.LogMsgIgnoreFilter(nMessageEncodingIs,[IntToStr(Log.MsgCount)]);
// source map options
if SrcMapEnable then begin
if SrcMapEnable then
begin
Log.LogMsgIgnoreFilter(nSrcMapSourceRootIs,[SrcMapSourceRoot]);
Log.LogMsgIgnoreFilter(nSrcMapBaseDirIs,[SrcMapBaseDir]);
end;
@ -3251,13 +3331,15 @@ begin
aFile:=FindPasFile(PasFilename);
if aFile<>nil then exit;
if (PasFilename='') or not DirectoryCache.FileExists(PasFilename) then begin
if (PasFilename='') or not DirectoryCache.FileExists(PasFilename) then
begin
Log.LogMsg(nSourceFileNotFound,[PasFilename]);
Terminate(ExitCodeFileNotFound);
end;
PasFilename:=ExpandFileNameUTF8(PasFilename);
if DirectoryExists(PasFilename) then begin
if DirectoryExists(PasFilename) then
begin
Log.LogMsg(nFileIsFolder,[PasFilename]);
Terminate(ExitCodeFileNotFound);
end;
@ -3313,7 +3395,8 @@ begin
if aFile.PasUnitName='' then
RaiseInternalError(20170504161347,'missing PasUnitName "'+aFile.PasFilename+'"');
OldFile:=FindUsedUnit(aFile.PasUnitName);
if OldFile<>nil then begin
if OldFile<>nil then
begin
if OldFile<>aFile then
RaiseInternalError(20170504161354,'duplicate unit "'+OldFile.PasUnitName+'" "'+aFile.PasFilename+'" "'+OldFile.PasFilename+'"');
end else begin

View File

@ -391,14 +391,17 @@ begin
SrcEncoding:=GuessEncoding(Src);
if Result='' then exit;
NormSrcEncoding:=NormalizeEncoding(SrcEncoding);
if NormSrcEncoding=NormalizeEncoding(EncodingUTF8) then begin
if NormSrcEncoding=NormalizeEncoding(EncodingUTF8) then
begin
p:=PChar(Result);
if (p^=#$EF) and (p[1]=#$BB) and (p[2]=#$BF) then begin
if (p^=#$EF) and (p[1]=#$BB) and (p[2]=#$BF) then
begin
// cut out UTF-8 BOM
Delete(Result,1,3);
end;
end else if (NormSrcEncoding=EncodingSystem)
or (NormSrcEncoding=GetDefaultTextEncoding) then begin
or (NormSrcEncoding=GetDefaultTextEncoding) then
begin
Result:=SystemCPToUTF8(Result);
end else
EPas2jsFileCache.Create('invalid encoding "'+SrcEncoding+'"');
@ -420,7 +423,8 @@ begin
l:=length(Src);
p:=PChar(Src);
repeat
if ord(p^)<128 then begin
if ord(p^)<128 then
begin
// ASCII
if (p^=#0) and (p-PChar(Src)>=l) then
exit(EncodingUTF8);
@ -478,7 +482,8 @@ begin
// Note: do not add a 'if not DirectoryExists then exit'.
// This will not work on automounted directories. You must use FindFirst.
if FindFirst(UnicodeString(Path+AllFilesMask),faAnyFile,Info)=0 then begin
if FindFirst(UnicodeString(Path+AllFilesMask),faAnyFile,Info)=0 then
begin
repeat
// check if special file
if (Info.Name='.') or (Info.Name='..') or (Info.Name='')
@ -712,8 +717,10 @@ begin
E('invalid entry "'+Entry.Name+'"');
if (Entry.Size<0) then
E('invalid size "'+Entry.Name+'" '+IntToStr(Entry.Size));
if Sorted then begin
if (LastEntry<>nil) then begin
if Sorted then
begin
if (LastEntry<>nil) then
begin
if LastEntry.Name=Entry.Name then
E('duplicate "'+Entry.Name+'"');
cmp:=CompareText(LastEntry.Name,Entry.Name);
@ -753,7 +760,8 @@ begin
Info.ShortFilename:=ExtractFilename(Info.Filename);
Info.DirPath:=ExtractFilePath(Info.Filename);
if (Info.ShortFilename<>'') and (Info.ShortFilename<>'.') and (Info.ShortFilename<>'..')
then begin
then
begin
Info.Dir:=GetDirectory(Info.DirPath,true,false);
end else begin
Info.Dir:=nil;
@ -903,12 +911,14 @@ begin
Dir:=WorkingDirectory+Dir;
Dir:=IncludeTrailingPathDelimiter(Dir);
Node:=FDirectories.FindKey(Pointer(Dir),@CompareAnsiStringWithDirectoryCache);
if Node<>nil then begin
if Node<>nil then
begin
Result:=TPas2jsCachedDirectory(Node.Data);
if DoReference then
Result.Reference;
Result.Update;
end else if DoReference or CreateIfNotExists then begin
end else if DoReference or CreateIfNotExists then
begin
{$IFDEF VerbosePas2JSDirCache}
writeln('TPas2jsCachedDirectories.GetDirectory "',Dir,'"');
{$ENDIF}
@ -973,7 +983,8 @@ begin
c:=p^;
case c of
#0:
if p-PChar(FSource)=length(FSource) then begin
if p-PChar(FSource)=length(FSource) then
begin
FIsEOF:=true;
GetLine;
exit;
@ -1020,9 +1031,11 @@ begin
{$IFDEF VerboseFileCache}
writeln('TPas2jsCachedFile.Load START "',Filename,'" Loaded=',Loaded);
{$ENDIF}
if Loaded then begin
if Loaded then
begin
// already loaded, check if it still valid
if (Cache.ResetStamp=FCacheStamp) then begin
if (Cache.ResetStamp=FCacheStamp) then
begin
// nothing changed
Result:=FLastErrorMsg='';
if (not Result) and RaiseOnError then
@ -1040,11 +1053,13 @@ begin
{$ENDIF}
// needs (re)load
Result:=false;
if not Cache.DirectoryCache.FileExists(Filename) then begin
if not Cache.DirectoryCache.FileExists(Filename) then
begin
Err('File not found "'+Filename+'"');
exit;
end;
if Cache.DirectoryCache.DirectoryExists(Filename) then begin
if Cache.DirectoryCache.DirectoryExists(Filename) then
begin
Err('File is a directory "'+Filename+'"');
exit;
end;
@ -1123,7 +1138,8 @@ begin
if Cache.ShowTriedUsedFiles then
Cache.Log.LogMsgIgnoreFilter(nIncludeSearch,[Filename]);
if FilenameIsAbsolute(Filename) then begin
if FilenameIsAbsolute(Filename) then
begin
Result:=Filename;
if not SearchLowUpCase(Result) then
Result:='';
@ -1134,7 +1150,8 @@ begin
Result:=SearchCasedInIncPath(Filename);
if Result<>'' then exit;
if ExtractFileExt(Filename)='' then begin
if ExtractFileExt(Filename)='' then
begin
// search with the default file extensions
Result:=SearchCasedInIncPath(Filename+'.inc');
if Result<>'' then exit;
@ -1174,7 +1191,8 @@ var
begin
Result:='';
if InFilename<>'' then begin
if InFilename<>'' then
begin
Cache.Log.LogMsgIgnoreFilter(nSearchingFileNotFound,['not yet implemented "in" '+Cache.FormatPath(InFilename)])
// ToDo
end;
@ -1182,7 +1200,8 @@ begin
// first search in foreign unit paths
IsForeign:=true;
for i:=0 to Cache.ForeignUnitPaths.Count-1 do
if SearchInDir(Cache.ForeignUnitPaths[i],Result) then begin
if SearchInDir(Cache.ForeignUnitPaths[i],Result) then
begin
IsForeign:=true;
exit;
end;
@ -1203,7 +1222,8 @@ function TPas2jsFileResolver.FindUnitJSFileName(const aUnitFilename: string
begin
Result:='';
if aUnitFilename='' then exit;
if Cache.AllJSIntoMainJS then begin
if Cache.AllJSIntoMainJS then
begin
Result:=Cache.GetResolvedMainJSFile;
end else begin
if Cache.UnitOutputPath<>'' then
@ -1284,12 +1304,14 @@ begin
exit(false);
{$IFNDEF CaseInsensitiveFilenames}
CasedFilename:=ExtractFilePath(Filename)+LowerCase(ExtractFileName(Filename));
if (Filename<>CasedFilename) and FileExistsLogged(CasedFilename) then begin
if (Filename<>CasedFilename) and FileExistsLogged(CasedFilename) then
begin
Filename:=CasedFilename;
exit(true);
end;
CasedFilename:=ExtractFilePath(Filename)+UpperCase(ExtractFileName(Filename));
if (Filename<>CasedFilename) and FileExistsLogged(CasedFilename) then begin
if (Filename<>CasedFilename) and FileExistsLogged(CasedFilename) then
begin
Filename:=CasedFilename;
exit(true);
end;
@ -1360,7 +1382,8 @@ var
end;
spkIdentifier:
begin
if aPath[length(aPath)]='-' then begin
if aPath[length(aPath)]='-' then
begin
Delete(aPath,length(aPath),1);
Remove:=true;
end;
@ -1374,18 +1397,22 @@ var
end;
end;
if Remove then begin
if Remove then
begin
// remove
if i>=0 then begin
if i>=0 then
begin
List.Delete(i);
if CmdLineCount>i then dec(CmdLineCount);
end;
exit(true);
end;
if FromCmdLine then begin
if FromCmdLine then
begin
// from cmdline: append in order to the cmdline params, in front of cfg params
if i>=0 then begin
if i>=0 then
begin
if i<=CmdLineCount then exit(true);
List.Delete(i);
end;
@ -1393,7 +1420,8 @@ var
inc(CmdLineCount);
end else begin
// from cfg: append in reverse order to the cfg params, behind cmdline params
if i>=0 then begin
if i>=0 then
begin
if i<=CmdLineCount+Added then exit(true);
List.Delete(i);
end;
@ -1421,7 +1449,8 @@ begin
if (aPath='') then continue;
aPaths.Clear;
FindMatchingFiles(aPath,1000,aPaths);
if aPaths.Count=0 then begin
if aPaths.Count=0 then
begin
if not Add(aPath) then exit;
end else begin
for i:=0 to aPaths.Count-1 do
@ -1522,7 +1551,8 @@ begin
Mask:=ResolveDots(Mask);
p:=1;
while p<=length(Mask) do begin
if Mask[p] in ['*','?'] then begin
if Mask[p] in ['*','?'] then
begin
while (p>1) and not (Mask[p-1] in AllowDirectorySeparators) do dec(p);
Dir:=DirectoryCache.GetDirectory(LeftStr(Mask,p-1),true,false);
StartP:=p;
@ -1532,7 +1562,8 @@ begin
Entry:=Dir.Entries[i];
if not MatchGlobbing(CurMask,Entry.Name) then continue;
Filename:=Dir.Path+Entry.Name;
if p>length(Mask) then begin
if p>length(Mask) then
begin
// e.g. /path/unit*.pas
if Files.Count>=MaxCount then
raise EListError.Create('found too many files "'+Mask+'"');
@ -1546,7 +1577,8 @@ begin
end;
inc(p);
end;
if DirectoryCache.FileExists(Mask) then begin
if DirectoryCache.FileExists(Mask) then
begin
if Files.Count>=MaxCount then
raise EListError.Create('found too many files "'+Mask+'"');
Files.Add(Mask);
@ -1639,8 +1671,10 @@ function TPas2jsFilesCache.FormatPath(const aPath: string): string;
begin
Result:=aPath;
if (Result='') or (BaseDirectory='') then exit;
if FilenameIsAbsolute(aPath) then begin
if not ShowFullPaths then begin
if FilenameIsAbsolute(aPath) then
begin
if not ShowFullPaths then
begin
if BaseDirectory=LeftStr(Result,length(BaseDirectory)) then
Delete(Result,1,length(BaseDirectory));
end;
@ -1652,14 +1686,17 @@ end;
function TPas2jsFilesCache.GetResolvedMainJSFile: string;
begin
if not (cfsMainJSFileResolved in FStates) then begin
if not (cfsMainJSFileResolved in FStates) then
begin
if MainJSFile='.' then
FMainJSFileResolved:=''
else begin
FMainJSFileResolved:=MainJSFile;
if FMainJSFileResolved='' then begin
if FMainJSFileResolved='' then
begin
// no option -o
if UnitOutputPath<>'' then begin
if UnitOutputPath<>'' then
begin
// option -FU and no -o => put into UnitOutputPath
FMainJSFileResolved:=UnitOutputPath+ChangeFileExt(ExtractFilename(MainSrcFile),'.js')
end else begin
@ -1683,7 +1720,8 @@ var
begin
Filename:=NormalizeFilename(Filename,true);
Node:=FFiles.FindKey(Pointer(Filename),@CompareFilenameWithCachedFile);
if Node=nil then begin
if Node=nil then
begin
// new file
Result:=TPas2jsCachedFile.Create(Self,Filename);
FFiles.Add(Result);

View File

@ -113,7 +113,8 @@ var
ExpPath: String;
l: integer;
begin
if Path='' then begin
if Path='' then
begin
Result:=false;
exit;
end;
@ -132,7 +133,8 @@ begin
if Path = '' then
exit;
Len:=length(Result);
if (Result[1] in AllowDirectorySeparators) then begin
if (Result[1] in AllowDirectorySeparators) then
begin
MinLen := 1;
{$IFDEF HasUNCPaths}
if (Len >= 2) and (Result[2] in AllowDirectorySeparators) then
@ -220,7 +222,8 @@ begin
// skip matching directories
SharedDirs:=0;
if FileP^ in AllowDirectorySeparators then begin
if FileP^ in AllowDirectorySeparators then
begin
if not (BaseP^ in AllowDirectorySeparators) then exit;
repeat
while FileP^ in AllowDirectorySeparators do inc(FileP);
@ -256,7 +259,8 @@ begin
//writeln('TryCreateRelativePath UpDirCount=',UpDirCount,' File="',FileP,'" Base="',BaseP,'"');
// create relative filename
if (FileP^=#0) and (UpDirCount=0) then begin
if (FileP^=#0) and (UpDirCount=0) then
begin
// Filename is the BaseDirectory
if UsePointDirectory then
RelPath:='.'
@ -327,14 +331,16 @@ begin
if (c in AllowDirectorySeparators) then c := PathDelim;
{$endif}
// check for duplicate path delims
if (c=PathDelim) then begin
if (c=PathDelim) then
begin
inc(SrcPos);
{$IFDEF Windows}
if (DestPos>2)
{$ELSE}
if (DestPos>1)
{$ENDIF}
and (Result[DestPos-1]=PathDelim) then begin
and (Result[DestPos-1]=PathDelim) then
begin
// skip duplicate PathDelim
continue;
end;
@ -343,10 +349,13 @@ begin
continue;
end;
// check for special dirs . and ..
if (c='.') then begin
if (SrcPos<Len) then begin
if (c='.') then
begin
if (SrcPos<Len) then
begin
if (AFilename[SrcPos+1] in AllowDirectorySeparators)
and IsPathDelim(Result,DestPos-1) then begin
and IsPathDelim(Result,DestPos-1) then
begin
// special dir ./ or */./
// -> skip
inc(SrcPos,2);
@ -365,31 +374,38 @@ begin
// 6. ../.. -> copy because if the first '..' was not resolved, the next can't neither
// 7. dir/.. -> trim dir and ..
// 8. dir$macro/.. -> copy
if DestPos=1 then begin
if DestPos=1 then
begin
// 1. .. or ../ -> copy
end else if (DestPos=2) and (Result[1]=PathDelim) then begin
end else if (DestPos=2) and (Result[1]=PathDelim) then
begin
// 2. /.. -> skip .., keep /
inc(SrcPos,2);
continue;
{$IFDEF Windows}
end else if (DestPos=3) and IsDriveDelim(Result,2) then begin
end else if (DestPos=3) and IsDriveDelim(Result,2) then
begin
// 3. C:.. -> copy
end else if (DestPos=4) and (Result[3]=PathDelim)
and IsDriveDelim(Result,2) then begin
and IsDriveDelim(Result,2) then
begin
// 4. C:\.. -> skip .., keep C:\
inc(SrcPos,2);
continue;
end else if (DestPos=3) and (Result[1]=PathDelim)
and (Result[2]=PathDelim) then begin
and (Result[2]=PathDelim) then
begin
// 5. \\.. -> skip .., keep \\
inc(SrcPos,2);
continue;
{$ENDIF}
end else if (DestPos>1) and (Result[DestPos-1]=PathDelim) then begin
end else if (DestPos>1) and (Result[DestPos-1]=PathDelim) then
begin
// */.
if (DestPos>3)
and (Result[DestPos-2]='.') and (Result[DestPos-3]='.')
and IsPathDelim(Result,DestPos-4) then begin
and IsPathDelim(Result,DestPos-4) then
begin
// 6. ../.. -> copy because if the first '..' was not resolved, the next can't neither
end else begin
// 7. xxxdir/.. -> trim dir and skip ..
@ -403,28 +419,34 @@ begin
MacroPos:=DirStart;
while MacroPos<DestPos do begin
if (Result[MacroPos]='$')
and (Result[MacroPos+1] in ['(','a'..'z','A'..'Z']) then begin
and (Result[MacroPos+1] in ['(','a'..'z','A'..'Z']) then
begin
// 8. directory contains a macro -> keep
break;
end;
inc(MacroPos);
end;
if MacroPos=DestPos then begin
if MacroPos=DestPos then
begin
// previous directory does not contain a macro -> remove dir/..
DestPos:=DirStart;
inc(SrcPos,2);
//writeln('ResolveDots ',DestPos,' SrcPos=',SrcPos,' File="',AFilename,'" Result="',copy(Result,1,DestPos-1),'"');
if SrcPos>Len then begin
if SrcPos>Len then
begin
// '..' at end of filename
if (DestPos>1) and (Result[DestPos-1]=PathDelim) then begin
if (DestPos>1) and (Result[DestPos-1]=PathDelim) then
begin
// foo/dir/.. -> foo
dec(DestPos);
end else if (DestPos=1) then begin
end else if (DestPos=1) then
begin
// foo/.. -> .
Result[1]:='.';
DestPos:=2;
end;
end else if DestPos=1 then begin
end else if DestPos=1 then
begin
// e.g. 'foo/../'
while (SrcPos<=Len) and (AFilename[SrcPos] in AllowDirectorySeparators) do
inc(SrcPos);
@ -436,7 +458,8 @@ begin
end;
end else begin
// special dir . at end of filename
if DestPos=1 then begin
if DestPos=1 then
begin
Result:='.';
exit;
end;
@ -535,7 +558,8 @@ function MatchGlobbing(Mask, Name: string): boolean;
#0:
exit(IsNameEnd(NameP));
'?':
if not IsNameEnd(NameP) then begin
if not IsNameEnd(NameP) then
begin
inc(MaskP);
c:=UTF8CharacterStrictLength(NameP);
if c<1 then c:=1;
@ -611,22 +635,26 @@ end;
function UTF8CharacterStrictLength(P: PChar): integer;
begin
if p=nil then exit(0);
if ord(p^)<%10000000 then begin
if ord(p^)<%10000000 then
begin
// regular single byte character
exit(1);
end
else if ord(p^)<%11000000 then begin
else if ord(p^)<%11000000 then
begin
// invalid single byte character
exit(0);
end
else if ((ord(p^) and %11100000) = %11000000) then begin
else if ((ord(p^) and %11100000) = %11000000) then
begin
// should be 2 byte character
if (ord(p[1]) and %11000000) = %10000000 then
exit(2)
else
exit(0);
end
else if ((ord(p^) and %11110000) = %11100000) then begin
else if ((ord(p^) and %11110000) = %11100000) then
begin
// should be 3 byte character
if ((ord(p[1]) and %11000000) = %10000000)
and ((ord(p[2]) and %11000000) = %10000000) then
@ -634,7 +662,8 @@ begin
else
exit(0);
end
else if ((ord(p^) and %11111000) = %11110000) then begin
else if ((ord(p^) and %11111000) = %11110000) then
begin
// should be 4 byte character
if ((ord(p[1]) and %11000000) = %10000000)
and ((ord(p[2]) and %11000000) = %10000000)
@ -648,7 +677,8 @@ end;
function GetDefaultTextEncoding: string;
begin
if EncodingValid then begin
if EncodingValid then
begin
Result:=DefaultTextEncoding;
exit;
end;
@ -660,7 +690,8 @@ begin
Result:=EncodingUTF8;
{$ELSE}
Lang := GetEnvironmentVariable('LC_ALL');
if Lang='' then begin
if Lang='' then
begin
Lang := GetEnvironmentVariable('LC_MESSAGES');
if Lang='' then
Lang := GetEnvironmentVariable('LANG');

View File

@ -90,7 +90,8 @@ begin
while Depth<12 do begin
inc(Depth);
LinkFilename:=fpReadLink(Result);
if LinkFilename='' then begin
if LinkFilename='' then
begin
AText:='"'+Filename+'"';
case fpGetErrno() of
ESysEAcces:
@ -108,7 +109,8 @@ begin
// not a symbolic link, just a regular file
exit;
end;
if (not ExceptionOnError) then begin
if (not ExceptionOnError) then
begin
Result:='';
exit;
end;

View File

@ -475,7 +475,8 @@ var
len: LongInt;
begin
Result:=s;
if IsASCII(Result) then begin
if IsASCII(Result) then
begin
// prevent codepage conversion magic
SetCodePage(RawByteString(Result), CP_ACP, False);
exit;
@ -485,7 +486,8 @@ begin
exit;
len:=WideCharToMultiByte(CP_ACP,0,PUnicodeChar(src),length(src),nil,0,nil,nil);
SetLength(Result,len);
if len>0 then begin
if len>0 then
begin
WideCharToMultiByte(CP_ACP,0,PUnicodeChar(src),length(src),@Result[1],length(Result),nil,nil);
// prevent codepage conversion magic
SetCodePage(RawByteString(Result), CP_ACP, False);
@ -507,7 +509,8 @@ var
UTF16Str: UnicodeString;
begin
Result:=s;
if IsASCII(Result) then begin
if IsASCII(Result) then
begin
// prevent codepage conversion magic
SetCodePage(RawByteString(Result), CP_ACP, False);
exit;

View File

@ -149,54 +149,67 @@ function DbgString(Element: TJSElement; Indent: integer): string;
begin
if Element=nil then
Result:='(*no element*)'
else if Element is TJSLiteral then begin
else if Element is TJSLiteral then
begin
Result:=DbgAsString(TJSLiteral(Element).Value,Indent+2);
end else if Element is TJSPrimaryExpressionIdent then begin
end else if Element is TJSPrimaryExpressionIdent then
begin
Result:=String(TJSPrimaryExpressionIdent(Element).Name);
// array literal
end else if Element is TJSArrayLiteral then begin
end else if Element is TJSArrayLiteral then
begin
Result:='['+DbgAsString(TJSArrayLiteral(Element).Elements,Indent+2)+']';
// object literal
end else if Element is TJSObjectLiteral then begin
end else if Element is TJSObjectLiteral then
begin
Result:='['+DbgAsString(TJSObjectLiteral(Element).Elements,Indent+2)+']';
// arguments
end else if Element is TJSArguments then begin
end else if Element is TJSArguments then
begin
Result:='('+DbgAsString(TJSArguments(Element).Elements,Indent+2)+')';
// member
end else if Element is TJSMemberExpression then begin
end else if Element is TJSMemberExpression then
begin
Result:='('+DbgString(TJSMemberExpression(Element).MExpr,Indent+2)+')';
// ToDo: TJSNewMemberExpression
// ToDo: TJSDotMemberExpression
// ToDo: TJSBracketMemberExpression
// call
end else if Element is TJSCallExpression then begin
end else if Element is TJSCallExpression then
begin
Result:=DbgString(TJSCallExpression(Element).Expr,Indent+2)
+DbgString(TJSCallExpression(Element).Args,Indent+2);
// unary
end else if Element is TJSUnary then begin
end else if Element is TJSUnary then
begin
Result:=TJSUnary(Element).PrefixOperator
+DbgString(TJSUnary(Element).A,Indent+2)
+TJSUnary(Element).PostFixOperator;
// binary
end else if Element is TJSBinary then begin
if Element is TJSStatementList then begin
end else if Element is TJSBinary then
begin
if Element is TJSStatementList then
begin
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2)+';'+LineEnding
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
end else if Element is TJSVariableDeclarationList then begin
end else if Element is TJSVariableDeclarationList then
begin
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2)+';'+LineEnding
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent);
end else if Element is TJSWithStatement then begin
end else if Element is TJSWithStatement then
begin
Result:='with ('+DbgString(TJSBinaryExpression(Element).A,Indent+2)+'){'+LineEnding
+Space(Indent)+DbgString(TJSBinaryExpression(Element).B,Indent+2)+LineEnding
+Space(Indent)+'}';
end else if Element is TJSBinaryExpression then begin
end else if Element is TJSBinaryExpression then
begin
Result:=DbgString(TJSBinaryExpression(Element).A,Indent+2);
if TJSBinaryExpression(Element).AllowCompact then
Result+=TJSBinaryExpression(Element).OperatorString
@ -208,25 +221,29 @@ begin
end;
// ? :
end else if Element is TJSConditionalExpression then begin
end else if Element is TJSConditionalExpression then
begin
Result:=DbgString(TJSConditionalExpression(Element).A,Indent+2)
+'?'+DbgString(TJSConditionalExpression(Element).B,Indent+2)
+':'+DbgString(TJSConditionalExpression(Element).C,Indent+2);
// assignment
end else if Element is TJSAssignStatement then begin
end else if Element is TJSAssignStatement then
begin
Result:=DbgString(TJSAssignStatement(Element).LHS,Indent+2)
+TJSAssignStatement(Element).OperatorString
+DbgString(TJSAssignStatement(Element).Expr,Indent+2);
// var
end else if Element is TJSVarDeclaration then begin
end else if Element is TJSVarDeclaration then
begin
Result:=TJSVarDeclaration(Element).Name;
if TJSVarDeclaration(Element).Init<>nil then
Result+='='+DbgString(TJSVarDeclaration(Element).Init,Indent+2);
// if(){} else {}
end else if Element is TJSIfStatement then begin
end else if Element is TJSIfStatement then
begin
Result:='if('+DbgString(TJSIfStatement(Element).Cond,Indent+2)+'){'+LineEnding
+Space(Indent+2)+DbgString(TJSIfStatement(Element).BTrue,Indent+2)+LineEnding
+Space(Indent);
@ -236,10 +253,12 @@ begin
+Space(Indent)+'}';
// body
end else if Element is TJSBodyStatement then begin
end else if Element is TJSBodyStatement then
begin
// while(){}
if Element is TJSWhileStatement then begin
if Element is TJSWhileStatement then
begin
Result:='while('+DbgString(TJSWhileStatement(Element).Cond,Indent+2)+')';
if TJSWhileStatement(Element).Body<>nil then
Result+=DbgString(TJSWhileStatement(Element).Body,Indent)
@ -247,7 +266,8 @@ begin
Result+='{}';
// do{}while()
end else if Element is TJSDoWhileStatement then begin
end else if Element is TJSDoWhileStatement then
begin
Result:='do';
if TJSDoWhileStatement(Element).Body<>nil then
Result+=DbgString(TJSDoWhileStatement(Element).Body,Indent)
@ -256,7 +276,8 @@ begin
Result+='('+DbgString(TJSDoWhileStatement(Element).Cond,Indent+2)+')';
// for(Init;Incr;Cond)Body
end else if Element is TJSForStatement then begin
end else if Element is TJSForStatement then
begin
Result:='for(';
if TJSForStatement(Element).Init<>nil then
Result+=DbgString(TJSForStatement(Element).Init,Indent+2);
@ -384,7 +405,8 @@ begin
else
exit(m);
end;
if FindInsertPos then begin
if FindInsertPos then
begin
Result:=m;
if l>m then inc(Result);
end else begin
@ -413,7 +435,8 @@ var
InsertPos, OldCount: Integer;
begin
OldCount:=FMsgNumberDisabledCount;
if AValue then begin
if AValue then
begin
// enable
InsertPos:=FindMsgNumberDisabled(MsgNumber,true);
if (InsertPos<OldCount) and (FMsgNumberDisabled[InsertPos]=MsgNumber) then
@ -520,7 +543,8 @@ var
i: Integer;
LastMsg, CurMsg: TPas2jsMessage;
begin
if FMsg.Count>1 then begin;
if FMsg.Count>1 then
begin;
FMsg.Sort(@CompareP2JMessage);
// check for duplicates
@ -664,12 +688,14 @@ var
s: String;
begin
s:='';
if Filename<>'' then begin
if Filename<>'' then
begin
if Assigned(OnFormatPath) then
s+=OnFormatPath(Filename)
else
s+=Filename;
if Line>0 then begin
if Line>0 then
begin
s+='('+IntToStr(Line);
if Col>0 then s+=','+IntToStr(Col);
s+=')';
@ -711,7 +737,8 @@ end;
procedure TPas2jsLogger.Reset;
begin
OutputFilename:='';
if FMsgNumberDisabled<>nil then begin
if FMsgNumberDisabled<>nil then
begin
ReAllocMem(FMsgNumberDisabled,0);
FMsgNumberDisabledCount:=0;
end;

View File

@ -1217,13 +1217,15 @@ var
StartPos:=p;
while not (p^ in [#0,#10,#13]) do inc(p);
ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
if p^ in [#10,#13] then begin
if p^ in [#10,#13] then
begin
if (p[1] in [#10,#13]) and (p^<>p[1]) then
inc(p,2)
else
inc(p);
end;
if (p<=ExpectedP) and (p^<>#0) then begin
if (p<=ExpectedP) and (p^<>#0) then
begin
writeln('= ',ExpLine);
end else begin
// diff line
@ -1458,8 +1460,10 @@ procedure TCustomTestModule.RaiseException(E: Exception);
var
MsgNumber: Integer;
begin
if ExpectedErrorClass<>nil then begin
if FExpectedErrorClass=E.ClassType then begin
if ExpectedErrorClass<>nil then
begin
if FExpectedErrorClass=E.ClassType then
begin
if E is EPas2JS then
MsgNumber:=EPas2JS(E).MsgNumber
else if E is EPasResolve then