|
@@ -288,6 +288,7 @@ type
|
|
Property MyFile : TPas2JSCompilerFile Read FFile;
|
|
Property MyFile : TPas2JSCompilerFile Read FFile;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ { TFindUnitInfo }
|
|
|
|
|
|
TFindUnitInfo = Record
|
|
TFindUnitInfo = Record
|
|
FileName : String;
|
|
FileName : String;
|
|
@@ -296,7 +297,9 @@ type
|
|
isForeign : Boolean;
|
|
isForeign : Boolean;
|
|
end;
|
|
end;
|
|
|
|
|
|
- TLoadInfo = Record
|
|
|
|
|
|
+ { TLoadUnitInfo }
|
|
|
|
+
|
|
|
|
+ TLoadUnitInfo = Record
|
|
UseFilename,
|
|
UseFilename,
|
|
UseUnitname,
|
|
UseUnitname,
|
|
InFilename: String;
|
|
InFilename: String;
|
|
@@ -304,9 +307,9 @@ type
|
|
InFileExpr: TPasExpr;
|
|
InFileExpr: TPasExpr;
|
|
UseIsForeign: boolean;
|
|
UseIsForeign: boolean;
|
|
IsPCU : Boolean;
|
|
IsPCU : Boolean;
|
|
-
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ { TPas2JSCompilerSupport }
|
|
|
|
|
|
TPas2JSCompilerSupport = Class
|
|
TPas2JSCompilerSupport = Class
|
|
private
|
|
private
|
|
@@ -372,7 +375,7 @@ type
|
|
procedure CreateConverter;
|
|
procedure CreateConverter;
|
|
function OnResolverFindModule(const UseUnitName, InFilename: String; NameExpr,
|
|
function OnResolverFindModule(const UseUnitName, InFilename: String; NameExpr,
|
|
InFileExpr: TPasExpr): TPasModule;
|
|
InFileExpr: TPasExpr): TPasModule;
|
|
-// function LoadUsedUnit(Info : TLoadInfo): TPas2jsCompilerFile;
|
|
|
|
|
|
+// function LoadUsedUnit(Info : TLoadUnitInfo): TPas2jsCompilerFile;
|
|
procedure OnResolverCheckSrcName(const Element: TPasElement);
|
|
procedure OnResolverCheckSrcName(const Element: TPasElement);
|
|
procedure OpenFile(aFilename: string);// beware: this changes FileResolver.BaseDirectory
|
|
procedure OpenFile(aFilename: string);// beware: this changes FileResolver.BaseDirectory
|
|
procedure ReadUnit;
|
|
procedure ReadUnit;
|
|
@@ -505,7 +508,7 @@ type
|
|
function HandleOptionOptimization(C: Char; aValue: String): Boolean;
|
|
function HandleOptionOptimization(C: Char; aValue: String): Boolean;
|
|
function IndexOfInsertJSFilename(const aFilename: string): integer;
|
|
function IndexOfInsertJSFilename(const aFilename: string): integer;
|
|
procedure InsertCustomJSFiles(aWriter: TPas2JSMapper);
|
|
procedure InsertCustomJSFiles(aWriter: TPas2JSMapper);
|
|
- function LoadUsedUnit(Info: TLoadInfo; Context: TPas2jsCompilerFile): TPas2jsCompilerFile;
|
|
|
|
|
|
+ function LoadUsedUnit(Info: TLoadUnitInfo; Context: TPas2jsCompilerFile): TPas2jsCompilerFile;
|
|
function OnMacroCfgDir(Sender: TObject; var Params: string; Lvl: integer): boolean;
|
|
function OnMacroCfgDir(Sender: TObject; var Params: string; Lvl: integer): boolean;
|
|
procedure RemoveInsertJSFilename(const aFilename: string);
|
|
procedure RemoveInsertJSFilename(const aFilename: string);
|
|
function ResolvedMainJSFile: string;
|
|
function ResolvedMainJSFile: string;
|
|
@@ -621,7 +624,7 @@ type
|
|
procedure SetOption(Flag: TP2jsCompilerOption; Enable: boolean);
|
|
procedure SetOption(Flag: TP2jsCompilerOption; Enable: boolean);
|
|
|
|
|
|
function GetUnitInfo(const UseUnitName, InFileName: String; PCUSupport: TPCUSupport): TFindUnitInfo;
|
|
function GetUnitInfo(const UseUnitName, InFileName: String; PCUSupport: TPCUSupport): TFindUnitInfo;
|
|
- function FindUnitWithFile(PasFilename: string): TPas2jsCompilerFile;
|
|
|
|
|
|
+ function FindUnitWithPasFilename(PasFilename: string): TPas2jsCompilerFile;
|
|
procedure LoadPasFile(UnitFilename, UseUnitName: string; out aFile: TPas2jsCompilerFile; isPCU : Boolean);
|
|
procedure LoadPasFile(UnitFilename, UseUnitName: string; out aFile: TPas2jsCompilerFile; isPCU : Boolean);
|
|
Function FindUnitJSFileName(aFileName : String) : String;
|
|
Function FindUnitJSFileName(aFileName : String) : String;
|
|
function FindLoadedUnit(const TheUnitName: string): TPas2jsCompilerFile;
|
|
function FindLoadedUnit(const TheUnitName: string): TPas2jsCompilerFile;
|
|
@@ -1602,13 +1605,14 @@ function TPas2jsCompilerFile.OnResolverFindModule(const UseUnitName,
|
|
var
|
|
var
|
|
aFile: TPas2jsCompilerFile;
|
|
aFile: TPas2jsCompilerFile;
|
|
UnitInfo : TFindUnitInfo;
|
|
UnitInfo : TFindUnitInfo;
|
|
- LoadInfo : TLoadInfo;
|
|
|
|
|
|
+ LoadInfo : TLoadUnitInfo;
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
aFile:=Nil;
|
|
aFile:=Nil;
|
|
- // duplicate identifier or unit cycle
|
|
|
|
|
|
+ // check duplicate identifier or unit cycle
|
|
if CompareText(ExtractFilenameOnly(PasFilename),UseUnitname)=0 then
|
|
if CompareText(ExtractFilenameOnly(PasFilename),UseUnitname)=0 then
|
|
Parser.RaiseParserError(nUnitCycle,[UseUnitname]);
|
|
Parser.RaiseParserError(nUnitCycle,[UseUnitname]);
|
|
|
|
+
|
|
UnitInfo:=Compiler.GetUnitInfo(UseUnitName,InFileName,PCUSupport);
|
|
UnitInfo:=Compiler.GetUnitInfo(UseUnitName,InFileName,PCUSupport);
|
|
if UnitInfo.FileName<>'' then
|
|
if UnitInfo.FileName<>'' then
|
|
begin
|
|
begin
|
|
@@ -1632,7 +1636,7 @@ begin
|
|
end;
|
|
end;
|
|
if aFile<>nil then
|
|
if aFile<>nil then
|
|
Result:=aFile.PasModule;
|
|
Result:=aFile.PasModule;
|
|
- // if Result=nil resolver will give a nice error position
|
|
|
|
|
|
+ // if Result=nil resolver will give a nice error position, so don't do it here
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1722,7 +1726,7 @@ begin
|
|
if MainFile=nil then exit;
|
|
if MainFile=nil then exit;
|
|
// parse and load Pascal files recursively
|
|
// parse and load Pascal files recursively
|
|
if Assigned(FMainFile.PCUSupport) then
|
|
if Assigned(FMainFile.PCUSupport) then
|
|
- FMainFile.PCUSupport.SetInitialCompileFlags;
|
|
|
|
|
|
+ FMainFile.PCUSupport.SetInitialCompileFlags;
|
|
FMainFile.ReadUnit;
|
|
FMainFile.ReadUnit;
|
|
ProcessQueue;
|
|
ProcessQueue;
|
|
|
|
|
|
@@ -4339,52 +4343,55 @@ begin
|
|
Options:=Options-[Flag];
|
|
Options:=Options-[Flag];
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TPas2jsCompiler.FindUnitWithFile(PasFilename: string): TPas2jsCompilerFile;
|
|
|
|
|
|
+function TPas2jsCompiler.FindUnitWithPasFilename(PasFilename: string): TPas2jsCompilerFile;
|
|
begin
|
|
begin
|
|
if PasFilename='' then exit(nil);
|
|
if PasFilename='' then exit(nil);
|
|
Result:=TPas2jsCompilerFile(FFiles.FindKey(Pointer(PasFilename)));
|
|
Result:=TPas2jsCompilerFile(FFiles.FindKey(Pointer(PasFilename)));
|
|
end;
|
|
end;
|
|
|
|
|
|
-Function TPas2jsCompiler.CreateCompilerFile(Const UnitFileName : String) :TPas2jsCompilerFile;
|
|
|
|
-
|
|
|
|
|
|
+Function TPas2jsCompiler.CreateCompilerFile(Const UnitFileName : String): TPas2jsCompilerFile;
|
|
begin
|
|
begin
|
|
Result:=TPas2jsCompilerFile.Create(Self,UnitFilename);
|
|
Result:=TPas2jsCompilerFile.Create(Self,UnitFilename);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPas2jsCompiler.LoadPasFile(UnitFilename, UseUnitName: string; out aFile: TPas2jsCompilerFile; IsPCU : Boolean);
|
|
|
|
|
|
+procedure TPas2jsCompiler.LoadPasFile(UnitFilename, UseUnitName: string;
|
|
|
|
+ out aFile: TPas2jsCompilerFile; IsPCU : Boolean);
|
|
var
|
|
var
|
|
aPasTree: TPas2jsCompilerResolver;
|
|
aPasTree: TPas2jsCompilerResolver;
|
|
|
|
+ ExpUnitFilename: String;
|
|
begin
|
|
begin
|
|
aFile:=nil;
|
|
aFile:=nil;
|
|
Log.LogMsg(nParsingFile,[FormatPath(UnitFilename)],'',0,0,not (coShowLineNumbers in Options));
|
|
Log.LogMsg(nParsingFile,[FormatPath(UnitFilename)],'',0,0,not (coShowLineNumbers in Options));
|
|
|
|
|
|
- aFile:=FindUnitWithFile(UnitFilename);
|
|
|
|
|
|
+ ExpUnitFilename:=UnitFilename;
|
|
|
|
+ if ExpUnitFilename<>'' then
|
|
|
|
+ ExpUnitFilename:=ExpandFileName(ExpUnitFilename);
|
|
|
|
+ aFile:=FindUnitWithPasFilename(ExpUnitFilename);
|
|
if aFile<>nil then exit;
|
|
if aFile<>nil then exit;
|
|
|
|
|
|
- if (UnitFilename='') or not FS.FileExists(UnitFilename) then
|
|
|
|
|
|
+ if (ExpUnitFilename='') or not FS.FileExists(ExpUnitFilename) then
|
|
begin
|
|
begin
|
|
if isPCU then
|
|
if isPCU then
|
|
- Log.LogMsg(nSourceFileNotFound,[QuoteStr(UnitFilename)])
|
|
|
|
|
|
+ Log.LogMsg(nUnitFileNotFound,[QuoteStr(UnitFilename)])
|
|
else
|
|
else
|
|
- Log.LogMsg(nUnitFileNotFound,[QuoteStr(UnitFilename)]);
|
|
|
|
|
|
+ Log.LogMsg(nSourceFileNotFound,[QuoteStr(UnitFilename)]);
|
|
Terminate(ExitCodeFileNotFound);
|
|
Terminate(ExitCodeFileNotFound);
|
|
end;
|
|
end;
|
|
|
|
|
|
- UnitFilename:=ExpandFileName(UnitFilename);
|
|
|
|
- if FS.DirectoryExists(UnitFilename) then
|
|
|
|
|
|
+ if FS.DirectoryExists(ExpUnitFilename) then
|
|
begin
|
|
begin
|
|
Log.LogMsg(nFileIsFolder,[QuoteStr(UnitFilename)]);
|
|
Log.LogMsg(nFileIsFolder,[QuoteStr(UnitFilename)]);
|
|
Terminate(ExitCodeFileNotFound);
|
|
Terminate(ExitCodeFileNotFound);
|
|
end;
|
|
end;
|
|
|
|
|
|
- aFile:=CreateCompilerFile(UnitFilename);
|
|
|
|
|
|
+ aFile:=CreateCompilerFile(ExpUnitFilename);
|
|
if UseUnitName<>'' then
|
|
if UseUnitName<>'' then
|
|
begin
|
|
begin
|
|
{$IFDEF VerboseSetPasUnitName}
|
|
{$IFDEF VerboseSetPasUnitName}
|
|
writeln('TPas2jsCompiler.LoadPasFile File="',aFile.PasFilename,'" UseUnit="',UseUnitName,'"');
|
|
writeln('TPas2jsCompiler.LoadPasFile File="',aFile.PasFilename,'" UseUnit="',UseUnitName,'"');
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
if CompareText(ExtractFilenameOnly(UnitFilename),UseUnitName)=0 then
|
|
if CompareText(ExtractFilenameOnly(UnitFilename),UseUnitName)=0 then
|
|
- aFile.PasUnitName:=UseUnitName
|
|
|
|
|
|
+ aFile.PasUnitName:=UseUnitName // e.g. when searching Unit1, found UNIT1.pas, use Unit1
|
|
else
|
|
else
|
|
aFile.PasUnitName:=ExtractFilenameOnly(UnitFilename);
|
|
aFile.PasUnitName:=ExtractFilenameOnly(UnitFilename);
|
|
end;
|
|
end;
|
|
@@ -4410,6 +4417,7 @@ begin
|
|
if Assigned(aFile.PCUSupport) then
|
|
if Assigned(aFile.PCUSupport) then
|
|
begin
|
|
begin
|
|
aFile.FileResolver.BaseDirectory:=ExtractFilePath(UnitFilename);
|
|
aFile.FileResolver.BaseDirectory:=ExtractFilePath(UnitFilename);
|
|
|
|
+ writeln('AAA1 TPas2jsCompiler.LoadPasFile ',GetObjName(aFile.PCUSupport));
|
|
aFile.PCUSupport.CreatePCUReader;
|
|
aFile.PCUSupport.CreatePCUReader;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -4509,7 +4517,8 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-function TPas2jsCompiler.GetUnitInfo(const UseUnitName,InFileName : String; PCUSupport : TPCUSupport) : TFindUnitInfo;
|
|
|
|
|
|
+function TPas2jsCompiler.GetUnitInfo(const UseUnitName, InFileName : String;
|
|
|
|
+ PCUSupport : TPCUSupport) : TFindUnitInfo;
|
|
|
|
|
|
var
|
|
var
|
|
FoundPasFilename, FoundPasUnitName: string;
|
|
FoundPasFilename, FoundPasUnitName: string;
|
|
@@ -4603,19 +4612,22 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
- if Assigned(PCUSupport) and (FoundPCUFilename='') then
|
|
|
|
|
|
+ if (FoundPasFilename='') and Assigned(PCUSupport) and (FoundPCUFilename='') then
|
|
begin
|
|
begin
|
|
|
|
+ // no pas file -> search pcu
|
|
FoundPCUFilename:=PCUSupport.FindPCU(UseUnitName);
|
|
FoundPCUFilename:=PCUSupport.FindPCU(UseUnitName);
|
|
- FoundPCUUnitName:=UseUnitName;
|
|
|
|
|
|
+ if FoundPCUFilename<>'' then
|
|
|
|
+ FoundPCUUnitName:=UseUnitName;
|
|
end;
|
|
end;
|
|
|
|
+
|
|
if (FoundPasFilename='') and (FoundPCUFilename<>'') then
|
|
if (FoundPasFilename='') and (FoundPCUFilename<>'') then
|
|
begin
|
|
begin
|
|
Result.FileName:=FoundPCUFilename;
|
|
Result.FileName:=FoundPCUFilename;
|
|
Result.UnitName:=FoundPCUUnitName;
|
|
Result.UnitName:=FoundPCUUnitName;
|
|
Result.isPCU:=True;
|
|
Result.isPCU:=True;
|
|
Result.isForeign:=False;
|
|
Result.isForeign:=False;
|
|
- end;
|
|
|
|
- if (FoundPasFileName<>'') then
|
|
|
|
|
|
+ end
|
|
|
|
+ else if (FoundPasFileName<>'') then
|
|
begin
|
|
begin
|
|
Result.FileName:=FoundPasFilename;
|
|
Result.FileName:=FoundPasFilename;
|
|
Result.UnitName:=FoundPasUnitName;
|
|
Result.UnitName:=FoundPasUnitName;
|
|
@@ -4624,25 +4636,30 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-
|
|
|
|
-function TPas2JSCompiler.LoadUsedUnit(Info : TLoadInfo; Context : TPas2jsCompilerFile): TPas2jsCompilerFile;
|
|
|
|
|
|
+function TPas2JSCompiler.LoadUsedUnit(Info : TLoadUnitInfo;
|
|
|
|
+ Context : TPas2jsCompilerFile): TPas2jsCompilerFile;
|
|
|
|
|
|
function FindCycle(aFile, SearchFor: TPas2jsCompilerFile;
|
|
function FindCycle(aFile, SearchFor: TPas2jsCompilerFile;
|
|
var Cycle: TFPList): boolean;
|
|
var Cycle: TFPList): boolean;
|
|
|
|
+ // Note: when traversing, add every search file to Cycle, to avoid running in circles.
|
|
|
|
+ // When a cycle is detected, clear the Cycle list and build the cycle path
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
aParent: TPas2jsCompilerFile;
|
|
aParent: TPas2jsCompilerFile;
|
|
begin
|
|
begin
|
|
|
|
+ Cycle.Add(aFile);
|
|
for i:=0 to aFile.UsedByCount[ubMainSection]-1 do begin
|
|
for i:=0 to aFile.UsedByCount[ubMainSection]-1 do begin
|
|
aParent:=aFile.UsedBy[ubMainSection,i];
|
|
aParent:=aFile.UsedBy[ubMainSection,i];
|
|
if aParent=SearchFor then
|
|
if aParent=SearchFor then
|
|
begin
|
|
begin
|
|
// unit cycle found
|
|
// unit cycle found
|
|
- Cycle:=TFPList.Create;
|
|
|
|
|
|
+ Cycle.Clear;
|
|
Cycle.Add(aParent);
|
|
Cycle.Add(aParent);
|
|
Cycle.Add(aFile);
|
|
Cycle.Add(aFile);
|
|
exit(true);
|
|
exit(true);
|
|
end;
|
|
end;
|
|
|
|
+ if Cycle.IndexOf(aParent)>=0 then
|
|
|
|
+ continue;// already searched
|
|
if FindCycle(aParent,SearchFor,Cycle) then
|
|
if FindCycle(aParent,SearchFor,Cycle) then
|
|
begin
|
|
begin
|
|
Cycle.Add(aFile);
|
|
Cycle.Add(aFile);
|
|
@@ -4668,7 +4685,7 @@ var
|
|
|
|
|
|
aFile.FUsedBy[ubMainSection].Add(Context);
|
|
aFile.FUsedBy[ubMainSection].Add(Context);
|
|
|
|
|
|
- Cycle:=nil;
|
|
|
|
|
|
+ Cycle:=TFPList.Create;
|
|
try
|
|
try
|
|
if FindCycle(aFile,aFile,Cycle) then
|
|
if FindCycle(aFile,aFile,Cycle) then
|
|
begin
|
|
begin
|
|
@@ -4694,7 +4711,7 @@ var
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
|
|
|
|
- aFile:=FindUnitWithFile(Info.UseFilename);
|
|
|
|
|
|
+ aFile:=FindUnitWithPasFilename(Info.UseFilename);
|
|
|
|
|
|
if aFile<>nil then
|
|
if aFile<>nil then
|
|
begin
|
|
begin
|
|
@@ -4763,7 +4780,7 @@ begin
|
|
else
|
|
else
|
|
RaiseInternalError(20170922143511,'UseUnitname='+Info.UseUnitname+' Found='+OtherFile.PasUnitName);
|
|
RaiseInternalError(20170922143511,'UseUnitname='+Info.UseUnitname+' Found='+OtherFile.PasUnitName);
|
|
end;
|
|
end;
|
|
- OtherFile:=FindUnitWithFile(Info.UseFilename);
|
|
|
|
|
|
+ OtherFile:=FindUnitWithPasFilename(Info.UseFilename);
|
|
if aFile<>OtherFile then
|
|
if aFile<>OtherFile then
|
|
begin
|
|
begin
|
|
if OtherFile=nil then
|
|
if OtherFile=nil then
|