|
@@ -230,7 +230,6 @@ type
|
|
FShowDebug: boolean;
|
|
FShowDebug: boolean;
|
|
FUseAnalyzer: TPasAnalyzer;
|
|
FUseAnalyzer: TPasAnalyzer;
|
|
FUsedBy: array[TUsedBySection] of TFPList; // list of TPas2jsCompilerFile
|
|
FUsedBy: array[TUsedBySection] of TFPList; // list of TPas2jsCompilerFile
|
|
- procedure FPasResolverContinueParsing(Sender: TObject);
|
|
|
|
function GetUsedBy(Section: TUsedBySection; Index: integer): TPas2jsCompilerFile;
|
|
function GetUsedBy(Section: TUsedBySection; Index: integer): TPas2jsCompilerFile;
|
|
function GetUsedByCount(Section: TUsedBySection): integer;
|
|
function GetUsedByCount(Section: TUsedBySection): integer;
|
|
function OnConverterIsElementUsed(Sender: TObject; El: TPasElement): boolean;
|
|
function OnConverterIsElementUsed(Sender: TObject; El: TPasElement): boolean;
|
|
@@ -260,6 +259,7 @@ type
|
|
procedure OnPasTreeCheckSrcName(const Element: TPasElement);
|
|
procedure OnPasTreeCheckSrcName(const Element: TPasElement);
|
|
procedure OpenFile(aFilename: string);// beware: this changes FileResolver.BaseDirectory
|
|
procedure OpenFile(aFilename: string);// beware: this changes FileResolver.BaseDirectory
|
|
procedure ParsePascal;
|
|
procedure ParsePascal;
|
|
|
|
+ procedure ParsePascalContinue;
|
|
procedure CreateJS;
|
|
procedure CreateJS;
|
|
function GetPasFirstSection: TPasSection;
|
|
function GetPasFirstSection: TPasSection;
|
|
function GetPasImplSection: TPasSection;
|
|
function GetPasImplSection: TPasSection;
|
|
@@ -309,6 +309,7 @@ type
|
|
FFileCache: TPas2jsFilesCache;
|
|
FFileCache: TPas2jsFilesCache;
|
|
FFileCacheAutoFree: boolean;
|
|
FFileCacheAutoFree: boolean;
|
|
FFiles: TAVLTree; // tree of TPas2jsCompilerFile sorted for PasFilename
|
|
FFiles: TAVLTree; // tree of TPas2jsCompilerFile sorted for PasFilename
|
|
|
|
+ FParsingModules: TFPList; // list of TPas2jsCompilerFile ordered by uses sections
|
|
FHasShownLogo: boolean;
|
|
FHasShownLogo: boolean;
|
|
FLog: TPas2jsLogger;
|
|
FLog: TPas2jsLogger;
|
|
FMainFile: TPas2jsCompilerFile;
|
|
FMainFile: TPas2jsCompilerFile;
|
|
@@ -340,6 +341,8 @@ type
|
|
): boolean;
|
|
): boolean;
|
|
procedure AddDefinesForTargetPlatform;
|
|
procedure AddDefinesForTargetPlatform;
|
|
procedure AddDefinesForTargetProcessor;
|
|
procedure AddDefinesForTargetProcessor;
|
|
|
|
+ procedure AddParsingModule(aFile: TPas2jsCompilerFile);
|
|
|
|
+ procedure RemoveParsingModule(aFile: TPas2jsCompilerFile);
|
|
procedure CfgSyntaxError(const Msg: string);
|
|
procedure CfgSyntaxError(const Msg: string);
|
|
procedure ConditionEvalLog(Sender: TCondDirectiveEvaluator;
|
|
procedure ConditionEvalLog(Sender: TCondDirectiveEvaluator;
|
|
Args: array of const);
|
|
Args: array of const);
|
|
@@ -373,6 +376,7 @@ type
|
|
// DoWriteJSFile: return false to use the default write function.
|
|
// DoWriteJSFile: return false to use the default write function.
|
|
function DoWriteJSFile(const DestFilename: String; aWriter: TPas2JSMapper): Boolean; virtual;
|
|
function DoWriteJSFile(const DestFilename: String; aWriter: TPas2JSMapper): Boolean; virtual;
|
|
procedure Compile(StartTime: TDateTime);
|
|
procedure Compile(StartTime: TDateTime);
|
|
|
|
+ procedure ParseQueue;
|
|
function MarkNeedBuilding(aFile: TPas2jsCompilerFile; Checked: TAVLTree;
|
|
function MarkNeedBuilding(aFile: TPas2jsCompilerFile; Checked: TAVLTree;
|
|
var SrcFileCount: integer): boolean;
|
|
var SrcFileCount: integer): boolean;
|
|
procedure OptimizeProgram(aFile: TPas2jsCompilerFile); virtual;
|
|
procedure OptimizeProgram(aFile: TPas2jsCompilerFile); virtual;
|
|
@@ -671,7 +675,6 @@ begin
|
|
FPasFilename:=aPasFilename;
|
|
FPasFilename:=aPasFilename;
|
|
FPasResolver:=TPas2jsCompilerResolver.Create;
|
|
FPasResolver:=TPas2jsCompilerResolver.Create;
|
|
FPasResolver.Owner:=Self;
|
|
FPasResolver.Owner:=Self;
|
|
- FPasResolver.OnContinueParsing:=@FPasResolverContinueParsing;
|
|
|
|
FPasResolver.OnFindModule:=@OnPasTreeFindModule;
|
|
FPasResolver.OnFindModule:=@OnPasTreeFindModule;
|
|
FPasResolver.OnCheckSrcName:=@OnPasTreeCheckSrcName;
|
|
FPasResolver.OnCheckSrcName:=@OnPasTreeCheckSrcName;
|
|
FPasResolver.OnLog:=@OnPasResolverLog;
|
|
FPasResolver.OnLog:=@OnPasResolverLog;
|
|
@@ -808,19 +811,6 @@ begin
|
|
Result:=TPas2jsCompilerFile(FUsedBy[Section][Index]);
|
|
Result:=TPas2jsCompilerFile(FUsedBy[Section][Index]);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPas2jsCompilerFile.FPasResolverContinueParsing(Sender: TObject);
|
|
|
|
-begin
|
|
|
|
- try
|
|
|
|
- Parser.ParseContinueImplementation;
|
|
|
|
- except
|
|
|
|
- on E: ECompilerTerminate do
|
|
|
|
- raise;
|
|
|
|
- on E: Exception do
|
|
|
|
- HandleException(E);
|
|
|
|
- end;
|
|
|
|
- ParserFinished;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
function TPas2jsCompilerFile.GetUsedByCount(Section: TUsedBySection): integer;
|
|
function TPas2jsCompilerFile.GetUsedByCount(Section: TUsedBySection): integer;
|
|
begin
|
|
begin
|
|
Result:=FUsedBy[Section].Count;
|
|
Result:=FUsedBy[Section].Count;
|
|
@@ -997,6 +987,8 @@ end;
|
|
procedure TPas2jsCompilerFile.ParserFinished;
|
|
procedure TPas2jsCompilerFile.ParserFinished;
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
|
|
+ Compiler.RemoveParsingModule(Self);
|
|
|
|
+
|
|
if ShowDebug then
|
|
if ShowDebug then
|
|
begin
|
|
begin
|
|
Log.LogPlain('Pas-Module:');
|
|
Log.LogPlain('Pas-Module:');
|
|
@@ -1031,20 +1023,16 @@ begin
|
|
if ShowDebug then
|
|
if ShowDebug then
|
|
Log.LogPlain(['Debug: Parsing Pascal "',PasFilename,'"...']);
|
|
Log.LogPlain(['Debug: Parsing Pascal "',PasFilename,'"...']);
|
|
if FPasModule<>nil then
|
|
if FPasModule<>nil then
|
|
- raise ECompilerTerminate.Create('TPas2jsCompilerFile.ParsePascal '+PasFilename);
|
|
|
|
|
|
+ Compiler.RaiseInternalError(20180305190321,PasFilename);
|
|
try
|
|
try
|
|
- // parse Pascal
|
|
|
|
|
|
+ Compiler.AddParsingModule(Self);
|
|
PascalResolver.InterfaceOnly:=IsForeign;
|
|
PascalResolver.InterfaceOnly:=IsForeign;
|
|
if IsMainFile then
|
|
if IsMainFile then
|
|
Parser.ParseMain(FPasModule)
|
|
Parser.ParseMain(FPasModule)
|
|
else
|
|
else
|
|
Parser.ParseSubModule(FPasModule);
|
|
Parser.ParseSubModule(FPasModule);
|
|
- if PasModule.CustomData=nil then
|
|
|
|
- PasModule.CustomData:=Self;
|
|
|
|
- if (FPasModule.ImplementationSection<>nil)
|
|
|
|
- and (FPasModule.ImplementationSection.PendingUsedIntf<>nil) then
|
|
|
|
- exit;
|
|
|
|
- ParserFinished;
|
|
|
|
|
|
+ if Parser.CurModule=nil then
|
|
|
|
+ ParserFinished;
|
|
except
|
|
except
|
|
on E: ECompilerTerminate do
|
|
on E: ECompilerTerminate do
|
|
raise;
|
|
raise;
|
|
@@ -1055,6 +1043,24 @@ begin
|
|
PasModule.CustomData:=Self;
|
|
PasModule.CustomData:=Self;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPas2jsCompilerFile.ParsePascalContinue;
|
|
|
|
+begin
|
|
|
|
+ if ShowDebug then
|
|
|
|
+ Log.LogPlain(['Debug: Continue parsing Pascal "',PasFilename,'"...']);
|
|
|
|
+ if FPasModule=nil then
|
|
|
|
+ Compiler.RaiseInternalError(20180305190338,PasFilename);
|
|
|
|
+ try
|
|
|
|
+ Parser.ParseContinue;
|
|
|
|
+ if Parser.CurModule=nil then
|
|
|
|
+ ParserFinished;
|
|
|
|
+ except
|
|
|
|
+ on E: ECompilerTerminate do
|
|
|
|
+ raise;
|
|
|
|
+ on E: Exception do
|
|
|
|
+ HandleException(E);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TPas2jsCompilerFile.CreateJS;
|
|
procedure TPas2jsCompilerFile.CreateJS;
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
@@ -1404,7 +1410,7 @@ begin
|
|
|
|
|
|
// parse Pascal
|
|
// parse Pascal
|
|
aFile.ParsePascal;
|
|
aFile.ParsePascal;
|
|
- // beware: the parser may not yet have finished due to unit cycles
|
|
|
|
|
|
+ // beware: the parser may not yet have finished
|
|
end;
|
|
end;
|
|
|
|
|
|
Result:=aFile.PasModule;
|
|
Result:=aFile.PasModule;
|
|
@@ -1451,6 +1457,18 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPas2jsCompiler.AddParsingModule(aFile: TPas2jsCompilerFile);
|
|
|
|
+begin
|
|
|
|
+ if FParsingModules.IndexOf(aFile)>=0 then
|
|
|
|
+ exit;
|
|
|
|
+ FParsingModules.Add(aFile);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPas2jsCompiler.RemoveParsingModule(aFile: TPas2jsCompilerFile);
|
|
|
|
+begin
|
|
|
|
+ FParsingModules.Remove(aFile);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TPas2jsCompiler.ConditionEvalLog(Sender: TCondDirectiveEvaluator;
|
|
procedure TPas2jsCompiler.ConditionEvalLog(Sender: TCondDirectiveEvaluator;
|
|
Args: array of const);
|
|
Args: array of const);
|
|
begin
|
|
begin
|
|
@@ -1510,6 +1528,7 @@ begin
|
|
if MainFile=nil then exit;
|
|
if MainFile=nil then exit;
|
|
// parse and load Pascal files recursively
|
|
// parse and load Pascal files recursively
|
|
FMainFile.ParsePascal;
|
|
FMainFile.ParsePascal;
|
|
|
|
+ ParseQueue;
|
|
|
|
|
|
// whole program optimization
|
|
// whole program optimization
|
|
if MainFile.PasModule is TPasProgram then
|
|
if MainFile.PasModule is TPasProgram then
|
|
@@ -1547,6 +1566,50 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPas2jsCompiler.ParseQueue;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+ aFile: TPas2jsCompilerFile;
|
|
|
|
+ Found: Boolean;
|
|
|
|
+ Section: TPasSection;
|
|
|
|
+begin
|
|
|
|
+ // parse til exception or all modules have finished
|
|
|
|
+ repeat
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPas2jsCompiler.ParseQueue FParsingModules.Count=',FParsingModules.Count);
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ Found:=false;
|
|
|
|
+ for i:=0 to FParsingModules.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ aFile:=TPas2jsCompilerFile(FParsingModules[i]);
|
|
|
|
+ if not aFile.Parser.CanParseContinue(Section) then
|
|
|
|
+ continue;
|
|
|
|
+ Found:=true;
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPas2jsCompiler.ParseQueue aFile=',aFile.PasFilename,' Section=',GetObjName(Section));
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ aFile.ParsePascalContinue;
|
|
|
|
+ break;
|
|
|
|
+ end;
|
|
|
|
+ until not Found;
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPas2jsCompiler.ParseQueue END FParsingModules.Count=',FParsingModules.Count);
|
|
|
|
+ {$ENDIF}
|
|
|
|
+
|
|
|
|
+ // check consistency
|
|
|
|
+ for i:=0 to FParsingModules.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ aFile:=TPas2jsCompilerFile(FParsingModules[i]);
|
|
|
|
+ if aFile.Parser.CurModule<>nil then
|
|
|
|
+ begin
|
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
|
+ writeln('TPas2jsCompiler.ParseQueue aFile=',aFile.PasFilename,' was not finished');
|
|
|
|
+ {$ENDIF}
|
|
|
|
+ RaiseInternalError(20180305185342,aFile.PasFilename);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPas2jsCompiler.MarkNeedBuilding(aFile: TPas2jsCompilerFile;
|
|
function TPas2jsCompiler.MarkNeedBuilding(aFile: TPas2jsCompilerFile;
|
|
Checked: TAVLTree; var SrcFileCount: integer): boolean;
|
|
Checked: TAVLTree; var SrcFileCount: integer): boolean;
|
|
|
|
|
|
@@ -3014,6 +3077,7 @@ begin
|
|
//FConditionEval.OnEvalFunction:=@ConditionEvalFunction;
|
|
//FConditionEval.OnEvalFunction:=@ConditionEvalFunction;
|
|
|
|
|
|
FFiles:=TAVLTree.Create(@CompareCompilerFilesPasFile);
|
|
FFiles:=TAVLTree.Create(@CompareCompilerFilesPasFile);
|
|
|
|
+ FParsingModules:=TFPList.Create;
|
|
FUnits:=TAVLTree.Create(@CompareCompilerFilesPasUnitname);
|
|
FUnits:=TAVLTree.Create(@CompareCompilerFilesPasUnitname);
|
|
|
|
|
|
InitParamMacros;
|
|
InitParamMacros;
|
|
@@ -3026,6 +3090,7 @@ begin
|
|
|
|
|
|
FMainFile:=nil;
|
|
FMainFile:=nil;
|
|
FreeAndNil(FUnits);
|
|
FreeAndNil(FUnits);
|
|
|
|
+ FreeAndNil(FParsingModules);
|
|
FFiles.FreeAndClear;
|
|
FFiles.FreeAndClear;
|
|
FreeAndNil(FFiles);
|
|
FreeAndNil(FFiles);
|
|
|
|
|
|
@@ -3116,6 +3181,7 @@ begin
|
|
|
|
|
|
FMainFile:=nil;
|
|
FMainFile:=nil;
|
|
FUnits.Clear;
|
|
FUnits.Clear;
|
|
|
|
+ FParsingModules.Clear;
|
|
FFiles.FreeAndClear;
|
|
FFiles.FreeAndClear;
|
|
|
|
|
|
FCompilerExe:='';
|
|
FCompilerExe:='';
|